How to stop showing player object in custom object list function
PsychoVyse
28 Apr 2022, 17:54I'm currently displaying a custom list of objects for a room but it's actually displaying the Player object verb in the output which shouldn't happen.
msg (FancyObjectList ("You can see ", GetDirectChildren(Reception), ".", ""))
https://i.imgur.com/Uik7leW.png
<function name="FancyObjectList" parameters="preList, objects, postList, empty, joiner" type="string"><![CDATA[
if (not IsDefined ("joiner")) {
joiner = "and"
}
if (TypeOf (objects) = "object") {
objects = GetDirectChildren (objects)
}
if (ListCount (objects) = 0) {
if (IsDefined ("empty")) {
return (empty)
}
else {
return ("")
}
}
else {
result = ""
itemsLeft = ListCount(objects)
foreach (item, objects) {
switch (TypeOf(item)) {
case ("object") {
if (DoesInherit (item, "defaultexit")) {
result = result + GetDisplayNameLink(item, "exit")
}
else {
result = result + GetDisplayNameLink(item, "object")
}
}
case ("string") {
result = result + item
}
default {
result = result + ToString (item)
}
}
itemsLeft = itemsLeft - 1
if (itemsLeft > 0) {
if (itemsLeft > 1 or (GetBoolean(game, "oxfordcomma") and not ListCount (objects) = 2)) {
result = result + ", "
}
else {
result = result + " "
}
if (itemsLeft = 1) {
result = result + joiner + " "
}
}
}
result = preList + result + postList
return (Trim (result))
}
]]></function>
mrangel
29 Apr 2022, 00:07It seems a little weird to be using GetDirectChildren
.
However, I would suggest the best fix for this is simply to remove the player from the list. Before:
if (ListCount (objects) = 0) {
you could add a simple check:
while (ListContains (objects, game.pov)) {
list remove (objects, game.pov)
}
(assuming you never want to use this function to display a list that includes the player - if you do, you'd need to put the list into a temporary variable and remove the player from it before calling the function)
(in case you've not come across it, the attribute game.pov
refers to the current player object. Using that rather than referring directly to an object named player
is a good habit to get into)
PsychoVyse
29 Apr 2022, 16:36Thanks, looks like that did the trick :)
PsychoVyse
01 May 2022, 10:41I want to also hide invisible objects but I'm sure of how to get a list of all direct children that are just visible ones only. I kind of need to make my own version of GetDirectChildren() but I don't know how.
PsychoVyse
01 May 2022, 10:50Nevermind, I fixed it with this line after the last one removing the player object pov.
visibleobjectsonly = FilterByAttribute(objects, "visible", true)
Then replaced the use of "objects" going forwards with "visibleobjectsonly".
So the full function is this now:
<function name="FancyObjectList" parameters="preList, objects, postList, empty, joiner" type="string"><![CDATA[
if (not IsDefined ("joiner")) {
joiner = "and"
}
if (TypeOf (objects) = "object") {
objects = GetDirectChildren (objects)
}
while (ListContains (objects, game.pov)) {
// Remove the game player object from the scope of the list
list remove (objects, game.pov)
}
visibleobjectsonly = FilterByAttribute(objects, "visible", true)
if (ListCount (visibleobjectsonly) = 0) {
if (IsDefined ("empty")) {
return (empty)
}
else {
return ("")
}
}
else {
result = ""
itemsLeft = ListCount(visibleobjectsonly)
foreach (item, visibleobjectsonly) {
switch (TypeOf(item)) {
case ("object") {
if (DoesInherit (item, "defaultexit")) {
result = result + GetDisplayNameLink(item, "exit")
}
else {
result = result + GetDisplayNameLink(item, "object")
}
}
case ("string") {
result = result + item
}
default {
result = result + ToString (item)
}
}
itemsLeft = itemsLeft - 1
if (itemsLeft > 0) {
if (itemsLeft > 1 or (GetBoolean(game, "oxfordcomma") and not ListCount (visibleobjectsonly) = 2)) {
result = result + ", "
}
else {
result = result + " "
}
if (itemsLeft = 1) {
result = result + joiner + " "
}
}
}
result = preList + result + postList
return (Trim (result))
}
]]></function>
mrangel
01 May 2022, 11:12I want to also hide invisible objects but I'm sure of how to get a list of all direct children that are just visible ones only. I kind of need to make my own version of GetDirectChildren() but I don't know how.
You could also use RemoveSceneryObjects
if that's useful.
objects = RemoveSceneryObjects (objects)
That removes objects that are scenery, objects that aren't visible, and the player object. It's what the core function FormatObjectList
uses.