ThePix / QuestJS

A major re-write of Quest that is written in JavaScript and will run in the browser.
MIT License
74 stars 16 forks source link

Giving Items to NPC's (Problems with adding future items) #84

Closed thaskef closed 2 years ago

thaskef commented 2 years ago

This took me a while to figure out but I finally discovered what is happening with some of my items I was trying to give NPC's:

The Functionality Trying to give a NPC items... Using the receiveItems list.

The Problem Sometimes response for items is wrong (it's mismatched with a predefined response for another item instead of the response I typed out for that specific item). Also, if you try to give an item to the NPC for which there isn't a predefined response (and you fail to provide a catch-all response), it will give this same mismatched response instead of throwing the usual error.

The Cause It took a ton of trial and error to pinpoint what was special about these mismatched response items (giving their response for other items it wasn't intended for) and also what was special about the random items that had a predefined response that was ignored and replaced with the mismatched response....

Finally I realized it was a repeatable bug and occurs when an item is created after the NPC is created (on a line of code further down). So basically to fix this, I can create all of my NPC's at the bottom of the document, or create all my items at the top (? maybe?).

Scope of the Bug This issue happens no matter how you declare the item and the response. (You can use item or test.... and you can use msg or script).

But I just wanted to bring this to your attention. (Perhaps I missed in the documentation in case it said somewhere that all the items needed to be clustered at the bottom of the data.js document?)

(Because if a player goes to one room and gets something and then backtracks and moves back to the original room to give it to the NPC, they're going to run into this bug... When they have more than one item they do this with or if they have items that don't have declared responses there will be an issue as far as I can see).

I've created a minimal data.js that demonstrates the issue for your convenience: In the below example:

"use strict"

createItem("me", PLAYER(), {
    loc:"Room1",
    examine:"a guy",
})

createRoom("Room1", {
    desc:"Big room"
})

createItem("floor_item", TAKEABLE(), {
    loc:"Room1",
    examine:"a thing on the floor",
})

createItem("inventory_item", TAKEABLE(), {
    loc:"me",
    examine:"a thing i have",
})

createItem("other_item", TAKEABLE(), {
    loc:"Room1",
    examine:"wonderful thing",
})

createItem("non_player_character", NPC(true), {
    loc:"Room1",
    examine:"a standard NPC",
    receiveItems:[
        {
            item:w.floor_item,
            msg:"FLOOR ITEM RECEIVED"
        },
        {
            item:w.inventory_item,
            msg:"INVENTORY ITEM RECEIVED"
        },
        {
            item:w.future_item,
            msg:"FUTURE ITEM RECEIVED"
        },
        {
            item:w.another_future_item,
            msg:"ANOTHER FUTURE ITEM RECEIVED"
        },
    ],
})

createItem("future_item", TAKEABLE(), {
    loc:"Room1",
    examine:"an item declared later",
})

createItem("another_future_item", TAKEABLE(), {
    loc:"Room1",
    examine:"an item declared even later",
})
thaskef commented 2 years ago

I just wanted to confirm that the workaround for this is indeed to put all the NPC's at the bottom of the document to avoid creating any items below them.

ThePix commented 2 years ago

Thanks for spotting that. It was just coincidence that in my tests the items were defined first so I had not come across it.

What is happening is when you define your "receiveItems" if the item does not exist at that moment, "item" is set to undefined and that matches things it should not.

I have updated lib/_templates.js so you can use either the item or its name. It you use the name, order does not matter. I have also updated the docs to make this clear.