Taking scenery objects
cdutton184
19 Dec 2013, 12:46Alex, I've noticed an error recently. If you create scenery objects and TAKE them within the game they become visible objects. Very annoying. You can fix them by doing a Run Script on scenery objects TAKE tab and create a message for each one (which I've now done now for my last couple of games.)
The Pixie
19 Dec 2013, 14:22I think this is by design.
Alex
19 Dec 2013, 15:21Yes, so you can see it in your inventory!
I'm struggle to understand in what scenario you would want scenery objects to be taken anyway...
I'm struggle to understand in what scenario you would want scenery objects to be taken anyway...
privateer
19 Dec 2013, 15:34Alex, I think you might have misunderstood the problem. I mentioned it in an email to you a while back. If the player decides to ATTEMPT to take a scenery object, that object will cease to be a scenery object. For example:
You're standing next to a lake. The water looks cool and inviting.
Exam water (a scenery object)
"Deep and lovely"
Get water
"You can't take it" (but now when you look at your location...)
You're standing next to a lake. The water looks cool and inviting. You can also see water. (suddenly the water is not scenery)
As Craig pointed out, you can circumvent this issue by making take a script. But if you like LOTS of scenery objects to make the game world nice and detailed, that's quite a chore!
Cheers.
You're standing next to a lake. The water looks cool and inviting.
Exam water (a scenery object)
"Deep and lovely"
Get water
"You can't take it" (but now when you look at your location...)
You're standing next to a lake. The water looks cool and inviting. You can also see water. (suddenly the water is not scenery)
As Craig pointed out, you can circumvent this issue by making take a script. But if you like LOTS of scenery objects to make the game world nice and detailed, that's quite a chore!
Cheers.
Alex
19 Dec 2013, 15:35OK if this is a bug then please add it to the issue tracker https://quest.codeplex.com/workitem/list/advanced
cdutton184
20 Dec 2013, 10:53It is a bug. I've played my older games and other games using version 5.3 onwards (that's when it started, it seems). Any game before that seems OK.
The reason for a GET (scenery object) would be due to a takeable scenery object, described in the room description, required a response e.g. 'It's too heavy.' or 'It's fixed to the wall.' or 'You don't need it.', etc.
In someone else's game, for example, I tried GET GATE, and it appeared in the object list as 'You can see a gate2.'
I'll report the bug if it hasn't been done be someone else already.
The reason for a GET (scenery object) would be due to a takeable scenery object, described in the room description, required a response e.g. 'It's too heavy.' or 'It's fixed to the wall.' or 'You don't need it.', etc.
In someone else's game, for example, I tried GET GATE, and it appeared in the object list as 'You can see a gate2.'
I'll report the bug if it hasn't been done be someone else already.
privateer
20 Dec 2013, 20:34I haven't reported it, so if you don't mind perhaps you would?
Liam315
21 Dec 2013, 14:26Ahhhhhh. I've noticed this as well, I thought there was a problem in my code somewhere and I couldn't work out what was going wrong. Glad to know it's not just me.
There are plenty of scenarios where you might want to do this. Masking the importance of an object for one so the description isn't just a bombardment of objects within a room shouting "look at me, take me without thinking because you'll probably need me!" Or an object you might not need but is fun to take anyway either for added realism or for some little bonus task. OK, that's only 2 scenarios but other people may have their reasons.
EDIT: I've found the problem, it exists in the DoTake function. Where it has
It's running that code indiscriminately whether the object is successfully taken or not.
By replacing DoTake with this you can stop it from happening while still changing the scenery attribute if the take is successful.
The key part is at the bottom. I've taken the original code that I posted at the top out and at the very bottom of the script placed this. This is only a quick fix though, as it doesn't account for scenery objects being moved around the room, only if you take the object and it ends up in your inventory.
Hope this helps.
Alex wrote:I'm struggle to understand in what scenario you would want scenery objects to be taken anyway...
There are plenty of scenarios where you might want to do this. Masking the importance of an object for one so the description isn't just a bombardment of objects within a room shouting "look at me, take me without thinking because you'll probably need me!" Or an object you might not need but is fun to take anyway either for added realism or for some little bonus task. OK, that's only 2 scenarios but other people may have their reasons.
EDIT: I've found the problem, it exists in the DoTake function. Where it has
if (GetBoolean ( object , "scenery" )) {
object.scenery = false
}
It's running that code indiscriminately whether the object is successfully taken or not.
By replacing DoTake with this you can stop it from happening while still changing the scenery attribute if the take is successful.
prefix = ""
if (ismultiple) {
prefix = GetDisplayAlias(object) + ": "
}
if (object.parent = game.pov) {
msg (prefix + DynamicTemplate("AlreadyTaken", object))
}
else if (not ListContains(ScopeReachable(), object)) {
msg (prefix + DynamicTemplate("ObjectNotOpen", GetBlockingObject(object)))
}
else {
volume = 0
continue = true
foreach (obj, GetAllChildObjects(game.pov)) {
if (HasInt(obj, "volume")) {
volume = volume + obj.volume
}
}
if (not Contains(game.pov, object)) {
volume = volume + GetVolume(object,true)
}
if (HasInt(game.pov, "maxvolume")) {
if (volume > game.pov.maxvolume) {
continue = false
if (HasString(game.pov, "containerfullmessage")) {
message = prefix + game.pov.containerfullmessage
}
else {
message = prefix + DynamicTemplate("FullInventory", object)
}
}
}
children = GetDirectChildren(game.pov)
if (HasInt(game.pov, "maxobjects")) {
if (game.pov.maxobjects > 0) {
if (ListCount(children) >= game.pov.maxobjects) {
continue = false
if (HasString(game.pov, "containermaxobjects")) {
message = prefix + game.pov.containermaxobjects
}
else {
message = prefix + DynamicTemplate("MaxObjectsInInventory", object)
}
}
}
}
if (continue = false) {
msg (message)
}
else {
found = true
takemsg = object.takemsg
switch (TypeOf(object, "take")) {
case ("script") {
if (ismultiple) {
msg (prefix)
}
do (object, "take")
takemsg = ""
}
case ("boolean") {
if (object.take = true) {
object.parent = game.pov
if (takemsg = null) {
takemsg = DynamicTemplate("TakeSuccessful", object)
}
}
else {
found = false
}
}
case ("string") {
object.parent = game.pov
takemsg = object.take
}
default {
found = false
}
}
if (not found and takemsg = null) {
takemsg = DynamicTemplate("TakeUnsuccessful", object)
}
if (LengthOf(takemsg) > 0) {
msg (prefix + takemsg)
}
if (HasScript(object, "ontake")) {
do (object, "ontake")
}
}
}
if (object.parent = game.pov) {
object.scenery = false
}
The key part is at the bottom. I've taken the original code that I posted at the top out and at the very bottom of the script placed this. This is only a quick fix though, as it doesn't account for scenery objects being moved around the room, only if you take the object and it ends up in your inventory.
if (object.parent = game.pov) {
object.scenery = false
}
Hope this helps.

Pertex
21 Dec 2013, 21:28Liam315 wrote: This is only a quick fix though, as it doesn't account for scenery objects being moved around the room, only if you take the object and it ends up in your inventory.
I think you can't take care for the scenery flag for all commands. If I remember right the problem was taking and then dropping a scenery object (still remaining a scenery object). After dropping a scenery objects in any other room, it could happen that you could not find it any more. So the take command was changed to set scenery to false. But you will still have this problem if you move the object into the inventory by script. So I think the solution is something like this:
if (LengthOf(takemsg) > 0) {
msg (prefix + takemsg)
}
if (HasScript(object, "ontake")) {
do (object, "ontake")
}
if (found and GetBoolean (object, "scenery") and object.parent = game.pov) {
object.scenery = false
}
}
}