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

[JASS] Map Header?

Status
Not open for further replies.
Level 5
Joined
Oct 9, 2008
Messages
112
Hey Guys,

i iam making a Jass Spell or System it always need to be in the Map Header or i cannot call any functions. Anyone have a solution for this problem?
Here are the triggers:



JASS:
function lightning_storm_height takes nothing returns nothing
    local real height = 500.00
    local real rate = 100.00
    call UnitAddAbilityBJ( 'Arav', udg_LS_Caster )
    call SetUnitFlyHeightBJ( udg_LS_Caster, height, rate )
    call UnitRemoveAbilityBJ( 'Arav', udg_LS_Caster )
endfunction

function cast_lightning_storm takes nothing returns nothing
    local unit caster = udg_LS_Caster
    call lightning_storm_height()
endfunction

//===========================================================================
function InitTrig_LSTrigger takes nothing returns nothing
    set gg_trg_LSTrigger = CreateTrigger(  )
    call TriggerAddAction( gg_trg_LSTrigger, function cast_lightning_storm )
    call TriggerAddAction( gg_trg_LSTrigger, function lightning_storm_height )
endfunction


  • LSIni
    • Ereignisse
      • Einheit - A unit Starts to cast a spell
    • Bedingungen
      • (Ability being cast) Equal Lightning Storm
    • Aktionen
      • Set LS_Caster = (Casting unit)
      • Set LS_Damage = 100.00
      • Custom script: call cast_lightning_storm()



-Atami
Enjoy! :>
For any solution you will get +rep! :>
 
Yes, it is normal. If you don't want to have them on the header of the map, use vJass and libraries.
P.S. You are making it the wrong way. Use this instead:
JASS:
function LightningStorm takes unit u returns nothing
    local real height = 500.00
    local real rate = 100.00
    call UnitAddAbility (u, 'Arav')
    call SetUnitFlyHeight ( u, height, rate )
    call UnitRemoveAbility (u, 'Arav')
    set u = null //To be honest I am not sure if you have to null it, but do so.
endfunction
and call the function as:
  • Trigger
  • Events
    • Unit - A unit starts the effect of an ability
  • Conditions
    • (Ability being cast) Equal to Lightning Storm
  • Actions
    • Custom script: call LightningStorm (GetTriggerUnit())
You really don't need a jass script for something that simple.

P.S. Don't use BJ's.
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
JASS:
//To be honest I am not sure if you have to null it, but do so.
Don't worry, it doesn't need to be.

It would be safer to do something like this though:
JASS:
if UnitAddAbility(u, 'Arav') then // This check prevents removing the ability if the unit already had it.
    call UnitRemoveAbility(u, 'Arav')
endif

I hope you do something better with the local variables, height and rate, because they're kind of useless the way you're using them now. (It would be better to just use the values directly.)
 
Level 21
Joined
Mar 19, 2009
Messages
444
You do not need to add scripts in map header if your scripts are used only for 1 trigger.

By the way, some examples of how you can do your spell.

Jass version

JASS:
function OnCast takes nothing returns boolean // A condition is enough, actions are useless and create leaks on trigger destruction; more, conditions are faster (of course it's a nano difference :p)
    local unit caster = GetTriggerUnit()
        if GetSpellAbilityId() == 'A000' then //In Jass, just put your spell/unit id directly, you do not need to create variables for them
            if GetUnitAbilityLevel(caster,'Arav') <= 0 then //Just to let you know, it would be more efficient to create a trigger which adds/remove the fly ability to any unit entering the map, if you get several triggers using it.
                call UnitAddAbility(caster,'Arav')
            endif
            call SetUnitFlyHeight(caster,500.,100.)
            if GetUnitAbilityLevel(caster,'Arav')>=1 then
                call UnitRemoveAbility(caster,'Arav')
            endif
        endif
        set caster = null
        return false
endfunction

//===========================================================================
function InitTrig_LSTrigger takes nothing returns nothing
    set gg_trg_LSTrigger = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_LSTrigger, EVENT_PLAYER_UNIT_SPELL_EFFECT)//Probably one of rare BJ functions which is really well made.
    call TriggerAddCondition( gg_trg_LSTrigger, Condition(function OnCast ))
endfunction

Vjass version, just with a scope and globals.

JASS:
scope MySpell initializer init // A scope works like a trigger. It will be placed "under" the custom script

globals
    private constant integer SPELL_ID = 'A000' //there, variables are cool. private means they are only used into your scope, and constant they will never change.
    private constant real FLY_HEIGHT = 500.
    private constant real FLY_RATE = 100.
    private constant integer FLY_SPELL = 'Arav'
endglobals

    private function OnCast takes nothing returns boolean
        local unit caster = GetTriggerUnit()
            if GetSpellAbilityId() == SPELL_ID then
                if GetUnitAbilityLevel(caster,FLY_SPELL) <= 0 then
                    call UnitAddAbility(caster,FLY_SPELL)
                endif
                call SetUnitFlyHeight(caster,FLY_HEIGHT,FLY_RATE)
                if GetUnitAbilityLevel(caster,FLY_SPELL)>=1 then
                    call UnitRemoveAbility(caster,FLY_SPELL)
                endif
            endif
            set caster = null
            return false
    endfunction


    public function init takes nothing returns nothing
        local trigger t = CreateTrigger(  )
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function OnCast ))
    endfunction

endscope

VJass version, with a library instead of a scope, showing you need an other library, SpellEvent, which is quite sexy.

JASS:
Library MySpell initializer init needs SpellEvent //library works like a scope, except you can specify if it needs any other library. There, it will be placed into the custom script under the library it needs.
//There, I want my spell to use SpellEvent library (w3c.net, by Anitarf)
globals
    private constant integer SPELL_ID = 'A000'//Same than a scope.
    private constant real FLY_HEIGHT = 500.
    private constant real FLY_RATE = 100.
    private constant integer FLY_SPELL = 'Arav'
endglobals

    private function OnCast takes nothing returns nothing
        if GetUnitAbilityLevel(SpellEvent.CastingUnit,FLY_SPELL) <= 0 then //The library spell event provides you informations to replace GetTriggerUnit(), GetSpellTargetX() etc.
            call UnitAddAbility(SpellEvent.CastingUnit,FLY_SPELL)
        endif
        call SetUnitFlyHeight(SpellEvent.CastingUnit,FLY_HEIGHT,FLY_RATE)
        if GetUnitAbilityLevel(SpellEvent.CastingUnit,FLY_SPELL)>=1 then
            call UnitRemoveAbility(SpellEvent.CastingUnit,FLY_SPELL)
        endif
    endfunction


    private function init takes nothing returns nothing
        call RegisterSpellEffectResponse(SPELL_ID,OnCast) //Sexier uh?
    endfunction

endlibrary
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
JASS:
            if GetUnitAbilityLevel(caster,'Arav') <= 0 then 
                call UnitAddAbility(caster,'Arav')
            endif
            call SetUnitFlyHeight(caster,500.,100.)
            if GetUnitAbilityLevel(caster,'Arav')>=1 then
                call UnitRemoveAbility(caster,'Arav')
            endif
        endif
There's a reason why I showed my check:

  1. It uses less function calls. Note it doesn't matter if the ability is removed before SetUnitFlyHeight is used.
  2. It doesn't remove the ability if the unit already had it. UnitAddAbility returns false if the ability couldn't be added to the unit; one of the reasons an ability can't be added to a unit is if it already has it.
    Your ability level check is useless like that since units already having the ability will have it removed.
Credit to azlier for AutoFly since that's where I first saw that check.
 
Status
Not open for further replies.
Top