[adv3lite] Issues with smelling...

So, I have code like this:

[code]/*
claGhost

This inherits from the Actor class, and defines generic behaviour for ghosts.
*/
class claGhost: Actor ‘;;spirit spook ghost;’
{
// As ghosts, there’s a lot they can’t do (such as pick up items and the like).
feelDesc = ‘{The subj dobj} {is} not solid and cannot ordinarily be touched except by other ghosts.’
shouldNotKissMsg = ‘{The subj dobj} {is} not kissable by mortals, as {that subj dobj} {is} not solid.’
smellDesc = ‘Being a ghost, {the subj dobj} {is} without any kind of scent you can detect.’
shouldNotAttackMsg = ‘{The subj dobj} {is} already dead and a ghost; trying to attack {the subj dobj} {is} pointless.’
}

[…]

npcShamus: claGhost ‘Shamus;;spirit guide;’
{
location = romAutopsyExaminationRoom
isHim = true
desc ()
{
// Salient points - transparent blue; looks as if he’d be in his early 30s if alive; mid-late 50s fashion (sweatshirt, casual shirt, trousers); trimmed looking beard and moustache; cheerful looking.
“<.p>TODO: Shamus desc

”;
}
}

[…]

romAutopsyExaminationRoom: Room ‘Autopsy Examination Room’
{
desc ()
{
// The description for what is going to be called the “Autopsy Examination Room” (yeah, I know) is to be based upon the room where Paul found the organs measurement board.
“<.p>It’s a fairly brightly-lit room with the window, but one whose decorations would have been purely for function. From what you gather some autopsies were conducted in here, though you wouldn’t know it with everything having been stripped from the room, down to the light fixtures. Even the door in here was taken off its hinges. When this place had been open perhaps the white tiles on the walls would’ve been cleaner. As it is, like everything else in this place they’re covered in a layer of grime, having been neglected for years.

”;
}
south: TravelConnector
{
canTravelerPass (traveler)
{
if (npcShamus.location != nil) // So long as Shamus is present, the player is not going to try to leave the location.
{
return (nil);
}
return (true);
}
explainTravelBarrier (traveler)
{
“<.p>You haven’t finished what you came here for.”;
}
travelDesc ()
{
// The epiphany event has happened, so allow the player to leave; give a brief outro and then end the game.
“CCCCCC”;
finishGameMsg (‘To be continued’, []);
}
}
}[/code]

Basically, one room, with one NPC which inherits from a class.

But I’ve come across something odd with the smell command. Specifying just ‘smell’ gets the response “Being a ghost, {the dobj subj} is without any kind of scent you get.” - which is clearly incorrect behaviour, but I am unsure why. Commands like “smell shamus”, “smell me” etc. work as expected. It may be a bug with adv3lite, but I’m more suspecting it’s something dumb I’ve done somewhere down the line.

According to the Adv3Lite Reference manual (adv3Lite/docs/manual/thing.htm#sensory)…

Yours is a single-quoted string.

Jerry

If you use the intransitive form of the SMELL command, there’s no dobj, so there’s nothing for {the subj dobj} to refer to. You need to use <> in place of {the subj dobj} {is}.

If you want to suppress the message about the smell of a ghost altogether in response to an intransitive SMELL command, then set its isProminentSmell property to nil (in which case you don’t need to make the other change above).

Thanks, Eric. But I must admit to not being entirely sure as to why it did things the way it did; it appears the best way for me to fix this is by modifying the Actor class directly.

Modifying the Actor class directly won’t help solve your problem.

When you write a property definition like this:

smellDesc = 'Being a ghost, {the subj dobj} {is} without any kind of scent you can detect.'

The parameter substitution {the subj dobj} will be replaced by the direct object of the command. But when you issue the command SMELL, without no direct object, there is no direct object of the command (the command SMELL causes the smellDesc of everything in range of the player to be shown), so there’s nothing for {the subj dobj} to expand to, hence what you saw.

What you actually want the smellDesc to refer to is not the direct object of the command, but the name of the object it’s defined on, which you can get at by using:

smellDesc = "Being a ghost, <<theNameIs>> without any kind of scent you can detect. "

This doesn’t rely on the ghost being the direct object of the command, and so will work under any circumstances.

But it fact you may not want that, since your smellDesc is reporting not so much a smell as the absence of a smell. So although you want to see your smellDesc in response to the transitive command SMELL GHOST, you probably don’t want to see it in response to an intransitive SMELL command (i.e. a SMELL command with no objects specified). For that reason you probably want to define isProminentSmell = nil on your clGhost class so the smell (or rather the absence of smell) of all the ghosts around won’t be reported when the player just types SMELL.

Ultimately, this is what I did:

[code]modify Actor
{
isProminentSmell = nil
}

/*
claGhost

This inherits from the Actor class, and defines generic behaviour for ghosts.
*/
class claGhost: Actor ‘;;spirit spook ghost;’
{
// As ghosts, there’s a lot they can’t do (such as pick up items and the like).
feelDesc = ‘{The subj dobj} {is} not solid and cannot ordinarily be touched except by other ghosts.’
shouldNotKissMsg = ‘{The subj dobj} {is} not kissable by mortals, as {that subj dobj} {is} not solid.’
smellDesc = ‘Being a ghost, {the subj dobj} {is} without any kind of scent you can detect.’
shouldNotAttackMsg = ‘{The subj dobj} {is} already dead and a ghost; trying to attack {the subj dobj} {is} pointless.’
}[/code]