I'm trying to figure out how to create a verb associated with an NPC's possessions. The examples are:
Take Demon's Sword
and
Grab Demon's Horns.
I can't figure out how to make an object that the game recognizes as "demon's sword" or "demon's horns."
Click the link for a much more efficient method. (http://textadventures.co.uk/forum/quest/topic/n5o624fsz0_kcw0kh6z46a/dealing-with-npcs-possessions#8f079b35-1292-4b9a-8967-65f789f55dfc)
( Also, to make it respond correctly (instead of saying 'You pick it up.' when you initially take it from an NPC), add a line with {once: You take the demon's sword.}{notfirst: You pick it up.}
)
TRANSCRIPT:
You are in a room.
You can see demon.
> take the demon's sword
You take the demon's sword.
> drop it
You drop it.
> get it
You pick it up.
Add an in-room description to your NPC that tells the player he is carrying a sword.
TRANSCRIPT:
You are in a room.
You can see demon.
The demon is carrying a sword.
> get the demon's sword
You take the demon's sword.
> l
You are in a room.
You can see demon.
Example game:
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="NPC possessions">
<gameid>51f2bdf9-9949-4a2a-9a6c-6cc593238a47</gameid>
<version>1.0</version>
<firstpublished>2017</firstpublished>
<feature_advancedscripts />
<scopebackdrop type="script">
foreach (o, GetDirectChildren(demon)) {
list add (items, o)
}
</scopebackdrop>
<appendobjectdescription />
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<object name="demon">
<inherit name="editor_object" />
<inherit name="namedmale" />
<alt type="stringlist" />
<listalias type="string"></listalias>
<inroomdescription><![CDATA[{if sword.parent=demon: <br/>The demon is carrying a sword.<br/>}]]></inroomdescription>
<object name="sword">
<inherit name="editor_object" />
<take />
<alt type="stringlist">
<value>demon's sword</value>
</alt>
<alias>demon's sword</alias>
<takemsg>{once: You take the demon's sword.}{notfirst: You pick it up.}</takemsg>
</object>
</object>
</object>
</asl>
http://docs.textadventures.co.uk/quest/advanced_scope.html
Interesting :p I was just playing with something that's tangentially relevant. I'm also trying to take a box off the demon; who obviously doesn't want to give it up. Here's the 'take' script I have for the box:
if (demon.is_distracted) {
msg ("You grab the box while the demon is distracted")
this.parent = game.pov
this.take = true
}
else {
dmg = GetRandomInt(5, 20)
take_damage (dmg, "The demon sees you reaching for his box, and gives you a slap that makes your ears ring")
}
I figured that's the easiest way to make a box that is initially a challenge to obtain, but later on reverts to the standard behaviour.
@mrangel
Hey, that's pretty good!
@Jador
An easier way would be just putting the sword in the room with the demon and making it scenery.
Then, you wouldn't have to deal with the scope script, and you could put the in-room description on the sword.
Throwing a take script in like mrangel posted would make it much more fun/challenging, too!
NOTE: You'd need a different script under ELSE, though. It appears that mrangel has created a function he's calling in that second line. ...and you'd probably want to put all of that under a firsttime
as well. Then set it up to just print the normal take message for taking the box once it has been moved.
KV: using afirsttime
block doesn't seem to make sense to me. The demon will keep on hitting you as long as you keep on trying to take his object, which seems like perfectly reasonable behaviour. Until you actually manage it, of course, at which point this.take = true
replaces the script attribute with a boolean, restoring the default behaviour for an object that can be taken. I figured that was simpler.
That scope script seems an awful lot of effort. I just made my NPCs containers ("surface" type, so they don't get open or close verbs, and change the prefix to "Carrying"). Then you can see his stuff when you look at him, and in the room description, depending on your settings.
using a firsttime block doesn't seem to make sense to me. The demon will keep on hitting you as long as you keep on trying to take his object...
Oh, I was running my fingertips without thinking it through (and, apparently, without reading your code through). (Sorry!) The this.take
attribute is the way I'd do it.
That scope script seems an awful lot of effort. I just made my NPCs containers
Yep, yep! This is probably the most efficient way to do it, but most new folks seem to be leery of using containers, so I went with the scope (for some reason -- even though it's complicated, too; ha-ha! I'm crazy).
All of the NPCs like this are transparent containers in my last game. (Of course, that was because I had no clue how to use the scope functions back then. )
Recently I've been using the scope script and altering the 'look' script to list the direct children. It seemed to be about the same amount of work as fooling around with all the container settings. Removing 'Open' and 'Close' from the verbs list and all that...
...but making them surfaces is pretty darn slick!!!
REVISED (thanks for the help, mrangel!)
Here's my example script for taking the sword:
if (not this.hasbeenmoved) {
msg ("\"Not so fast!\" roars the demon as he moves the sword out of your reach. \"A game first, I think!<br/><br/>\"Tell me a word that rhymes with DUCK!\"<br/><br/><center><h3>JUST ENTER THE WORD BY ITSELF AND PRESS <b>ENTER</b></h3></center>")
get input {
result = LCase(result)
if (EndsWith(result, "uck")) {
msg ("\"Well played, lad!\" exclaims the demon, handing you his sword and giving you a pat on the back.<br/>")
MoveObject (this, player)
this.alias = "demon's sword"
}
else {
msg ("\"Wrong!\" <br/><br/>The demon laughs at your lack of poetic skill and returns to doing nothing in particular.<br/>")
}
}
}
else {
msg ("You pick it up.")
MoveObject (this, player)
}
TRANSCRIPT:
You are in a room.
You can see a demon.
> get the demon's sword
I can't see that.
> x demon
The demon is green, ugly, and generally nasty-looking.
...and he doesn't appear to like it when you stare at him...
He is carrying a sword.
> get the demon's sword
"Not so fast!" roars the demon as he moves the sword out of your reach. "A game first, I think!
"Tell me a word that rhymes with DUCK!"
You entered: truck.
"Well played, lad!" exclaims the demon, handing you his sword and giving you a pat on the back.
> i
You are carrying a demon's sword.
> drop sword
You drop it.
> get it
You pick it up.
<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="NPC possessions">
<gameid>51f2bdf9-9949-4a2a-9a6c-6cc593238a47</gameid>
<version>1.0</version>
<firstpublished>2017</firstpublished>
<appendobjectdescription type="boolean">false</appendobjectdescription>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<object name="demon">
<inherit name="editor_object" />
<inherit name="namedmale" />
<inherit name="surface" />
<feature_container />
<hidechildren />
<listchildren />
<listchildrenprefix>He is carrying</listchildrenprefix>
<look><![CDATA[The demon is green, ugly, and generally nasty-looking.<br/>...and he doesn't appear to like it when you stare at him...<br/>]]></look>
<scenery type="boolean">false</scenery>
<speak>"No time to talk right now, lad," he says.</speak>
<contentsprefix>who is carrying </contentsprefix>
<object name="sword">
<inherit name="editor_object" />
<look><![CDATA[The Sword of Whatever - once thought to be a myth, but now you know that's not the case!<br/><br/>It's said to have been forged by WhoEvers back in the day, so it's probably a pretty good sword, right?<br/>]]></look>
<take type="script"><![CDATA[
if (not this.hasbeenmoved) {
msg ("\"Not so fast!\" roars the demon as he moves the sword out of your reach. \"A game first, I think!<br/><br/>\"Tell me a word that rhymes with DUCK!\"<br/><br/><center><h3>JUST ENTER THE WORD BY ITSELF AND PRESS <b>ENTER</b></h3></center>")
get input {
result = LCase(result)
if (EndsWith(result, "uck")) {
msg ("<br><b>You entered: " + result + ".<b><br/>")
msg ("\"Well played, lad!\" exclaims the demon, handing you his sword and giving you a pat on the back.<br/>")
MoveObject (this, player)
this.alias = "demon's sword"
}
else {
msg ("\"Wrong!\" <br/><br/>The demon laughs at your lack of poetic skill and returns to doing nothing in particular.<br/>")
}
}
}
else {
msg ("You pick it up.")
MoveObject (this, player)
}
]]></take>
<alt type="stringlist">
<value>demon's sword</value>
</alt>
</object>
</object>
</object>
</asl>
mrangel: http://textadventures.co.uk/forum/quest/topic/n5o624fsz0_kcw0kh6z46a/dealing-with-npcs-possessions#30a1324d-1d3b-4f98-8568-02a9e6385241
http://docs.textadventures.co.uk/quest/tutorial/using_containers.html
EQUIPMENT SYSTEM BASICS:
for an equipment system:
use Object (reference/pointer) Attributes and/or Objectlist (reference/pointer) Attributes, Objects, and Object Types / Types / Inherited Attributes
as for identification/flagging of what Object, there's a few methods:
http://docs.textadventures.co.uk/quest/functions/#string
'StartsWith', 'EndsWith', 'Mid', etc
'HasAttribute', 'HasXXX', 'GetAttribute', 'GetXXX'
'DoesInherit'
Also, using Commands with the identification/flagging and scripting methods mentioned above, an example:
<object name="demon_sword">
</object>
<object name="demon_axe">
</object>
<object name="holy_sword">
</object>
</object name="holy_axe">
</object>
<command name="example_command">
<pattern>example #object_parameter#</pattern>
<script>
if (StartsWith (object_parameter.name, "demon")) {
object_parameter.parent = game.pov
game.pov.equipment_object_attribute = object_parameter
}
</script>
<unresolved>Wrong input: the '#object#' Parameter, looks for that inputted Object ONLY within the room you're currently in, so either you typed in an Object that doesn't exist at all, or it just doesn't exist within the room you're currently in</unresolved>
</command>
Ah, I didn't know about this.hasbeenmoved
. I think I prefer my version though… avoid wrapping an 'if' statement around everything, fewer levels of indentation in case the function later gets big enough that you're scrolling up and down to find the matching braces.