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

[Solved] Difference between unit class and target types?

Status
Not open for further replies.
Level 28
Joined
Apr 6, 2010
Messages
3,106
I'm trying to make a spell that specifically targets units classed as Giants, but Giant doesn't appear in the "targets allowed" menu. I checked the Ancestral Spirit spell, and it also lacks a target-only-Tauren checkbox.

Is there a way to include unit classes as a target type in abilities?
 
Level 28
Joined
Feb 18, 2014
Messages
3,579
I'm afraid that Ancestral Spirit is very hardcoded. You could however use triggers instead?
JASS:
function Trig_Revive_Giants_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'Absk' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Revive_Giants_Boolean takes nothing returns boolean
    return ( IsUnitDeadBJ(GetFilterUnit()) == true ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_GIANT) == true ) and ( GetOwningPlayer(GetFilterUnit()) == GetOwningPlayer(GetTriggerUnit()) )
endfunction

function Trig_Revive_Giants_Revive takes nothing returns nothing
    set udg_Revive_Point = GetUnitLoc(GetEnumUnit())
    call CreateNUnitsAtLoc( 1, GetUnitTypeId(GetEnumUnit()), GetOwningPlayer(GetTriggerUnit()), udg_Revive_Point, bj_UNIT_FACING )
    call RemoveUnit( GetEnumUnit() )
endfunction

function Trig_Revive_Giants_Actions takes nothing returns nothing
    set udg_Temp_Point = GetUnitLoc(GetTriggerUnit())
    set udg_Temp_Group = GetRandomSubGroup(1, GetUnitsInRangeOfLocMatching(512, udg_Temp_Point, Condition(function Trig_Revive_Giants_Boolean)))
    call ForGroupBJ( udg_Temp_Group, function Trig_Revive_Giants_Revive )
    call RemoveLocation (udg_Temp_Point)
    call RemoveLocation (udg_Revive_Point)
    call DestroyGroup (udg_Temp_Group)
endfunction

//===========================================================================
function InitTrig_Revive_Giants takes nothing returns nothing
    set gg_trg_Revive_Giants = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Revive_Giants, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Revive_Giants, Condition( function Trig_Revive_Giants_Conditions ) )
    call TriggerAddAction( gg_trg_Revive_Giants, function Trig_Revive_Giants_Actions )
endfunction
P:S : I used JASS because there is no condition to check if a unit is a "Giant" classification in GUI.
 
Level 28
Joined
Feb 18, 2014
Messages
3,579
So you want Hurl Boulder to only target a specific type/class of units? Well, you can set up a trigger that checks if the target of the ability is different than the "specific unit-type" and then interrupt the casting the ability by ordering the caster to stop.
JASS:
function Trig_Huld_Boulder_JASS_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'ACtb' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Huld_Boulder_JASS_Function takes nothing returns boolean
    if ( not ( IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_GIANT) == false ) ) then
        return false
    endif
    return true
endfunction

function Trig_Huld_Boulder_JASS_Actions takes nothing returns nothing
    if ( Trig_Huld_Boulder_JASS_Function() ) then
        call IssueImmediateOrderBJ( GetTriggerUnit(), "stop" )
        if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
        call DisplayTextToForce( GetPlayersAll(), "You can not target this unit" )
        endif
    else
    endif
endfunction

//===========================================================================
function InitTrig_Huld_Boulder_JASS takes nothing returns nothing
    set gg_trg_Huld_Boulder_JASS = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Huld_Boulder_JASS, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Huld_Boulder_JASS, Condition( function Trig_Huld_Boulder_JASS_Conditions ) )
    call TriggerAddAction( gg_trg_Huld_Boulder_JASS, function Trig_Huld_Boulder_JASS_Actions )
endfunction
 
Last edited:
Level 28
Joined
Apr 6, 2010
Messages
3,106
Thanks for that.

-

Editor says there's an error with the line "set gg_trg_Huld_Boulder_JASS = CreateTrigger( )" and suggests replacing "gg_trg_Huld_Boulder_JASS" with "set gg_trg_Huld_Boulder".

Doing so for that line and the next three lines causes the checker to say there are no errors, but also causes the trigger to fail (as in, doesn't prevent the ability from being used on non-giants).


What am I doing wrong?
 
Level 28
Joined
Feb 18, 2014
Messages
3,579
@Wrda is right. Also, if you're using a custom hurl boulder ability, change ( GetSpellAbilityId() == 'ACtb' ) to the new ability's rawcode.

Edit : Actually, you don't need JASS at all, you can directly use GUI instead. (I totally forgot that you can add conditions with custom scripts. :p)

  • Hurl Boulder GUI
    • Events
      • Unit - A unit Begins casting of an ability
    • Conditions
      • (Ability being cast) Equal to Hurl Boulder
    • Actions
      • Custom script: if IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_GIANT) == false then
      • Unit - Order (Triggering unit) to Stop
      • Custom script: endif
 
Last edited:
Level 28
Joined
Apr 6, 2010
Messages
3,106
upload_2020-1-9_14-29-56.png


Spell (trigger named "harpoon", spell based off Hurl Boulder and numbered A000)

JASS:
function Trig_harpoon_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_harpoon_Function takes nothing returns boolean
    if ( not ( IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_GIANT) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_harpoon_Actions takes nothing returns nothing
    if ( Trig_harpoon_Function() ) then
        call IssueImmediateOrderBJ( GetTriggerUnit(), "stop" )
        if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
        call DisplayTextToForce( GetPlayersAll(), "You can not target this unit" )
        endif
    else
    endif
endfunction

//===========================================================================
function InitTrig_harpoon takes nothing returns nothing
    set gg_trg_harpoon = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_harpoon, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_harpoon, Condition( function Trig_harpoon_Conditions ) )
    call TriggerAddAction( gg_trg_harpoon, function Trig_harpoon_Actions )
 
Level 28
Joined
Apr 6, 2010
Messages
3,106
Me again: Is there a way to prevent the spell from even being cast on the wrong target, instead of interrupting the unit as it starts casting?

For example, trying to use Hurl Boulder on a mechanical unit makes the cursor stay gray instead of red, and displays a "Must target an organic unit" message, preventing the unit from even starting the spell animation.
 
Level 28
Joined
Feb 18, 2014
Messages
3,579
Me again: Is there a way to prevent the spell from even being cast on the wrong target, instead of interrupting the unit as it starts casting?

For example, trying to use Hurl Boulder on a mechanical unit makes the cursor stay gray instead of red, and displays a "Must target an organic unit" message, preventing the unit from even starting the spell animation.
No, I don't think so because there is no "Giant" type in Target Allowed, unless you want to change that to something like "Ancient" for example so that the ability can only be casted on ancient-type units.
 
Status
Not open for further replies.
Top