Random NPC Movement Procedure (Update)
Cryophile
21 Jun 2005, 15:42Since everyone was complaining about my bad coding habits and laziness, I updated my npc_move procedure considerably. Here's the new version:
The first parameter is the object you want to move. Ignore the enemy and dungeon properties... that was for my game so enemies can't enter cities. If you don't use those two properties than you will be fine. Go ahead and remove them if they bother you...
Each object that can use this procedure has a custom action called move that simply displays a msg when the enemy moves. An example is: The orc runs away.
define procedure <npc_move>
set string <direction[1]; north>
set string <direction[2]; south>
set string <direction[3]; east>
set string <direction[4]; west>
set string <direction[5]; northwest>
set string <direction[6]; northeast>
set string <direction[7]; southwest>
set string <direction[8]; southeast>
set string <direction[9]; up>
set string <direction[10]; down>
set string <temp; $parameter(1)$>
set string <locob; $locationof(#temp#)$>
set string <locob; $locationof(#temp#)$>
set numeric <rand; $rand(1;10)$>
if property <#locob#; #direction[rand]#> then {
if ( $locationof(#temp#)$ = #quest.currentroom# ) then doaction <#temp#; move>
move <#temp#; $objectproperty(#locob#;#direction[rand]#)$>
}
else do <npc_move(#temp#)>
}
else {
if ( $locationof(#temp#)$ = #quest.currentroom# ) then doaction <#temp#; move>
move <#temp#; $objectproperty(#locob#;#direction[rand]#)$>
end define
The first parameter is the object you want to move. Ignore the enemy and dungeon properties... that was for my game so enemies can't enter cities. If you don't use those two properties than you will be fine. Go ahead and remove them if they bother you...
Each object that can use this procedure has a custom action called move that simply displays a msg when the enemy moves. An example is: The orc runs away.
Arbutus
21 Jun 2005, 21:39Thanks for that; it was inspiring. I was using an older procedure that had a set array of rooms available to the NPC (because I wasn't familiar with room properties at the time). This is more natural and tidier.
I put the variable declarations in the startscript so they won't be defined every time the procedure runs. I added a couple more directions. I also cut out the re-run line because when a direction is not available, the NPC just stands there for that cycle and I like that.
If it's a corner, the NPC will stand longer, but this can be changed by adding another direction that when tested causes the NPC to remain.
I put the variable declarations in the startscript so they won't be defined every time the procedure runs. I added a couple more directions. I also cut out the re-run line because when a direction is not available, the NPC just stands there for that cycle and I like that.
If it's a corner, the NPC will stand longer, but this can be changed by adding another direction that when tested causes the NPC to remain.
paul_one
22 Jun 2005, 09:16That shouldn't work.
If it does there's something wrong in Quest, seeing as how you don't have an opening bracket on your second if.
You also have two sections of code doing exactly the same thing, even though one's in the "then" of an if, and the other is in the "else".
Better code would be two bits, like so:
Should do exactly what you had before - just about.
Then again that is a totally odd procedure... You're saying:
"if the property is (north/south/whatever) then do the object action and move the object... If it's NOT the property (north/south/whatever) then STILL do the object action and move the object.
Oh, and go into a loop if the room property is north/south/whatever and the location isn't the current room.
That's really strange.
I'm taking it the object action is just a script that the game maker usually should use to print a message of "#object# leaps to the #direction# gracefully" or something similar...
If it does there's something wrong in Quest, seeing as how you don't have an opening bracket on your second if.
You also have two sections of code doing exactly the same thing, even though one's in the "then" of an if, and the other is in the "else".
Better code would be two bits, like so:
[b]startscript {
' Added to startscript so only defined once at game start[/b]
set string <direction[1]; north>
set string <direction[2]; south>
set string <direction[3]; east>
set string <direction[4]; west>
set string <direction[5]; northwest>
set string <direction[6]; northeast>
set string <direction[7]; southwest>
set string <direction[8]; southeast>
set string <direction[9]; up>
set string <direction[10]; down>
}
define procedure <npc_move>
set string <temp; $parameter(1)$>
set string <locob; $locationof(#temp#)$>
[b]' Deleted uneeded line[/b]
set numeric <rand; $rand(1;10)$>
if property <#locob#; #direction[rand]#> then {
if [b]not ( #locob# = #quest.currentroom# ) then do <npc_move(#temp#)>[/b]
}
if ( [b]#locob#[/b] = #quest.currentroom# ) then {
doaction <#temp#; move>
move <#temp#; $objectproperty(#locob#;#direction[rand]#)$>
}
end define
Should do exactly what you had before - just about.
Then again that is a totally odd procedure... You're saying:
"if the property is (north/south/whatever) then do the object action and move the object... If it's NOT the property (north/south/whatever) then STILL do the object action and move the object.
Oh, and go into a loop if the room property is north/south/whatever and the location isn't the current room.
That's really strange.
I'm taking it the object action is just a script that the game maker usually should use to print a message of "#object# leaps to the #direction# gracefully" or something similar...
Cryophile
22 Jun 2005, 15:35Lol I never even noticed that. I removed some of the script concerning a few properties you wouldn't need - the enemy and dungeon properties. I forgot to remove those lines as well. If you can fix it up a bit it will work. I was in a hurry and I didn't bother to read through the procedure when I was editing it.
Arbutus
22 Jun 2005, 17:05That's why I said it was inspiring. I didn't use the same code, it just got me to write was I was planning. hehe I see Tron agrees with my startscript declarations.
Cryophile
22 Jun 2005, 18:04It's nothing like the script that I use. I quickly tried to erase everything that was Shadow Project specific... I obviously butchered my code beyond comprehension. Most of what is there is either unneeded or now wrong 
You can get the gist of it though... If anyone wants I'll post the full code or my game code (83k but mostly procedures and dialogue)

You can get the gist of it though... If anyone wants I'll post the full code or my game code (83k but mostly procedures and dialogue)
steve the gaming guy
22 Jun 2005, 20:49I probably need to revisit this question once my maze question is answered but in reference to an NPC moving around, I'm reading this as the NPC moving in random directions.
What if I had a maze of rooms (about 40 rooms) and I had one NPC that will randomly appear in only three of them? Would that be an entirely different monster of a code?
What if I had a maze of rooms (about 40 rooms) and I had one NPC that will randomly appear in only three of them? Would that be an entirely different monster of a code?
francisstokes
22 Jun 2005, 21:57I cant imagine the being hard to code.mabey something like:
define procedure <npc_move>
if ( $rand(1;3)$ = 1 ) then move <npc; 1>
if ( $rand(1;3)$ = 2 ) then move <npc; 2>
if ( $rand(1;3)$ = 3 ) then move <npc; 3>
end define
steve the gaming guy
23 Jun 2005, 05:04...hard to a semi-non-programmer like me.
Thanks, I'll try that...however, there might be a twist here. If the player enters the room and the NPC is there, I want the NPC to stay there as long as the player remains in the room. I'm thinking an if/then statement of some sorts would solve that.

Thanks, I'll try that...however, there might be a twist here. If the player enters the room and the NPC is there, I want the NPC to stay there as long as the player remains in the room. I'm thinking an if/then statement of some sorts would solve that.
francisstokes
23 Jun 2005, 06:44Ok for that i would say:
That should keep you npc in the same room, and if you leave it will start the moving procedure again.You need to put those procedures in the after turn in the game properties (i assume your using QDK?).
I hope that helps!
define procedure <npc_stay>
if here <npc> then flag on <npc_here>
if not here <npc> and flag <npc_here> then flag off <npc_here>
end define
'well,that was easy :)
define procedure <npc_move>
if not flag <npc> then {
if ( $rand(1;3)$ = 1 ) then move <npc; 1>
if ( $rand(1;3)$ = 2 ) then move <npc; 2>
if ( $rand(1;3)$ = 3 ) then move <npc; 3>
}
end define
That should keep you npc in the same room, and if you leave it will start the moving procedure again.You need to put those procedures in the after turn in the game properties (i assume your using QDK?).
I hope that helps!
paul_one
23 Jun 2005, 09:56Or you could put the code into one procedure and call that procedure when the player enters the room:
procedure (maze_guy)
if $rand(1;10)$ then move <guy; #quest.currentroom#>
end procedure
enter script (room1)
call procedure
end script
exit script (room1)
move <guy; void>
end script
that gives a 1 in 10 chance.
procedure (maze_guy)
if $rand(1;10)$ then move <guy; #quest.currentroom#>
end procedure
enter script (room1)
call procedure
end script
exit script (room1)
move <guy; void>
end script
that gives a 1 in 10 chance.