A context sensitive use menu, with hyperlinks

Hey 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!


I 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.


Ah, 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))
  }
}

I 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)

That works perfectly, and it's much simpler than the solution I had in mind. Thanks!


You're doing the lords work here scrim.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums