Axe Software Forums
  Quest Developer Forum
  Not again...


Author Topic:   Not again...
Mega posted 14-10-2001 01:59 GMT     
I tried to solve this one on my own. I really did. But it just won't woooooooooooooooooooooooooork!!!!!!!!!!!!!

Basically, the long and short of it is, I wrote a function (not a command) called Resolve, which was meant to accept an object parameter (a real name or an alias) and convert it into the actual object name so it can be interacted with. Simple, right? Well, for some reason, when I invoke the function, it runs TWICE when it should only run once, and doesn't do what it's supposed to. I've tried everything I could think of, declared tons of useless variables to try to control the code's sequence, and it just won't do what I want!! If someone could recommend a better way to accomplish this, or tell me where I'm once again going wrong, I'd be much obliged.
Here's the code. I'll include the whole thing since I don't know where the problem is.

' Created with QDK 3.02

define game <firstGame>
asl-version <300>
start <outside gate>
game info <Created with QDK 3.02>

startscript {
for each object in game if type <#quest.thing#; openable> then doaction <#quest.thing#; startup>
'here are all the useless control variables
set numeric <res; 0>
set string <tempstring;>
set string <display;>
}
beforeturn {
if not is <$instr(#quest.originalcommand#;look)$;1> and not is <$instr(#quest.originalcommand#;go)$;1> then msg <Ok.>
}

afterturn {
if not is <$instr(#quest.originalcommand#; look)$; 1> then {
outputoff
exec <look;normal>
outputon
}
}


command <open #object#> if action <#object#; open> then doaction <#object#; open> else msg <You can't do that.>
command <close #object#> if action <#object#; close> then doaction <#object#; close> else msg <You can't do that.>
command <go to #object#> if action <#object#; go> then doaction <#object#; go> else msg <You can't go there.>
command <go #object#> if action <#object#; go> then doaction <#object#; go> else msg <You can't go there.>
command <look #lookthing#> {
if is <#lookthing#;> then exec <look; normal>
else {
if (%res% = 0) then {
set <tempstring; #lookthing#>
set <lookthing; $Resolve (#tempstring#)$>
set <res; 1>
}
msg <back from Resolve, lookthing is #lookthing#>
wait
doaction <#lookthing#; look>
set <res; 0>
msg <display is #display#>
}
}
command <talk #talkthing#> {
if is <$instr(#talkthing#; to_)$; 1> then exec <speak #talkthing#; normal>
else exec <speak to #talkthing#; normal>
}
command <speak #talkthing#> {
if is <$instr(#talkthing#; to_)$; 1> then exec <speak #talkthing#; normal>
else exec <speak to #talkthing#; normal>
}
command <objects> msg <#quest.objects#>

end define

define type <openable>
'property <$thisobject$; alias=closed $thisobjectname$>
'prefix
alias=''
closed
lookcloseddesc = null
lookopendesc = null
closedesc = null
opendesc = null
objname = ''

action <startup> {
property <$thisobject$; objname=$thisobjectname$>
set string <lookedat; $thisobject$>
property <$thisobject$; alias=closed $objectproperty(#lookedat#; objname)$>
}
action <open> {
set string <lookedat; $thisobject$>
property <$thisobject$; alias=open $objectproperty(#lookedat#; objname)$>
if property <$thisobject$; closed> then {
if ($objectproperty(#lookedat#; opendesc)$ = null) then {
property <$thisobject$ ;opendesc =You open the #lookedat#.>
}
else {
property <$thisobject$ ;opendesc = $objectproperty(#lookedat#; opendesc)$>
}
property <$thisobject$; not closed>
msg <$objectproperty(#lookedat#; opendesc)$>
}
else msg <The #object# is already open.>
}

action <close> {
set string <lookedat; $thisobject$>
property <$thisobject$; alias=closed $objectproperty(#lookedat#; objname)$>
if not property <$thisobject$;closed> then {
if ($objectproperty(#lookedat#; closedesc)$ = null) then {
property <$thisobject$ ;closedesc =You close the #lookedat#.>
}
else {
property <$thisobject$ ;closedesc = $objectproperty(#lookedat#; closedesc)$>
}
property <$thisobject$; closed>
msg <$objectproperty(#lookedat#; closedesc)$>
}
else msg <The #object# is already closed.>
}

action <look> {
set string <lookedat; $thisobject$>
if property <$thisobject$; closed> then {
if ($objectproperty(#lookedat#; lookcloseddesc)$ = null) then {
set string <lookmessage ;The #lookedat# is closed>
}
else {
set string <lookmessage ;$objectproperty(#lookedat#; lookcloseddesc)$>
}
}
else {
if ($objectproperty(#lookedat#; lookopendesc)$ = null) then {
set string <lookmessage ;The #lookedat# is open>
}
else {
set string <lookmessage ;$objectproperty(#lookedat#; lookopendesc)$>
}
}
msg <#lookmessage#.>
}

end define


define synonyms
end define

define room <outside gate>
description msg <You are standing outside the gate of the gloomy castle of the evil wizard Moldrok.>

define object <gate>
type <openable>
properties <lookcloseddesc = This ancient gate is made of sturdy iron bars, which over the years have become covered in rust and entangling vines. Beyond the gate you can see the castle courtyard; lookopendesc = The ancient, rusty gate lies open, beckoning you into the castle courtyard; opendesc = With an eerie creak, the ancient gate slowly opens.; closedesc = The ancient gate slowly closes.>
action <go> {
if property <$thisobject$; closed> then msg <You can't. The gate is closed.>
else goto <south courtyard>
}
end define

indescription <You are standing>
end define

define room <inventory>

end define

define room <south courtyard>
description msg <You are in the south courtyard.>

end define

define function <Resolve>
msg <starting Resolve with parameter $parameter(1)$>
set string <mylookthing; $parameter(1)$>
if (%res% = 1) then {
msg <returning #display#>
return <#display#>
}
if (%res% = 0) then {
set <display;>
set <res; 1>
if ($numberparameters$ < 1) then msg <Error>
else {
set <mylookthing; $parameter(1)$>
if ($instr(#mylookthing#; at_)$ = 1) or ($instr(#mylookthing#; to_)$ = 1) then {
set <mylookthing; $mid(#mylookthing#;3)$>
}
if exists <#mylookthing#> then {
set <display; $displayname(#mylookthing#)$>
return <#display#>
}
else {
msg <starting script>
for each object in <#quest.currentroom#> {
msg <current thing is #quest.thing#>
msg <its alias is $objectproperty(#quest.thing#; alias)$>
if ($objectproperty(#quest.thing#; alias)$ = #mylookthing#) then {
set <display; #quest.thing#>
msg <returning #display#>
wait
return <#display#>
}
}
if is <#display#;> then msg <I don't see that here>
else return <#display#>
}
}
}

end define

define text <intro>

end define

define text <win>

end define

define text <lose>

end define


Mega posted 14-10-2001 02:43 GMT          
Correction: The function is supposed to convert it to the DISPLAYED name, not the ACTUAL name. The reason for this is, once again, the door thing; if the 'door' object is aliased 'closed door' and I type 'look door', it says 'no such object'. Only typing 'look closed door' had the desired effect -- sometimes...
MaDbRiT posted 14-10-2001 10:08 GMT          
Flippin 'eck Mega, that's a whole lot of code you've written there :-)

Here's my way of writing / using a 'resolve function that does what I think you want it to - I've mercilessly hacked your posted code so that there's just enough left to see it in action.

quote:

' Created with QDK 3.02

define game <firstGame>
asl-version <300>
start <outside gate>
game info <Created with QDK 3.02>

command <look at #lookthing#> do <lookproc>
command <look> exec <look;normal>

command <open #object#> if action <#object#; open> then doaction <#object#; open> else msg <You can't do that.>

end define

define type <openable>
property <$thisobject$; alias=closed $thisobjectname$>
prefix
alias=''
closed
lookcloseddesc = null
lookopendesc = null
closedesc = null
opendesc = null
objname = ''

action <open> {
set string <lookedat; $thisobject$>
property <$thisobject$; alias=open $objectproperty(#lookedat#; objname)$>
if property <$thisobject$; closed> then {
if ($objectproperty(#lookedat#; opendesc)$ = null) then {
property <$thisobject$ ;opendesc =You open the #lookedat#.>
}
else {
property <$thisobject$ ;opendesc = $objectproperty(#lookedat#; opendesc)$>
}
property <$thisobject$; not closed>
msg <$objectproperty(#lookedat#; opendesc)$>
}
else msg <The #object# is already open.>
}

action <look> {
set string <lookedat; $thisobject$>
if property <$thisobject$; closed> then {
if ($objectproperty(#lookedat#; lookcloseddesc)$ = null) then {
set string <lookmessage ;The #lookedat# is closed>
}
else {
set string <lookmessage ;$objectproperty(#lookedat#; lookcloseddesc)$>
}
}
else {
if ($objectproperty(#lookedat#; lookopendesc)$ = null) then {
set string <lookmessage ;The #lookedat# is open>
}
else {
set string <lookmessage ;$objectproperty(#lookedat#; lookopendesc)$>
}
}
msg <#lookmessage#.>
}

end define


define synonyms
end define

define room <outside gate>
description msg <You are standing outside the gate of the gloomy castle of the evil wizard Moldrok.>

define object <gate>
type <openable>
properties <lookcloseddesc = This ancient gate is made of sturdy iron bars, which over the years have become covered in rust and entangling vines. Beyond the gate you can see the castle courtyard; lookopendesc = The ancient, rusty gate lies open, beckoning you into the castle courtyard; opendesc = With an eerie creak, the ancient gate slowly opens.; closedesc = The ancient gate slowly closes.>
action <go> {
if property <$thisobject$; closed> then msg <You can't. The gate is closed.>
else goto <south courtyard>
}
alias <iron gate>
end define

indescription <You are standing>
end define

define room <inventory>

end define

define room <south courtyard>
description msg <You are in the south courtyard.>

end define

define procedure <lookproc>
if is <#resolved#;> then {
if not action <$resolve$;look> then {
exec <look at $resolve$; normal>
set string <resolved;>
}
else {
doaction <$resolve$;look>
set string <resolved;>
}
}
end define

'This function returns the display name of the object #lookthing# no matter
'whether the content of #lookthing# is the alias or real name of the object.
'If you want to return the real name instead, change the line thet reads
' set <resolved;$displayname(#quest.thing#)$>
' to
' set <resolved;#quest.thing#>

define function <resolve>
set string <resolved;#lookthing#>
for each object in <#quest.currentroom#> {
set <display;$displayname(#quest.thing#)$>
if (#lookthing# = #display#) or (#lookthing# = #quest.thing#) then {
set <resolved;$displayname(#quest.thing#)$>
}
}
return <#resolved#>
end define

define text <intro>

end define

define text <win>

end define

define text <lose>

end define


I'm not promising this code is perfect or bug free, but it seems to work in my limited testing and it is a whole lot smaller!

Al

MaDbRiT posted 14-10-2001 10:20 GMT          
Oh yes..

I only 'reworked' the code that deals with 'look at' the gate object in the above, you'd need to make your own arrangements for dealing with your user commands like 'open & close', these can still use 'resolve' though and it was that function I was trying to demo here. :-)

Al

Mega posted 14-10-2001 18:30 GMT          
That did it!!!! Many thanx!!!!
There were a few little kinks to work out, but now it's running exactly as it should. I'd still like to know why the hell the function was running twice in a row, though :-)
MaDbRiT posted 14-10-2001 18:41 GMT          
Mega wrote

quote:

I'd still like to know why the hell the function was running twice in a row, though.

I think because your code which is a command then runs the 'look' command with the normal option.

One iteration for the original, one for the 'exec' ...

I used a 'toggle' variable in my code to prevent that.

Al

Mega posted 14-10-2001 19:32 GMT          
Actually, no you didn't. Add the following line to the very beginning of your resolve function: msg <starting resolve>
Now run it. The message will print about four times, at least. What the hell is going on?! Functions are only supposed to execute when you call them!!!
MaDbRiT posted 14-10-2001 22:41 GMT          
quote:

Actually, no you didn't. Add the following line to the very beginning of your resolve function: msg <starting resolve>
Now run it. The message will print about four times, at least. What the hell is going on?! Functions are only supposed to execute when you call them!!!

Oh yes I did... the LOOK procedure is the thing being run twice, my 'toggle' is intended to make that do different things on each iteration. Agreed 'prevent that' was a bad choice of words, what I should have written was 'prevent the second call from having an adverse affect on the game.'

Using exec <look> inside the Look procedure means the look proc gets called twice. As the look procedure calls the resolve function in three different places it follows that means more than one call to the function will usually be made. It will probably be two calls, but more are possible.

Therein is the reason a 'msg <whatever>' in the top of the function is printed repeatedly. Remember that the function is called every time the code '$resolve$' is processed. In the case of looking at the iron gate, this is twice.

So as the function is being called from the procedure more than once on some occasions it is only being called when asked for by the code :-)

Because functions are fast, and as written mine doesn't actually print anything, I didn't bother to assign the result of the call to the function to a variable, just let the code re-evaluate the function whenever required. Had I assigned the result of the first call of $resolve$ to a variable and made my tests against that, the code would not need to call the function again. As the repeated calls don't show (or matter) unless you have the function printing things to the screen (in which case it ought to be a procedure) I didn't bother about it overly much. :-)

Al


MaDbRiT posted 14-10-2001 22:55 GMT          
Oh yeah..

In point of fact Mega, the code above is entirely dependent on the 'look proc' being called twice and the 'toggle' controls that.

First call (by direct user command) uses the 'resolve' function to establish just what object the player wants to manipulate, it then sets the toggle and calls 'exec <look at #lookthing# ;normal>.

Because on checking the toggle it is set, this time through the code actually performs the 'look' function - calling '$resolve$' again where needed. After performing the actions - it resets the toggle and the sequence is over.

Without the toggle to check the code would either not work at all - or loop indefinitely.


Al