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

Blinky V.1

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
This is a rather simple spell, so i tried to make is as customizable as possible.
It uses a damage formula like the following:

Damage = ((Stat x (Multiplier x Ability Level)) + Base Damage)


A dummy Unit
Jass



  • A single powerful ranged attack that leaves a trail of blight like terrain in its wake and surprises the target.
  • A melee(Range of 80-150) barrage of attacks using a tiny or invisible dummy unit.
  • A barrage of weak arrows spawned from everywhere on the map with a huge range to pin down the unit.
  • Etc...



This spell does the following:
  • Pauses both spell caster and target.
  • Makes caster Invincible so that units will not acquire it as a target or receive AOE damage.
  • Sets a fog modifier over the target.
    Loop Start, Ends when Target is dead or NumA is reached. (Read readme below for NumA details)
  • Moves caster.
  • Spawns (dummy) unit at caster that is given the attackonce command on the target.
  • Sets Custom Value of dummy unit to the damage to give to target.
  • Uses a wait to prevent all the attacks from happening at once.
    Loop End
  • Removes Pause and Invincibility.


Another Trigger in the same trigger (confusing I know) handles the dummy unit.

It loops until the dummy units order is not equal to attackonce (so the unit cannot be manipulated.)
During the loop if the terrain Boolean is true it will leave a trail of a different type of terrain.
When the loop ends (because the unit is no longer ordered attackonce) it removes the dummy unit. (This also prevents dummy units from leaking when they lose a target as when they reach that point they will be ordered to stop.)



This spell was designed with one thing in mind.
Making it what you want it to be.


Its almost like a system, used to make more spells however you want to make them.
But because of this I had to keep everything as minimal as possible.
There are quite a few definable values in this. And I will attempt to outline them below.

Definable Variables:
  • TC (Boolean) - Used to check if it should apply "terrain streaks", in other words it checks if the missile should change the terrain beneath it as it travels.
  • TT (Integer) - Used to store the terrain type's RAW ID code for leaving terrain streaks.
  • Attribute (String) - Sets what attribute to check the hero for. (STR, AGI, INT)
  • Mult (Real) - Sets the Attribute Multiplier, Refer to the formula above for reference.
  • MWait (Real) - Sets a time for the unit to wait before moving/attacking again.
  • NumA (Integer) - Sets the amount of times to move/attack before exiting the spell.
  • Bx (Integer) - Sets the range of the blink from the target of the spell. (Will move inside this range but not outside it.)
  • Dmmy (Integer) - Sets the dummy RAW ID of the missile for spawning.
  • BD (Real) - Sets the amount of damage the spell will always deal. See above formula for details.

IMPORTANT!:
There are 2 constant variables that I could not pass values to. They must also be changed as described. Eg.
JASS:
//=====================================================
//CHANGE 'h000' TO YOUR DUMMY UNITS RAW ID==============
//=====================================================
function DC_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'h000'
endfunction

//=======================================================
//========================================================
//=======================================================



This is hidden as the sight of JASS scares some people :p
JASS:
//=====================================================
//============== Blinky Spell(Custom) =================
//================ By: Drenferalis ====================
//=====================================================
//=====================================================
//==== This spell is used for Imitating multiple =====
//== attacks within few seconds. It requires the use ==
//== of a dummy unit to imitate an  attack sequence ==
//== and uses a damage target function to define how ==
//== much damage is dealt. The damage can be defined ==
//=== by changing  the appropriate variables in the ===
//============= function Spell_Actions. ===============
//=====================================================
//===WARNING: DO NOT CHANGE ANYTHING EXCEPT WHAT IS====
//====LABELED WITH CHANGE OR DEFINE SUCH AS BELOW!=====
//=====================================================
//=====================================================


//=====================================================
//CHANGE 'h000' TO YOUR DUMMY UNITS RAW ID==============
//=====================================================
function DC_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'h000'
endfunction

//=======================================================
//========================================================
//=======================================================


function DC_Actions takes nothing returns nothing
    local real craterx
    local real cratery
    local unit target =  GetOrderTargetUnit()
    local integer DMG1
    local integer TT
//=======================================================
//Define this for terrain changes=========================
//=======================================================
    //Actively Changes the terrain below missle?
    local boolean TC = true
    //If true what type? (Uses terrain raw code.)
    set TT = 'Nice'
//=======================================================
//========================================================
//=======================================================
    loop
        exitwhen GetUnitCurrentOrder(GetTriggerUnit()) != OrderId("attackonce")
        call TriggerSleepAction(RMaxBJ(bj_WAIT_FOR_COND_MIN_INTERVAL, 0.10))
        if (TC == true)then
            set cratery = GetUnitY(GetTriggerUnit())
            set craterx = GetUnitX(GetTriggerUnit())
            call SetTerrainType(craterx,cratery,TT,-1,1,0)
        endif
    endloop
    set DMG1 = GetUnitUserData(GetTriggerUnit())
    call UnitDamageTarget(GetTriggerUnit(),target,I2R(DMG1),true,false,ATTACK_TYPE_PIERCE,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
    set target = null
    call RemoveUnit(GetTriggerUnit())
endfunction

function Loc_trg takes nothing returns nothing
    local trigger DC = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(DC,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
    call TriggerAddCondition(DC,Condition(function DC_Conditions))
    call TriggerAddAction(DC,function DC_Actions)
    set DC = null
endfunction







//Checks if the ability being cast is "Blinky"
//==========================================================
//REPLACE 'A000' WITH YOUR CUSTOM SPELL RAW ID!=============
//==========================================================
function Trig_Blinky_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction
//==========================================================
//END REPLACE===============================================
//==========================================================




//The main spell is here.
function Spell_Actions takes nothing returns nothing
    //Sets locals for MUI and leak removal.
    local unit Blinky = GetSpellTargetUnit()
    local unit Blink_E = GetSpellAbilityUnit()
    local unit B_Dummy
    local integer LI = 1
    local location TR
    local real BlinkX = GetUnitX(Blinky)
    local real BlinkY = GetUnitY(Blinky)
    local rect BlinkRect
    local location BlinkELoc
    local real Stat
    local integer AL
    local real BD
    local real DMG
    local integer Dmmy
    local fogmodifier Fog
//==================================================================
//Definable Variables Below==========================================
//==================================================================
    //Change to STR for Strength, AGI for Agility, and INT for intelligence.
    local string Attribute = "AGI"
    //Multiplier Percentage of the spell (Will be multiplied by Spell Level [eg. Mult=.1) and Spell level is 3 the final Mult will be .3])
    local real Mult = 0
    //Wait between movement/attacks.
    local real MWait = .01
    //Number of attacks
    local integer NumA = 500
    //Square Range of "Blink"
    local integer Bx = 5000
    //Dummy Unit RAW ID
    set Dmmy = 'h000'
    //Base Spell Damage
    set BD = 5
    //End of Definable Variables
//==================================================================
//===================================================================
//==================================================================

    if ( Attribute == "STR")then
        set Stat = I2R(GetHeroStr(Blink_E,true))
    elseif (Attribute == "AGI")then
        set Stat = I2R(GetHeroAgi(Blink_E,true))
    elseif (Attribute == "INT")then
        set Stat = I2R(GetHeroInt(Blink_E,true))
    endif
    set AL = GetUnitAbilityLevel(Blink_E,GetSpellAbilityId())
    set DMG =((Stat*(Mult*(I2R(AL))))+BD)
    call Loc_trg()
    call PauseUnit(Blinky,true)
    call PauseUnit(Blink_E,true)
    call SetUnitInvulnerable(Blink_E,true)
    set Fog = CreateFogModifierRadius(GetOwningPlayer(Blink_E),FOG_OF_WAR_VISIBLE,BlinkX,BlinkY,512,true,false)
    call FogModifierStart(Fog)  
    loop
        exitwhen LI > NumA
        if GetUnitState(Blinky,UNIT_STATE_LIFE) >= 0.45 then
            set BlinkX = GetUnitX(Blinky)
            set BlinkY = GetUnitY(Blinky)
            set BlinkRect = Rect(BlinkX-Bx*0.5,BlinkY-Bx*0.5,BlinkX+Bx*0.5,BlinkY+Bx*0.5) 
            set TR = Location(GetRandomReal(GetRectMinX(BlinkRect), GetRectMaxX(BlinkRect)), GetRandomReal(GetRectMinY(BlinkRect), GetRectMaxY(BlinkRect)))
            call SetUnitPositionLoc(Blink_E,TR)
            call SetUnitFacing(Blink_E,bj_RADTODEG*Atan2(BlinkY-GetLocationY(TR),BlinkX-GetLocationX(TR)))
            set B_Dummy = CreateUnit(GetOwningPlayer(Blink_E),Dmmy,GetUnitX(Blink_E),GetUnitY(Blink_E),bj_RADTODEG*Atan2(GetUnitY(Blinky)-BlinkY,GetUnitX(Blinky)-BlinkX))
            call IssueTargetOrder(B_Dummy,"attackonce",Blinky)
            call SetUnitUserData(B_Dummy,R2I(DMG))
            call TriggerSleepAction(MWait)
            call RemoveLocation(TR)
        else
            call PauseUnit(Blink_E,false)
            call SetUnitInvulnerable(Blink_E,false)            
            call DestroyFogModifier(Fog)
            return
        endif        
        set LI = LI + 1
    endloop
    call PauseUnit(Blink_E,false)
    call DestroyFogModifier(Fog)
    call SetUnitInvulnerable(Blink_E,false)
    call PauseUnit(Blinky,false)
    call RemoveRect(BlinkRect)
    call RemoveLocation(BlinkELoc)
    set Fog = null
    set BlinkRect = null
    set Blinky = null
    set Blink_E = null
    set B_Dummy = null
    set BlinkELoc = null
    set TR = null
    set LI = 0
endfunction

//===========================================================================
function InitTrig_Blinky takes nothing returns nothing
    set gg_trg_Blinky = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Blinky, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Blinky, Condition( function Trig_Blinky_Conditions ) )
    call TriggerAddAction( gg_trg_Blinky, function Spell_Actions )
endfunction



I may just add special effects on the attack and spawning of the dummy unit and to the moving of the caster.


Comments appreciated,
But please do not rate this spell until the bugs(if any, I'm sure there are a few) have been fixed :/




Keywords:
Blink, Fast, Fast-Blink, Attack, Drenferalis, Terrain, Streaks
Contents

BLINKY TEST (Map)

Reviews
15 November 2015 BPower: Rejecting due to the status of this resource being "needs fix" for years. 12:12, 20th Feb 2010 TriggerHappy: Don't use locations, use GetWidgetLife instead of GetUnitState and do not pause non-dummy units.

Moderator

M

Moderator

15 November 2015
BPower: Rejecting due to the status of this resource being "needs fix" for years.

12:12, 20th Feb 2010
TriggerHappy:

Don't use locations, use GetWidgetLife instead of GetUnitState and do not pause non-dummy units.
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
Local variables should always have lower caps names.

You should add a global block for settings instead of the settings being inside a function.

The sound of the unit hitting the target is annoying,remove it.

The terrain deformation is unnecesarry.

There should be a blink effect.

The interval of blinking should be lower.

You should add the Locust ability to the dummies.

You should kill the dummy before you remove it.

You shouldn't pause the caster, it causes an irreversable issue.

The dummy units should have a point value of 0 in order not to increase the score in a map for the casting player.

You shouldn't use waits, you should use timers, also wait cannot be used under 0.27, everything below 0.27 is automatically used as 0.27.
 
Level 4
Joined
Dec 30, 2009
Messages
60
Local variables should always have lower caps names.

You should add a global block for settings instead of the settings being inside a function.

The sound of the unit hitting the target is annoying,remove it.

The terrain deformation is unnecesarry.

There should be a blink effect.

The interval of blinking should be lower.

You should add the Locust ability to the dummies.

You should kill the dummy before you remove it.

You shouldn't pause the caster, it causes an irreversable issue.

The dummy units should have a point value of 0 in order not to increase the score in a map for the casting player.

You shouldn't use waits, you should use timers, also wait cannot be used under 0.27, everything below 0.27 is automatically used as 0.27.

  1. Global Blocks are vJass and I'm not sure I want to use JNGP for other reasons.
  2. The sound of the unit attacking is in the dummy unit, completely customizable to what the spell user wants.
  3. The terrain deformation can be turned off.
  4. New version(unreleased) has a special effect during the "blink".
  5. The interval for the blink is a definable value. So its more of what the spell user wants than what 1 person wants.
  6. Locust ability added to new version.
  7. Dummy is killed before removed in new version.
  8. Could you link to this phenomena please?
  9. Without using globals (not MUI if i remember correctly) I cant pass the damage between triggers without using the custom point value. And I dont believe it changes a users score...
  10. Trying to figure out how to use a timer as a wait without TimerUtils.
I suggest you to remove those BJ.

The BJ will be removed when I figure out timers being used as waits in a loop with conditional statements.

To all what Kingz and Septimus said I`ll add that you should X/Y instead of locations.
On my to fix list, I was tired when I was replacing Loc's

you did not use the local variable BlinkELoc or have I missed it?

Forgot to remove it :p
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
Point value isn't Custom value.

Point value is an field in the Object Editor for units, it determines how much points you get for creating that unit.

Also lazyness is no excuse, remove the sound and don't use pause.

For the pause issue you should ask TriggerHappy, i only remember it caused issues when it came to handle recycling or handling unit handles :p

EDIT:

Using lower caps variable names for locals is a standard, try to follow it.
 
Level 4
Joined
Dec 30, 2009
Messages
60
in the new version I have:

*Fixed the variables and made them lowercase.
*Removed the sound of the dummy unit attacking.
*Added a blink effect.

I am trying to get rid of waits.

I will ask trigger happy what happens with pause.

I may have replaced custom value BJ with the wrong native, I was tired when finishing.(Edit: Point value in the object editor, duh. Fixed in new version.)

After making this work in jass I will release a vJass version to make it work better.

Thanks for the help and criticism. +rep when I get back on a computer :p
I'm on my phone.
 
Last edited:
Top