diff --git a/scripts/object/tangible/wearables/ring/aakuan_ring.py b/scripts/object/tangible/wearables/ring/aakuan_ring.py index 2540ccc0..a7a9a10b 100644 --- a/scripts/object/tangible/wearables/ring/aakuan_ring.py +++ b/scripts/object/tangible/wearables/ring/aakuan_ring.py @@ -2,4 +2,5 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/item_bounty_hunter_ring_01_02.py b/scripts/object/tangible/wearables/ring/item_bounty_hunter_ring_01_02.py index e8042f0b..110a5ec1 100644 --- a/scripts/object/tangible/wearables/ring/item_bounty_hunter_ring_01_02.py +++ b/scripts/object/tangible/wearables/ring/item_bounty_hunter_ring_01_02.py @@ -1,6 +1,7 @@ import sys def setup(core, object): + object.setAttachment('objType', 'ring') object.setStfFilename('static_item_n') object.setStfName('item_bounty_hunter_ring_01_02') object.setDetailFilename('static_item_d') diff --git a/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_01_02.py b/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_01_02.py index 1219d4db..a22d7967 100644 --- a/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_01_02.py +++ b/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_01_02.py @@ -1,6 +1,7 @@ import sys def setup(core, object): + object.setAttachment('objType', 'ring') object.setStfFilename('static_item_n') object.setStfName('item_force_sensitive_ring_01_02') object.setDetailFilename('static_item_d') diff --git a/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_02_01.py b/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_02_01.py index 7fc2c243..01a05612 100644 --- a/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_02_01.py +++ b/scripts/object/tangible/wearables/ring/item_force_sensitive_ring_02_01.py @@ -1,6 +1,7 @@ import sys def setup(core, object): + object.setAttachment('objType', 'ring') object.setStfFilename('static_item_n') object.setStfName('item_force_sensitive_ring_02_01') object.setDetailFilename('static_item_d') diff --git a/scripts/object/tangible/wearables/ring/ring_base.py b/scripts/object/tangible/wearables/ring/ring_base.py index ccad8904..21d2e709 100644 --- a/scripts/object/tangible/wearables/ring/ring_base.py +++ b/scripts/object/tangible/wearables/ring/ring_base.py @@ -1,4 +1,6 @@ import sys def setup(core, object): + object.setAttachment('objType', 'ring') + object.setAttachment('radial_filename', 'ring/unity') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/ring_gcw_imperial.py b/scripts/object/tangible/wearables/ring/ring_gcw_imperial.py index 2540ccc0..a7a9a10b 100644 --- a/scripts/object/tangible/wearables/ring/ring_gcw_imperial.py +++ b/scripts/object/tangible/wearables/ring/ring_gcw_imperial.py @@ -2,4 +2,5 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/ring_gcw_rebel.py b/scripts/object/tangible/wearables/ring/ring_gcw_rebel.py index 2540ccc0..a7a9a10b 100644 --- a/scripts/object/tangible/wearables/ring/ring_gcw_rebel.py +++ b/scripts/object/tangible/wearables/ring/ring_gcw_rebel.py @@ -2,4 +2,5 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/ring_mark_hero.py b/scripts/object/tangible/wearables/ring/ring_mark_hero.py index 2540ccc0..a7a9a10b 100644 --- a/scripts/object/tangible/wearables/ring/ring_mark_hero.py +++ b/scripts/object/tangible/wearables/ring/ring_mark_hero.py @@ -2,4 +2,5 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/ring_nightsister.py b/scripts/object/tangible/wearables/ring/ring_nightsister.py index 2540ccc0..a7a9a10b 100644 --- a/scripts/object/tangible/wearables/ring/ring_nightsister.py +++ b/scripts/object/tangible/wearables/ring/ring_nightsister.py @@ -2,4 +2,5 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/ring_s01.py b/scripts/object/tangible/wearables/ring/ring_s01.py index 83da2342..f311265b 100644 --- a/scripts/object/tangible/wearables/ring/ring_s01.py +++ b/scripts/object/tangible/wearables/ring/ring_s01.py @@ -2,6 +2,7 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return def equip(core, actor, object): diff --git a/scripts/object/tangible/wearables/ring/ring_s02.py b/scripts/object/tangible/wearables/ring/ring_s02.py index f594fe2b..467d8fb3 100644 --- a/scripts/object/tangible/wearables/ring/ring_s02.py +++ b/scripts/object/tangible/wearables/ring/ring_s02.py @@ -2,6 +2,7 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return def equip(core, actor, object): diff --git a/scripts/object/tangible/wearables/ring/ring_s03.py b/scripts/object/tangible/wearables/ring/ring_s03.py index c4aa2f2f..52d2d1d2 100644 --- a/scripts/object/tangible/wearables/ring/ring_s03.py +++ b/scripts/object/tangible/wearables/ring/ring_s03.py @@ -2,6 +2,7 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return def equip(core, actor, object): diff --git a/scripts/object/tangible/wearables/ring/ring_s03_quest.py b/scripts/object/tangible/wearables/ring/ring_s03_quest.py index 2540ccc0..a7a9a10b 100644 --- a/scripts/object/tangible/wearables/ring/ring_s03_quest.py +++ b/scripts/object/tangible/wearables/ring/ring_s03_quest.py @@ -2,4 +2,5 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/ring/ring_s04.py b/scripts/object/tangible/wearables/ring/ring_s04.py index 8eee5461..c00caed9 100644 --- a/scripts/object/tangible/wearables/ring/ring_s04.py +++ b/scripts/object/tangible/wearables/ring/ring_s04.py @@ -2,6 +2,7 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'ring/unity') + object.setAttachment('objType', 'ring') return def equip(core, actor, object): diff --git a/scripts/radial/ring/unity.py b/scripts/radial/ring/unity.py index 18352da7..f57f3034 100644 --- a/scripts/radial/ring/unity.py +++ b/scripts/radial/ring/unity.py @@ -2,6 +2,7 @@ from resources.common import RadialOptions from services.sui.SUIWindow import Trigger from java.util import Vector from main import NGECore +from engine.resources.objects import SWGObject import sys def createRadial(core, owner, target, radials): @@ -10,10 +11,11 @@ def createRadial(core, owner, target, radials): if ghost is None: return - if ghost.getSpouseName() is None or "": + if ghost.getSpouseName() is None or ghost.getSpouseName() is "": targetPlayer = core.objectService.getObject(owner.getTargetId()) if targetPlayer is not None and targetPlayer.getSlottedObject('ghost') is not None: radials.add(RadialOptions(0, 69, 1, '@unity:mnu_propose')) + return else: radials.add(RadialOptions(0, 70, 1, '@unity:mnu_divorce')) return @@ -21,32 +23,43 @@ def createRadial(core, owner, target, radials): def handleSelection(core, owner, target, option): if option == 69 and target: - tGhost = core.objectService.getObject(owner.getTargetId()).getSlottedObject('ghost') + player = core.objectService.getObject(owner.getTargetId()) + tGhost = player.getSlottedObject('ghost') suiSvc = core.suiService - if tGhost.getSpouseName() is not None: - owner.sendSystemMessage('@unity:target_married', 0) - return - if tGhost.getPosition().getDistance2D(owner.getWorldPosition()) < 50: owner.sendSystemMessage('@unity:out_of_range', 0) return + if tGhost.getSpouseName() is not None: + owner.sendSystemMessage('@unity:target_married', 0) + return + + if player.getAttachment("proposer") is not None: + owner.sendSystemMessage('@unity:target_proposed', 0) + return + else: + + owner.sendSystemMessage('You propose unity to ' + player.getCustomName() + '.', 0) targetWindow = suiSvc.createMessageBox(3, '@unity:accept_title', owner.getCustomName() + ' is proposing unity to you. Do you wish to accept?', tGhost.getContainer(), owner, 15) returnList = Vector() - targetWindow.addHandler(0, '', Trigger.TRIGGER_OK, returnList, handleSUI) - targetWindow.addHandler(1, '', Trigger.TRIGGER_CANCEL, returnList, handleSUI) - tGhost.getContainer().setAttachment("proposer", owner.getCustomName()) + targetWindow.addHandler(0, '', Trigger.TRIGGER_OK, returnList, handlePropose) + targetWindow.addHandler(1, '', Trigger.TRIGGER_CANCEL, returnList, handlePropose) + player.setAttachment("proposer", owner.getCustomName()) suiSvc.openSUIWindow(targetWindow) - target.setAttachment("unity", target) + target.setAttachment("unity", True) + core.equipmentService.equip(owner, target) + + core.commandService.callCommand(owner, 'kneel', None, '') return return if option == 70: married = owner.getSlottedObject('ghost').getSpouseName() + myGhost = owner.getSlottedObject('ghost') otherPlayer = NGECore.getInstance().objectService.getObjectByCustomName(married) if otherPlayer is None: @@ -56,42 +69,38 @@ def handleSelection(core, owner, target, option): if ghost is None: return - owner.sendSystemMessage('Your union with ' + married + 'has ended.', 0) - - owner.setSpouseName("") - otherPlayer.setSpouseName("") + owner.sendSystemMessage('Your union with ' + married + ' has ended.', 0) + otherPlayer.sendSystemMessage('Your union with ' + owner.getCustomName() + ' has ended.', 0) + myGhost.setSpouseName(None) + ghost.setSpouseName(None) target.setAttachment("unity", None) + #TODO: Divorce offline players return return -def handleSUI(owner, window, eventType, returnList): +def handlePropose(owner, window, eventType, returnList): + core = NGECore.getInstance() + + if owner is None: + return + if eventType == 0: - ghost = owner.getSlottedObject('ghost') - if ghost is None: - return - - print (owner.getAttachment("proposer")) - core = NGECore.getInstance() proposer = core.objectService.getObjectByCustomName(owner.getAttachment("proposer")) if proposer is None: return - print ('not none') - pGhost = proposer.getSlottedObject('ghost') - if pGhost is None: - return - - ghost.setSpouseName(proposer.getCustomName()) - pGhost.setSpouseName(owner.getCustomName()) - - owner.sendSystemMessage('Your union with ' + proposer.getCustomName() + ' is complete.', 0) - proposer.sendSystemMessage('Your union with ' + owner.getCustomName() + ' is complete.', 0) - owner.setAttachment("proposer", None) - + + core.playerService.performUnity(owner, proposer) return + if eventType == 1: proposer = core.objectService.getObjectByCustomName(owner.getAttachment("proposer")) proposer.sendSystemMessage('@unity:declined', 0) + for SWGObject in proposer.getEquipmentList(): + if SWGObject.getAttachment("unity") is not None: + SWGObject.setAttachment("unity", None) + break + owner.setAttachment("proposer", None) return return \ No newline at end of file diff --git a/src/services/EquipmentService.java b/src/services/EquipmentService.java index 9f8ce9a5..ca9af8a5 100644 --- a/src/services/EquipmentService.java +++ b/src/services/EquipmentService.java @@ -35,6 +35,7 @@ import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; public class EquipmentService implements INetworkDispatch { @@ -214,14 +215,16 @@ public class EquipmentService implements INetworkDispatch { } } - if(!actor.getEquipmentList().contains(item)) + if(!actor.getEquipmentList().contains(item)) { + TangibleObject inventory = (TangibleObject) actor.getSlottedObject("inventory"); + inventory.transferTo(actor, actor, item); actor.addObjectToEquipList(item); - -} + } + } public void unequip(CreatureObject actor, SWGObject item) { - + String template = ((item.getAttachment("customServerTemplate") == null) ? item.getTemplate() : (item.getTemplate().split("shared_")[0] + "shared_" + ((String) item.getAttachment("customServerTemplate")) + ".iff")); String serverTemplate = template.replace(".iff", ""); PyObject func = core.scriptService.getMethod("scripts/" + serverTemplate.split("shared_" , 2)[0].replace("shared_", ""), serverTemplate.split("shared_" , 2)[1], "unequip"); @@ -230,15 +233,15 @@ public class EquipmentService implements INetworkDispatch { if (item.getStringAttribute("protection_level") != null) calculateForceProtection(actor, item, false); - + if(item.getStringAttribute("cat_wpn_damage.wpn_category") != null) if (actor.getSlotNameForObject(item).contentEquals("hold_r") == true) weaponCriticalToDisplay(actor, item, false); - + Map attributes = new TreeMap(item.getAttributes()); - + for(Entry e : attributes.entrySet()) { - + if(e.getKey().startsWith("cat_skill_mod_bonus.@stat_n:")) { core.skillModService.deductSkillMod(actor, e.getKey().replace("cat_skill_mod_bonus.@stat_n:", ""), Integer.parseInt((String) e.getValue())); } @@ -248,17 +251,16 @@ public class EquipmentService implements INetworkDispatch { if(e.getKey().startsWith("cat_attrib_mod_bonus.attr_action")) { actor.setMaxAction(actor.getMaxAction() - Integer.parseInt((String) e.getValue())); } - + } - + if(item.getAttachment("unity") != null) { actor.sendSystemMessage("@unity:cannot_remove_ring", (byte) 0); return; } - - if(actor.getEquipmentList().contains(item)) - actor.removeObjectFromEquipList(item); + if (actor.getEquipmentList().contains(item)) + actor.removeObjectFromEquipList(item); } } diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index 04ff8f72..c1d1095d 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; @@ -51,7 +52,6 @@ import protocol.swg.SetWaypointColor; import protocol.swg.objectControllerObjects.ChangeRoleIconChoice; import protocol.swg.objectControllerObjects.ShowFlyText; import protocol.swg.objectControllerObjects.ShowLootBox; -import resources.common.Console; import resources.common.FileUtilities; import resources.common.ObjControllerOpcodes; import resources.common.Opcodes; @@ -65,6 +65,7 @@ import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerMessageBuilder; import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; import resources.objects.waypoint.WaypointObject; import services.sui.SUIService.ListBoxType; import services.sui.SUIWindow; @@ -76,6 +77,7 @@ import engine.clientdata.visitors.CrcStringTableVisitor; import engine.clientdata.visitors.DatatableVisitor; import engine.clients.Client; import engine.resources.common.CRC; +import engine.resources.container.Traverser; import engine.resources.objects.DraftSchematic; import engine.resources.objects.SWGObject; import engine.resources.scene.Point3D; @@ -806,6 +808,128 @@ public class PlayerService implements INetworkDispatch { client.getSession().write(objController.serialize()); } + public void performUnity(final CreatureObject acceptor, final CreatureObject proposer){ + TangibleObject acceptorInventory = (TangibleObject) acceptor.getSlottedObject("inventory"); + final AtomicBoolean acceptorHasRing = new AtomicBoolean(); + + acceptorInventory.viewChildren(acceptor, false, false, new Traverser() { + + @Override + public void process(SWGObject obj) { + if(obj.getAttachment("objType") != null) { + String objType = (String) obj.getAttachment("objType"); + if(objType == "ring") { + acceptorHasRing.set(true); + } + } + } + }); + + if(acceptorHasRing.get() == false) { + acceptor.sendSystemMessage("@unity:no_ring", (byte) 0); + proposer.sendSystemMessage("@unity:accept_fail", (byte) 0); + acceptor.setAttachment("proposer", null); + } else { + PlayerObject aGhost = (PlayerObject) acceptor.getSlottedObject("ghost"); + PlayerObject pGhost = (PlayerObject) proposer.getSlottedObject("ghost"); + + if (aGhost == null || pGhost == null) { + acceptor.sendSystemMessage("@unity:wed_error", (byte) 0); + proposer.sendSystemMessage("@unity:wed_error", (byte) 0); + acceptor.setAttachment("proposer", null); + return; + } else { + final Vector ringList = new Vector(); + acceptorInventory.viewChildren(acceptor, false, false, new Traverser() { + + @Override + public void process(SWGObject obj) { + if (obj.getAttachment("objType") != null) { + if (obj.getAttachment("objType") == "ring") { + ringList.add(obj); + } + } + } + }); + + if (ringList.size() > 1) { + sendRingSelectWindow(acceptor, proposer, ringList); + } else { + // Proposer's ring is already 'unified' from the start, so no + // need to set a unity attachment. + ringList.get(0).setAttachment("unity", (Boolean) true); + + if(!acceptor.getEquipmentList().contains(ringList.get(0))) + core.equipmentService.equip(acceptor, ringList.get(0)); + + aGhost.setSpouseName(proposer.getCustomName()); + pGhost.setSpouseName(acceptor.getCustomName()); + + acceptor.sendSystemMessage("Your union with " + proposer.getCustomName() + " is complete.", (byte) 0); + proposer.sendSystemMessage("Your union with " + acceptor.getCustomName() + " is complete.", (byte) 0); + + acceptor.setAttachment("proposer", null); + } + } + } + } + + private void sendRingSelectWindow(final CreatureObject actor, final CreatureObject proposer, Vector ringList) { + Map ringData = new HashMap(); + + for(SWGObject obj : ringList) { + ringData.put(obj.getObjectId(), obj.getCustomName()); + } + + final SUIWindow ringWindow = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@unity:ring_prompt", "@unity:ring_prompt", ringData, actor, proposer, (float) 15); + Vector returnList = new Vector(); + returnList.add("List.lstList:SelectedRow"); + + ringWindow.addHandler(0, "", Trigger.TRIGGER_OK, returnList, new SUICallback() { + + @Override + public void process(SWGObject owner, int eventType, Vector returnList) { + int index = Integer.parseInt(returnList.get(0)); + + SWGObject selectedRing = core.objectService.getObject(ringWindow.getObjectIdByIndex(index)); + selectedRing.setAttachment("unity", (Boolean) true); + + if(!actor.getEquipmentList().contains(selectedRing)) + core.equipmentService.equip(actor, selectedRing); + + PlayerObject aGhost = (PlayerObject) actor.getSlottedObject("ghost"); + PlayerObject pGhost = (PlayerObject) proposer.getSlottedObject("ghost"); + aGhost.setSpouseName(proposer.getCustomName()); + pGhost.setSpouseName(actor.getCustomName()); + + actor.sendSystemMessage("Your union with " + proposer.getCustomName() + " is complete.", (byte) 0); + proposer.sendSystemMessage("Your union with " + actor.getCustomName() + " is complete.", (byte) 0); + } + + }); + + ringWindow.addHandler(1, "", Trigger.TRIGGER_CANCEL, returnList, new SUICallback() { + + @Override + public void process(SWGObject owner, int eventType, Vector returnList) { + + PlayerObject aGhost = (PlayerObject) actor.getSlottedObject("ghost"); + PlayerObject pGhost = (PlayerObject) proposer.getSlottedObject("ghost"); + + actor.sendSystemMessage("@unity:decline", (byte) 0); + proposer.sendSystemMessage("@unity:declined", (byte) 0); + actor.setAttachment("proposer", null); + for(SWGObject obj : proposer.getEquipmentList()) { + if(obj.getAttachment("unity") != null) { + obj.setAttachment("unity", null); + break; + } + } + } + }); + core.suiService.openSUIWindow(ringWindow); + } + @Override public void shutdown() { // TODO Auto-generated method stub diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 14be116d..a71cb9c3 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -697,6 +697,9 @@ public class SimulationService implements INetworkDispatch { final CreatureObject object = (CreatureObject) client.getParent(); PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); + if(object.getAttachment("proposer") != null) + object.setAttachment("proposer", null); + //session.suspendWrite(); final long objectId = object.getObjectID();