QuestJS icon indicating copy to clipboard operation
QuestJS copied to clipboard

getContents() is undefined

Open Woodhouse3D opened this issue 1 year ago • 9 comments

I'm working on a game and I've found that I need to be able to check for every object of a certain type in a room.

however, the function getContents() is undefined for some reason.

Fortunately, I eventually discovered a workaround: const get_all_children = function(_room) { var list = scopeBy(item => item.isAtLoc(_room)) var newlist = list list.forEach(function(thingy){ newlist = newlist.concat(get_all_children(thingy)) }) return newlist }

Woodhouse3D avatar Nov 11 '24 00:11 Woodhouse3D

That's great!

To build off of that (using your script), ThePix might be more inclined to add it like this (which builds off of existing code and uses the same "style" as (I think) Pixie would):

//Edited to use ThePix's getContents suggestion

function getContents(obj) {
  if (obj.getContents) return obj.getContents()
  return []
}

function getDirectChildren(o){
  return getContents(o); 
}

function getAllChildren(o) {
  const directChildren = getDirectChildren(o);
  var allChildren = directChildren;
  directChildren.forEach(function(c){
    allChildren = allChildren.concat(getAllChildren(c));
  });
  return allChildren;
}

KVonGit avatar Nov 23 '24 08:11 KVonGit

however, the function getContents() is undefined for some reason.

I found it as a prototype function (and I used that code to make the getContents() function above), but the prototype function seems to only work for rooms. w.lounge.getContents() will work, but if you have a foo item (not a room), w.foo.getContents() will throw an error.

KVonGit avatar Nov 23 '24 08:11 KVonGit

Interesting. Secondary issue: COMPONENT() objects are not considered to be isAtLoc of their parents..is this a bug or intended? I haven't found a workaround yet.

Woodhouse3D avatar Nov 23 '24 13:11 Woodhouse3D

UPDATE, I did some testing and I've found what was the problem. getContents() is a method of objects. For instance, here is how its supposed to be used: msg("OBJECTS HERE: " + formatList(w["lounge"].getContents(world.PARSER), {article:INDEFINITE, lastJoiner:'and'})) + "."

Basicaly, getContents(my_room) isn't defined. However it's somewhat ambiguous in the docs what the syntax is. I blame a lack of consistent formatting.

Woodhouse3D avatar Nov 23 '24 17:11 Woodhouse3D

Basicaly, getContents(my_room) isn't defined. However it's somewhat ambiguous in the docs what the syntax is. I blame a lack of consistent formatting.

Yeah, it's only set up to do w.my_room.getContents() (or w["my_room"].getContents()), as a method. I used the script from that to make the function last night:

function getContents(o, situation) {
  const list = [];
  for (let key in w) {
    if (w[key].isAtLoc(o.name, situation)) {
      list.push(w[key]);
    }
  }
  return list;
}

I would question Pixie's logic, but, every time I've ever questioned Pixie's logic, I've always felt silly and like I should have understood all along once it was explained to me.


Interesting. Secondary issue: COMPONENT() objects are not considered to be isAtLoc of their parents..is this a bug or intended? I haven't found a workaround yet.

Hrmm.... I think Pixie is using isAtLoc for all sorts of things when loading a game, finishing a turn, etc.

So, it might be intentional.

KVonGit avatar Nov 23 '24 18:11 KVonGit

You know... If we did this in the forum, there is a chance that people with much more JS knowledge would help out. They probably won't because most of them only frequent the Quest Forum, but there is a chance that mrangel or someone like that might see all this activity and become interested.

(I know I was the one who advised posting issues here, but that was really only because it was more likely to get Pixie's attention once he's no longer tied up.)

KVonGit avatar Nov 23 '24 18:11 KVonGit

QuestJS needs the counterpart of this Quest 5 function (if it doesn't already have it somewhere):

https://docs.textadventures.co.uk/quest/functions/contains.html

Contains

Contains (object parent, object child)

Returns a boolean - true if the child object is contained by the parent. This doesn’t necessarily mean that there is a direct parent-child relationship - for example if object A has parent B, and B has parent C, then

 Contains(C, A)

will return true.

KVonGit avatar Nov 23 '24 18:11 KVonGit

Okay, I think I fixed getAllChildren to work with components too.

function getDirectChildren(o){
  const list = [];
  for (let key in w) {
    if (w[key]["loc"] === o.name) {
      list.push(w[key]);
    }
  }
  return list;
}

function getAllChildren(o) {
  const directChildren = getDirectChildren(o);
  var allChildren = directChildren;
  directChildren.forEach(function(c){
    allChildren = allChildren.concat(getAllChildren(c));
  });
  return allChildren;
}

KVonGit avatar Nov 23 '24 18:11 KVonGit

As KVonGit says, you need to do it as room.getContents(), rather than getContents(room). The function is an attribute of the room.

If you want a function like that, I would suggest:

function getContents(obj) {
  if (obj.getContents) return obj.getContents()
  return []
}

That will work for containers too, but can also handle objects without contents.

To filter, you might want to look at filterByAttribute

ThePix avatar Dec 05 '24 20:12 ThePix