Page 1 of 1

Doublekill help

Posted: Sat Feb 16, 2008 1:38 am
by Wierdo
I need some help making a statement which will check for two kills occuring in the same 5 second period. To make it easier, there are only two targets. This is the code I am currently working with:

Code: Select all

doublekill:

$elite1 waittill death

if ($elite2 isAlive) 
{
wait 5
goto double1 
} 
else 
{ 
end
}

double1:
if ($elite2 isAlive)
{
end
}
else
{
$Narrator playsound Doublekill_snd
}

end

doublekill2:

$elite2 waittill death

if ($elite1 isAlive) 
{
wait 5 
goto double2
} 
else 
{ 
end
}

double2:
if ($elite1 isAlive)
{
end
}
else
{
$Narrator playsound Doublekill_snd
}

end
I placed 2 lines at the top of my code to thread the conditions to occur:

Code: Select all

thread doublekill
thread doublekill2
I need to make sure the code will work, no matter which AI dies first, yet not print twice in the event the condition rings true for both.

Posted: Sat Feb 16, 2008 9:30 am
by jv_map
Your current code may work but that's not the way to do it since you've made it very hard for anyone to oversee the code's path of execution. A better way would be:

Code: Select all

// call from main or so
thread register_death_time "elite1"
thread register_death_time "elite2"
thread double_kill_notice "elite1" "elite2" 5.0

// -----------------------------------

// Waits till entity with targetname 
// 'local.name' has died, then stores 
// time of death in  global array 
// 'level.death_time' at named 
// index 'local.name'.
register_death_time local.name:
  level.death_time[local.name] = -1
  $(local.name) waittill death
  level.death_time[local.name] = level.time  
end

// Prints a notice when both entities with 
// targetnames 'local.name1' and 'local.name2'
// have been killed. If these were killed within 
// 5 seconds from each other, the message 
// is positive, otherwise negative (unfriendly).
double_kill_notice local.name1 local.name2 local.max_time_in_between_secs:
  $(local.name1) waittill death
  $(local.name2) waittill death
  local.time_in_between_secs = level.death_time[local.name2] - level.death_time[local.name1]
  if(abs(local.time_in_between_secs) < local.max_time_in_between_secs)
    iprintlnbold_noloc "Double kill! Well done!"
  else
    iprintlnbold_noloc "Too slow! Nanananananaa!"
end

Doublekill script

Posted: Sat Feb 16, 2008 9:45 pm
by Wierdo
JV . . . You da man! I might actually owe you beer. However, the "else" condition will not print on screen. This is preffered, but I cannot understand why it will not show.

Thanks again, dude.


edit -----------------------

JV, I noticed one inconvenience in the script:

If $Elite2 dies before $Elite1 . . . even if by a second, the script will be omitted. It only works in one order, and one order alone.

Is there anything that can be done to correct this, aside careful aiming?

edit------------------------

Nevermind, fixed it by flipping elite1 and 2 around and repeating the last part of the code a second time.

Posted: Sun Feb 17, 2008 8:48 am
by jv_map
Hmm it should work in any order and definitely print the else message as well.

However, it's probably best to place a waitframe here:

// Prints a notice when both entities with
// targetnames 'local.name1' and 'local.name2'
// have been killed. If these were killed within
// 5 seconds from each other, the message
// is positive, otherwise negative (unfriendly).
double_kill_notice local.name1 local.name2 local.max_time_in_between_secs:
$(local.name1) waittill death
$(local.name2) waittill death
waitframe
local.time_in_between_secs = level.death_time[local.name2] - level.death_time[local.name1]
if(abs(local.time_in_between_secs) < local.max_time_in_between_secs)
iprintlnbold_noloc "Double kill! Well done!"
else
iprintlnbold_noloc "Too slow! Nanananananaa!"
end

This guarantees the register_death_time threads exit before double_kill_notice continues.

Posted: Sun Feb 17, 2008 9:02 am
by Rookie One.pl
Are you trying to make a killing spree mod? :)

Doublekill

Posted: Tue Feb 19, 2008 10:23 pm
by Wierdo
Hmm it should work in any order and definitely print the else message as well.
It did actually run the "else" condition, I just couldn't get it to work both ways and assumed it was because I was too slow. :oops:

The reason I believe it cannot work both ways is because of the way the logic statement is setup, with:

Code: Select all

level.death_time[local.name2] - level.death_time[local.name1] 
Assuming my killspan = 3 seconds, the condition = 3 for [local2 minus local 1]. However, the number is -3 if I kill in the other order. I think that a negative number is a bad number or something, unless you have a means of dealing for the negative condition built into the code.

Otherwise, the code works wonderfully.
Are you trying to make a killing spree mod? :D
I like the way you guys think. Answer = . . . somewhat, yes. There are some spots in my map that have a nice amount of generic human AI. I feel that a quick trigger finger deserves an audible reward. So far, I have 3 possible Doublekills, (Thank you JV) and one Triplekill, which is made of a combo with two other existing baddies.



I am assembling a cooperative play objective map, which requires players to storm a huge concrete bunker, and do . . . stuff . . . which I cannot spoil at this time.

Re: Doublekill

Posted: Wed Feb 20, 2008 5:32 pm
by jv_map
Wierdo wrote:I think that a negative number is a bad number or something
Eeek... that's scary :shock: :shock: evil - eh :twisted:
Wierdo wrote:unless you have a means of dealing for the negative condition built into the code.
Phew, then we're safe :)

The abs(...) just below makes it not matter if local.time_in_between_secs is positive or negative, as

abs(x) = x if x >= 0
or........ -x if x < 0