Page 1 of 1

Killtread isn't working

Posted: Sun Apr 29, 2007 8:43 pm
by Guderian
Huy !
Let me anybody say: why killthreaddidn't work in singleplayer map (i.e. when soldier is dead thread didn't work). Functionisalivei don't want to use.

P.S.:where i can read tutorial about hitting and exploding static vehicles (for example, airfield m1l3b AA)

Posted: Mon Apr 30, 2007 3:00 am
by lizardkid
don't understand the question. killthread? post the script you're using and what you're trying to accomplish

Posted: Mon Apr 30, 2007 10:13 am
by Guderian
1) If you open SDK/docs/MOH_GameClasses, you can read this function killthread ( String thread ) (Set the thread to execute when this model is killed).
2) And here is script:

level waittill prespawn

$player item weapons/m1_garand.tik
$player ammo rifle 50
$player useweaponclass rifle

level waittill spawn

thread mission1
thread mission2

end

mission1:

waitthread global/objectives.scr::add_objectives 1 2 "Kill the officer." $officer_1.origin
waitthread global/objectives.scr::current_objectives 1

if (isalive $officer_1)
$officer_1 waittill death
{
waitthread global/objectives.scr::add_objectives 1 3 "Kill the officer." $officer_1.origin
waitthread global/objectives.scr::current_objectives 0

}
end

mission2:

while ((isalive $soldier_1)||(isalive $soldier_2)||(isalive $soldier_3))
{
if (isalive $soldier_1)
$soldier_1 waittill death
{iprintln_noloc "Soldier_1 is dead."}

if (isalive $soldier_2)
$soldier_1 waittill death
{iprintln_noloc "Soldier_2 is dead."}

if (isalive $soldier_3)
$soldier_1 waittill death
{iprintln_noloc "Soldier_3 is dead."}
}
end

When I killed the 2-nd soldier, but the 1-st isalive, function don't print
"Soldier_2 is dead". That's why I decide to use killthread (as entering the trigger, work setthread)
P.S.: I want to kill enemyes in different ways, not following step by step.

Try this

Posted: Mon Apr 30, 2007 11:55 am
by tltrude
This might work. The "!" symbol means "not" or "is not".
I'm not sure if the "wait" line is needed, but it may loop too fast without it.

Code: Select all

mission2: 

	while ((isalive $soldier_1)||(isalive $soldier_2)||(isalive $soldier_3)) 

		{ 
			if !(isalive $soldier_1)  // If not alive. 
			{
				iprintln_noloc "Soldier_1 is dead."
			}

			if !(isalive $soldier_2)  // If not alive. 
			{
				iprintln_noloc "Soldier_2 is dead."
			}

			if !(isalive $soldier_3)  // If not alive. 
			{
				iprintln_noloc "Soldier_3 is dead."
			}

		wait .01
 
		}
 
end 
"Waittill" (wait until) makes the script stop reading lines until that event happens. So, your thread was waiting until soldier_1 died before checking soldier_2.

PS: The above thread is not correct. Use Ric-hard's thread below.

Posted: Mon Apr 30, 2007 2:44 pm
by bdbodger
That will start spamming as soon as the first soldier dies and won't end untill the last soldier dies .

yep

Posted: Mon Apr 30, 2007 3:50 pm
by tltrude
Yes, I see that now. So, how would you do it without using three threads?

Posted: Mon Apr 30, 2007 6:04 pm
by Ric-hard
Something like this would be ok I think.

Code: Select all

mission2:
	while ( (isalive $soldier_1)||(isalive $soldier_2)||(isalive $soldier_3) )
	{
		if ( !(isalive $soldier_1) && (level.soldier_1_checked == NIL) )
		{ 
		level.soldier_1_checked = 1
		iprintln_noloc "Soldier_1 is dead." 
		} 

		if ( !(isalive $soldier_2) && (level.soldier_2_checked == NIL) )
		{
		level.soldier_2_checked = 1
		iprintln_noloc "Soldier_2 is dead."
		} 

		if ( !(isalive $soldier_3) && (level.soldier_3_checked == NIL) )
		{
		level.soldier_3_checked = 1
		iprintln_noloc "Soldier_3 is dead."
		}
	waitframe // I dont think u can wait .01, .05/waitframe is minimum
	}
end

Nice

Posted: Mon Apr 30, 2007 7:38 pm
by tltrude
Yeah, looks like that will work. Only, you have "NULL" and I think it should be "NIL".

Posted: Mon Apr 30, 2007 8:40 pm
by Ric-hard
eh... I think it shall be NIL :lol:
I hope I?ve finally managed to memorize which one is which ... still have to scratch my head a few sec before the elevator arrives at topfloor:P

NULL = something that have existed ... and now is missing.
NIL = a variable that hasnt been set.

Posted: Tue May 01, 2007 7:16 am
by Guderian
Thank's all, now it work as i want !

Posted: Tue May 01, 2007 4:11 pm
by lizardkid
Because i'm bored, and feeling adventurous, this is how i would do the thing. Plus, i just scored an apple in a different thread and feel professor-ey.

1. You're making a lot of duplicate compares, checking the isAlive for one soldier (on average) 4 times in one frame, times 3 soldiers. You only need to get it once and use that variable. Using memory > using compares.

2. You only need to check if all of the soldiers are dead when one dies. They cannot die and not be caught by the thread, so why check them every update?

3. You can wait as much as .5 to .8, to upgrade the performance, nobody will notice if a message is displayed a frame later, depending on the map and machine it's running on, you could be making these compares 25-200 times in a second. Waiting a half a second splits that down to 2 calls a second.

One last thing, soldier_#_checked doesn't need to be level.; if you're only using it in this thread it should be local.. But that doesn't affect performance at all, i think.

Code: Select all

mission2: 

   while ( true ) 
   { 
      local.soldier1Alive = (isAlive $soldier_1)
      local.soldier2Alive = (isAlive $soldier_2)
      local.soldier3Alive = (isAlive $soldier_3)

      if ( !local.soldier1Alive && (level.soldier_1_checked == NIL) ) 
      { 
              level.soldier_1_checked = 1 
              iprintln_noloc "Soldier_1 is dead." 
              
              if( !local.soldier2Alive && !local.soldier3Alive)
              {
                       // point of interest, if 'return' works in mohaa scripting you could just do that too.
                       break;
              }
      } 

      if ( !local.soldier2Alive && (level.soldier_2_checked == NIL) ) 
      { 
              level.soldier_2_checked = 1 
              iprintln_noloc "Soldier_2 is dead." 

              if( !local.soldier1Alive && !local.soldier3Alive)
              {
                       break;
              }

      } 

      if ( !local.soldier3Alive && (level.soldier_3_checked == NIL) ) 
      { 
              level.soldier_3_checked = 1 
              iprintln_noloc "Soldier_3 is dead." 

              if( !local.soldier1Alive && !local.soldier2Alive)
              {
                       break;
              }

      } 
      wait .7
   } 
end

Posted: Wed May 02, 2007 12:31 am
by bdbodger
My turn

Code: Select all

mission2:

$soldier1 thread living 1
$soldier2 thread living 2
$soldier3 thread living 3

end

living local.num:

self waittill death

iprintln_noloc ( "Soldier_" + local.num + " is dead" )

end

Posted: Wed May 02, 2007 1:56 am
by lizardkid
oright, there's a waittill event.

been away too long :(

<- pwnt

btw if you think that's going to get you the apple you're out of luck.

objective

Posted: Wed May 02, 2007 2:35 am
by tltrude
My guess is that Guderian is replacing the printing lines with singleplayer objectives. But, bdbodger's two threads are cool, none the less.

Posted: Wed May 02, 2007 3:02 pm
by bdbodger
Hmm I didn't get the apple just the worm :(