diff --git a/scripts/conversation/junk_dealer.py b/scripts/conversation/junk_dealer.py index 5e5c435b..b0741467 100644 --- a/scripts/conversation/junk_dealer.py +++ b/scripts/conversation/junk_dealer.py @@ -5,357 +5,71 @@ from resources.common import RadialOptions from services.sui import SUIWindow from services.sui.SUIWindow import Trigger from java.util import Vector +from main import NGECore import sys -sellItemListRef = 0 -buyItemListRef = 0 -coreRef = 0 -junkDealerRef = 0 - def startConversation(core, actor, npc): - #core.lootService.prepInv(actor) - global coreRef - global junkDealerRef - global sellItemListRef - sellItemListRef = core.lootService.getSellableInventoryItems(actor) - coreRef = core - junkDealerRef = npc convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_bef51e38') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - prose2 = ProsePackage('conversation/junk_dealer_generic', 's_54fab04f') - outOfBand2 = OutOfBand() - outOfBand2.addProsePackage(prose2) - prose3 = ProsePackage('conversation/junk_dealer_generic', 's_48') - outOfBand3 = OutOfBand() - outOfBand3.addProsePackage(prose3) - prose4 = ProsePackage('conversation/junk_dealer_generic', 's_3aa18b2d') - outOfBand4 = OutOfBand() - outOfBand4.addProsePackage(prose4) - option1 = ConversationOption(outOfBand2, 0) - option2 = ConversationOption(outOfBand3, 1) - option3 = ConversationOption(outOfBand4, 1) + + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_bef51e38')) options = Vector() - options.add(option1) - options.add(option2) - options.add(option3) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_54fab04f'), 0)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_48'), 1)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_3aa18b2d'), 2)) - if len(core.lootService.getBuyHistory(actor,npc))!= 0: - prose5 = ProsePackage('conversation/junk_dealer_generic', 's_43') - outOfBand5 = OutOfBand() - outOfBand5.addProsePackage(prose5) - option4 = ConversationOption(outOfBand5, 1) - options.add(option4) + buyBack = actor.getAttachment('buy_back') + + if buyBack is not None and buyBack != 0 and core.objectService.objsInContainer(actor, core.objectService.getObject(buyBack)) > 0: + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_43'), 3)) convSvc.sendConversationOptions(actor, npc, options, handleFirstScreen) return def handleFirstScreen(core, actor, npc, selection): - convSvc = core.conversationService if selection == 0: # sell items - - prose = ProsePackage('conversation/junk_dealer_generic', 's_84a67771') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - + sellItemListRef = core.lootService.getSellableInventoryItems(actor) if len(sellItemListRef) == 0: actor.sendSystemMessage('@loot_dealer:no_items', 1) - startConversation(coreRef,actor,junkDealerRef) + startConversation(core, actor, npc) return # no point - window = core.suiService.createSUIWindow('Script.listBox', actor, npc, 0) - window.setProperty('bg.caption.lblTitle:Text', '@loot_dealer:sell_title') - window.setProperty('Prompt.lblPrompt:Text', '@loot_dealer:sell_prompt') - - for item in sellItemListRef: - window.addListBoxMenuItem(item.getCustomName(), 0); - - window.setProperty('btnOther:visible', 'True') - window.setProperty('btnCancel:visible', 'True') - window.setProperty('btnOk:visible', 'True') - window.setProperty('btnOther:Text', '@loot_dealer:examine') - window.setProperty('btnCancel:Text', '@cancel') - window.setProperty('btnOk:Text', '@loot_dealer:btn_sell') - returnList = Vector() - returnList.add('List.lstList:SelectedRow') - - window.addHandler(0, '', Trigger.TRIGGER_OK, returnList, sellWindowCallBack) - window.addHandler(1, '', Trigger.TRIGGER_CANCEL, returnList, sellWindowCallBack) - window.addHandler(2, '', Trigger.TRIGGER_UPDATE, returnList, sellWindowCallBack) - core.suiService.openSUIWindow(window); - + convSvc.sendStopConversation(actor, npc, 'conversation/junk_dealer_generic', 's_84a67771') + core.lootService.handleJunkDealerSellWindow(actor, npc, sellItemListRef) return if selection == 1: - # mark items - window = core.suiService.createSUIWindow('Script.listBox', actor, npc, 0) - window.setProperty('bg.caption.lblTitle:Text', '@loot_dealer:junk_no_sell_title') - window.setProperty('Prompt.lblPrompt:Text', '@loot_dealer:junk_no_sell_desc') - - sellItemListRef = core.lootService.getSellableInventoryItems(actor) - - for item in sellItemListRef: - nameString = item.getCustomName() - nameString = 'TestJunkItem' - if item.isNoSell(): - nameString = '[*No Sell*]' + item.getCustomName() - window.addListBoxMenuItem(nameString, 0) - else: - nameString = '[Sellable]' + item.getCustomName() - window.addListBoxMenuItem(nameString, 0) - - window.setProperty('btnOther:visible', 'True') - window.setProperty('btnCancel:visible', 'True') - window.setProperty('btnOk:visible', 'True') - window.setProperty('btnOther:Text', '@loot_dealer:examine') - window.setProperty('btnCancel:Text', '@cancel') - window.setProperty('btnOk:Text', '@loot_dealer:junk_no_sell_button') - returnList = Vector() - returnList.add('List.lstList:SelectedRow') - - #window.addHandler(0, '', Trigger.TRIGGER_OK, returnList, noSellWindowCallBack) - #window.addHandler(1, '', Trigger.TRIGGER_CANCEL, returnList, noSellWindowCallBack) - window.addHandler(0, '',9, returnList, noSellWindowCallBack) - window.addHandler(1, '',10, returnList, noSellWindowCallBack) - window.addHandler(2, '',11, returnList, noSellWindowCallBack) - core.suiService.openSUIWindow(window); + # Mark Items + convSvc.sendStopConversation(actor, npc, 'conversation/junk_dealer_generic', 's_50') + core.lootService.handleJunkDealerMarkItems(actor, npc) return if selection == 2: lootKitScreen1(core, actor, npc) - + return if selection == 3: # buy back - buyHistory = coreRef.lootService.getBuyHistory(actor,npc) - if len(buyHistory) == 0: + buyHistory = core.objectService.objsInContainer(actor, core.objectService.getObject(actor.getAttachment('buy_back'))) + if buyHistory == 0: actor.sendSystemMessage('@loot_dealer:no_buy_back_items_found', 1) - startConversation(coreRef,actor,npc) + startConversation(core,actor,npc) return - prose = ProsePackage('conversation/junk_dealer_generic', 's_44') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - - window = core.suiService.createSUIWindow('Script.listBox', actor, npc, 0) - window.setProperty('bg.caption.lblTitle:Text', '@loot_dealer:buy_back_title') - window.setProperty('Prompt.lblPrompt:Text', '@loot_dealer:buy_back_prompt') - - buyHistory = core.lootService.getBuyHistory(actor,junkDealerRef) - if buyHistory==None: - return - - - - for item in buyHistory: - junkDealerPrice = item.getJunkDealerPrice() - if junkDealerPrice == 0: - junkDealerPrice = 20 - nameString = '[%s' % junkDealerPrice + ']' + item.getCustomName() #% - window.addListBoxMenuItem(nameString, 0) - - window.setProperty('btnOther:visible', 'True') - window.setProperty('btnCancel:visible', 'True') - window.setProperty('btnOk:visible', 'True') - window.setProperty('btnOther:Text', '@loot_dealer:examine') - window.setProperty('btnCancel:Text', '@cancel') - window.setProperty('btnOk:Text', '@loot_dealer:btn_buy_back') - returnList = Vector() - returnList.add('List.lstList:SelectedRow') - - window.addHandler(0, '', Trigger.TRIGGER_OK, returnList, buyBackWindowCallBack) - window.addHandler(1, '', Trigger.TRIGGER_CANCEL, returnList, buyBackWindowCallBack) - window.addHandler(2, '', Trigger.TRIGGER_UPDATE, returnList, buyBackWindowCallBack) - core.suiService.openSUIWindow(window); - + convSvc.sendStopConversation(actor, npc, 'conversation/junk_dealer_generic', 's_44') + core.lootService.handleJunkDealerBuyBackWindow(actor, npc) return - -def handleRespecScreen(core, actor, npc, selection): - - if selection == 0: - core.skillService.sendRespecWindow(actor) - - core.conversationService.handleEndConversation(actor, npc) - - return - - -def handleResetScreen(core, actor, npc, selection): - - if selection == 0: - core.skillService.resetExpertise(actor) - - core.conversationService.handleEndConversation(actor, npc) - return def endConversation(core, actor, npc): core.conversationService.sendStopConversation(actor, npc, 'conversation/junk_dealer_generic', 's_4bd9d15e') return - - -def sellWindowCallBack(owner, window, eventType, returnList): - - sellItemListRef = coreRef.lootService.getSellableInventoryItems(owner) - - #sell - if eventType == 0: - - sellItem = sellItemListRef.get(int(returnList.get(0))) - - #if len(sellItemListRef): - #owner.sendSystemMessage('@junk_dealer:no_items', 1) - #return - - if sellItem == None: - owner.sendSystemMessage('@junk_dealer:no_items', 1) - return - - inventory = owner.getSlottedObject('inventory') - - - junkDealerPrice = sellItem.getJunkDealerPrice() - if junkDealerPrice == 0: - junkDealerPrice = 20 - owner.setCashCredits(owner.getCashCredits()+junkDealerPrice) - - # add item to 10-item junk dealer history - coreRef.lootService.addToBuyHistory(owner,junkDealerRef,sellItem) - - owner.sendSystemMessage(OutOfBand.ProsePackage("@junk_dealer:prose_sold_junk", "TT", sellItem.getCustomName(),junkDealerPrice), 0) - - inventory.remove(sellItem) - - coreRef.suiService.closeSUIWindow(owner,window.getWindowId()) - handleFirstScreen(coreRef, owner, junkDealerRef, 0) - return - - #cancel - if eventType == 1: - owner.sendSystemMessage("cancel ", 1) - coreRef.suiService.closeSUIWindow(owner,window.getWindowId()) - startConversation(coreRef,owner,junkDealerRef) - return - - #examine - if eventType == 2: - owner.sendSystemMessage("examine ", 1) - #coreRef.suiService.closeSUIWindow(window,window.getWindowId()) - #startConversation(coreRef,owner,junkDealerRef) - #owner.sendSystemMessage('Examine', 0) - return - - return - -def noSellWindowCallBack(owner, window, eventType, returnList): - - if returnList.get(0) == 0: - startConversation(coreRef,owner,junkDealerRef) - return - - #toggle - if eventType == 0: - owner.sendSystemMessage('Toggle', 0) - toggleItem = sellItemListRef.get(int(returnList.get(0))) - if toggleItem.isNoSell(): - toggleItem.setNoSell(0) - else: - toggleItem.setNoSell(1) - - #core.suiService.closeSUIWindow(window) - handleFirstScreen(coreRef, owner, junkDealerRef, 1) - return - - #cancel - if eventType == 1: - owner.sendSystemMessage('Cancel', 0) - sellItem = returnList.get(0) - startConversation(coreRef,owner,junkDealerRef) - return - - #examine - if eventType == 2: - owner.sendSystemMessage('Ex', 0) - sellItem = returnList.get(0) - startConversation(coreRef,owner,junkDealerRef) - owner.sendSystemMessage('Examine', 0) - return - -def buyBackWindowCallBack(owner, window, eventType, returnList): - - convSvc = coreRef.conversationService - - if returnList.get(0) == 0: - startConversation(coreRef,owner,junkDealerRef) - return - - #buy - if eventType == 0: - index = int(returnList.get(0)) - buyHistory = coreRef.lootService.getBuyHistory(owner,junkDealerRef) - if len(buyHistory) == 0: - owner.sendSystemMessage('@loot_dealer:no_buy_back_items_found', 1) - startConversation(coreRef,owner,junkDealerRef) - return - - buyBackItem = buyHistory.get(index) - - if buyBackItem == None: - owner.sendSystemMessage('@loot_dealer:no_buy_back_items_found', 0) - startConversation(coreRef,owner,junkDealerRef) - return - - if owner.getInventoryItemCount() >= 80: - prose = ProsePackage('conversation/junk_dealer_generic', 's_47') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(owner, junkDealerRef, outOfBand) - return - - junkDealerPrice = buyBackItem.getJunkDealerPrice() - if junkDealerPrice == 0: - junkDealerPrice = 20 - owner.setCashCredits(owner.getCashCredits()+junkDealerPrice) - - if owner.getCashCredits()>=junkDealerPrice: - owner.setCashCredits(owner.getCashCredits()-junkDealerPrice) - inventory = owner.getSlottedObject('inventory') - inventory.add(buyBackItem) - owner.sendSystemMessage('You buy back ' + buyBackItem.getCustomName() + ' for %s' % junkDealerPrice + ' credits.', 0) - # remove from junk dealer history - coreRef.lootService.removeBoughtBackItemFromHistory(owner,junkDealerRef,buyBackItem) - else: - owner.sendSystemMessage('@loot_dealer:prose_no_buy_back', 0) - - coreRef.suiService.closeSUIWindow(owner,window.getWindowId()); - handleFirstScreen(coreRef, owner, junkDealerRef, 3) - return - - #cancel - if eventType == 1: - owner.sendSystemMessage('Cancel', 0) - sellItem = returnList.get(0) - startConversation(coreRef,owner,junkDealerRef) - return - - #examine - if eventType == 2: - owner.sendSystemMessage('Ex', 0) - sellItem = returnList.get(0) - startConversation(coreRef,owner,junkDealerRef) - owner.sendSystemMessage('Examine', 0) - return def handleLootScreenSelection1(core, actor, npc, selection): @@ -402,11 +116,8 @@ def handleLootScreenSelection5(core, actor, npc, selection): def handleLootScreenSelection6(core, actor, npc, selection): - convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_14efaaa2') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) + convSvc = core.conversationService + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_14efaaa2')) if selection == 0: template = 'object/tangible/loot/collectible/kits/shared_orange_rug_kit.iff' addLootKit(core, actor, npc,template) @@ -439,19 +150,11 @@ def addLootKit(core, actor, npc,template): def lootKitScreen1(core, actor, npc): convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_d9e6b751') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - prose2 = ProsePackage('conversation/junk_dealer_generic', 's_6d53d062') - outOfBand2 = OutOfBand() - outOfBand2.addProsePackage(prose2) - - option1 = ConversationOption(outOfBand2, 0) - + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_d9e6b751')) + options = Vector() - options.add(option1) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_6d53d062'), 0)) convSvc.sendConversationOptions(actor, npc, options, handleLootScreenSelection2) @@ -460,19 +163,11 @@ def lootKitScreen1(core, actor, npc): def lootKitScreen2(core, actor, npc): convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_e29f48dc') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) + + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_e29f48dc')) - prose2 = ProsePackage('conversation/junk_dealer_generic', 's_324b9b0f') - outOfBand2 = OutOfBand() - outOfBand2.addProsePackage(prose2) - - option1 = ConversationOption(outOfBand2, 0) - options = Vector() - options.add(option1) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_324b9b0f'), 0)) convSvc.sendConversationOptions(actor, npc, options, handleLootScreenSelection3) @@ -481,86 +176,42 @@ def lootKitScreen2(core, actor, npc): def lootKitScreen3(core, actor, npc): convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_12fe83a6') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - prose2 = ProsePackage('conversation/junk_dealer_generic', 's_e1a103e5') - outOfBand2 = OutOfBand() - outOfBand2.addProsePackage(prose2) - - option1 = ConversationOption(outOfBand2, 0) - + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_12fe83a6')) + options = Vector() - options.add(option1) - + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_e1a103e5'), 0)) + convSvc.sendConversationOptions(actor, npc, options, handleLootScreenSelection4) - + return def lootKitScreen4(core, actor, npc): convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_4d65752') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - prose2 = ProsePackage('conversation/junk_dealer_generic', 's_d347bee3') - outOfBand2 = OutOfBand() - outOfBand2.addProsePackage(prose2) - prose3 = ProsePackage('conversation/junk_dealer_generic', 's_b60b73f8') - outOfBand3 = OutOfBand() - outOfBand3.addProsePackage(prose3) - - option1 = ConversationOption(outOfBand2, 0) - option2 = ConversationOption(outOfBand3, 0) - + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_4d65752')) + options = Vector() - options.add(option1) - options.add(option2) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_d347bee3'), 0)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_b60b73f8'), 1)) convSvc.sendConversationOptions(actor, npc, options, handleLootScreenSelection5) - + return def lootKitScreen5a(core, actor, npc): convSvc = core.conversationService - prose = ProsePackage('conversation/junk_dealer_generic', 's_3fc7eb45') - outOfBand = OutOfBand() - outOfBand.addProsePackage(prose) - convSvc.sendConversationMessage(actor, npc, outOfBand) - prose2 = ProsePackage('conversation/junk_dealer_generic', 's_ee977dee') - outOfBand2 = OutOfBand() - outOfBand2.addProsePackage(prose2) - prose3 = ProsePackage('conversation/junk_dealer_generic', 's_8f39769') - outOfBand3 = OutOfBand() - outOfBand3.addProsePackage(prose3) - prose4 = ProsePackage('conversation/junk_dealer_generic', 's_fe657cdd') - outOfBand4 = OutOfBand() - outOfBand4.addProsePackage(prose4) - prose5 = ProsePackage('conversation/junk_dealer_generic', 's_9ede4b84') - outOfBand5 = OutOfBand() - outOfBand5.addProsePackage(prose5) - prose6 = ProsePackage('conversation/junk_dealer_generic', 's_87c5851b') - outOfBand6 = OutOfBand() - outOfBand6.addProsePackage(prose6) - - option1 = ConversationOption(outOfBand2, 0) - option2 = ConversationOption(outOfBand3, 0) - option3 = ConversationOption(outOfBand4, 0) - option4 = ConversationOption(outOfBand5, 0) - option5 = ConversationOption(outOfBand6, 0) - + convSvc.sendConversationMessage(actor, npc, OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_3fc7eb45')) + options = Vector() - options.add(option1) - options.add(option2) - options.add(option3) - options.add(option4) - options.add(option5) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_ee977dee'), 0)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_8f39769'), 1)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_fe657cdd'), 2)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_9ede4b84'), 3)) + options.add(ConversationOption(OutOfBand.ProsePackage('@conversation/junk_dealer_generic:s_87c5851b'), 4)) convSvc.sendConversationOptions(actor, npc, options, handleLootScreenSelection6) diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 68eea2b3..316045c5 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -278,6 +278,15 @@ public class CreatureObject extends TangibleObject implements Serializable { } } + public void deductCashCredits(int amountToDeduct) { + synchronized(objectMutex) { + this.cashCredits -= amountToDeduct; + } + if(getClient() != null && getClient().getSession() != null) { + getClient().getSession().write(messageBuilder.buildCashCreditsDelta(cashCredits)); + } + } + public void setCashCredits(int cashCredits) { synchronized(objectMutex) { this.cashCredits = cashCredits; @@ -1805,5 +1814,4 @@ public class CreatureObject extends TangibleObject implements Serializable { } } } - } diff --git a/src/services/LootService.java b/src/services/LootService.java index 8ee55da3..1b009f25 100644 --- a/src/services/LootService.java +++ b/src/services/LootService.java @@ -31,22 +31,33 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; import protocol.swg.PlayClientEffectObjectTransformMessage; import protocol.swg.SceneCreateObjectByCrc; +import resources.common.OutOfBand; +import resources.datatables.DisplayType; import resources.loot.LootGroup; import resources.loot.LootRollSession; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; +import resources.objects.intangible.IntangibleObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; +import services.sui.SUIService.ListBoxType; +import services.sui.SUIService.MessageBoxType; +import services.sui.SUIWindow; +import services.sui.SUIWindow.SUICallback; +import services.sui.SUIWindow.Trigger; import main.NGECore; +import engine.resources.common.Stf; import engine.resources.container.CreatureContainerPermissions; import engine.resources.container.Traverser; import engine.resources.objects.SWGObject; @@ -212,6 +223,252 @@ public class LootService implements INetworkDispatch { // ToDo: Group loot settings etc. actual loot chance was lootgroupchance*lootchance } + public void handleJunkDealerSellWindow(CreatureObject actor, SWGObject junkDealer, Vector sellableItems) { + + if (sellableItems.size() == 0) { + SUIWindow notInterestedWindow = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, "@loot_dealer:sell_title", "@loot_dealer:no_items", actor, junkDealer, (float) 10); + core.suiService.openSUIWindow(notInterestedWindow); + return; + } + + Map itemsToSell = new HashMap(); + sellableItems.forEach(obj -> { + if (!((TangibleObject)obj).isNoSell()) { + int price = ((TangibleObject) obj).getJunkDealerPrice(); + if (((TangibleObject) obj).getUses() > 0) { price = price * ((TangibleObject) obj).getUses(); } + + itemsToSell.put(obj.getObjectID(), "[" + price + "] " + obj.getCustomName()); + } + }); + + if (itemsToSell.size() == 0) { // Every item is in the sellable's vector, however only items the player is offering gets put in list. + SUIWindow notInterestedWindow = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, "@loot_dealer:sell_title", "@loot_dealer:no_items", actor, junkDealer, (float) 10); + core.suiService.openSUIWindow(notInterestedWindow); + return; + } + + final SUIWindow window = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@loot_dealer:sell_title", "@loot_dealer:sell_prompt", itemsToSell, actor, junkDealer, (float) 10); + + window.setProperty("btnOther:Visible", "True"); + window.setProperty("btnOther:Text", "@loot_dealer:examine"); + window.setProperty("btnOk:Text", "@loot_dealer:btn_sell"); + + Vector returnList = new Vector(); + returnList.add("List.lstList:SelectedRow"); + + SUICallback windowCallback = ((owner, eventType, resultList) -> { + switch(eventType) { + case 0: // Sell + TangibleObject itemToSell = null; + int index = Integer.parseInt(resultList.get(0)); + long sellItemId = window.getObjectIdByIndex(index); + + if(sellItemId == 0 || core.objectService.getObject(sellItemId) == null) + return; + + itemToSell = (TangibleObject) core.objectService.getObject(sellItemId); + + int price = itemToSell.getJunkDealerPrice(); + + if (price == 0) + price = 20; + + if (itemToSell.getUses() > 0) + price *= itemToSell.getUses(); + + TangibleObject inventory = (TangibleObject) actor.getSlottedObject("inventory"); + + if (inventory == null) + return; + + addToBuyBack(actor, itemToSell); + + actor.addCashCredits(price); + actor.sendSystemMessage(OutOfBand.ProsePackage("@junk_dealer:prose_sold_junk", "TT", itemToSell.getCustomName(), "DI", price), DisplayType.Broadcast); + + inventory.remove(itemToSell); + + core.suiService.closeSUIWindow(actor, window.getWindowId()); + handleJunkDealerSellWindow(actor, junkDealer, getSellableInventoryItems(actor)); + break; + case 1: // Cancel + core.suiService.closeSUIWindow(actor, window.getWindowId()); + break; + case 2: // TODO: Show Examine Window for objects - Junk Dealer (/examine command?) + break; + } + }); + + window.addHandler(0, "", Trigger.TRIGGER_OK, returnList, windowCallback); + window.addHandler(1, "", Trigger.TRIGGER_CANCEL, returnList, windowCallback); + window.addHandler(2, "", Trigger.TRIGGER_UPDATE, returnList, windowCallback); + + core.suiService.openSUIWindow(window); + + } + + public void handleJunkDealerBuyBackWindow(CreatureObject actor, SWGObject junkDealer) { + + TangibleObject bbContainer = (TangibleObject) core.objectService.getObject((long) actor.getAttachment("buy_back")); + Map soldItems = new HashMap(); + bbContainer.viewChildren(actor, false, false, (obj) -> { + int price = ((TangibleObject) obj).getJunkDealerPrice(); + if (((TangibleObject) obj).getUses() > 0) { price = price * ((TangibleObject) obj).getUses(); } + + soldItems.put(obj.getObjectID(), "[" + price + "] " + obj.getCustomName()); + }); + + final SUIWindow window = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@loot_dealer:buy_back_title", "@loot_dealer:buy_back_prompt", soldItems, actor, junkDealer, (float) 10); + window.setProperty("btnOther:Visible", "True"); + window.setProperty("btnOther:Text", "@loot_dealer:examine"); + window.setProperty("btnOk:Text", "@loot_dealer:btn_buy_back"); + + Vector returnList = new Vector(); + returnList.add("List.lstList:SelectedRow"); + + SUICallback windowCallback = ((owner, eventType, resultList) -> { + switch(eventType) { + case 0: // Buy Back + TangibleObject retrieveItem = null; + int index = Integer.parseInt(resultList.get(0)); + long retrieveItemId = window.getObjectIdByIndex(index); + + if(retrieveItemId == 0 || core.objectService.getObject(retrieveItemId) == null) { + actor.sendSystemMessage("@loot_dealer:no_buy_back_items_found", DisplayType.Broadcast); + return; + } + + retrieveItem = (TangibleObject) core.objectService.getObject(retrieveItemId); + + if (actor.getInventoryItemCount() >= 80) { + actor.sendSystemMessage("@loot_dealer:no_space_in_inventory", DisplayType.Broadcast); + return; + } + + TangibleObject inventory = (TangibleObject) actor.getSlottedObject("inventory"); + + if (inventory == null) + return; + + int value = retrieveItem.getJunkDealerPrice(); + + if (retrieveItem.getUses() > 0) + value *= retrieveItem.getUses(); + + if (actor.getCashCredits() < value) { + actor.sendSystemMessage(OutOfBand.ProsePackage("@loot_dealer:prose_no_buy_back", "TT", retrieveItem.getCustomName()), DisplayType.Broadcast); + return; + } + + actor.deductCashCredits(value); + + actor.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_pay_success", "DI", value, "TT", "a Junk Dealer"), DisplayType.Broadcast); + + bbContainer.transferTo(actor, inventory, retrieveItem); + actor.sendSystemMessage(OutOfBand.ProsePackage("@loot_dealer:prose_buy_back_junk", "DI", value, "TT", retrieveItem.getCustomName()), DisplayType.Broadcast); + + core.suiService.closeSUIWindow(actor, window.getWindowId()); + + handleJunkDealerBuyBackWindow(actor, junkDealer); + break; + case 1: // Cancel + break; + case 2: // TODO: Show Examine Window for objects - Junk Dealer (/examine command?) + break; + } + }); + + window.addHandler(0, "", Trigger.TRIGGER_OK, returnList, windowCallback); + window.addHandler(1, "", Trigger.TRIGGER_CANCEL, returnList, windowCallback); + window.addHandler(2, "", Trigger.TRIGGER_UPDATE, returnList, windowCallback); + core.suiService.openSUIWindow(window); + } + + public void handleJunkDealerMarkItems(CreatureObject actor, SWGObject junkDealer) { + + Vector sellableItems = getSellableInventoryItems(actor); + + if (sellableItems.size() == 0) { + SUIWindow notFoundWindow = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, + "@loot_dealer:junk_not_found_title", "@loot_dealer:junk_not_found_description", actor, junkDealer, (float) 10); + core.suiService.openSUIWindow(notFoundWindow); + return; + } + + Map markableItems = new HashMap(); + sellableItems.forEach(obj -> { + if (((TangibleObject) obj).isNoSell()) markableItems.put(obj.getObjectID(), "[ *No Sell* ] " + obj.getCustomName()); + else markableItems.put(obj.getObjectID(), "[ Sellable ] " + obj.getCustomName()); + }); + + final SUIWindow window = core.suiService.createListBox(ListBoxType.LIST_BOX_OK_CANCEL, "@loot_dealer:junk_no_sell_title", "@loot_dealer:junk_no_sell_description", + markableItems, actor, junkDealer, (float) 10); + + window.setProperty("btnOther:visible", "True"); + window.setProperty("btnOther:Text", "@loot_dealer:examine"); + window.setProperty("btnOk:Text", "@loot_dealer:junk_no_sell_button"); + + Vector returnList = new Vector(); + returnList.add("List.lstList:SelectedRow"); + + SUICallback windowCallback = ((owner, eventType, resultList) -> { + switch(eventType) { + case 0: + TangibleObject markItem = null; + int index = Integer.parseInt(resultList.get(0)); + long markItemId = window.getObjectIdByIndex(index); + + if(markItemId == 0 || core.objectService.getObject(markItemId) == null) + return; + + markItem = (TangibleObject) core.objectService.getObject(markItemId); + + if (markItem.isNoSell()) markItem.setNoSell(false); + else markItem.setNoSell(true); + + core.suiService.closeSUIWindow(actor, window.getWindowId()); + handleJunkDealerMarkItems(actor, junkDealer); + break; + case 1: // Cancel + break; + case 2: // TODO: Show Examine Window for objects - Junk Dealer (/examine command?) + break; + } + }); + + window.addHandler(0, "", Trigger.TRIGGER_OK, returnList, windowCallback); + window.addHandler(1, "", Trigger.TRIGGER_CANCEL, returnList, windowCallback); + window.addHandler(2, "", Trigger.TRIGGER_UPDATE, returnList, windowCallback); + + core.suiService.openSUIWindow(window); + } + + public void addToBuyBack(CreatureObject actor, TangibleObject item) { + if (actor.getAttachment("buy_back") == null) + createBuyBackDevice(actor); + + TangibleObject buyBackContainer = (TangibleObject) core.objectService.getObject((long) actor.getAttachment("buy_back")); + + if (buyBackContainer == null) { + createBuyBackDevice(actor); + addToBuyBack(actor, item); + return; + } + + buyBackContainer.transferTo(actor, buyBackContainer, item); + + final AtomicInteger count = new AtomicInteger(); + + buyBackContainer.viewChildren(actor, false, true, new Traverser() { + + @Override + public void process(SWGObject child) { + if (count.incrementAndGet() >= 11) { + core.objectService.destroyObject(child); // This obj should be the last added object (top-down), so it's safe to remove it. + } + } + }); + } private void handleLootGroup(LootGroup lootGroup,LootRollSession lootRollSession){ @@ -1605,59 +1862,21 @@ public class LootService implements INetworkDispatch { return true; } - @SuppressWarnings("unchecked") - public Vector getBuyHistory(CreatureObject actor, CreatureObject dealer){ - LinkedHashMap businessHistory = (LinkedHashMap )dealer.getAttachment("BusinessHistory"); - if (businessHistory==null){ - businessHistory = new LinkedHashMap(); - dealer.setAttachment("BusinessHistory",businessHistory); - } + public void createBuyBackDevice(CreatureObject actor) { + TangibleObject datapad = (TangibleObject) actor.getSlottedObject("datapad"); + if (datapad == null) + return; - TangibleObject[] actorsBuyHistory = businessHistory.get(actor.getObjectID()); - if (actorsBuyHistory==null) - return new Vector(); + IntangibleObject device = (IntangibleObject) core.objectService.createObject("object/intangible/buy_back/shared_buy_back_control_device.iff", actor.getPlanet()); + datapad.add(device); - Vector actorHistory = new Vector(); - for (TangibleObject item : actorsBuyHistory){ - if (item!=null) - actorHistory.add(item); - } - return actorHistory; - } - - @SuppressWarnings("unchecked") - public boolean addToBuyHistory(CreatureObject actor, CreatureObject dealer, TangibleObject item){ - LinkedHashMap businessHistory = (LinkedHashMap )dealer.getAttachment("BusinessHistory"); - if (businessHistory==null){ - businessHistory = new LinkedHashMap(); - dealer.setAttachment("BusinessHistory",businessHistory); - } + TangibleObject container = (TangibleObject) core.objectService.createObject("object/intangible/buy_back/shared_buy_back_container.iff", actor.getPlanet()); + container.setStaticObject(false); + container.setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); - TangibleObject[] actorsBuyHistory = businessHistory.get(actor.getObjectID()); - if (actorsBuyHistory==null){ - actorsBuyHistory = new TangibleObject[10]; - actorsBuyHistory[0] = item; - } else { - // Check Array for zeros - int lastObject=0; - for (int i=0;i>shift right and add - for (int i = 8; i >= 0; i--) { - actorsBuyHistory[i+1] = actorsBuyHistory[i]; - } - actorsBuyHistory[0] = item; - } else { - actorsBuyHistory[lastObject+1] = item; - } - } - businessHistory.put(actor.getObjectID(),actorsBuyHistory); - dealer.setAttachment("BusinessHistory",businessHistory); - //printArrayElements(actorsBuyHistory); - return true; + device.add(container); + + actor.setAttachment("buy_back", container.getObjectID()); // We can use device.getSlottedObject("inventory"), but this way we won't have to traverse.. } @SuppressWarnings("unchecked") diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 1e21f27c..4c4e3c3d 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -249,9 +249,11 @@ public class ObjectService implements INetworkDispatch { object = new TangibleObject(objectID, planet, position, orientation, Template); } else if(Template.startsWith("object/intangible")) { + if (Template.equals("object/intangible/buy_back/shared_buy_back_container.iff")) // Container sends TANO baselines but is in intangible folder.. lolsoe. + object = new TangibleObject(objectID, planet, position, orientation, Template); + else + object = new IntangibleObject(objectID, planet, position, orientation,Template); - object = new IntangibleObject(objectID, planet, position, orientation,Template); - } else if(Template.startsWith("object/weapon")) { object = new WeaponObject(objectID, planet, position, orientation, Template);