• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Spells & Systems Mini-Contest #16

Status
Not open for further replies.
  • Touch of Nature
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Touch of Nature
    • Actions
      • Custom script: local unit udg_UnitVarAlly
      • Set UnitVarAlly = (Target unit of ability being cast)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Real((Integer((Percentage life of UnitVarAlly))))) Less than or equal to 33.00
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Random integer number between 1 and 100) Less than or equal to 35
            • Then - Actions
              • Unit - Set life of UnitVarAlly to 100.00%
              • Unit - Set mana of UnitVarAlly to 100.00%
              • Unit - Add Armor Bonus to UnitVarAlly
              • Unit - Set level of Armor Bonus for UnitVarAlly to (Level of Touch of Nature for (Triggering unit))
              • Unit - Add Damage Bonus to UnitVarAlly
              • Unit - Set level of Damage Bonus for UnitVarAlly to (Level of Touch of Nature for (Triggering unit))
              • Countdown Timer - Start TimerAlly as a One-shot timer that will expire in 10.00 seconds
              • Unit - Remove Negative buffs considered Magic and physical from UnitVarAlly (Exclude expiration timers, Exclude auras)
              • Special Effect - Create a special effect attached to the origin of UnitVarAlly using Objects\Spawnmodels\NightElf\EntBirthTarget\EntBirthTarget.mdl
              • Special Effect - Destroy (Last created special effect)
              • Special Effect - Create a special effect attached to the origin of UnitVarAlly using Abilities\Spells\Human\Invisibility\InvisibilityTarget.mdl
              • Special Effect - Destroy (Last created special effect)
              • Floating Text - Create floating text that reads Natures Blessing! above UnitVarAlly with Z offset 0.00, using font size 10.00, color (0.00%, 60.00%, 0.00%), and 0.00% transparency
              • Floating Text - Change (Last created floating text): Disable permanence
              • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
              • Floating Text - Change the fading age of (Last created floating text) to 2.00 seconds
              • Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
              • Skip remaining actions
            • Else - Actions
        • Else - Actions
      • Countdown Timer - Start TimerAlly as a One-shot timer that will expire in 10.00 seconds
      • Unit - Add Armor Bonus to UnitVarAlly
      • Unit - Set level of Armor Bonus for UnitVarAlly to (Level of Touch of Nature for (Triggering unit))
      • Unit - Add Damage Bonus to UnitVarAlly
      • Unit - Set level of Damage Bonus for UnitVarAlly to (Level of Touch of Nature for (Triggering unit))
      • Unit - Set life of UnitVarAlly to ((Real((Integer((Life of UnitVarAlly))))) + (120.00 x (Real((Level of Touch of Nature for (Triggering unit))))))
Now i have set the local unit and the whole trigger fucks up, without a local it works...Any ideas how to fix it?
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
hmm im not sure but i think i read before somewhere that you can't use a local unit in GUI inside a loop or if then else... i might just be bullshi*ting cos its the morning :p

Correct, because in GUI they call at least one more function and the local is no longer present there.
 
Level 5
Joined
Jun 25, 2008
Messages
118
learn JASS and remake it? people always seem to think its a really hard thing to do... i learnt JASS in 1 hour... then made my Dragon Roar spell the next hour, since then ive added a tiny few things to my knowledge of JASS but pretty much learnt everything in that 1 hour. And last night i learnt vJASS in 1 hour (although i still got to learn methods and onDestroy(), the most important things probs lol). But yea you get the idea, its pretty simple, and from your spell i can see you already have good GUI knowledge so why not take the next step? xD

here's a link to Daelin's JASS tutorial of utter overwhelming awesomeness (yes its really that good):
Daelin's JASS tutorial (of utter overwhelming awesomeness)
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
Lol it only took me like 2 hours to get down the basics of vJASS and recreate my spell in it >< but theres still problems with it lol. Hopefully easier to fix now tho :con: - ya' know, or harder :gg:

EDIT: hmm yet again i cant find a solution and in my eyes everything looks fine, don't know where else to post this to get feedback on anything i may have missed so here it is:
JASS:
scope BeeSwarm initializer Init

//=========================Bee Swarm by BlackShogun==========================//
//=================================Setup=====================================//

//spell rawcode
private constant function BeeSwarmRawCode takes nothing returns integer
    return 'A000'
endfunction

//dummy unit rawcode
private constant function BeeSwarmModel takes nothing returns integer
    return 'h000'
endfunction

//dummy unit model
private constant function BeeSwarmSFX takes nothing returns string
    return "Abilities\\Weapons\\CryptFiendMissile\\CryptFiendMissile.mdl"
endfunction

//base damage per second
private function BeeSwarmBaseDPS takes integer lvl returns real
    return 5.0*lvl
endfunction

//increase in damage per second for every second the target is moving
private function BeeSwarmIncDPS takes integer lvl returns real
    return 0.5*lvl
endfunction

//decrease in damage per second for every second the target is moving
private constant function BeeSwarmDecDPS takes nothing returns real
    return 0.5
endfunction

//duration of spell
private constant function BeeSwarmDur takes nothing returns real
    return 20.0
endfunction

//the movement and effects interval
private constant function BeeSwarmInterval takes nothing returns real
    return 0.03
endfunction

//distance moved by projectile each interval
private constant function BeeSwarmDist takes nothing returns real
    return 15.0
endfunction

//===============================EndSetup====================================//
//==================NOTE: DO NOT EDIT ANYTHING BEYOND HERE===================//

struct BeeSwarm_Data
    unit cast
    unit targ
    unit u
    real x
    real y
    real dmg
    real time
    effect sfx
endstruct

globals
    private timer t = CreateTimer()
    private BeeSwarm_Data array ar
    private integer total = 0
endglobals

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == BeeSwarmRawCode()
endfunction

private function Effects takes nothing returns nothing
    local BeeSwarm_Data dat
    local integer i=0
    local real x1=GetUnitX(dat.u)
    local real y1=GetUnitY(dat.u)
    local real x2=GetUnitX(dat.targ)
    local real y2=GetUnitY(dat.targ)
    local real a=Atan2(y2-y1, x2-x1)
    local real mx=BeeSwarmDist()*Cos(a)
    local real my=BeeSwarmDist()*Sin(a)
    local integer lvl=GetUnitAbilityLevel(dat.cast, BeeSwarmRawCode())
    
    loop
        exitwhen i>=total
        set dat=ar[i]
        
        if not IsUnitInRange(dat.u, dat.targ, 50) then
            call SetUnitX(dat.u, x1+mx)
            call SetUnitY(dat.u, y1+my)
            call SetUnitFacing(dat.u, 57.29583*a)
        endif
        
        if IsUnitInRange(dat.u, dat.targ, 50) and (not IsUnitType(dat.targ, UNIT_TYPE_DEAD)) then
            call SetUnitX(dat.u, x2)
            call SetUnitY(dat.u, y2)
            call UnitDamageTarget(dat.cast, dat.targ, (BeeSwarmBaseDPS(lvl)*BeeSwarmInterval())+dat.dmg, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            if dat.x!=null then
                if IsUnitInRangeXY(dat.targ, dat.x, dat.y, 5) then
                    set dat.dmg=dat.dmg-(BeeSwarmDecDPS()*BeeSwarmInterval())
                else
                    set dat.dmg=dat.dmg+(BeeSwarmIncDPS(lvl)*BeeSwarmInterval())
                endif
            endif
            set dat.x=x2
            set dat.y=y2
        endif
        
        if (BeeSwarmBaseDPS(lvl)+dat.dmg<=0) or (dat.time>=BeeSwarmDur()) or (IsUnitInRange(dat.u, dat.targ, 50) and IsUnitType(dat.targ, UNIT_TYPE_DEAD)) then
            call DestroyEffect(dat.sfx)
            call RemoveUnit(dat.u)
            set ar[i]=ar[total-1]
            set total=total-1
            call dat.destroy()
        endif
        
        set dat.time=dat.time+(1*BeeSwarmInterval())
        set i=i+1
    endloop
    
    if total==0 then
        call PauseTimer(t)
    endif
endfunction

private function Actions takes nothing returns BeeSwarm_Data
    local BeeSwarm_Data dat=BeeSwarm_Data.create()
    local player p
    local real a
    
    set dat.cast=GetTriggerUnit()
    set p = GetOwningPlayer(dat.cast)
    set dat.targ=GetSpellTargetUnit()
    set a=57.29583*Atan2(GetUnitY(dat.targ)-GetUnitY(dat.cast), GetUnitX(dat.targ)-GetUnitX(dat.cast))
    set dat.u=CreateUnit(p, BeeSwarmModel(), GetUnitX(dat.cast), GetUnitY(dat.cast), a)
    set dat.sfx=AddSpecialEffectTarget(BeeSwarmSFX(), dat.u, "chest")
    set dat.dmg=0
    set dat.time=0
    set p=null
    
    if total==0 then
        call TimerStart(t, BeeSwarmInterval(), true, function Effects)
    endif
    
    set total=total+1
    set ar[total-1]=dat
    
    return dat
endfunction

private function Init takes nothing returns nothing
    local trigger T = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(T, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction(T, function Actions)
    call TriggerAddCondition(T, Condition(function Conditions))
endfunction

endscope
I'm guessing it would help if i explain the spell so: Its based on channel and is single target. Creates dummy unit that acts as projectile homing in on the target unit. Once it reaches the target it deals damage over time. When the target is moving the periodic damage increases, when the target stands still the periodic damage decreases, lasts 20 seconds or until damage per second drops to 0.

I found a part which is not working, if you havent solved it already. Everything which stands here:
JASS:
private function Effects takes nothing returns nothing
    local BeeSwarm_Data dat
    local integer i=0
    local real x1=GetUnitX(dat.u)
    local real y1=GetUnitY(dat.u)
    local real x2=GetUnitX(dat.targ)
    local real y2=GetUnitY(dat.targ)
    local real a=Atan2(y2-y1, x2-x1)
    local real mx=BeeSwarmDist()*Cos(a)
    local real my=BeeSwarmDist()*Sin(a)
    local integer lvl=GetUnitAbilityLevel(dat.cast, BeeSwarmRawCode())
it will not work properly... You create a local data which has no reference. And then you try to get its components, but it has none.
You shall declare all the locals before everything else, that is correct... But then, dont forget to make a reference inside the loop, for instance:
JASS:
private function Effects takes nothing returns nothing
    local BeeSwarm_Data dat
    local integer i=0
    local real x1
    local real y1
    local real x2
    local real y2
    local real a
    local real mx
    local real my
    local integer lvl
    
    loop
        exitwhen i>=total
        set dat=ar[i]
        set everything here...

Reminder: This may not be the efficient code I have seen, but the result of doing this way should at least work. It was a quick observation, so there might be more which I didnt see.

EDIT: And Berzeker, you could ask Poot about his MUI but GUI 'Jass structalike system'. Im sure it will be taken as a 'Small not-do it for you system'.
 
Level 15
Joined
Jan 31, 2007
Messages
502
Soo.. after i had less time i finally started with the code
The basics are done , it took much time cuz i used Structs and Methods the first time in my live , i do not like vJass - would be finished 5 times without it

Heres what ive done now , Basics done , Birth animation done , Default animation (stand) done , Return to Default animation done

death animation left
Plant damage left
Grabing and pulling units left

i think i could be finished tomorrow

Here are some funny other tendril variations i tested :p
But ill stick to the original one i already posted
tendrilvariationsqe6.jpg

 

Attachments

  • ManEatingPlant.w3x
    31.3 KB · Views: 63
Level 12
Joined
Apr 27, 2008
Messages
1,228
Yeap, amazing :)
The code needs some polishing.
For instance - array structs:
JASS:
struct playerdata extends array //syntax to declare an array struct
    integer a
    integer b
    integer c
endstruct

function init takes nothing returns nothing
 local playerdata pd

    set playerdata[3].a=12  //modifying player 3's fields.
    set playerdata[3].b=34  //notice it behaves as a global array
    set playerdata[3].c=500

    set pd=playerdata[4]
    set pd.a=17             //modifying player 4's fields.
    set pd.b=111            //yep, this is also valid
    set pd.c=501
endfunction

function updatePlayerStuff takes player p returns nothing
 local integer i=GetPlayerId(p)

    //some random function.
    set playerdata[i].a=playerdata[i].b

endfunction
Quoted from the Jass Helper manual.
 
Level 15
Joined
Jan 31, 2007
Messages
502
Totally, and some of the code is like wtf too:p
Thanks , it was really hard because its my real vJass spell

ive got to thank Dart3mpl3r for teaching me some vJass and helping me finding some mistakes

Im not sure if theres still a leak , after casting 20 Tendrils a 16 units the fps seem to slow down after some time but im not sure and found nothing

Later ill continue working
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
Yeah, my computer here (at my mom) is not very great (in fact its totally suckage). If I cast around 7 of them at the same time its drastically turning my fps to minimum (I guess). I havent checked by a fps number but I can tell its low because it freezes for around 5-10 seconds then move something and then freezes as much again. But mainly I think its due to the fact that the spell itself are creating so many handle at once, and uses so many handles at the same time.

Edit: And Berz, Im reviwing it right away :)
Edit2: My pc just froze so I had to turn it of the bad way. I hope its not your spell Berz :/
Edit3: Nah it seemed to be temporary. My critique eh

- Not mui =(
- Try to find more effects. I think it lacks that now
- Looks like a mixture between Inner Fire and dispel magic :s (But the chance is nice)

Berz, actually if you want it Mui... You can do so. Now, the code below will also optimize the trigger a bit (and it looks like it works from here).
I am aware if that I am using this wait action at the end of the trigger. But in this situation its the easiest way to make it MUI am I right?

  • Touch of Nature Alternative
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Touch of Nature
    • Actions
      • Custom script: local unit udg_UnitVarAlly
      • Set UnitVarAlly = (Target unit of ability being cast)
      • Custom script: if GetUnitLifePercent(udg_UnitVarAlly) <= 33.00 and GetRandomInt(1, 100) <= 10 + 10 * GetUnitAbilityLevel(GetTriggerUnit(), 'A000') then
      • Unit - Set life of UnitVarAlly to 100.00%
      • Unit - Set mana of UnitVarAlly to 100.00%
      • Unit - Remove Negative buffs considered Magic and physical from UnitVarAlly (Exclude expiration timers, Exclude auras)
      • Special Effect - Create a special effect attached to the origin of UnitVarAlly using Objects\Spawnmodels\NightElf\EntBirthTarget\EntBirthTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of UnitVarAlly using Abilities\Spells\Human\Invisibility\InvisibilityTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Floating Text - Create floating text that reads Natures Blessing! above UnitVarAlly with Z offset 0.00, using font size 10.00, color (0.00%, 60.00%, 0.00%), and 0.00% transparency
      • Floating Text - Change (Last created floating text): Disable permanence
      • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
      • Floating Text - Change the fading age of (Last created floating text) to 2.00 seconds
      • Floating Text - Change the lifespan of (Last created floating text) to 3.50 seconds
      • Custom script: else
      • Unit - Set life of UnitVarAlly to ((Real((Integer((Life of UnitVarAlly))))) + (120.00 x (Real((Level of Touch of Nature for (Triggering unit))))))
      • Custom script: endif
      • Unit - Add Armor Bonus to UnitVarAlly
      • Unit - Set level of Armor Bonus for UnitVarAlly to (Level of Touch of Nature for (Triggering unit))
      • Unit - Add Damage Bonus to UnitVarAlly
      • Unit - Set level of Damage Bonus for UnitVarAlly to (Level of Touch of Nature for (Triggering unit))
      • Wait 10.00 seconds (Or perhaps polled wait 10 seconds)
      • Unit - Remove Armor Bonus from UnitVarAlly
      • Unit - Remove Damage Bonus from UnitVarAlly
      • // Silly me forgot this part...
      • Custom script: set udg_UnitVarAlly = null
 
Last edited:
Level 12
Joined
Apr 27, 2008
Messages
1,228
@-JonNny
Problem is that the timer has a rather low timeout combined with the fact that there is only one timer.
So when the callback is called if there are a lot of plants wc3 has to execute a lot of code before the next frame is drawn.
 
Last edited:
Level 12
Joined
Apr 27, 2008
Messages
1,228
@-BerZeKeR-
Fix the hotkey ;)
Also note that some of the actions are repeated more than once in the trigger.
And since they will happen anyway, you can remove them from the if block and leave only the ones that are out of it, also removing the Skip Remaining Actions action. This way the code will be shorter and the actions will always end at the end :p
 
I put Skip remaining actions, because of the healing part, like he gets full hp and and than he gets (lets say) 500 damage and bam the other heal triggers and he gets healed for another 360 hp, thats why. I wouldn't put it in if it wouldn't be because of that :p
Hotkey? Isn't the default c? (i'm not in editor) xD

Thanks, spiwn! ;)

Edit:
*I'm off for today*
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Nope, didn't see the edit :D
My spell was/is almost complete, but when I saw what -JonNny is doing I decided to hold off for a little while and try to improve mine :p
Here is the spell for now.
 
Last edited:
Level 30
Joined
Dec 6, 2007
Messages
2,228
  • DebugDeadTargetBirds
    • Events
      • Time - Every 0.40 seconds of game time
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup=true
      • Unit Group - Pick every unit in (Units in (Entire map) matching ((((Matching unit) is in (Units of type Birds (MB))) Gleich True) and ((((Matching unit) is in A_AllBirdsGroup) Gleich False) and ((Current order of (Matching unit)) Gleich (Order(stop)))))) and do (Actions)
        • Loop - Actions
          • Set A_TempPoint[1] = (Position of (Picked unit))
          • Unit - Order (Picked unit) to Neutral - 'Kaboom!' A_TempPoint[1]
          • Custom script: call RemoveLocation (udg_A_TempPoint[1])
I wonder why this trigger creates a lag everytime the trigger triggers (=every 0.40 seconds) o_O
Has anyone a proper solution for my problem?
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Because of the:
Unit Group - Pick every unit in (Units in (Entire map) matching
My suggestion is to pick every unit in a unit group.
When the unit(s) is(are) created add it(them) to the group.
P.s. Just found out that destructables die at 0.401 (at 0.4010001 they are alive or was it 0.401001 :D )life and units at ~0.404998751 (at 0.404998752 they are still alive :p ).
Yeah it was know that units die at ~0.405 but this is more accurate :p
 
Last edited:
Level 12
Joined
Apr 27, 2008
Messages
1,228
A growing and dying tree, and an attachment on the hero are not enough??
:D
Yeah I know. But if I add some visible to all players special effects the point of camouflaging might be gone.
I also know that some trees have a very slow birth animation. Am thinking of a solution to that too.
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
Spiwn yeah, camoflaguing should perhaps not use any uber AoE sfxes. But you know the spell has been made before, you may probably get lower score for unoriginality :/

StaberFire, I am sorry to hear that. Ill send you my finest goat to eat all your nasty papers up =).
Good luck with those anyway. Im sure Poot is continuing with this contest a few more times.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Spiwn yeah, camoflaguing should perhaps not use any uber AoE sfxes. But you know the spell has been made before, you may probably get lower score for unoriginality :/
Not surprised at all. I will most probably abandon this idea an think of something that can compete with the man eating plant :D
But first, I will sleep on it :)
 
Level 30
Joined
Dec 6, 2007
Messages
2,228
I created a new entry.
I know, i already made an entry but i think i´ll replace my entry with this one.
But first i´d like to hear some opinions about it ;)
__________________________________________________________________________
Magical Birds
The druid is able to call the powers of the nature to support his battle against the foes. However, this allows him to conjure five magical birds which will fly around the druid. If there is at least one enemy in 400 AoE of a bird, the bird will leave the druid to charge this enemy. If a bird reaches an enemy, the bird will sacrifice his life to release the combined powers of the nature in 200 AoE. Every enemy in this area will receive one of the three following effects and receives 15/30/45 extra damage.
Effect 1: Enchant
The target may miss with a chance of 50% on attacks. Lasts 5/10/15 seconds.
Effect 2: Poison
The target receives 10 damage per second. Lasts 5/10/15 seconds.
Effect 3: Root
The units movement and attackspeed is slowed down for 50%. Lasts 5/10/15 seconds.
While the birds rotate around the druid, they will improve the life regeneration of him and all allied units in 300 AoE by 1/2/3 HP per second.
__________________________________________________________________________
My first entry was Purge of Nature.

EDIT: My entry is available here.
 
Last edited:
Level 15
Joined
Dec 18, 2007
Messages
1,098
Paladon, nice spell :) However, the triggers could be better.
For example, you can use Unit-Type of Triggering Unit equals to x rather than Unit is in Units of Type Matching x. Then, you can also use another method to do stuff to each bird. Instead of A_B1, A_B2 etc. Use A_B[(((MUIInteger-1)x5)+{Bird no. e.g 1, 2})]. This way, you can refer to the birds using a loop instead of copy+paste.
PS: I realised the file size is rather large.
Also, Man-Eating Plant looks great :).
EDIT: Just checked spiwn's spell, it is indeed somewhat boring :(. However, I do have some suggestions, for example, you could make lightning effects from the trees to you, say create a dummy unit with life drain which takes their hp and gives it to you and create them at the trees. Or maybe a ring of trees to "Embrace" your hero or a treant thing.
 
Level 9
Joined
Dec 26, 2007
Messages
202
You might want to use Starts the effect of an ability instead of Begins casting an ability.

Wellz, here is my entry.

Icon
Tooltip
29uvfqc.jpg
Learn Mother Nature's Recipe (Q) - [Level 1]

Creates a swarm of moving treants
which will move towards the target point,
and after some time,
they will freeze and transform into trees,
blocking the way of enemies.

Level 1 - 7 seconds.
Level 2 - 5 seconds.
Level 3 - 3 seconds.
[jass=Code]library MotherNaturesRecipe initializer onInit requires TimerUtils

globals
private constant integer ABILID_SPELL = 'A000' //raw code of the spell
private constant integer ABILID_LOCUST = 'Aloc' //raw code of the locust ability

private constant boolean BOOL_TREEREMOVE = false //remove trees or kill them?

private constant integer UNITID_UNITSUMMONED = 'efon' //raw code of the summoned unit
private constant integer DESTID_TREESUMMONED = 'WTst' //raw code of the summoned tree
private constant integer INTEGER_MAXSUMMONS = 23 //maximum number of units at one time
private constant integer INTEGER_TREEMAXVAR = 10 //number of variations of the tree model

private constant real REAL_MAXDISTANCE = 1500 //maximum distance away
private constant real REAL_MAXFROMNORM = 900 //maximum distance from the normal target loc, for the moving orders
private constant real REAL_MAXANGLE = 180 //maximum angle of the polar projection
private constant real REAL_TREESCALE = 1.10 //scaling of the tree
private constant real REAL_TREETIME = 10 //the time the trees last

private constant string MODELPATH_ONSUMMON = "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"//the fx which is spawned when a treant is created or dies
private constant string MODELPATH_ONTREE = "Abilities\\Spells\\NightElf\\ThornsAura\\ThornsAura.mdl"//the fx which is spawned when the tree is created
private constant string MODELPATH_BODYFX = "Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl" //a fx which is attached to the summoned unit
private constant string MODELPATH_ATTACH = "origin" //attaching point
endglobals

//===========================================================================
// Time formula
private function REAL_TIME takes integer lvl returns real
return 9.-(2*lvl) // the time before the treant are transformed
endfunction

//===========================================================================
// Real code, don't touch

//===========================================================================
// Conditions
private constant function spellConditions takes nothing returns boolean
return GetSpellAbilityId()==ABILID_SPELL
endfunction

//===========================================================================
// treantData struct
private struct treantData
unit t
unit o
destructable d
timer tmr

//===========================================================================
// onDestroy method
method onDestroy takes nothing returns nothing
call ReleaseTimer(.tmr)
endmethod

//===========================================================================
// initTreant method, the method which creates and orders the treant
static method initTreant takes unit p,real x,real y,real tx,real ty,real angle returns treantData
local treantData td=treantData.allocate()
local real px=tx+(GetRandomReal(-REAL_MAXFROMNORM,REAL_MAXFROMNORM))*Cos(angle+(GetRandomReal(-REAL_MAXANGLE,REAL_MAXANGLE)))
local real py=ty+(GetRandomReal(-REAL_MAXFROMNORM,REAL_MAXFROMNORM))*Sin(angle+(GetRandomReal(-REAL_MAXANGLE,REAL_MAXANGLE)))
set td.t=CreateUnit(GetOwningPlayer(p),UNITID_UNITSUMMONED,x,y,0)
call UnitAddAbility(td.t,ABILID_LOCUST)
call DestroyEffect(AddSpecialEffectTarget(MODELPATH_ONSUMMON,td.t,MODELPATH_ATTACH))
call AddSpecialEffectTarget(MODELPATH_BODYFX,td.t,MODELPATH_ATTACH)
call IssuePointOrder(td.t,"move",px,py)
set td.tmr=NewTimer()
call SetTimerData(td.tmr,td)
call TimerStart(td.tmr,REAL_TIME(GetUnitAbilityLevel(GetTriggerUnit(),ABILID_SPELL)),false,function treantData.transform)
set td.o=p
return 0
endmethod

//===========================================================================
// Transformation from treant to tree function
static method transform takes nothing returns nothing
local treantData td=GetTimerData(GetExpiredTimer())
set td.d=CreateDestructable(DESTID_TREESUMMONED,GetUnitX(td.t),GetUnitY(td.t),GetUnitFacing(td.t),REAL_TREESCALE,INTEGER_TREEMAXVAR)
call DestroyEffect(AddSpecialEffect(MODELPATH_ONSUMMON,GetUnitX(td.t),GetUnitY(td.t)))
call ShowUnit(td.t,false)
call KillUnit(td.t)
call DestroyEffect(AddSpecialEffectTarget(MODELPATH_ONTREE,td.d,MODELPATH_ATTACH))
call TimerStart(td.tmr,REAL_TREETIME,false,function treantData.remove)
endmethod

//===========================================================================
// Removal of the trees
static method remove takes nothing returns nothing
local treantData td=GetTimerData(GetExpiredTimer())
call KillDestructable(td.d)
if BOOL_TREEREMOVE then
call RemoveDestructable(td.d)
endif
call td.destroy()
endmethod
endstruct

//===========================================================================
// Main function, intializes all treants and starts timers
private function onSpellEffect takes nothing returns nothing
local integer i=-1
local location l=GetSpellTargetLoc()
local real x=GetUnitX(GetTriggerUnit())
local real y=GetUnitY(GetTriggerUnit())
local real tx=GetLocationX(l)
local real ty=GetLocationY(l)
local real angle=Atan2(ty-y,tx-x)
local treantData array td
loop
set i=i+1
exitwhen i>INTEGER_MAXSUMMONS
set td=treantData.initTreant(GetTriggerUnit(),x,y,tx,ty,angle)
endloop
call RemoveLocation(l)
set l=null
endfunction

//===========================================================================
// Initialization function
private function onInit takes nothing returns nothing
local trigger t=CreateTrigger()
local integer index=0

loop
call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)

set index=index+1
exitwhen index==bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function spellConditions))
call TriggerAddAction(t,function onSpellEffect)
endfunction

endlibrary[/code]
 

Attachments

  • SpellSystemsMiniContestTHV_Vestras.w3x
    165.2 KB · Views: 77
Level 12
Joined
Apr 27, 2008
Messages
1,228
Nope, it should work.
But anyway generally if a unit has more than 0 hp it is alive if it has 0 or less hp it is dead, that is what IsUnitAliveBJ checks.
P.s. But to be a bit more accurate the exact amount is ~0.404998751 (at 0.404998752 they are still alive).
GetUnitState(whichUnit, UNIT_STATE_LIFE) >0.404998751//:P
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Oh don't play innocent. You missed that on purpose so that he gets points reduction in order for you to win ;)
 
Status
Not open for further replies.
Top