HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Simple efficient algorith idea needed for a simple spell

03-19-2009, 09:57 PM#1
Flame_Phoenix
Hi guys, I am making a ward spell. Basically anytime a unit dies near the ward I want to raise 2 skelies from it (simple skely sumon). Thing is I could use a timer and make a periodic check to see if there are any nearby corpses, but I think that using an event "Unit_death" would be more efficient. Problem is that I can't find a solution for this problem without using dynamic triggers (which are evil).
Then, I started having all kinds of ideas (what if my ward is activated when a building finished construction? or some other event happens?) but my brain is formated to think "timers and dynamic triggers only" and now they won't get out of my head.

Does some one know a simple algorithm for this simple spell?
03-19-2009, 10:02 PM#2
Thunder_Eye
Autocast Raise Dead?
Or perhaps you want it scripted anyway?
03-19-2009, 10:10 PM#3
Zerzax
Use TriggerRegisterAnyUnitEventBJ with EVENT_PLAYER_UNIT_DEATH. Then use a global group to enum any wards in range of the dying units' X/Y coordinates.
03-19-2009, 10:14 PM#4
Flame_Phoenix
Quote:
Autocast Raise Dead?
Or perhaps you want it scripted anyway?
You got my question wrong, this is not what I want sorry xD

Quote:
Use TriggerRegisterAnyUnitEventBJ with EVENT_PLAYER_UNIT_DEATH. Then use a global group to enum any wards in range of the dying units' X/Y coordinates.
mmm, what if there are 2 wards from different players in that range of the dying unit? Who wins? Who gets the skelies?

Also, this may be a silly question but, if a unit is within 300 range of a ward, then a ward is also withing 300 range of a unit, I mean the intersection area for both is exactly the same and mathematically equivalent right?
03-19-2009, 10:17 PM#5
akolyt0r
you may not even need to enum units near the dying unit ...

you could store all active wards in an unit-array or unit-group and then only check if your unit is in range of any of them...
03-19-2009, 10:27 PM#6
Flame_Phoenix
Quote:
you may not even need to enum units near the dying unit ...

you could store all active wards in an unit-array or unit-group and then only check if your unit is in range of any of them...
Mmm, I dunno about this, it will be slower in some cases. If 1 unit dies, and if my map has 30 wards on an array, I have to search all the wards on the array [complexity O(n)]. With the group trick I don't have to do that.
Also, if I use arrays, I will have the problem of "who gets the skelies" as well =S
03-19-2009, 10:47 PM#7
akolyt0r
hmm ..yeah ..it would be applicable for a hero spell though (i thought it would be a hero spell..).

Well then do the groupenum stuff on generic unitdeath event... but add a condition ...ammount of wards > 0 ... so you dont have to search for a ward when you dont have any wards at all...
03-19-2009, 11:08 PM#8
Zerzax
Everyone "wins" the skellies - I don't see why there needs to be any disctinction. But if you do want to limit the skellies, store a GetRandomReal from 1 to 100. Then divide the range of options up based on the number of wards in range. Say there are 10 wards. That means check if RandReal is between 1 and 10 for first. For the nth ward, check if the rand is between (n-1)*10 and n*10. This can be easily done with a FirstOfGroup loop and an integer incremented each time the group detects a ward.

Or honestly, just check which ward is closest to the dying unit. SquareRoot heavy, but it gets the job done since the choice of ward is entirely arbitrary.
03-20-2009, 12:45 AM#9
Anitarf
Quote:
Originally Posted by Zerzax
Or honestly, just check which ward is closest to the dying unit. SquareRoot heavy
No it's not.
03-20-2009, 01:03 AM#10
Zerzax
No, I guess it isn't now that I think about it.
03-20-2009, 01:35 AM#11
cosmicat
You could also just let "everybody" win - create two units one at a time for each player so you can add timers to all of them, then remove the dead unit from the game (corpse is gone).
03-20-2009, 04:26 PM#12
Flame_Phoenix
MMm, if I have 5 wards, raising 5 skelies from a dead body is quite unbalanced for a melee spell xD
I think I will follow the suggestion above. If a unit dies and I have 2 wards near it, the closest ward "claims" the body for the skely. If 2 wards have same distance, then I pick a random one =D

I may post some code for people to see.
ANyway, when I am done I will give +rep to all people for help and suggestions!

EDIT EDIT EDIT


Ok guys, here is the code for people who are interested. Suggestions on how to make the spell nice are also welcome:

Expand JASS:

Btw, +rep to all as promised.
03-20-2009, 05:25 PM#13
Bobo_The_Kodo
Collapse JASS:
        local real minDist = RANGE*RANGE + 1

...

Collapse JASS:
            set dx =(x - vicX) * (x - vicX) + (y - vicY) * (y - vicY)
03-20-2009, 10:08 PM#14
Flame_Phoenix
@Bobo_The_Kodo

Ahhh right ... I always forget to do that small optimization.

Anyway, I did a few more modifications:

Expand JASS:

I think that now I start another thread, but about the spell, which I intend to improve using TimedLightning and fx_ reverse animation (I am going to give each skely a chance to get back to life, playing their death animation in reverse! xD ).

Anyway thx for help, +rep!

PS: It seems I have to wait 24 to give more reputation =(