bdmn@Posted: Thu Sep 23, 2010 4:19 pm :
hi guys,

im kidding around with spawning and controling monsters in different ways. as the outcome is not 100% what i wanted, i ask here for help.

in this thread ill show how i spawned the monsters, ill post another thread for the controlling of it.

i implemented several ways to spawn the monster waves and store them into run-time-persistent target_null lists, to keep reference for further controlling.

in the map i got target_nulls for:

blueSpawnPoint01
blueSpawnPoint02
blueSpawnPoint03

redSpawnPoint01
redSpawnPoint02
redSpawnPoint03

spawning my creatures way one: ( a func_spawner comes in handy )

Code:
namespace world{

   float redMonsterCount = 0;
   float blueMonsterCount = 0;

   void reportMonster(){
      sys.println("reporting monster");
      entity target;
      entity list = $redMonsterNulls;
      entity list2 = $blueMonsterNulls;
      sys.println("size of red:" + qListCount(list));
      sys.println("size of blue:" + qListCount(list2));
   }

   string registerRedMonster(entity monster){
      string name = "redMonster_" + redMonsterCount;
      monster.setKey("name", name);
      monster.setKey("target", "ai_tether_behind_3");
      qListInsert($redMonsterNulls, monster);
      redMonsterCount++;   
      return name;
   }   

   string registerBlueMonster(entity monster){
      string name = "blueMonster_" + redMonsterCount;
      monster.setKey("name", name);
      monster.setKey("target", "ai_tether_behind_4");
      qListInsert($blueMonsterNulls, monster);
      blueMonsterCount++;      
      return name;
   }
}


entity createBlueSpawner(){
    sys.setSpawnArg("target","blueSpawn01");
    sys.setSpawnArg("target_1","blueSpawn02");
    sys.setSpawnArg("target_2","blueSpawn03");
    sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
    sys.setSpawnArg("max_active", "30");
    sys.setSpawnArg("delay","4");       
    sys.setSpawnArg("auto_target", "1");
    sys.setSpawnArg("face_enemy", "1");
    sys.waitFrame();
    sys.setSpawnArg("waves","3");
    sys.setSpawnArg("skipVisible", "0");
    sys.setSpawnArg("remove", "0");       
    sys.setSpawnArg("call_spawned","world::registerBlueMonster");
    sys.setSpawnArg("spawn_neverdormant", "1");
    sys.setSpawnArg("spawn_team", "1");    // for spawning loots

    sys.waitFrame();
    entity blueSpawner = sys.spawn( "func_spawner" );
    return blueSpawner;
}


entity createRedSpawner(){
    sys.setSpawnArg("target","redSpawn01");
    sys.setSpawnArg("target_1","redSpawn02");
    sys.setSpawnArg("target_2","redSpawn03");
    sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
    sys.setSpawnArg("max_active", "30");
    sys.setSpawnArg("delay","4");       
    sys.setSpawnArg("auto_target", "1");
    sys.setSpawnArg("face_enemy", "1");
    sys.waitFrame();
    sys.setSpawnArg("waves","3");
    sys.setSpawnArg("skipVisible", "0");
    sys.setSpawnArg("remove", "0");       
    sys.setSpawnArg("call_spawned","world::registerRedMonster");
    sys.setSpawnArg("spawn_neverdormant", "1");
    sys.setSpawnArg("spawn_team", "0");    // for spawning loots

    sys.waitFrame();
    entity redSpawner = sys.spawn( "func_spawner" );
    return redSpawner;
}



void startCreeps(){
    entity redspawner = createRedSpawner();
    sys.waitFrame();
    entity bluespawner = createBlueSpawner();
    sys.waitFrame();
    sys.trigger(redspawner);
    sys.waitFrame();
    sys.trigger(bluespawner);
}

void main(){
    startCreeps();
}



to explain the code:

main function calls startcreeps which spawns two func_spawners. these funcspawners will populate the map. after spawning a monster, the function world::registerBlueMonster or world::registerRedMonster is called which adds the name of the new monster as a target location in a target_null list. so i can iterate over all the monsters for each time during the runtime to give further commands to them.

i experienced some situations where the func_spawner stopped to spawn even if the max_active limit wasnt reached, so i tried to implement it on another way:

Code:
   
#define ForEachTargetOf( ent, target )               \
   float index_##ent;                     \
   ent.removeNullTargets();                  \            
   for( index_##ent = 0; $null_entity != (target = ent.getTarget(index_##ent)); index_##ent++ )

#define qListForEach(list,ent) ForEachTargetOf(list,ent)

namespace world{

   float redMonsterCount = 0;
   float blueMonsterCount = 0;
   entity redMonsterNulls;
   entity blueMonsterNulls;

   void reportMonster(){
      sys.println("reporting monster");
      entity target;
      entity list = $redMonsterNulls;
      entity list2 = $blueMonsterNulls;
      sys.println("size of red:" + qListCount(list));
      sys.println("size of blue:" + qListCount(list2));
   }

   string registerRedMonster(entity monster){
      string name = "redMonster_" + redMonsterCount;
      monster.setKey("name", name);
      qListInsert(redMonsterNulls, monster);
      redMonsterCount++;   
      return name;
   }   

   string registerBlueMonster(entity monster){
      string name = "blueMonster_" + redMonsterCount;
      monster.setKey("name", name);
      qListInsert(blueMonsterNulls, monster);
      blueMonsterCount++;      
      return name;
   }

   void spawnRedWave(){
      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster1 = sys.spawn("monster_tactical_mgun");
      
      string name;
      name = registerRedMonster(monster1);

      $ai_tether_radius_1.setKey("target",name);

      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster2 = sys.spawn("monster_tactical_mgun");
      name = registerRedMonster(monster2);
      
      $ai_tether_radius_1.setKey("target_1",name);

      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster3 = sys.spawn("monster_tactical_mgun");
      name = registerRedMonster(monster3);
      $ai_tether_radius_1.setKey("target_2",name);

      monster1.setWorldOrigin($redSpawn01.getWorldOrigin());
      monster2.setWorldOrigin($redSpawn02.getWorldOrigin());
      monster3.setWorldOrigin($redSpawn03.getWorldOrigin());
      sys.waitFrame();
      sys.trigger($ai_tether_radius_1);
   }

   
   void spawnBlueWave(){
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster1 = sys.spawn("monster_strogg_marine");
      registerBlueMonster(monster1);
      
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster2 = sys.spawn("monster_strogg_marine");
      registerBlueMonster(monster2);
      
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster3 = sys.spawn("monster_strogg_marine");
      
      registerBlueMonster(monster3);
      monster1.setWorldOrigin($blueSpawn01.getWorldOrigin());
      monster2.setWorldOrigin($blueSpawn02.getWorldOrigin());
      monster3.setWorldOrigin($blueSpawn03.getWorldOrigin());
      
   }


   void init(){
      sys.setSpawnArg("name","blueMonsterNulls");
      blueMonsterNulls = sys.spawn("target_null");
      sys.waitFrame();
      sys.setSpawnArg("name","redMonsterNulls");
      redMonsterNulls = sys.spawn("target_null");
   }

}



void sendWaves(){
   while(1){
      world::spawnRedWave();
      sys.waitFrame();
      //world::spawnBlueWave();
      sys.waitFrame();
      sys.wait(2);
   }
}

void reportMonster(){
   while(1){
      world::reportMonster();
      sys.wait(5);
   }
   
}
void main(){
   sys.waitFrame();
//   startCreeps();   
   world::init();
//   thread(sendWaves());
   world::spawnRedWave();
   world::spawnBlueWave();
   sys.waitFrame();
   thread(reportMonster());
}



in this example the spawning is done in the world::spawnRedWave and world::spawnBlueWave. Monsters will be spawned with their keys/values. after spawning theyll placed on the worldOrigins of the spawnpoints. same behaviour, we got monsters on the map....

as i plan several waves for both teams on different spawnlocations in different intervalls, kept in mind that the func_spawner didn't work as i expected, i wonder if its the best way to put my own spawners as threads.

eg.

Code:
void spawnred(){
        while(flag){
        world::spawnRedWave();
        sys.wait(30);
      }
}
void main(){
      thread spawnred();
}


there will be lots of this so i wonder if its good to have like 10 - 20 threads waiting 30secs or if its better to have a control thread with a duration of like 1 min each iteration through the while which controls evrything.

spawnred - blue
wait 5
spawnsomething else
wait 15
trigger ai, whatever
wait 8.. etc.

what do you think ? :-)

greets



AnthonyJa@Posted: Mon Sep 27, 2010 11:06 pm :
bdmn wrote:
there will be lots of this so i wonder if its good to have like 10 - 20 threads waiting 30secs or if its better to have a control thread with a duration of like 1 min each iteration through the while which controls evrything.


Hm, well having lots of threads doesn't sound a good thing, but in reality, since they're not real threads but just different pieces of scripts each with their own state, it probably would work OK.

I'd be more concerned about why the spawner stopped working - perhaps you're hitting some other limit? I know you mentioned you'd checked "max_active" - you could also have hit the spawnArg "count" (default "-1") which sets the number of things to spawn. I guess you don't have "max_team_test" but if you do remove it (appears to be obsolete but may be used in some Q4 maps).



bdmn@Posted: Thu Sep 23, 2010 4:19 pm :
hi guys,

im kidding around with spawning and controling monsters in different ways. as the outcome is not 100% what i wanted, i ask here for help.

in this thread ill show how i spawned the monsters, ill post another thread for the controlling of it.

i implemented several ways to spawn the monster waves and store them into run-time-persistent target_null lists, to keep reference for further controlling.

in the map i got target_nulls for:

blueSpawnPoint01
blueSpawnPoint02
blueSpawnPoint03

redSpawnPoint01
redSpawnPoint02
redSpawnPoint03

spawning my creatures way one: ( a func_spawner comes in handy )

Code:
namespace world{

   float redMonsterCount = 0;
   float blueMonsterCount = 0;

   void reportMonster(){
      sys.println("reporting monster");
      entity target;
      entity list = $redMonsterNulls;
      entity list2 = $blueMonsterNulls;
      sys.println("size of red:" + qListCount(list));
      sys.println("size of blue:" + qListCount(list2));
   }

   string registerRedMonster(entity monster){
      string name = "redMonster_" + redMonsterCount;
      monster.setKey("name", name);
      monster.setKey("target", "ai_tether_behind_3");
      qListInsert($redMonsterNulls, monster);
      redMonsterCount++;   
      return name;
   }   

   string registerBlueMonster(entity monster){
      string name = "blueMonster_" + redMonsterCount;
      monster.setKey("name", name);
      monster.setKey("target", "ai_tether_behind_4");
      qListInsert($blueMonsterNulls, monster);
      blueMonsterCount++;      
      return name;
   }
}


entity createBlueSpawner(){
    sys.setSpawnArg("target","blueSpawn01");
    sys.setSpawnArg("target_1","blueSpawn02");
    sys.setSpawnArg("target_2","blueSpawn03");
    sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
    sys.setSpawnArg("max_active", "30");
    sys.setSpawnArg("delay","4");       
    sys.setSpawnArg("auto_target", "1");
    sys.setSpawnArg("face_enemy", "1");
    sys.waitFrame();
    sys.setSpawnArg("waves","3");
    sys.setSpawnArg("skipVisible", "0");
    sys.setSpawnArg("remove", "0");       
    sys.setSpawnArg("call_spawned","world::registerBlueMonster");
    sys.setSpawnArg("spawn_neverdormant", "1");
    sys.setSpawnArg("spawn_team", "1");    // for spawning loots

    sys.waitFrame();
    entity blueSpawner = sys.spawn( "func_spawner" );
    return blueSpawner;
}


entity createRedSpawner(){
    sys.setSpawnArg("target","redSpawn01");
    sys.setSpawnArg("target_1","redSpawn02");
    sys.setSpawnArg("target_2","redSpawn03");
    sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
    sys.setSpawnArg("max_active", "30");
    sys.setSpawnArg("delay","4");       
    sys.setSpawnArg("auto_target", "1");
    sys.setSpawnArg("face_enemy", "1");
    sys.waitFrame();
    sys.setSpawnArg("waves","3");
    sys.setSpawnArg("skipVisible", "0");
    sys.setSpawnArg("remove", "0");       
    sys.setSpawnArg("call_spawned","world::registerRedMonster");
    sys.setSpawnArg("spawn_neverdormant", "1");
    sys.setSpawnArg("spawn_team", "0");    // for spawning loots

    sys.waitFrame();
    entity redSpawner = sys.spawn( "func_spawner" );
    return redSpawner;
}



void startCreeps(){
    entity redspawner = createRedSpawner();
    sys.waitFrame();
    entity bluespawner = createBlueSpawner();
    sys.waitFrame();
    sys.trigger(redspawner);
    sys.waitFrame();
    sys.trigger(bluespawner);
}

void main(){
    startCreeps();
}



to explain the code:

main function calls startcreeps which spawns two func_spawners. these funcspawners will populate the map. after spawning a monster, the function world::registerBlueMonster or world::registerRedMonster is called which adds the name of the new monster as a target location in a target_null list. so i can iterate over all the monsters for each time during the runtime to give further commands to them.

i experienced some situations where the func_spawner stopped to spawn even if the max_active limit wasnt reached, so i tried to implement it on another way:

Code:
   
#define ForEachTargetOf( ent, target )               \
   float index_##ent;                     \
   ent.removeNullTargets();                  \            
   for( index_##ent = 0; $null_entity != (target = ent.getTarget(index_##ent)); index_##ent++ )

#define qListForEach(list,ent) ForEachTargetOf(list,ent)

namespace world{

   float redMonsterCount = 0;
   float blueMonsterCount = 0;
   entity redMonsterNulls;
   entity blueMonsterNulls;

   void reportMonster(){
      sys.println("reporting monster");
      entity target;
      entity list = $redMonsterNulls;
      entity list2 = $blueMonsterNulls;
      sys.println("size of red:" + qListCount(list));
      sys.println("size of blue:" + qListCount(list2));
   }

   string registerRedMonster(entity monster){
      string name = "redMonster_" + redMonsterCount;
      monster.setKey("name", name);
      qListInsert(redMonsterNulls, monster);
      redMonsterCount++;   
      return name;
   }   

   string registerBlueMonster(entity monster){
      string name = "blueMonster_" + redMonsterCount;
      monster.setKey("name", name);
      qListInsert(blueMonsterNulls, monster);
      blueMonsterCount++;      
      return name;
   }

   void spawnRedWave(){
      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster1 = sys.spawn("monster_tactical_mgun");
      
      string name;
      name = registerRedMonster(monster1);

      $ai_tether_radius_1.setKey("target",name);

      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster2 = sys.spawn("monster_tactical_mgun");
      name = registerRedMonster(monster2);
      
      $ai_tether_radius_1.setKey("target_1",name);

      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster3 = sys.spawn("monster_tactical_mgun");
      name = registerRedMonster(monster3);
      $ai_tether_radius_1.setKey("target_2",name);

      monster1.setWorldOrigin($redSpawn01.getWorldOrigin());
      monster2.setWorldOrigin($redSpawn02.getWorldOrigin());
      monster3.setWorldOrigin($redSpawn03.getWorldOrigin());
      sys.waitFrame();
      sys.trigger($ai_tether_radius_1);
   }

   
   void spawnBlueWave(){
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster1 = sys.spawn("monster_strogg_marine");
      registerBlueMonster(monster1);
      
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster2 = sys.spawn("monster_strogg_marine");
      registerBlueMonster(monster2);
      
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster3 = sys.spawn("monster_strogg_marine");
      
      registerBlueMonster(monster3);
      monster1.setWorldOrigin($blueSpawn01.getWorldOrigin());
      monster2.setWorldOrigin($blueSpawn02.getWorldOrigin());
      monster3.setWorldOrigin($blueSpawn03.getWorldOrigin());
      
   }


   void init(){
      sys.setSpawnArg("name","blueMonsterNulls");
      blueMonsterNulls = sys.spawn("target_null");
      sys.waitFrame();
      sys.setSpawnArg("name","redMonsterNulls");
      redMonsterNulls = sys.spawn("target_null");
   }

}



void sendWaves(){
   while(1){
      world::spawnRedWave();
      sys.waitFrame();
      //world::spawnBlueWave();
      sys.waitFrame();
      sys.wait(2);
   }
}

void reportMonster(){
   while(1){
      world::reportMonster();
      sys.wait(5);
   }
   
}
void main(){
   sys.waitFrame();
//   startCreeps();   
   world::init();
//   thread(sendWaves());
   world::spawnRedWave();
   world::spawnBlueWave();
   sys.waitFrame();
   thread(reportMonster());
}



in this example the spawning is done in the world::spawnRedWave and world::spawnBlueWave. Monsters will be spawned with their keys/values. after spawning theyll placed on the worldOrigins of the spawnpoints. same behaviour, we got monsters on the map....

as i plan several waves for both teams on different spawnlocations in different intervalls, kept in mind that the func_spawner didn't work as i expected, i wonder if its the best way to put my own spawners as threads.

eg.

Code:
void spawnred(){
        while(flag){
        world::spawnRedWave();
        sys.wait(30);
      }
}
void main(){
      thread spawnred();
}


there will be lots of this so i wonder if its good to have like 10 - 20 threads waiting 30secs or if its better to have a control thread with a duration of like 1 min each iteration through the while which controls evrything.

spawnred - blue
wait 5
spawnsomething else
wait 15
trigger ai, whatever
wait 8.. etc.

what do you think ? :-)

greets



AnthonyJa@Posted: Mon Sep 27, 2010 11:06 pm :
bdmn wrote:
there will be lots of this so i wonder if its good to have like 10 - 20 threads waiting 30secs or if its better to have a control thread with a duration of like 1 min each iteration through the while which controls evrything.


Hm, well having lots of threads doesn't sound a good thing, but in reality, since they're not real threads but just different pieces of scripts each with their own state, it probably would work OK.

I'd be more concerned about why the spawner stopped working - perhaps you're hitting some other limit? I know you mentioned you'd checked "max_active" - you could also have hit the spawnArg "count" (default "-1") which sets the number of things to spawn. I guess you don't have "max_team_test" but if you do remove it (appears to be obsolete but may be used in some Q4 maps).



bdmn@Posted: Thu Sep 23, 2010 4:19 pm :
hi guys,

im kidding around with spawning and controling monsters in different ways. as the outcome is not 100% what i wanted, i ask here for help.

in this thread ill show how i spawned the monsters, ill post another thread for the controlling of it.

i implemented several ways to spawn the monster waves and store them into run-time-persistent target_null lists, to keep reference for further controlling.

in the map i got target_nulls for:

blueSpawnPoint01
blueSpawnPoint02
blueSpawnPoint03

redSpawnPoint01
redSpawnPoint02
redSpawnPoint03

spawning my creatures way one: ( a func_spawner comes in handy )

Code:
namespace world{

   float redMonsterCount = 0;
   float blueMonsterCount = 0;

   void reportMonster(){
      sys.println("reporting monster");
      entity target;
      entity list = $redMonsterNulls;
      entity list2 = $blueMonsterNulls;
      sys.println("size of red:" + qListCount(list));
      sys.println("size of blue:" + qListCount(list2));
   }

   string registerRedMonster(entity monster){
      string name = "redMonster_" + redMonsterCount;
      monster.setKey("name", name);
      monster.setKey("target", "ai_tether_behind_3");
      qListInsert($redMonsterNulls, monster);
      redMonsterCount++;   
      return name;
   }   

   string registerBlueMonster(entity monster){
      string name = "blueMonster_" + redMonsterCount;
      monster.setKey("name", name);
      monster.setKey("target", "ai_tether_behind_4");
      qListInsert($blueMonsterNulls, monster);
      blueMonsterCount++;      
      return name;
   }
}


entity createBlueSpawner(){
    sys.setSpawnArg("target","blueSpawn01");
    sys.setSpawnArg("target_1","blueSpawn02");
    sys.setSpawnArg("target_2","blueSpawn03");
    sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
    sys.setSpawnArg("max_active", "30");
    sys.setSpawnArg("delay","4");       
    sys.setSpawnArg("auto_target", "1");
    sys.setSpawnArg("face_enemy", "1");
    sys.waitFrame();
    sys.setSpawnArg("waves","3");
    sys.setSpawnArg("skipVisible", "0");
    sys.setSpawnArg("remove", "0");       
    sys.setSpawnArg("call_spawned","world::registerBlueMonster");
    sys.setSpawnArg("spawn_neverdormant", "1");
    sys.setSpawnArg("spawn_team", "1");    // for spawning loots

    sys.waitFrame();
    entity blueSpawner = sys.spawn( "func_spawner" );
    return blueSpawner;
}


entity createRedSpawner(){
    sys.setSpawnArg("target","redSpawn01");
    sys.setSpawnArg("target_1","redSpawn02");
    sys.setSpawnArg("target_2","redSpawn03");
    sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
    sys.setSpawnArg("max_active", "30");
    sys.setSpawnArg("delay","4");       
    sys.setSpawnArg("auto_target", "1");
    sys.setSpawnArg("face_enemy", "1");
    sys.waitFrame();
    sys.setSpawnArg("waves","3");
    sys.setSpawnArg("skipVisible", "0");
    sys.setSpawnArg("remove", "0");       
    sys.setSpawnArg("call_spawned","world::registerRedMonster");
    sys.setSpawnArg("spawn_neverdormant", "1");
    sys.setSpawnArg("spawn_team", "0");    // for spawning loots

    sys.waitFrame();
    entity redSpawner = sys.spawn( "func_spawner" );
    return redSpawner;
}



void startCreeps(){
    entity redspawner = createRedSpawner();
    sys.waitFrame();
    entity bluespawner = createBlueSpawner();
    sys.waitFrame();
    sys.trigger(redspawner);
    sys.waitFrame();
    sys.trigger(bluespawner);
}

void main(){
    startCreeps();
}



to explain the code:

main function calls startcreeps which spawns two func_spawners. these funcspawners will populate the map. after spawning a monster, the function world::registerBlueMonster or world::registerRedMonster is called which adds the name of the new monster as a target location in a target_null list. so i can iterate over all the monsters for each time during the runtime to give further commands to them.

i experienced some situations where the func_spawner stopped to spawn even if the max_active limit wasnt reached, so i tried to implement it on another way:

Code:
   
#define ForEachTargetOf( ent, target )               \
   float index_##ent;                     \
   ent.removeNullTargets();                  \            
   for( index_##ent = 0; $null_entity != (target = ent.getTarget(index_##ent)); index_##ent++ )

#define qListForEach(list,ent) ForEachTargetOf(list,ent)

namespace world{

   float redMonsterCount = 0;
   float blueMonsterCount = 0;
   entity redMonsterNulls;
   entity blueMonsterNulls;

   void reportMonster(){
      sys.println("reporting monster");
      entity target;
      entity list = $redMonsterNulls;
      entity list2 = $blueMonsterNulls;
      sys.println("size of red:" + qListCount(list));
      sys.println("size of blue:" + qListCount(list2));
   }

   string registerRedMonster(entity monster){
      string name = "redMonster_" + redMonsterCount;
      monster.setKey("name", name);
      qListInsert(redMonsterNulls, monster);
      redMonsterCount++;   
      return name;
   }   

   string registerBlueMonster(entity monster){
      string name = "blueMonster_" + redMonsterCount;
      monster.setKey("name", name);
      qListInsert(blueMonsterNulls, monster);
      blueMonsterCount++;      
      return name;
   }

   void spawnRedWave(){
      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster1 = sys.spawn("monster_tactical_mgun");
      
      string name;
      name = registerRedMonster(monster1);

      $ai_tether_radius_1.setKey("target",name);

      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster2 = sys.spawn("monster_tactical_mgun");
      name = registerRedMonster(monster2);
      
      $ai_tether_radius_1.setKey("target_1",name);

      sys.setSpawnArg("team","0");
      sys.setSpawnArg("auto_target","1");
      sys.setSpawnArg("target","ai_tether_radius_1");
      entity monster3 = sys.spawn("monster_tactical_mgun");
      name = registerRedMonster(monster3);
      $ai_tether_radius_1.setKey("target_2",name);

      monster1.setWorldOrigin($redSpawn01.getWorldOrigin());
      monster2.setWorldOrigin($redSpawn02.getWorldOrigin());
      monster3.setWorldOrigin($redSpawn03.getWorldOrigin());
      sys.waitFrame();
      sys.trigger($ai_tether_radius_1);
   }

   
   void spawnBlueWave(){
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster1 = sys.spawn("monster_strogg_marine");
      registerBlueMonster(monster1);
      
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster2 = sys.spawn("monster_strogg_marine");
      registerBlueMonster(monster2);
      
      sys.setSpawnArg("team","1");
      sys.setSpawnArg("auto_target","1");
      entity monster3 = sys.spawn("monster_strogg_marine");
      
      registerBlueMonster(monster3);
      monster1.setWorldOrigin($blueSpawn01.getWorldOrigin());
      monster2.setWorldOrigin($blueSpawn02.getWorldOrigin());
      monster3.setWorldOrigin($blueSpawn03.getWorldOrigin());
      
   }


   void init(){
      sys.setSpawnArg("name","blueMonsterNulls");
      blueMonsterNulls = sys.spawn("target_null");
      sys.waitFrame();
      sys.setSpawnArg("name","redMonsterNulls");
      redMonsterNulls = sys.spawn("target_null");
   }

}



void sendWaves(){
   while(1){
      world::spawnRedWave();
      sys.waitFrame();
      //world::spawnBlueWave();
      sys.waitFrame();
      sys.wait(2);
   }
}

void reportMonster(){
   while(1){
      world::reportMonster();
      sys.wait(5);
   }
   
}
void main(){
   sys.waitFrame();
//   startCreeps();   
   world::init();
//   thread(sendWaves());
   world::spawnRedWave();
   world::spawnBlueWave();
   sys.waitFrame();
   thread(reportMonster());
}



in this example the spawning is done in the world::spawnRedWave and world::spawnBlueWave. Monsters will be spawned with their keys/values. after spawning theyll placed on the worldOrigins of the spawnpoints. same behaviour, we got monsters on the map....

as i plan several waves for both teams on different spawnlocations in different intervalls, kept in mind that the func_spawner didn't work as i expected, i wonder if its the best way to put my own spawners as threads.

eg.

Code:
void spawnred(){
        while(flag){
        world::spawnRedWave();
        sys.wait(30);
      }
}
void main(){
      thread spawnred();
}


there will be lots of this so i wonder if its good to have like 10 - 20 threads waiting 30secs or if its better to have a control thread with a duration of like 1 min each iteration through the while which controls evrything.

spawnred - blue
wait 5
spawnsomething else
wait 15
trigger ai, whatever
wait 8.. etc.

what do you think ? :-)

greets



AnthonyJa@Posted: Mon Sep 27, 2010 11:06 pm :
bdmn wrote:
there will be lots of this so i wonder if its good to have like 10 - 20 threads waiting 30secs or if its better to have a control thread with a duration of like 1 min each iteration through the while which controls evrything.


Hm, well having lots of threads doesn't sound a good thing, but in reality, since they're not real threads but just different pieces of scripts each with their own state, it probably would work OK.

I'd be more concerned about why the spawner stopped working - perhaps you're hitting some other limit? I know you mentioned you'd checked "max_active" - you could also have hit the spawnArg "count" (default "-1") which sets the number of things to spawn. I guess you don't have "max_team_test" but if you do remove it (appears to be obsolete but may be used in some Q4 maps).