• 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.

[JASS] What's wrong with my script?

Status
Not open for further replies.
Level 1
Joined
Oct 3, 2010
Messages
2
Hi! I'm learning JASS tutorials with the site and decided to convert a spell done in GUI to Jass to try to improve learning, but it does not work for some reason in Jass. She is a "rain" spell, but not as "Starfall" or "blizzard", it has a time between each "raindrop" and every drop run AOE damage, the droplets are points in randomness. I've tried changing the variable "FFCaster" local to global, but rain only works, but without causing damage. I using Newgen. Please help me!

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

function Trig_D_Conditions takes nothing returns boolean
    if ( not ( GetUnitTypeId(GetDyingUnit()) == 'h001' ) ) then
        return false
    endif
    return true
endfunction

globals
     unit FFCaster = null
endglobals

function Damage takes nothing returns nothing
    call IssueImmediateOrder( FFCaster, "stomp" )
endfunction

function Trig_D_Actions takes nothing returns nothing
    local group FFDying
    local location FFDamage
    set FFDamage = GetUnitLoc(GetDyingUnit())
    set FFDying = GetUnitsInRangeOfLocAll(300.00, FFDamage)
    call ForGroupBJ( FFDying, function Damage )
    call DestroyGroup(FFDying)
    call RemoveLocation(FFDamage)
endfunction

function Trig_F_Actions takes nothing returns nothing
    local location FFPoint
    local location FFRandom
    local integer A=1
    set FFPoint = GetUnitLoc(GetTriggerUnit())
    call TriggerSleepAction( 0.30 )
    call PauseUnitBJ( true, GetTriggerUnit() )
    loop
        exitwhen A>46
        set FFRandom = PolarProjectionBJ(FFPoint, GetRandomReal(0, 600.00), GetRandomReal(1.00, 360.00))
        call CreateNUnitsAtLoc( 1, 'h001', Player(0), FFRandom, bj_UNIT_FACING )
        set FFCaster = GetLastCreatedUnit()
        call SetUnitAnimation( GetTriggerUnit(), "Stand Channel" )
        call SetUnitFlyHeightBJ( FFCaster, 1.00, 850.00 )
        call UnitApplyTimedLifeBJ( 1.00, 'BTLF', FFCaster )
        call TriggerSleepAction( 0.10 )
        set A=A+1
    endloop
    call ResetUnitAnimation( GetTriggerUnit() )
    call PauseUnitBJ( false, GetTriggerUnit() )
    call RemoveUnit(FFCaster)
    call RemoveLocation(FFPoint)
    call RemoveLocation(FFRandom)
endfunction

//===========================================================================
function InitTrig_FF takes nothing returns nothing
    local trigger F
    set F=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( F, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( F, Condition( function Trig_F_Conditions ) )
    call TriggerAddAction( F, function Trig_F_Actions )
endfunction

function InitTrig_D takes nothing returns nothing
    local trigger D
    set D = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( D, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( D, Condition( function Trig_D_Conditions ) )
    call TriggerAddAction( D, function Trig_D_Actions )
endfunction

Gui mode:

  • Frezzing Field
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (==) Frezzing Field
    • Actions
      • Wait 0.30 seconds
      • Set FrezzingFieldPoint = (Position of (Triggering unit))
      • Unit - Pause (Triggering unit)
        • Do Multiple ActionsFor each (Integer B) from 1 to 46, do (Actions)
          • Loop - Actions
            • Set FrezzingFieldRandom = (FrezzingFieldPoint offset by (Random real number between 0.00 and 600.00) towards (Random real number between 1.00 and 360.00) degrees)
            • Unit - Create 1 Frezzing Field Dummy for Player 1 (Red) at FrezzingFieldRandom facing Default building facing (270.0) degrees
            • Set FrezzingFieldCaster = (Last created unit)
            • Animation - Play (Triggering unit)'s Stand Channel animation
            • Animation - Change FrezzingFieldCaster flying height to 1.00 at 850.00
            • Unit - Add a 1.00 second Generic expiration timer to FrezzingFieldCaster
            • Wait 0.15 seconds
      • Animation - Reset (Triggering unit)'s animation
      • Unit - Unpause (Triggering unit)
      • Custom script: call RemoveUnit(udg_FFCaster)
      • Custom script: call RemoveLocation(udg_FrezzingFieldPoint)
      • Custom script: call RemoveLocation(udg_FrezzingFieldRandom)
  • Frezzing Damage
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to (==) Frezzing Field Dummy
    • Actions
      • Set FrezzingFieldDamage = (Position of (Dying unit))
      • Set FrezzingFieldDying = (Units within 300.00 of FrezzingFieldDamage)
      • Unit Group - Pick every unit in FrezzingFieldDying and do (Actions)
        • Loop - Actions
          • Unit - Order FrezzingFieldCaster to Orc Tauren Chieftain - War Stomp
      • Custom script: call DestroyGroup(udg_FrezzingFieldDying)
      • Custom script: call RemoveLocation(udg_FrezzingFieldDamage)
Another question: in gui mode usually use a loop inside another loop, jass not apply it?
 
Last edited by a moderator:
Level 14
Joined
Nov 18, 2007
Messages
1,084
Gah, use Jass tags.
JASS:
function Trig_F_Conditions takes nothing returns boolean
     if ( not ( GetSpellAbilityId() == 'A000' ) ) then
          return false
     endif
     return true
endfunction

function Trig_D_Conditions takes nothing returns boolean
     if ( not ( GetUnitTypeId(GetDyingUnit()) == 'h001' ) ) then
          return false
     endif
     return true
endfunction

globals
     unit FFCaster = null
endglobals

function Damage takes nothing returns nothing
     call IssueImmediateOrder( FFCaster, "stomp" )
endfunction

function Trig_D_Actions takes nothing returns nothing
     local group FFDying
     local location FFDamage
     set FFDamage = GetUnitLoc(GetDyingUnit())
     set FFDying = GetUnitsInRangeOfLocAll(300.00, FFDamage)
     call ForGroupBJ( FFDying, function Damage )
     call DestroyGroup(FFDying)
     call RemoveLocation(FFDamage)
endfunction

function Trig_F_Actions takes nothing returns nothing
     local location FFPoint
     local location FFRandom
     local integer A=1
     set FFPoint = GetUnitLoc(GetTriggerUnit())
     call TriggerSleepAction( 0.30 )
     call PauseUnitBJ( true, GetTriggerUnit() )
     loop
          exitwhen A>46
          set FFRandom = PolarProjectionBJ(FFPoint, GetRandomReal(0, 600.00), GetRandomReal(1.00, 360.00))
          call CreateNUnitsAtLoc( 1, 'h001', Player(0), FFRandom, bj_UNIT_FACING )
          set FFCaster = GetLastCreatedUnit()
          call SetUnitAnimation( GetTriggerUnit(), "Stand Channel" )
          call SetUnitFlyHeightBJ( FFCaster, 1.00, 850.00 )
          call UnitApplyTimedLifeBJ( 1.00, 'BTLF', FFCaster )
          call TriggerSleepAction( 0.10 )
          set A=A+1
     endloop
     call ResetUnitAnimation( GetTriggerUnit() )
     call PauseUnitBJ( false, GetTriggerUnit() )
     call RemoveUnit(FFCaster)
     call RemoveLocation(FFPoint)
     call RemoveLocation(FFRandom)
endfunction

//===========================================================================
function InitTrig_FF takes nothing returns nothing
     local trigger F
     set F=CreateTrigger()
     call TriggerRegisterAnyUnitEventBJ( F, EVENT_PLAYER_UNIT_SPELL_EFFECT )
     call TriggerAddCondition( F, Condition( function Trig_F_Conditions ) )
     call TriggerAddAction( F, function Trig_F_Actions )
endfunction

function InitTrig_D takes nothing returns nothing
     local trigger D
     set D = CreateTrigger()
     call TriggerRegisterAnyUnitEventBJ( D, EVENT_PLAYER_UNIT_DEATH )
     call TriggerAddCondition( D, Condition( function Trig_D_Conditions ) )
     call TriggerAddAction( D, function Trig_D_Actions )
endfunction
Your code could certainly use improvement.

First off, one of the functions, InitTrig_FF or InitTrig_D will not be called depending on the trigger name. In your case, it sounds like InitTrig_D will not not be called. There's a very easy remedy for this:
JASS:
function InitTrig_FF takes nothing returns nothing
     local trigger F = =CreateTrigger()
     call TriggerRegisterAnyUnitEventBJ( F, EVENT_PLAYER_UNIT_SPELL_EFFECT )
     call TriggerAddCondition( F, Condition( function Trig_F_Conditions ) )
     call TriggerAddAction( F, function Trig_F_Actions )
     // Trigger for unit Death
     set F = CreateTrigger()
     call TriggerRegisterAnyUnitEventBJ( F, EVENT_PLAYER_UNIT_DEATH )
     call TriggerAddCondition( F, Condition( function Trig_D_Conditions ) )
     call TriggerAddAction( F, function Trig_D_Actions )
endfunction
Other improvements

  • Don't use BJ's when they just simply call something else. Example:
    PauseUnitBJ( true, GeTriggerUnit() -> PauseUnit(GetTriggerUnit(), true)
  • Your conditions function should look like this:
    JASS:
    function Trig_F_Conditions takes nothing returns boolean
         return GetSpellAbilityId() == 'A000'
    endfunction
    
    function Trig_D_Conditions takes nothing returns boolean
         return GetUnitTypeId(GetTriggerUnit()) == 'h001' 
    endfunction
  • Don't use locations, use coordinates instead.
    In other words, you should have used GetUnitX/GetUnitY instead of GetUnitLoc
  • You should not destroy groups, instead have a global variable as your group and never destroy it.
  • You should have better names for your function since you're not making them private.
  • You should use local variables, such as using one to store GetTriggerUnit() Remember to null it afterwards.
 
Last edited:
Level 1
Joined
Oct 3, 2010
Messages
2
Thanks! I had thought that the second trigger will not start but did not know why! Now I know! Thanks for the tips, right now only need to understand
JASS:
 GetUnitX/GetUnitY
to apply too! And sorry for the tags, no idea what that was! LOL!
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Basically, those are the coordinates of the unit as the name implies. Both functions would return real values.
Using coordinates are nearly the same as using locations, but reals are better and more efficient than using locations.

Something on using coordinates over locations:
If there's a function that uses a location, there's almost always another function that can use coordinates.
The only exception to the rule is GetLocationZ which has no coordinates substitute.

An example of this in your code would be
JASS:
set FFDamage = GetUnitLoc(GetDyingUnit())
set FFDying = GetUnitsInRangeOfLocAll(300.00, FFDamage)
To avoid using locations, you could do this:
JASS:
call GroupEnumUnitsInRange(FFDying, GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()), 300., null)
which would be the inlined version of GetUnitsInRangeOfLocAll that uses coordinates.
Note that GetTriggerUnit is the same as GetDyingUnit
 
Status
Not open for further replies.
Top