• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Spell Help] Need Two fire spells

Status
Not open for further replies.
Level 3
Joined
Jul 29, 2006
Messages
61
I need help with two spells. Both preferably in Jass, and MUI

First of all, is a blaze spell. Cliche, I know.
Currently I have this set up:
-I have a unit that is locust, has a model of fire, and is flying with no shadow, It has immolation. It is currently "n004"
-The spell creates these fires whenever the character walks. It is passive. They last for 3/4/5 seconds (Expiration timers of course).
-My Current, Horribly flawed Script (as I knew when I made it):
JASS:
function Trig_Blaze_Conditions2 takes nothing returns boolean
    if ( ( GetIssuedOrderIdBJ() == String2OrderIdBJ("smart") ) ) then
        return true
    endif
    if ( ( GetIssuedOrderIdBJ() == String2OrderIdBJ("patrol") ) ) then
        return true
    endif
    if ( ( GetIssuedOrderIdBJ() == String2OrderIdBJ("move") ) ) then
        return true
    endif
    return false
endfunction

function Trig_Blaze_Conditions takes nothing returns boolean
    if ( not ( GetUnitAbilityLevelSwapped('A00C', GetTriggerUnit()) > 0 ) ) then
        return false
    endif
    if ( not Trig_Blaze_Conditions2() ) then
        return false
    endif
    return true
endfunction

function Trig_Blaze_Actions takes nothing returns nothing
    local location o
    local location p
    local location r
    local real ox
    local real oy
    local real rx
    local real ry
    local unit u
    set u = GetOrderedUnit()
    set o = GetOrderPointLoc()
    set r = GetUnitLoc(u)
    set rx = GetUnitX(u)
    set ry = GetUnitY(u)
    set ox = GetOrderPointX()
    set oy = GetOrderPointY()
    loop
       exitwhen GetBooleanAnd(ox==rx,oy==ry)
       set p = r
       set r = GetUnitLoc(u)
       set rx = GetUnitX(u)
       set ry = GetUnitY(u)
       call CreateNUnitsAtLocFacingLocBJ( 1, 'n004', GetOwningPlayer(u), p, p)
       call UnitApplyTimedLifeBJ( ( 2.00 + I2R(GetUnitAbilityLevelSwapped('A00C', u)) ), 'BTLF', GetLastCreatedUnit() )
       call TriggerSleepAction(0.05)       
    endloop
    set u = null
    set p = null
    set o = null
    set r = null
endfunction

//===========================================================================
function InitTrig_Blaze takes nothing returns nothing
    set gg_trg_Blaze = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Blaze, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerAddCondition( gg_trg_Blaze, Condition( function Trig_Blaze_Conditions ) )
    call TriggerAddAction( gg_trg_Blaze, function Trig_Blaze_Actions )
endfunction
This, I'd knew would cause problems, But I can't think of a better way.



Second question:
I'm creating a spell that is a combination Mana Shield and Thorns Aura. I need a script that will keep a dummy at the casters location (the dummy should have thorns.), and will kill the dummy when the buff is gone. For simplicities sake, lets call the unit Thorns Aura "A00D", the Mana Shield buff "B006", and the Dummy "N000". The Shield should seem to burn the unit.
- From another direction, I can see editing a previous script that created an Area of attack Critical strike. It detects when the caster is attacked, If he has the buff, and then deals damage from there. That would probably be a better route.

Ok, Heres my script for this one, hoping it will work.
JASS:
//=================================
//Burning Shield
//by Gralamin
//
//To implement, Copy the script
//into a converted trigger
//named FireShield
//
//Requires the HandleVars
//Be sure to set the options below
//
//Give credit if you use this spell
//==================================
//=======================
// --- Spell options --- 
//=======================
constant function FS_AbilityRC takes nothing returns integer
    return 'A00D' //The ability's raw code.
endfunction

constant function FS_DamageMultiplier takes integer level returns real
    return 0.1 + level * 0.1 //Return 20%/30%/40% damage
endfunction

constant function FS_Effect takes nothing returns string
    //Effect on target. no effect is ""
    return "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationRedTarget.mdl"
endfunction

//=======================
//   --- The Spell --- 
//=======================
function Trig_FireShield_Damage_Conditions takes nothing returns boolean
    return GetEventDamageSource() == GetHandleUnit(GetTriggeringTrigger(), "Attacker")
endfunction

function Trig_FireShield_Damage_Actions takes nothing returns nothing
    local trigger tr = GetTriggeringTrigger()
    local unit u = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    local real dmg = GetEventDamage()*FS_DamageMultiplier(GetUnitAbilityLevel(a,FS_AbilityRC()))
    local real dist = 100.00 // "Melee Distance". Adds in the don't get to close effect.
    call TriggerRemoveCondition(tr,GetHandleTriggerCondition(tr,"Condition"))
    call TriggerRemoveAction(tr,GetHandleTriggerAction(tr,"Action"))
    call FlushHandleLocals(tr)
    call DestroyTrigger(tr)
    call SetHandleHandle(a, "DamageTrig", null)
    
    if IsUnitInRange(u, a, dist)==true then
            call UnitDamageTarget(u, a, dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, null)
    endif
    if FS_Effect() != "" then
        call DestroyEffect(AddSpecialEffectTarget(FS_Effect(),u,"chest"))
    endif
    set tr = null
    set u = null
    set a = null
endfunction

function Trig_FireShield_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetAttacker(), FS_AbilityRC()) > 0 and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) and GetHandleTrigger(GetAttacker(), "DamageTrig") == null and UnitHasBuffBJ(GetTriggerUnit(), 'B007') == true
endfunction

function Trig_FireShield_Actions takes nothing returns nothing
    local unit a = GetAttacker()
    local unit u = GetTriggerUnit()
    local trigger t
    local boolexpr be
    
    set t = CreateTrigger()
    call SetHandleHandle(a, "DamageTrig", t)
    call SetHandleHandle(t, "Attacker", a)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DAMAGED)
    set be = Condition(function Trig_FireShield_Damage_Conditions)
    call SetHandleHandle(t,"Condition", TriggerAddCondition(t, be))
    call DestroyBoolExpr(be)
    set be = null
    call SetHandleHandle(t,"Action", TriggerAddAction(t, function Trig_FireShield_Damage_Actions))
    call TriggerSleepAction(1.5)
    call FlushHandleLocals(t)
    call DestroyTrigger(t)
    call SetHandleHandle(a, "DamageTrig", null)
    set t = null
    set a = null
    set u = null
endfunction
//===========================================================================
function InitTrig_FireShield takes nothing returns nothing
    set gg_trg_FireShield = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_FireShield, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_FireShield, Condition( function Trig_FireShield_Conditions ) )
    call TriggerAddAction( gg_trg_FireShield, function Trig_FireShield_Actions )
endfunction

Nope, not working. How do I change that...
 
Last edited:
Level 11
Joined
Jul 12, 2005
Messages
764
For your fisrt spell, I'd use a timer to detect if the unit is moving or not.
Inside the (1 second periodic) timer:
-Check if the last attached X (or Y) coordinate is the same as the current
--If yes, the unit is not moving
--If no, the unit is moving, so place a fire dummy, and attach current X (or Y) coordinate to the unit with HandleVars

Start the timr when the unit learns the ability.
USE HANDLE VARS!


I recognise your second script, the original was written by me. It detects if the unit with an ability damages another one (like Critical Strike), but not when the unit is damaged (like Evasion, or Thorns Aura, etc...).
For this one, when the hero learns the ability, you have to create only one trigger that fires when the unit is damaged.
 
Level 3
Joined
Jul 29, 2006
Messages
61
Ah, thanks for the tips, I'll give it a try.
(On another note, I thought I had left the comment giving credit to you in there. Odd.)
 
Level 3
Joined
Jul 29, 2006
Messages
61
I'm not sure How you'd use local vars for Blaze, but I've made this script:
JASS:
function Trig_Blaze_Conditions takes nothing returns boolean
    if ( not ( GetLearnedSkillBJ() == 'A00C' ) ) then
        return false
    endif
    return true
endfunction

function Blaze_Fire takes unit u, real px, real py, location p returns nothing
    local real cx
    local real cy
    
    set cx = GetUnitX(u)
    set cy = GetUnitY(u)
    
    if ( not (cx == px) ) or ( not ( cy == py) ) then
        call CreateNUnitsAtLocFacingLocBJ( 1, 'n004', GetOwningPlayer(u), p, p)
        call UnitApplyTimedLifeBJ( ( 2.00 + I2R(GetUnitAbilityLevelSwapped('A00C', u)) ), 'BTLF', GetLastCreatedUnit() )
    endif
endfunction

function Trig_Blaze_Actions takes nothing returns nothing
    local timer t
    local unit u
    local real px
    local real py
    local location p
    
    set u = GetTriggerUnit()
    set t = CreateTimer()
    
    loop
        exitwhen GetUnitLifePercent(u) == 0.00
        set p = GetUnitLoc(u)
        set px = GetUnitX(u)
        set py = GetUnitY(u)
        call TimerStart(t, 1.00, true, function Blaze_Fire(u, px, py, p))
    endloop    
    
    call DestroyTimer(t)
    set t = null
    set u = null
endfunction

//===========================================================================
function InitTrig_Blaze takes nothing returns nothing
    set gg_trg_Blaze = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Blaze, EVENT_PLAYER_HERO_SKILL )
    call TriggerAddCondition( gg_trg_Blaze, Condition( function Trig_Blaze_Conditions ) )
    call TriggerAddAction( gg_trg_Blaze, function Trig_Blaze_Actions )
endfunction
which works until it dies, then a separate script for when they are revived. How can I code this more efficiently?

Also an odd note while trying to implement, this line:
JASS:
call TimerStart(t, 1.00, true, function Blaze_Fire(u, px, py, p))
Gives me a error (expected ') where do is it want a '?

As for the Second one, This might be me being dumb. But If I change this line of code (in Conditions):
JASS:
GetUnitAbilityLevel(GetAttacker(), FS_AbilityRC()) > 0
To this:
JASS:
GetUnitAbilityLevel(GetTriggerUnit(), FS_AbilityRC()) > 0
Wouldn't that work? I'm going to test it regardless.
 
Last edited:
Level 3
Joined
Jul 29, 2006
Messages
61
Ah. That would explain that. Any better way to do it then two scripts, One for revive and one for learning? Also, How exactly would I use handle vars to reference the function?

edit: Workaround Acheived! This even seems to work when he is revived...
JASS:
function Trig_Blaze_Conditions takes nothing returns boolean
    if ( not ( GetLearnedSkillBJ() == 'A00C' ) ) or (GetUnitAbilityLevelSwapped('A00C', GetTriggerUnit()) >= 2)  then
        return false
    endif
    return true
endfunction

function Blaze_Fire takes unit u, real px, real py, location p returns nothing
    local real cx
    local real cy
    
    set cx = GetUnitX(u)
    set cy = GetUnitY(u)
    
    if ( not (cx == px) ) or ( not ( cy == py) ) then
        call CreateNUnitsAtLocFacingLocBJ( 1, 'n004', GetOwningPlayer(u), p, p)
        call UnitApplyTimedLifeBJ( ( 2.00 + I2R(GetUnitAbilityLevelSwapped('A00C', u)) ), 'BTLF', GetLastCreatedUnit() )
    endif
endfunction

function Trig_Blaze_Actions takes nothing returns nothing
    local unit u
    local real px
    local real py
    local location p
    
    set u = GetTriggerUnit()
    
    loop
        exitwhen GetUnitLifePercent(u) == 0.00
        set p = GetUnitLoc(u)
        set px = GetUnitX(u)
        set py = GetUnitY(u)
        call TriggerSleepAction(0.10)
        call Blaze_Fire(u, px, py, p)
    endloop    
    
    set u = null
endfunction

//===========================================================================
function InitTrig_Blaze takes nothing returns nothing
    set gg_trg_Blaze = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Blaze, EVENT_PLAYER_HERO_SKILL )
    call TriggerAddCondition( gg_trg_Blaze, Condition( function Trig_Blaze_Conditions ) )
    call TriggerAddAction( gg_trg_Blaze, function Trig_Blaze_Actions )
endfunction

As for my second script, It currently looks like this:
JASS:
//=================================
//Fire Shield
//by Gralamin
//
//To implement, Copy the script
//into a converted trigger
//named FireShield
//
//Requires the HandleVars
//Be sure to set the options below
//
//Give credit if you use this spell
//==================================
//=======================
// --- Spell options --- 
//=======================
constant function FS_AbilityRC takes nothing returns integer
    return 'A00D' //The ability's raw code.
endfunction

constant function FS_DamageMultiplier takes integer level returns real
    return 0.1 + level * 0.1 //Return 20%/30%/40% damage
endfunction

constant function FS_Effect takes nothing returns string
    //Effect on target. no effect is ""
    return "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationRedTarget.mdl"
endfunction

//=======================
//   --- The Spell --- 
//=======================
function Trig_FireShield_Damage_Conditions takes nothing returns boolean
    return GetEventDamageSource() == GetHandleUnit(GetTriggeringTrigger(), "Attacker")
endfunction

function Trig_FireShield_ManaCheck takes unit u, real dmg returns boolean
    if (not ( GetUnitStateSwap(UNIT_STATE_MANA, u) >= ( dmg / ( 0.50 + ( I2R(GetUnitAbilityLevelSwapped('A00D', u)) / 2.00 ) ) ) ) ) then
        return false
    endif
    return true
endfunction

function Trig_FireShield_Damage_Actions takes nothing returns nothing
    local trigger tr = GetTriggeringTrigger()
    local unit u = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    local real dmg = GetEventDamage()
    local real dmgm = GetEventDamage()*FS_DamageMultiplier(GetUnitAbilityLevel(a,FS_AbilityRC()))
    call TriggerRemoveCondition(tr,GetHandleTriggerCondition(tr,"Condition"))
    call TriggerRemoveAction(tr,GetHandleTriggerAction(tr,"Action"))
    call FlushHandleLocals(tr)
    call DestroyTrigger(tr)
    call SetHandleHandle(a, "DamageTrig", null)
    
    if Trig_FireShield_ManaCheck(u,dmg)==true then
        call SetUnitLifeBJ( u, ( GetUnitStateSwap(UNIT_STATE_LIFE, u) + dmg ) )
        call SetUnitManaBJ( u, ( GetUnitStateSwap(UNIT_STATE_MANA, u) - ( dmg / ( 0.50 + ( I2R(GetUnitAbilityLevelSwapped('A00D', u)) / 2.00 ) ) ) ) )
        
        if not IsUnitType(a, UNIT_TYPE_RANGED_ATTACKER) then
            call UnitDamageTarget(u, a, dmgm, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, null)
        endif

        if FS_Effect() != "" then
            call DestroyEffect(AddSpecialEffectTarget(FS_Effect(),a,"chest"))
        endif
        
        if ( GetUnitStateSwap(UNIT_STATE_MANA, u) == 0.00 ) then
            call IssueImmediateOrderBJ( u, "manashieldoff" )
        endif
    else
        call IssueImmediateOrderBJ( u, "manashieldoff")
        call SetUnitManaBJ(u, 0.00)
    endif
    set tr = null
    set u = null
    set a = null
endfunction

function Trig_FireShield_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetTriggerUnit(), FS_AbilityRC()) > 0 and GetHandleTrigger(GetAttacker(), "DamageTrig") == null and UnitHasBuffBJ(GetTriggerUnit(), 'B007') == true
endfunction

function Trig_FireShield_Actions takes nothing returns nothing
    local unit a = GetAttacker()
    local unit u = GetTriggerUnit()
    local trigger t
    local boolexpr be
    
    set t = CreateTrigger()
    call SetHandleHandle(a, "DamageTrig", t)
    call SetHandleHandle(t, "Attacker", a)
    call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_DAMAGED)
    set be = Condition(function Trig_FireShield_Damage_Conditions)
    call SetHandleHandle(t,"Condition", TriggerAddCondition(t, be))
    call DestroyBoolExpr(be)
    set be = null
    call SetHandleHandle(t,"Action", TriggerAddAction(t, function Trig_FireShield_Damage_Actions))
    call TriggerSleepAction(1.5)
    call FlushHandleLocals(t)
    call DestroyTrigger(t)
    call SetHandleHandle(a, "DamageTrig", null)
    set t = null
    set a = null
    set u = null
endfunction
//===========================================================================
function InitTrig_FireShield takes nothing returns nothing
    set gg_trg_FireShield = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_FireShield, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_FireShield, Condition( function Trig_FireShield_Conditions ) )
    call TriggerAddAction( gg_trg_FireShield, function Trig_FireShield_Actions )
endfunction
This still Isn't working, What is the difference between what I'm Trying to do, and what this script does?
 
Last edited:
Status
Not open for further replies.
Top