Fix load shop, implement vendor NPC transactions

Splits out the original merchandise chest into two chests: a private merchandise chest in a dummy cell that sources the shelves when visiting a shop and a public chest in the interior of the shop that allows visitors to sell items and owners to deposit or withdraw items from the shop merchandise.
This commit is contained in:
Tyler Hallada 2020-11-18 23:31:41 -05:00
parent 5cf8deea30
commit e032084c1c
5 changed files with 209 additions and 39 deletions

View File

@ -1,4 +1,4 @@
Scriptname BRMerchChestScript extends ObjectReference scriptname BRMerchChestScript extends ObjectReference
Keyword property BRLinkMerchShelf auto Keyword property BRLinkMerchShelf auto
Keyword property BRLinkMerchChest auto Keyword property BRLinkMerchChest auto
@ -8,46 +8,116 @@ Keyword property BRLinkMerchToggle auto
Keyword property BRLinkMerchNext auto Keyword property BRLinkMerchNext auto
Keyword property BRLinkMerchPrev auto Keyword property BRLinkMerchPrev auto
Activator property ActivatorStatic auto Activator property ActivatorStatic auto
Actor Property PlayerRef Auto Actor property PlayerRef auto
Quest Property BRQuest Auto Quest property BRQuest auto
MiscObject property Gold001 auto
FormList property BREmptyFormList auto
ObjectReference property boughtItemRef auto
Form property boughtItemBase auto
int property boughtItemQuantity auto
int property boughtAmount auto
ObjectReference property soldItemRef auto
Form property soldItemBase auto
int property soldItemQuantity auto
int property soldAmount auto
event OnInit()
debug.Trace("BRMerchChestScript OnInit")
AddInventoryEventFilter(BREmptyFormList)
endEvent
event OnMenuClose(string menuName) event OnMenuClose(string menuName)
if menuName == "ContainerMenu" if menuName == "BarterMenu"
Debug.Trace("BRMerchChestScript container menu closed") debug.Trace("BRMerchChestScript barter menu closed, stop listending to add/remove events")
AddInventoryEventFilter(BREmptyFormList)
UnregisterForMenu("BarterMenu")
endif
endEvent
event OnMenuOpen(string menuName)
if menuName == "BarterMenu"
debug.Trace("BRMerchChestScript barter menu opened, start listening to add/remove events")
RemoveAllInventoryEventFilters()
endif
endEvent
Event OnItemRemoved(Form baseItem, int itemCount, ObjectReference itemRef, ObjectReference destContainer)
if destContainer == PlayerRef
debug.Trace("BRMerchChestScript item moved to player: " + itemRef + " " + baseItem + " " + itemCount)
if baseItem == Gold001 as Form
soldAmount = itemCount
MaybeCreateTransaction()
else
boughtItemRef = itemRef
boughtItemBase = baseItem
boughtItemQuantity = itemCount
MaybeCreateTransaction()
endif
endif
endEvent
Event OnItemAdded(Form baseItem, int itemCount, ObjectReference itemRef, ObjectReference sourceContainer)
if sourceContainer == PlayerRef
debug.Trace("BRMerchChestScript item moved to container from player: " + itemRef + " " + baseItem + " " + itemCount)
if baseItem == Gold001 as Form
boughtAmount = itemCount
MaybeCreateTransaction()
else
soldItemRef = itemRef
soldItemBase = baseItem
soldItemQuantity = itemCount
MaybeCreateTransaction()
endif
endif
endEvent
function MaybeCreateTransaction()
if boughtAmount > 0 && boughtItemBase && boughtItemQuantity > 0
debug.Trace("BRMerchChestScript MaybeCreateTransaction creating buy transaction")
BRQuestScript BRScript = BRQuest as BRQuestScript BRQuestScript BRScript = BRQuest as BRQuestScript
bool result = BRMerchandiseList.Create(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ShopId, self) bool result = BRTransaction.CreateFromVendorSale(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ActiveShopId, false, boughtItemQuantity, boughtAmount, boughtItemBase, self)
if !result if !result
Debug.MessageBox("Failed to save shop merchandise.\n\n" + BRScript.BugReportCopy) Debug.MessageBox("Failed to buy merchandise.\n\n" + BRScript.BugReportCopy)
endif endif
UnregisterForMenu("ContainerMenu") boughtAmount = 0
endif boughtItemBase = None
endEvent boughtItemRef = None
boughtItemQuantity = 0
event OnActivate(ObjectReference akActionRef) elseif soldAmount > 0 && soldItemBase && soldItemQuantity > 0
if akActionRef == PlayerRef debug.Trace("BRMerchChestScript MaybeCreateTransaction creating sell transaction")
Debug.Trace("BRMerchChestScript container was opened")
RegisterForMenu("ContainerMenu")
endif
endEvent
event OnCreateMerchandiseSuccess(bool created, int id)
Debug.Trace("BRMerchChestScript OnCreateMerchandiseSuccess created: " + created + " id: " + id)
if created
BRQuestScript BRScript = BRQuest as BRQuestScript BRQuestScript BRScript = BRQuest as BRQuestScript
BRScript.MerchandiseListId = id; bool result = BRTransaction.CreateFromVendorSale(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ActiveShopId, false, boughtItemQuantity, soldAmount, soldItemBase, self)
Debug.Notification("Saved merchandise successfully") if !result
Debug.MessageBox("Failed to buy merchandise.\n\n" + BRScript.BugReportCopy)
ObjectReference merchantShelf = self.GetLinkedRef(BRLinkMerchShelf)
if !BRMerchandiseList.Refresh(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ActiveShopId, merchantShelf, ActivatorStatic, BRLinkMerchShelf, BRLinkMerchChest, BRLinkItemRef, BRLinkActivatorRef, BRLinkMerchToggle, BRLinkMerchNext, BRLinkMerchPrev)
Debug.MessageBox("Failed refresh merchandise.\n\n" + BRScript.BugReportCopy)
endif endif
soldAmount = 0
soldItemBase = None
soldItemRef = None
soldItemQuantity = 0
else else
Debug.Trace("BRMerchChestScript no container changes to save to the server") debug.Trace("BRMerchChestScript MaybeCreateTransaction sale not yet finalized")
endif endif
endFunction
function RefreshMerchandise()
BRQuestScript BRScript = BRQuest as BRQuestScript
ObjectReference merchantShelf = self.GetLinkedRef(BRLinkMerchShelf)
if !BRMerchandiseList.Refresh(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ActiveShopId, merchantShelf, ActivatorStatic, BRLinkMerchShelf, BRLinkMerchChest, BRLinkItemRef, BRLinkActivatorRef, BRLinkMerchToggle, BRLinkMerchNext, BRLinkMerchPrev)
Debug.MessageBox("Failed refresh merchandise.\n\n" + BRScript.BugReportCopy)
endif
endFunction
event OnCreateTransactionSuccess(int id, int quantity, int amount)
debug.Trace("BRMerchChestScript OnCreateTransactionSuccess id: " + id + " quantity: " + quantity + " amount: " + amount)
ObjectReference merchRef = self.GetLinkedRef(BRLinkItemRef)
RefreshMerchandise()
endEvent endEvent
event OnCreateMerchandiseFail(string error) ; TODO: gracefully handle expected error cases (e.g. someone else buys all of item before this player can buy them)
Debug.Trace("BRMerchChestScript OnCreateMerchandiseFail error: " + error) Event OnCreateTransactionFail(string error)
Debug.Trace("BRMerchChestScript OnCreateTransactionFail error: " + error)
BRQuestScript BRScript = BRQuest as BRQuestScript BRQuestScript BRScript = BRQuest as BRQuestScript
Debug.MessageBox("Failed to save shop merchandise.\n\n" + error + "\n\n" + BRScript.BugReportCopy) Debug.MessageBox("Failed to buy merchandise.\n\n" + error + "\n\n" + BRScript.BugReportCopy)
RefreshMerchandise()
endEvent endEvent

View File

@ -0,0 +1,82 @@
scriptname BRPublicMerchChestScript extends ObjectReference
Keyword property BRLinkMerchShelf auto
Keyword property BRLinkMerchChest auto
Keyword property BRLinkItemRef auto
Keyword property BRLinkActivatorRef auto
Keyword property BRLinkMerchToggle auto
Keyword property BRLinkMerchNext auto
Keyword property BRLinkMerchPrev auto
Activator property ActivatorStatic auto
Actor property PlayerRef auto
Quest property BRQuest auto
FormList property BREmptyFormList auto
event OnInit()
Debug.Trace("BRPublicMerchChestScript OnInit")
AddInventoryEventFilter(BREmptyFormList)
endEvent
event OnMenuClose(string menuName)
if menuName == "ContainerMenu"
Debug.Trace("BRPublicMerchChestScript container menu closed")
BRQuestScript BRScript = BRQuest as BRQuestScript
if BRScript.ActiveShopId == BRScript.ShopId
bool result = BRMerchandiseList.Create(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ShopId, self)
if !result
Debug.MessageBox("Failed to save shop merchandise.\n\n" + BRScript.BugReportCopy)
endif
endif
UnregisterForMenu("ContainerMenu")
AddInventoryEventFilter(BREmptyFormList)
endif
endEvent
event OnMenuOpen(string menuName)
if menuName == "ContainerMenu"
debug.Trace("BRPublicMerchChestScript container menu opened, start listening to add/remove events")
BRQuestScript BRScript = BRQuest as BRQuestScript
if BRScript.ActiveShopId != BRScript.ShopId
debug.Notification("Add items to chest to sell them to this shop")
RemoveAllInventoryEventFilters()
endif
endif
endEvent
event OnActivate(ObjectReference akActionRef)
if akActionRef == PlayerRef
Debug.Trace("BRPublicMerchChestScript container was opened")
RegisterForMenu("ContainerMenu")
endif
endEvent
Event OnItemAdded(Form baseItem, int itemCount, ObjectReference itemRef, ObjectReference sourceContainer)
if sourceContainer == PlayerRef
; TODO: implement selling, for now it rejects all additions
debug.Notification("Trade rejected")
RemoveAllItems()
PlayerRef.AddItem(baseItem, 1)
endif
endEvent
event OnCreateMerchandiseSuccess(bool created, int id)
Debug.Trace("BRPublicMerchChestScript OnCreateMerchandiseSuccess created: " + created + " id: " + id)
if created
BRQuestScript BRScript = BRQuest as BRQuestScript
BRScript.MerchandiseListId = id;
Debug.Notification("Saved merchandise successfully")
ObjectReference merchantShelf = self.GetLinkedRef(BRLinkMerchShelf)
if !BRMerchandiseList.Refresh(BRScript.ApiUrl, BRScript.ApiKey, BRScript.ActiveShopId, merchantShelf, ActivatorStatic, BRLinkMerchShelf, BRLinkMerchChest, BRLinkItemRef, BRLinkActivatorRef, BRLinkMerchToggle, BRLinkMerchNext, BRLinkMerchPrev)
Debug.MessageBox("Failed refresh merchandise.\n\n" + BRScript.BugReportCopy)
endif
else
Debug.Trace("BRPublicMerchChestScript no container changes to save to the server")
endif
endEvent
event OnCreateMerchandiseFail(string error)
Debug.Trace("BRPublicMerchChestScript OnCreateMerchandiseFail error: " + error)
BRQuestScript BRScript = BRQuest as BRQuestScript
Debug.MessageBox("Failed to save shop merchandise.\n\n" + error + "\n\n" + BRScript.BugReportCopy)
endEvent

View File

@ -133,21 +133,18 @@ bool function SaveInteriorRefs()
endFunction endFunction
event OnCreateInteriorRefListSuccess(int id) event OnCreateInteriorRefListSuccess(int id)
Debug.Trace("BRQuestSCript OnCreateInteriorRefListSuccess id: " + id) Debug.Trace("BRQuestScript OnCreateInteriorRefListSuccess id: " + id)
InteriorRefListId = id InteriorRefListId = id
Debug.MessageBox("Successfully saved shop.") Debug.MessageBox("Successfully saved shop.")
endEvent endEvent
event OnCreateInteriorRefListFail(string error) event OnCreateInteriorRefListFail(string error)
Debug.Trace("BRQuestSCript OnCreateInteriorRefListFail error: " + error) Debug.Trace("BRQuestScript OnCreateInteriorRefListFail error: " + error)
Debug.MessageBox("Failed to save shop.\n\n" + error + "\n\n" + BugReportCopy) Debug.MessageBox("Failed to save shop.\n\n" + error + "\n\n" + BugReportCopy)
endEvent endEvent
bool function LoadInteriorRefs() bool function LoadInteriorRefs()
; TODO: this should not load anything if player is not currently in their shop ; TODO: this should not load anything if player is not currently in their shop
ActiveShopId = ShopId
ActiveShopName = ShopName
ActiveShopDescription = ShopDescription
bool result = BRInteriorRefList.ClearCell() bool result = BRInteriorRefList.ClearCell()
if !result if !result
Debug.MessageBox("Failed to clear existing shop before loading in new shop.\n\n" + BugReportCopy) Debug.MessageBox("Failed to clear existing shop before loading in new shop.\n\n" + BugReportCopy)
@ -164,12 +161,15 @@ bool function LoadInteriorRefs()
endFunction endFunction
event OnLoadInteriorRefListSuccess(bool result) event OnLoadInteriorRefListSuccess(bool result)
Debug.Trace("BRQuestSCript OnLoadInteriorRefListSuccess result: " + result) Debug.Trace("BRQuestScript OnLoadInteriorRefListSuccess result: " + result)
ActiveShopId = ShopId
ActiveShopName = ShopName
ActiveShopDescription = ShopDescription
Debug.MessageBox("Successfully loaded shop") Debug.MessageBox("Successfully loaded shop")
endEvent endEvent
event OnLoadInteriorRefListFail(string error) event OnLoadInteriorRefListFail(string error)
Debug.Trace("BRQuestSCript OnLoadInteriorRefListFail error: " + error) Debug.Trace("BRQuestScript OnLoadInteriorRefListFail error: " + error)
Debug.MessageBox("Failed to load shop.\n\n" + error + "\n\n" + BugReportCopy) Debug.MessageBox("Failed to load shop.\n\n" + error + "\n\n" + BugReportCopy)
endEvent endEvent

View File

@ -1,3 +1,4 @@
scriptname BRTransaction scriptname BRTransaction
bool function Create(string apiUrl, string apiKey, int shop_id, bool is_sell, int quantity, int amount, Keyword item_keyword, ObjectReference activator) global native bool function Create(string apiUrl, string apiKey, int shop_id, bool is_sell, int quantity, int amount, Keyword item_keyword, ObjectReference activator) global native
bool function CreateFromVendorSale(string apiUrl, string apiKey, int shop_id, bool is_sell, int quantity, int amount, Form merch_base, ObjectReference merch_chest) global native

View File

@ -0,0 +1,17 @@
scriptname BRVendorScript extends Actor
ObjectReference property BRMerchChest auto
event OnActivate(ObjectReference akActionRef)
debug.Trace("BRVendorScript OnActivate")
BRMerchChest.RegisterForMenu("BarterMenu")
RegisterForMenu("Dialogue Menu")
endEvent
event OnMenuClose(string menuName)
if menuName == "Dialogue Menu"
debug.Trace("BRVendorScript OnMenuClose Dialogue Menu")
BRMerchChest.UnregisterForMenu("BarterMenu")
UnregisterForMenu("Dialogue Menu")
endif
endEvent