Jump to content

Online shopping holotape mod,Seeking help for terminal scripts


616647379

Recommended Posts

Hello everyone!
I am making an “online shopping holotape” mod. After inserting this holotape into a terminal, player can get an experience similar to shopping on Amazon.
I added a script for one of the options of the terminal (the content of the script is placed below), and declared a Actor Property in the script, associated the attribute with Myrna (who lives in Diamond City), and then opened the game for testing.
In the test, I successfully opened Myrna's barter menu on a terminal, but the mouse and keyboard still only work for the terminal, not work for the barter menu.
I think this is because there is a conflict between the keys, because the barter menu is not completely out of control. For example, I can press "Q" to invest , and press "X" to view the details of the first item, but "WASD" and the mouse do not work. when I exit the holotape ,The barter menu can fully take over the control .
Yes,I did indeed create an online shopping feature,but” it just works!”,I don't want to insert holotape every time when I check the next vendor.
So, have a powerful friend who knows how to solve this situation?

ScriptName Fragments:Terminals:ShoppingMenu_Test_01000802 extends Terminal Const hidden

Actor Property Myrna Auto Const

Function Fragment_Terminal_01(ObjectReference akTerminalRef)
	Myrna.ShowBarterMenu()
EndFunction

 

Link to comment
Share on other sites

TerminalMenu and BarterMenu weren't designed to be opened and used simultaneously so unfortuantely they are conflicting.

I can't think of any non-F4SE way to solve this conflict (and even those are rather "hacks")... generally speaking, the game pausing menu, BarterMenu should be opened first while the other, the TerminalMenu is not open to make it work. I haven't tested it but the problem is that even if you close the TerminalMenu after BarterMenu was opened on top of it, input events won't be redirected to BarterMenu and there's a chance controls will "freeze" as long as BarterMenu remains open.

Edited by LarannKiar
Link to comment
Share on other sites

8 hours ago, LarannKiar said:

TerminalMenu and BarterMenu weren't designed to be opened and used simultaneously so unfortuantely they are conflicting.

I can't think of any non-F4SE way to solve this conflict (and even those are rather "hacks")... generally speaking, the game pausing menu, BarterMenu should be opened first while the other, the TerminalMenu is not open to make it work. I haven't tested it but the problem is that even if you close the TerminalMenu after BarterMenu was opened on top of it, input events won't be redirected to BarterMenu and there's a chance controls will "freeze" as long as BarterMenu remains open.

Thank you !
If it is necessary to use F4SE to solve it, will the solving process be very complicated? May I ask if you can provide some ideas?

Link to comment
Share on other sites

12 hours ago, 616647379 said:

Thank you !
If it is necessary to use F4SE to solve it, will the solving process be very complicated? May I ask if you can provide some ideas?

These are just guesses but you can give these a try:

  1) Close TerminalMenu on MenuOpenCloseEvent (asEventName=BarterMenu; abOpening=true) with F4SE's UI.CloseMenu("TerminalMenu"). This releases the input to use it for the BarterMenu. But you'll need to reopen TerminalMenu afterward: on MenuOpenCloseEvent (asEventName=BarterMenu; abOpening=false) you can disable the vanilla "enter terminal" animation that play OnActivate event (akSenderRef=TerminalRef) then call TerminalRef.Activate(akActionRef=Game.GetPlayer()) to reenter the TerminalMenu by activating the terminal's reference. (Without the animations, it should open the TerminalMenu instantly). Unfortunately it won't navigate you back to Terminal's submenu that you closed earlier. (I haven't tested how this approach would actually look ingame but in theory it should work :).

  2) For a cpp (F4SE plugin) project, you can take a look into GameMenuBase:BSInputEventUser, IMenu::flags ( especially: kFlag_UsesCursor, kFlag_OnStack to freeze the TerminalMenu "in the background" without closing it ), IMenu::OnMenuDisplayStateChange(), IMenu::OnAddedToMenuStack(), etc. (Once you set up the code, it could still be a lot of trial and errors...).

By the way, I was rather thinking about a cpp project than F4SE Papyrus to "nicely" enable input events for the BarterMenu without closing TerminalMenu. If you decide to exit the TerminalMenu anyway, you don't have to use F4SE.

Edited by LarannKiar
Link to comment
Share on other sites

13 hours ago, SKK50 said:

Your solution is trying to force the game into unnatural acts.

A quick but nasty way to force close any menu, scene or animation is Game.GetPlayer().MoveTo(Game.GetPlayer())

 

Thank you. But in fact, according to the existing script, it is already possible to fully control the barter menu when exiting the holotape. The idea What I need is being able to control the barter menu while maintaining the display of the terminal menu.

Link to comment
Share on other sites

12 hours ago, LarannKiar said:

These are just guesses but you can give these a try:

  1) Close TerminalMenu on MenuOpenCloseEvent (asEventName=BarterMenu; abOpening=true) with F4SE's UI.CloseMenu("TerminalMenu"). This releases the input to use it for the BarterMenu. But you'll need to reopen TerminalMenu afterward: on MenuOpenCloseEvent (asEventName=BarterMenu; abOpening=false) you can disable the vanilla "enter terminal" animation that play OnActivate event (akSenderRef=TerminalRef) then call TerminalRef.Activate(akActionRef=Game.GetPlayer()) to reenter the TerminalMenu by activating the terminal's reference. (Without the animations, it should open the TerminalMenu instantly). Unfortunately it won't navigate you back to Terminal's submenu that you closed earlier. (I haven't tested how this approach would actually look ingame but in theory it should work :).

  2) For a cpp (F4SE plugin) project, you can take a look into GameMenuBase:BSInputEventUser, IMenu::flags ( especially: kFlag_UsesCursor, kFlag_OnStack to freeze the TerminalMenu "in the background" without closing it ), IMenu::OnMenuDisplayStateChange(), IMenu::OnAddedToMenuStack(), etc. (Once you set up the code, it could still be a lot of trial and errors...).

By the way, I was rather thinking about a cpp project than F4SE Papyrus to "nicely" enable input events for the BarterMenu without closing TerminalMenu. If you decide to exit the TerminalMenu anyway, you don't have to use F4SE.

It sounds beyond my current abilities. Because I don't have any experience in CPP. But I will try it out in my spare time. Thank you very much for providing these ideas!

Link to comment
Share on other sites

20 hours ago, 616647379 said:

It sounds beyond my current abilities. Because I don't have any experience in CPP.

I'm about to update Garden of Eden SE, and I just saw this question was your first post.. also, I like your shopping idea (and shopping in general) so here you go..:)

PWJvQfQ.gif

All keyboard and mouse input goes to BarterMenu as long as it's open (without exiting or "freezing" TerminalMenu).

I'm still testing the new update but the functions will be probably be:

Int Function SetMenuPriorityMask(String asMenuName, int aiMaskIndex, bool abSet) native global
Int[] Function GetMenuPriorityMasks(String asMenuName) native global

I'll add notes to them when they're properly tested..

 

The update may also contain these, in case you'd like to control BarterMenu from Papyrus.

Int Function CompleteBarterMenuTrade() native global
Int Function ClearBarterMenuTradingData() native global
Int Function SetBarterMenuSuppressed(bool abSuppressed) native global

(Suppress means "hide" just like the when the game is paused with Esc).

 

Off-topic: if you decide to use F4SE and you'd like to use your "shopping holotape" in the Pip-Boy, I'll also add the ability to dynamically overwrite the text displayed on the Pip-Boy. (Vanilla game allows only terminal references). Header and Welcome texts are done, I'll test the rest (body and menu item entry texts) soon.. the update will probably be released tomorrow or maybe the day after...

 

By the way, the blurry background is just an Image Space Modifier. Here's the Papyrus code, attached to the Terminal form. It's just a quick demo script.. it'll probably need to be edited.

Scriptname DeleteMe extends Terminal

Actor Property MyrnaRef Auto Const

import GardenOfEden2

Int Property iVendorItemCount = 0 Auto


Event OnMenuItemRun(int auiMenuItemID, ObjectReference akTerminalRef)
	(Game.GetFormFromFile(0x1B2CBA, "Fallout4.esm") as ImageSpaceModifier).Apply()
	RegisterForMenuOpenCloseEvent("BarterMenu")
	MyrnaRef.ShowBarterMenu()
	Utility.WaitMenuMode(0.5)
	SetMenuPriorityMask("BarterMenu", 10, true)
	RegisterForMenuOpenCloseEvent("ExamineMenu")
	RegisterForMenuOpenCloseEvent("MessageBoxMenu")
	RegisterForMenuOpenCloseEvent("TerminalMenu")
EndEvent

Event OnMenuOpenCloseEvent(String asMenuName, bool abOpening)
	If abOpening == true
		If asMenuName == "MessageBoxMenu"
			SetMenuPriorityMask("MessageBoxMenu", 10, false)
		ElseIf asMenuName == "BarterMenu"
			iVendorItemCount = GetMenuTargetVendorChestRef().GetItemCount()
		EndIf
	Else
		If asMenuName == "ExamineMenu"
			(Game.GetFormFromFile(0x1B2CBA, "Fallout4.esm") as ImageSpaceModifier).Apply()
		ElseIf asMenuName == "TerminalMenu"
			UnregisterForAllEvents()
		ElseIf asMenuName == "MessageBoxMenu"
			SetMenuPriorityMask("MessageBoxMenu", 10, true)
			If GetMenuTargetVendorChestRef().GetItemCount() != iVendorItemCount
				UI.CloseMenu("BarterMenu")
			EndIf
		ElseIf asMenuName == "BarterMenu"
			(Game.GetFormFromFile(0x1B2CBA, "Fallout4.esm") as ImageSpaceModifier).Remove()
			UnregisterForMenuOpenCloseEvent("BarterMenu")
		EndIf
	EndIf
EndEvent

Edited by LarannKiar
Link to comment
Share on other sites

9 hours ago, LarannKiar said:

I'm about to update Garden of Eden SE, and I just saw this question was your first post.. also, I like your shopping idea (and shopping in general) so here you go..:)

Wow, that's great! I am honored that my idea has been liked by you !
I am indeed a new Modder, and this is my first post. I currently only have some C # experience and am completely clueless about CPP , So I'm really looking forward to your updates on Garden of Eden SE !
By the way, besides the online shopping function, My mod also has some other functions, such as the function to deposit & withdraw caps, similar to online banking (Mainly for the attribute bonus of Nuka-World Magazine). Overall, this holotape will resemble an online banking U-shield. 
At present, all other functions have been completed, except for the online shopping function .After I finish making this mod, I will upload it here and share it with everyone.

Edited by 616647379
Link to comment
Share on other sites

15 hours ago, 616647379 said:

Wow, that's great! I am honored that my idea has been liked by you !
I am indeed a new Modder, and this is my first post. I currently only have some C # experience and am completely clueless about CPP , So I'm really looking forward to your updates on Garden of Eden SE !
By the way, besides the online shopping function, My mod also has some other functions, such as the function to deposit & withdraw caps, similar to online banking (Mainly for the attribute bonus of Nuka-World Magazine). Overall, this holotape will resemble an online banking U-shield. 
At present, all other functions have been completed, except for the online shopping function .After I finish making this mod, I will upload it here and share it with everyone.

The ability to shop online from time to time is nice addition to the game indeed. 🙂

I mostly finished the testing of the TerminalMenu functions recently but some of them are still in beta. I'll look into some reports I received earlier, run a few tests again then release the update, probably as v16.0.

I made a Menu Item entry "constructor" and "destructor" too, if you're looking to add or remove entries to the interface on the fly (without the need of adding a condition to each of them to dynamically show/hide them...).

Here's a list of the new Terminal functions if you're interested. Signatures are unlikely to be changed.. or maybe just a bit. Some of the "Get" functions are already available but I decided to delete the old ones and rewrote all from scratch.

 
Bool Function SetWelcomeText(Terminal akTerminal, String asText) native global
Bool Function SetHeaderText(Terminal akTerminal, String asText) native global

String Function GetWelcomeText(Terminal akTerminal) native global
String Function GetHeaderText(Terminal akTerminal) native global

Bool Function SetNthMenuItemSubmenu(Terminal akTerminal, int aiMenuItemID, Terminal akSubmenu) native global
Terminal Function GetNthMenuItemSubmenu(Terminal akTerminal, int aiMenuItemID) native global

String Function GetNthBodyText(Terminal akTerminal, int aiBodyTextIndex) native global
String Function GetNthMenuItemItemText(Terminal akTerminal, int aiMenuItemID) native global
String Function GetNthMenuItemResponseText(Terminal akTerminal, int aiMenuItemID) native global
String Function GetNthMenuItemDisplayText(Terminal akTerminal, int aiMenuItemID) native global
Int Function GetMenuItemIDByIndex(Terminal akTerminal, int aiMenuItemIndex) native global

Bool Function SetNthBodyText(Terminal akTerminal, int aiBodyTextIndex, String asText) native global
Bool Function SetNthMenuItemItemText(Terminal akTerminal, int aiMenuItemID, String asText) native global
Bool Function SetNthMenuItemResponseText(Terminal akTerminal, int aiMenuItemID, String asText) native global
Bool Function SetNthMenuItemDisplayText(Terminal akTerminal, int aiMenuItemID, String asText) native global
Int Function GetMenuItemIndexByID(Terminal akTerminal, int aiMenuItemID) native global

Int Function GetNthMenuItemType(Terminal akTerminal, int aiMenuItemID) native global
Bool Function SetNthMenuItemType(Terminal akTerminal, int aiMenuItemID, int aiMenuItemType) native global

Bool Function SetMenuItemID(Terminal akTerminal, int aiNewMenuItemID, int aiMenuItemID = 0, int aiMenuItemIndex = 0, bool abPermitOverlap = false) native global

Bool Function CreateTerminalMenuItem(Terminal akTerminal, int aiMenuItemID, int aiMenuItemType, \
	String asItemText = "", String asResponseText = "",  String asDisplayText = "", Terminal akSubmenu = None) native global

Bool Function RemoveNthMenuItem(Terminal akTerminal, int aiMenuItemID) native global

 

Edited by LarannKiar
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...