• 🏆 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!

Diffusive Poison v1.03

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Hurls a dagger from a short distance that infects the target unit dealing 20/40/60/80/100/120 damage every second. Whenever an infected unit touches another unit, this unit also becomes infected.
Lasts 2 seconds on each unit.

Lasts until no more units are infected. A unit can be infected more than once.


Features
---------
Very customizable
No leaks (I think)
No dummy unit necessary

UPDATE@Jul10:
Spell now has a duration (30 seconds total, but still 2 seconds on each unit)
Damage text removed (code looks nicer, easier to read)
Leaks fixed, thanks to Thanathos

UPDATE@Jul11:
Removed the only BJ

UPDATE@Jul14:
Removed the total spell duration (caused bugs & lag).
Fixed some code
Added 100+ units to test map


JASS:
scope DPteehee initializer Init
globals
    //SpellId of the spell
    private constant integer SpellId = 'A000'  
    //How close units need to be to become infected
    private constant real effectRadius = 125
    //This is the total amount of damage a unit will recieve over the time it is infected
    private constant real damagePerLevel = 40
    //This is the set amount of time a unit will take damage before the infection leaves
    private constant real timeOnEachUnit = 2.00
    //sets the frequency that the spell checks for infectable units, how often the damage text is displayed
    //and the amount of damage per interval.  Does not change total amount of damage.
    private constant real interval = .1
    //special effect displayed over the heads of infected units
    private constant string effectPath = "Abilities\\Spells\\NightElf\\shadowstrike\\shadowstrike.mdl"
    //string for where the effect named above is attached
    private constant string effectPoint = "overhead"
endglobals

private struct DP
    unit hurter
    unit which
    real time = timeOnEachUnit
    real damagePerTick
    effect sfx
endstruct

globals
    private DP array c
    private integer i = 0
    private timer t = CreateTimer()
    private integer instances = 0
    private group affected = CreateGroup()
endglobals

private function IsGroundUnit takes nothing returns boolean
    local unit u = GetFilterUnit()
    local boolean b = IsUnitType(u, UNIT_TYPE_FLYING) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitType(u, UNIT_TYPE_DEAD) == false and IsUnitInGroup(u, affected) == false
    set u = null
    return b
endfunction

private function looping takes nothing returns boolean
    local integer z = i
    local group g = CreateGroup()
    local unit target
    local unit caster
    loop
        exitwhen z <= 0
        call GroupEnumUnitsInRange(g, GetUnitX(c[z].which), GetUnitY(c[z].which), effectRadius, Condition(function IsGroundUnit))
        call GroupRemoveUnit(g, c[z].hurter)
        loop
            set target = FirstOfGroup(g)
            exitwhen target == null
            call GroupRemoveUnit(g, target)
            if IsUnitAlly(target, GetOwningPlayer(c[z].hurter)) == false then
                set caster = c[z].which
                set i = i+1
                if i > instances then
                    set instances = instances+1
                    set c[i] = DP.create()
                endif
                set c[i].hurter = c[z].hurter
                set c[i].which = target
                set c[i].damagePerTick = GetUnitAbilityLevel(c[i].hurter, SpellId) * damagePerLevel * interval / timeOnEachUnit
                set c[i].sfx = AddSpecialEffectTarget(effectPath, target, effectPoint)
                call GroupAddUnit(affected, c[i].which)
                set target = null
                set caster = null
            endif
        endloop
        call UnitDamageTarget(c[z].hurter, c[z].which, c[z].damagePerTick, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        call DestroyGroup(g)
        set g = null
        set c[z].time = c[z].time - interval
        if c[z].time <= 0 or IsUnitType(c[z].which, UNIT_TYPE_DEAD) == true then
            call GroupRemoveUnit(affected, c[z].which)
            call DestroyEffect(c[z].sfx)
            set c[z] = c[i]
            set i = i-1
            set instances = instances - 1
            if i==0 then
                call GroupClear(affected)
                call PauseTimer(t)
            endif
        endif
        set z = z-1
    endloop
    return false
endfunction

private function Actions takes unit caster, unit target returns nothing
    set i = i+1
    if i > instances then
        set instances = instances+1
        set c[i] = DP.create()
    endif
    set c[i].hurter = caster
    set c[i].which = target
    set c[i].damagePerTick = GetUnitAbilityLevel(c[i].hurter, SpellId) * damagePerLevel * interval / timeOnEachUnit
    set c[i].sfx = AddSpecialEffectTarget(effectPath, target, effectPoint)
    call GroupAddUnit(affected, c[i].which)
    set target = null
    set caster = null
    if i == 1 then
        call TimerStart(t, interval, true, function looping)
    endif
endfunction

private function Conditions takes nothing returns boolean
    if SpellId == GetSpellAbilityId() then
        call Actions(GetTriggerUnit(), GetSpellTargetUnit())
    endif
    return false
endfunction

private function Init 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 Conditions) )
endfunction

endscope

Credits:
Trollvottel @ thehelper.net
Flare @ thehelper.net

Keywords:
poison diffusive shadow strike
Contents

Diffusive Poison (Map)

Reviews
22:21, 2nd Jan 2010 TriggerHappy: You could use UnitAlive instead of IsUnitType. FirstOfGroup loops are slow. Why are you dynamically creating groups? Please re-use a global one or at the very least recycle them. ATTACK_TYPE_NORMAL...

Moderator

M

Moderator

22:21, 2nd Jan 2010
TriggerHappy:

  • You could use UnitAlive instead of IsUnitType.
  • FirstOfGroup loops are slow.
  • Why are you dynamically creating groups? Please re-use a global one or at the very least recycle them.
  • ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS should be configurable.
  • There is no need to inline the event.
  • Timer Attachment system would be wiser than looping through instances.
 
Level 11
Joined
Jul 2, 2008
Messages
601
I'm not a jasser, but why can I see just a bunch of numbers in game and unstopable "Poison Dagger" sound? Really, you should work better on it. Unfortunately, I can't tell anything about your triggering, but both those numbers and sound are annoying. Also the screenshot isn't from the test map - in the test-map we play Archmage, but on the screeny there is a watcher hero. :)
 
Level 6
Joined
Nov 7, 2007
Messages
39
1st: I'd rather not post a 1mb map when i can post a 50kb one.
2nd:
I'm not a jasser, but why can I see just a bunch of numbers in game and unstopable "Poison Dagger" sound?
WTH is that? That's not english, I'm sure.

Disclaimer: Screeny might not be exactly the same as in game. For instance, my screenshot doesn't move, but in the game beware! You may see the my screenshot doesn't exactly show what the map portrays.

On a less sarcastic and bloodthirsty note:
Thank you for your feedback. <3
 
Level 11
Joined
Jul 2, 2008
Messages
601
Ehm, well, yeah, that was English, but there should be "what" instead of "why" :)

Anyway, you can think anything you want, but your spell perfoms like unstopable sound of "Poison Dagger" (While units poison each other, OMG, they do this unstopable, so the sound is unstopable, yeah?) and bunch of numbers overhead the units. It's also always 2 and creates additional one floating text each nano-second, if the units are near each other. ;D

And, well, I'm not going to argue, I can't tell anything about your Jass codding, but this can be easily done in GUI just with two location variables, If/Then/Else condition, dummy unit, spell and effect. So if you are going to keep up your "sarcasm" (which I didn't find :D As far as I got that you are unable to switch the "Why" with "What"), I won't reply anymore.
 
Level 6
Joined
Nov 7, 2007
Messages
39
okay. Do this in gui and if you can make it MUI as efficiently as this I will gladly accept your critique, which I find does not make any sense. I understand, now, that you are foreign (i hope) and I do not expect you to detect the sarcasm. Anyway, back to relevant posts about this spell.
 
Level 9
Joined
Aug 2, 2008
Messages
219
uff this thing is ok, but it still has some flaws....
the code looks a bit ugly, because the the functions are massive textblocks...you should just add some free lines. And you may choose some better names for your variables:
JASS:
globals
[....]
private DP array c
[....]
endglobals
Seriously, just c as a global ?! man that can get really confusing...
Your code also contains a wait and some BJ´s and that is not very good. In my Eyes thiis here is really weird...
JASS:
private function KillText takes texttag tt returns nothing
    local texttag ttt = tt
    call TriggerSleepAction(1.)
    call DestroyTextTag(ttt)
endfunction

First of all ttt = tt ? This is just pointless and you forgot to remove the local...this construction leaks. Well the TSA is obvious.


Anyway, you can think anything you want, but your spell perfoms like unstopable sound of "Poison Dagger" (While units poison each other, OMG, they do this unstopable, so the sound is unstopable, yeah?) and bunch of numbers overhead the units.
The Poison Dagger sound comes along with the creation of the SFX model...if you don´t like just change the model, but yes the sound is really annoing. Well and i just added some more units to the map and casted the spell...the result was the spell would never end since everyone was effect again when the poison was gone. You should really fix that.
I understand, now, that you are foreign (i hope)....
Foreign ?! LOL i thought this is an international site

~TNT
 
Level 4
Joined
Jun 16, 2009
Messages
92
Good spell, though I think it could be cleaned up a bit. The number 2 spammed repeatedly is annoying.

Works well though.
 
Level 6
Joined
Nov 7, 2007
Messages
39
geez you guys are picky >.<
The only BJ was a function to write events, so it only runs at the beginning of the game. If it leaks, it only leaks once. Nevertheless, I removed it. Also, if we're going into particulars about who copied who, this is my original thread for this spell over at thehelper (two months before -JonNny's (although I do see some stuff I like in his, now that I look at it))
 
Top