• 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] Area of Effect Critical Strike

Status
Not open for further replies.
Level 3
Joined
Jul 29, 2006
Messages
61
I'm posting this in a new thread since it's a different topic then my last two questions.

I'm attempting to make an AoE Critical Strike spell. I Currently have two problems. One is the errors my current script has when being saved in the editor. The Second is Changing it so that it doesn't injure the user.

I am using The Local Vars.

Here is my Current Script, Based on paskovich's from this thread
JASS:
//=================================
//Area of Effect Critical Strike
//by Gralamin
//Based on code by paskovich
//
//To implement, Copy the script
//into a converted trigger
//named AoECriticalStrike
//
//Requires the HandleVars
//Be sure to set the options below
//
//Give credit if you use this spell
//==================================
//=======================
// --- Spell options --- 
//=======================
constant function ACS_AbilityRC takes nothing returns integer
    return 'A009' //The ability's raw code.
endfunction

constant function ACS_DamageMultiplier takes integer level returns real
    return 1 + level * 0.5 //Crit multipler. 1.5,2,2.5,3...
endfunction

constant function ACS_Effect takes nothing returns string
    //Effect on target. no effect is ""
    return "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
endfunction

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

function Trig_AOECriticalStrike_Damage_Actions takes nothing returns nothing
    local trigger tr = GetTriggeringTrigger()
    local unit u = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    local texttag t = CreateTextTag()
    local real dmg = GetEventDamage()*ACS_DamageMultiplier(GetUnitAbilityLevel(a,ACS_AbilityRC()))
    call TriggerRemoveCondition(tr,GetHandleTriggerCondition(tr,"Condition"))
    call TriggerRemoveAction(tr,GetHandleTriggerAction(tr,"Action"))
    call FlushHandleLocals(tr)
    call DestroyTrigger(tr)
    call SetHandleHandle(a, "DamageTrig", null)
    call UnitDamagePointLoc(a, 0, 200.00, GetUnitLoc(u), dmg-GetEventDamage(), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE)
    call SetTextTagText(t, I2S(R2I(dmg))+"!",0.024)
    call SetTextTagPos(t,GetUnitX(a),GetUnitY(a), 0.00)
    call SetTextTagColor(t,255,0,0,255)
    call SetTextTagVelocity(t,0,0.04)
    call SetTextTagFadepoint(t, 1.2)
    call SetTextTagLifespan(t, 4.5)
    call SetTextTagPermanent(t, false)
    call SetTextTagVisibility(t,true)
    if ACS_Effect() != "" then
        call DestroyEffect(AddSpecialEffectTarget(ACS_Effect(),u,"chest"))
    endif
    set tr = null
    set u = null
    set a = null
    set t = null
endfunction

function Trig_AOECriticalStrike_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetAttacker(), ACS_AbilityRC()) > 0 and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) and GetHandleTrigger(GetAttacker(), "DamageTrig") == null
endfunction

function Trig_AOECriticalStrike_Actions takes nothing returns nothing
    local unit a = GetAttacker()
    local unit u = GetTriggerUnit()
    local integer chc
    local trigger t
    local boolexpr be
    
    set chc = GetUnitAbilityLevel(a,ACS_AbilityRC()) * 15
    // Play with that to get it right
    
    if chc >= GetRandomInt(1,100) then
        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_AOECriticalStrike_Damage_Conditions)
        call SetHandleHandle(t,"Condition", TriggerAddCondition(t, be))
        call DestroyBoolExpr(be)
        set be = null
        call SetHandleHandle(t,"Action", TriggerAddAction(t, function Trig_AOECriticalStrike_Damage_Actions))
        call TriggerSleepAction(1.5)
        call FlushHandleLocals(t)
        call DestroyTrigger(t)
        call SetHandleHandle(a, "DamageTrig", null)
        set t = null
    endif
    set a = null
    set u = null
endfunction
//===========================================================================
function InitTrig_AOECriticalStrike takes nothing returns nothing
    set gg_trg_AOECriticalStrike = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_AOECriticalStrike, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_AOECriticalStrike, Condition( function Trig_AOECriticalStrike_Conditions ) )
    call TriggerAddAction( gg_trg_AOECriticalStrike, function Trig_AOECriticalStrike_Actions )
endfunction

The Errors I'm Having problems with:
2 Compile Errors
Line 1134: Expected a name
Line 1135: Expected a name
These lines are these two:
JASS:
call TriggerRemoveCondition(tr,GetHandleTriggerCondition(tr,"Condition"))
    call TriggerRemoveAction(tr,GetHandleTriggerAction(tr,"Action"))

Thanks for any and all help.

edit: I don't seem to have GetHandleTriggerCondition or GetHandleTriggerAction.
Stealing from Paskovich's thread.

Edit2: Errors are gone. Now I just need the "not kill myself element"
 
Last edited:
Level 3
Joined
Jul 29, 2006
Messages
61
I think you have to customly make GetHandleTriggerCondition and GetHandleTriggerAction.

As for not injuring the user, just enumerate all the nearby units from the striker, and damage them if they meet certain conditions (enemies, flying, whatever)

Alright, heres my new code. I'm hoping this will work.

JASS:
//=================================
//Area of Effect Critical Strike
//by Gralamin
//Based on code by paskovich
//
//To implement, Copy the script
//into a converted trigger
//named AoECriticalStrike
//
//Requires the HandleVars
//Be sure to set the options below
//
//Give credit if you use this spell
//==================================
//=======================
// --- Spell options --- 
//=======================
constant function ACS_AbilityRC takes nothing returns integer
    return 'A009' //The ability's raw code.
endfunction

constant function ACS_DamageMultiplier takes integer level returns real
    return 1 + level * 0.5 //Crit multipler. 1.5,2,2.5,3...
endfunction

constant function ACS_Effect takes nothing returns string
    //Effect on target. no effect is ""
    return "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
endfunction

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

function Trig_AOECriticalStrike_Damage_Actions takes nothing returns nothing
    local trigger tr = GetTriggeringTrigger()
    local unit u = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    local unit f
    local group g
    local texttag t
    local real dmg = GetEventDamage()*ACS_DamageMultiplier(GetUnitAbilityLevel(a,ACS_AbilityRC()))
    call TriggerRemoveCondition(tr,GetHandleTriggerCondition(tr,"Condition"))
    call TriggerRemoveAction(tr,GetHandleTriggerAction(tr,"Action"))
    call FlushHandleLocals(tr)
    call DestroyTrigger(tr)
    call SetHandleHandle(a, "DamageTrig", null)
    
    set g = GetUnitsInRangeOfLocAll(200.00, GetUnitLoc(u))
    set f = FirstOfGroup(g)
    loop
        exitwhen f==null
        set f = FirstOfGroup(g)
        if IsUnitEnemy(f, GetOwningPlayer(a))==true then
            call UnitDamageTarget(a, f, dmg-GetEventDamage(), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, null)
            set t = CreateTextTag()
            call SetTextTagText(t, I2S(R2I(dmg))+"!",0.024)
            call SetTextTagPos(t,GetUnitX(f),GetUnitY(f), 0.00)
            call SetTextTagColor(t,255,0,0,255)
            call SetTextTagVelocity(t,0,0.04)
            call SetTextTagFadepoint(t, 1.2)
            call SetTextTagLifespan(t, 4.5)
            call SetTextTagPermanent(t, false)
            call SetTextTagVisibility(t,true)
            set t = null
        endif
        call GroupRemoveUnit(g,f)
    endloop
    set t = CreateTextTag()
    call SetTextTagText(t, I2S(R2I(dmg))+"!",0.024)
    call SetTextTagPos(t,GetUnitX(a),GetUnitY(a), 0.00)
    call SetTextTagColor(t,255,0,0,255)
    call SetTextTagVelocity(t,0,0.04)
    call SetTextTagFadepoint(t, 1.2)
    call SetTextTagLifespan(t, 4.5)
    call SetTextTagPermanent(t, false)
    call SetTextTagVisibility(t,true)
    if ACS_Effect() != "" then
        call DestroyEffect(AddSpecialEffectTarget(ACS_Effect(),u,"chest"))
    endif
    set tr = null
    set u = null
    set a = null
    set t = null
    set f = null
    set g = null
endfunction

function Trig_AOECriticalStrike_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetAttacker(), ACS_AbilityRC()) > 0 and not IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) and GetHandleTrigger(GetAttacker(), "DamageTrig") == null
endfunction

function Trig_AOECriticalStrike_Actions takes nothing returns nothing
    local unit a = GetAttacker()
    local unit u = GetTriggerUnit()
    local integer chc
    local trigger t
    local boolexpr be
    
    set chc = GetUnitAbilityLevel(a,ACS_AbilityRC()) * 15
    // Play with that to get it right
    
    if chc >= GetRandomInt(1,100) then
        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_AOECriticalStrike_Damage_Conditions)
        call SetHandleHandle(t,"Condition", TriggerAddCondition(t, be))
        call DestroyBoolExpr(be)
        set be = null
        call SetHandleHandle(t,"Action", TriggerAddAction(t, function Trig_AOECriticalStrike_Damage_Actions))
        call TriggerSleepAction(1.5)
        call FlushHandleLocals(t)
        call DestroyTrigger(t)
        call SetHandleHandle(a, "DamageTrig", null)
        set t = null
    endif
    set a = null
    set u = null
endfunction
//===========================================================================
function InitTrig_AOECriticalStrike takes nothing returns nothing
    set gg_trg_AOECriticalStrike = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_AOECriticalStrike, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_AOECriticalStrike, Condition( function Trig_AOECriticalStrike_Conditions ) )
    call TriggerAddAction( gg_trg_AOECriticalStrike, function Trig_AOECriticalStrike_Actions )
endfunction

Edit: Oops I found my one remaining problem. Fixed.
 
Last edited:
Level 11
Joined
Jul 12, 2005
Messages
764
I listed ALL necessary functions in the tread.

The looping-through group should look like this:
JASS:
local group g = CreateGroup()
local unit f = null
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),200,null)
loop
    set f = FirstOfGroup(g)
    call GroupRemoveUnit(g,f)
    exitwhen f == null
    if IsUnitEnemy(f,GetOwningPlayer(a)) then
        //do damage
    endif
endloop
call DestroyGroup(g)
Yours won't work, because you remove the unit from the group only if the unit is an enemy of "a". -> Infinity loop, because the group will never be empty. Hope you understand... but I think you do.
 
Level 3
Joined
Jul 29, 2006
Messages
61
I listed ALL necessary functions in the tread.

The looping-through group should look like this:
JASS:
local group g = CreateGroup()
local unit f = null
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),200,null)
loop
    set f = FirstOfGroup(g)
    call GroupRemoveUnit(g,f)
    exitwhen f == null
    if IsUnitEnemy(f,GetOwningPlayer(a)) then
        //do damage
    endif
endloop
call DestroyGroup(g)
Yours won't work, because you remove the unit from the group only if the unit is an enemy of "a". -> Infinity loop, because the group will never be empty. Hope you understand... but I think you do.

Yeah, I realized that before I saw this and fixed it. Thanks though. And I did grab those functions off the thread.
 
Status
Not open for further replies.
Top