A context sensitive use menu, with hyperlinks
scrimshaw04
12 Jan 2017, 04:39Hey all. I'm trying to create a system where the player can click on a hyperlink for an object that has a 'use' verb attached to it, and then choose from a list of the usable items in their inventory. Here's what I've worked out so far:
useList = NewStringList()
foreach (item, ScopeInventory()) {
list add (useList, item.alias)
}
ShowMenu ("What would you like to use?", useList, true) {
if (GetObject(result) = inventory_item) {
msg ("You use the " + this.alias)
--SCRIPT--
}
else {
msg ("You can't use " this.alias + " on that.")
}
}
There are three things that I'm not sure how to do.
Firstly, how do I detect if the chosen item is a usable option? In the above code I'm currently trying to use if (GetObject(result) = inventory_item) to do that.
Secondly, how would I execute the command of 'use inventory_item on other_item' using a script? I could run an attribute script, but since this would require two arguments, I'm not sure how to do it.
Lastly, once the player has selected an object, how do I print the object's alias?
Thanks!
The Pixie
12 Jan 2017, 07:43I think (I could be wrong) the built in USE command will do this. Turn it on on the Features tab, and see what happens with "Use with another object" bit.
scrimshaw04
12 Jan 2017, 09:45Ah, that's very close to what I'm looking for! Unfortunately the list doesn't discriminate between objects. It lists every object in the room and the player's inventory that isn't scenery. Unfortunately because I have a random spawn system in my game, the spawned creatures also show up in the list, which I don't want, but I also don't want to mark them as scenery.
Maybe there's a way to work around this... If I can find the original script for selfuseon then I might be able to alter it into what I'm looking for.
EDIT: I think I've found the scripts, but I don't quite understand them yet. I'll keep working on it
CreateUseMenuList
objectlist = NewObjectList()
objectlist = ScopeReachableInventory()
objectlist = ListCombine (objectlist, ScopeReachableNotHeld())
excludelist = NewObjectList()
list add (excludelist, game.pov)
list add (excludelist, object)
candidates = NewObjectList()
candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
return (candidates)
use
if (HasScript(object, "use")) {
do (object, "use")
}
else {
if (GetBoolean(object, "use")) {
menu = NewStringDictionary()
candidates = NewObjectList()
candidates = CreateUseMenuList (object)
if (ListCount(candidates) = 0) {
msg (Template("NoObjectsAvailable"))
}
else {
GenerateMenuChoices (menu, candidates)
game.pov.usemenuobject = object
if (HasString(object, "usemenuprompt")) {
menucaption = object.usemenuprompt
}
else {
menucaption = Template("UseOnMenu")
}
ShowMenu (menucaption, menu, true) {
if (result <> null) {
HandleUseOn (game.pov.usemenuobject, GetObject(result))
game.pov.usemenuobject = null
}
}
}
}
else {
msg (DynamicTemplate("CantUse", object))
}
}
Pertex
12 Jan 2017, 14:09I did not test it but this could work. Add an attribute to every object which should not be shown in the use menu e.g. "spawnedcreature.nouse=true"
Then you could exclude objects with that attribute in the function CreateUseMenuList
objectlist = NewObjectList()
objectlist = ScopeReachableInventory()
objectlist = ListCombine (objectlist, ScopeReachableNotHeld())
excludelist = NewObjectList()
list add (excludelist, game.pov)
list add (excludelist, object)
foreach (item, objectlist) {
if (GetBoolean(item,"nouse") {
list add (excludelist, item)
}
}
candidates = NewObjectList()
candidates = ListExclude(RemoveSceneryObjects(objectlist), excludelist)
return (candidates)
scrimshaw04
14 Jan 2017, 09:41That works perfectly, and it's much simpler than the solution I had in mind. Thanks!
101titan101
14 Jan 2017, 10:37You're doing the lords work here scrim.