Jump to content


Tips on advanced AI patrolling?


26 replies to this topic

#26 Obsttorte


    Scripting guru, Mapper

  • Active Developer
  • PipPipPipPipPip
  • 5823 posts

Posted 11 May 2018 - 03:08 PM

The script looks good so far.


Some notes:

  • Instead of storing the name of the target marking the start of the patrol route you should use the entity directly (you'll probably need it anyways). Either use getEntityKey("target0") or getTarget(0)
  • if (m_current_patrol_duration == m_max_patrol_duration) You probably want to use >= here, to avoid the condition to not be met due to rounding errors (unlikely, but never say never ;) )
  • iirc you cannot instantiate a new patrol to an ai by simple adding a path_corner as a target after spawn. What may work (haven't tested it) is to first issue a stopMove() on the ai and then add the path_corner as a target (preferable overriding an older one if existent) and issue a restartPatrol() on the ai. The ai will only use the target, though, if there is no more pathing information left for it, and I am not sure whether the stopMove() command will delete the older one if existent. The code is a bit hard to understand in that regard. You have to test it.

FM's: Builder Roads, Old Habits, Old Habits Rebuild
WIP's: Several. Although after playing Thief 4 I really wanna make a city mission.
Mapping and Scripting: Apples and Peaches
Sculptris Models and Tutorials: Obsttortes Models
My wiki articles: Obstipedia
Let's Map TDM YouTube playlist: ObstlerTube
Texture Blending in DR: DR ASE Blend Exporter

End of shameless self promotion.

#27 Rooz



  • Member
  • PipPip
  • 22 posts

Posted 11 May 2018 - 09:31 PM

I'm getting closer. Passing the patrol's starting path_corner was giving me issues until I decided to just use a random entity as a spawnarg storage. There's gotta be a better way to do that, but this one works. In my case, the "patrol_base" is a nice rug.


You're right that changing a spawnarg doesn't initiate new behavior. Unfortunately, the stopMove/restartPatrol didn't either. The most I got it working was making the backup walk to the first corner (with the path kicks off) and then stand there. I got real excited the first time for about 3 seconds. I see that Grayman worked on the restartPatrol code. Maybe he has an idea.


Edit: with the current_duration == max_duration, it was the easiest way to have the situation occur once. I don't like using a == when things are getting incremented either... it'll do while I'm still learning though.

object patrol : ai_darkmod_base {
    float  m_current_patrol_duration; 	//duration in seconds
    float  m_max_patrol_duration; 		//time in minutes of expected patrol loop, spawnarg
    float  m_update_period; 			//going to be a constant 1 second
    entity m_route; 					//spawnarg target0
    void   init();
    void   updateLoop();
void patrol::init() {
	m_current_patrol_duration = 0.0;
        m_max_patrol_duration = getFloatKey( "max_patrol_duration" );
	m_update_period = 1.0; 				//checks every second
	m_route = getEntityKey("target0");
	thread updateLoop();
void patrol::updateLoop() {
    while (!AI_DEAD || !AI_KNOCKEDOUT)
		if (m_current_patrol_duration == m_max_patrol_duration)
			$patrol_base.setKey("missing_patrol", m_route.getKey("name"));
		m_current_patrol_duration = m_current_patrol_duration + 1.0;
		wait( m_update_period ); // wait a second

object captain : ai_darkmod_base {
	float dummy;
	entity patrol_start;
	void DispatchSearch();
	void init();
	void updateLoop();
void captain::init() {
	dummy = 1.0;
	thread updateLoop();
void captain::updateLoop() {
    while (!AI_DEAD || !AI_KNOCKEDOUT) { wait(5); }
void captain::DispatchSearch() {
	patrol_start = $patrol_base.getEntityKey("missing_patrol");
	sys.println("DispatchSearch fired");
	sys.println("patrol starting at " + $backup_1.getKey("target0"));

Edited by Rooz, 11 May 2018 - 09:33 PM.

Reply to this topic


Also tagged with one or more of these keywords: ai

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users