I'm creating a dungeon crawling RPG like Nethack, Rogue, etc... and I need the enemies to only move when the player moves or takes an action.
I understand how the step_rand(ref) works but putting it into practice in the way described way is bugging me. I tried to put it in an IF to check whether the player is moving - if(usr.Move(1)) - but that comes up with an error involving Enter.null. Anyone got any ideas?
Thank in advance
- Milo
ID:164448
![]() Jun 7 2007, 8:14 am
|
|
![]() Jun 7 2007, 8:26 am
|
|
You can make enemies move by directly overwriting the Move() proc... but ony if you know what you are doing (meaning, read about Move() in both DM Reference [F1] and DM Guide... this is very important if you do not want to have a headache such as why an atom is unable to move if you modify Move())
|
You can probably do something like:
mob Of course that's the simple version, I leave it up to you to do the fun stuff. |
Nadrew wrote:
You can probably do something like: mob Probably want to make this for mob/player or something, since when all those monsters step_rand(), they'll also be calling Move(), and you'll have one hell of a loop. I'd definitely set this up through the Move() proc though, like Nadrew has. |
Ok, Nadrew, here's how I implemented your code:
Move() By the way, monster_move() is a proc for testing whether the monster is an NPC. Here it is: monster_move() |
mob
proc Wander() sleep(10) step_rand(src) src.Wander() When you want certain mobs to walk automatically New() ..() Wander() That's how I got my npcs to move it just takes a little longer coding. |
For a more roguelike feel, I'd suggest an action schedule. Each mob will schedule their next action, and the schedule will proceed only when the player schedules something.
Naturally: this is going to be complicated. You should've expected this when setting forth to create a roguelike. var/list/actionSchedule = list() //list containing times for actions to be taken (actually, that wasn't as bad as I was expecting) And that's the groundwork for what you need. Now: whenever the player takes an action, add the time of their next move to the schedule (if the action takes 20 units, then scheduleAction(usr, 20)). Then, lock the player's actions (to be unlocked later, in takeTurn()), and call advanceTheClock(). For mobs besides the player, takeTurn() will have the AI perform one action, such as moving or attacking, then scheduling the next action. Additioanlly, all non-player mobs should do a scheduleAction() call, so that they're active. If a mob isn't in the action schedule, then they won't do anything. You can, of course, exploit this to keep only the mobs you want to be doing anything (as in, they're on the same level as the player) in the schedule, disabling the AI of any other mobs. And, other important detail: because worldtime is totally arbitrary, you can decide how to use it. A step could be 1, or it could be 1000. It doesn't have to have anything to do with ticks. |