• 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] Need helps for noob.!

Status
Not open for further replies.

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Hmmm... Today I upload my first custom ability, call it "earth pressure"... I made it by myself...
But the code doesn't work properly...
I need ur help to change my jass code... Mod says that it has many errors to fix.. Haha... I'm a noob so just help me... Thanks bro sist...:thumbs_up:

This is cast event
_____________________________________________
JASS:
function Trig_EarthCompoundCast_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_EarthCompoundCast_Actions takes nothing returns nothing
    set udg_EPCaster = GetSpellAbilityUnit()
    set udg_EPPointNumber = 1
    set udg_EPPoint[1] = GetUnitLoc(udg_EPCaster)
    call EnableTrigger( gg_trg_EarthPressureDamage )
    call EnableTrigger( gg_trg_EarthPressureKnockback )
    call EnableTrigger( gg_trg_EarthPressureKnockedUnit )
    call PolledWait( 10.00 )
    call DisableTrigger( gg_trg_EarthPressureDamage )
    call DisableTrigger( gg_trg_EarthPressureKnockback )
    call DisableTrigger( gg_trg_EarthPressureKnockedUnit )
    set udg_EPCaster = null
    set udg_EPPointNumber = 0
    set udg_EPKnockedUnitNumber = 0
    set udg_EPKnockedUnitNumber2 = 0
    set udg_EPKnockedUnitNumber2 = 0
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 100
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set udg_EPKnockedUnit[GetForLoopIndexA()] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction

//===========================================================================
function InitTrig_EarthPressureCast takes nothing returns nothing
    set gg_trg_EarthPressureCast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_EarthPressureCast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_EarthPressureCast, Condition( function Trig_EarthCompoundCast_Conditions ) )
    call TriggerAddAction( gg_trg_EarthPressureCast, function Trig_EarthCompoundCast_Actions )
endfunction

Damage trigger
________________________________________________
JASS:
function Trig_EarthCompoundDamage_Func010001003001001 takes nothing returns boolean
    return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false )
endfunction

function Trig_EarthCompoundDamage_Func010001003001002 takes nothing returns boolean
    return ( IsUnitAliveBJ(GetFilterUnit()) == true )
endfunction

function Trig_EarthCompoundDamage_Func010001003001 takes nothing returns boolean
    return GetBooleanAnd( Trig_EarthCompoundDamage_Func010001003001001(), Trig_EarthCompoundDamage_Func010001003001002() )
endfunction

function Trig_EarthCompoundDamage_Func010001003002 takes nothing returns boolean
    return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_EPCaster)) == true )
endfunction

function Trig_EarthCompoundDamage_Func010001003 takes nothing returns boolean
    return GetBooleanAnd( Trig_EarthCompoundDamage_Func010001003001(), Trig_EarthCompoundDamage_Func010001003002() )
endfunction

function Trig_EarthCompoundDamage_Func010A takes nothing returns nothing
    call UnitDamageTargetBJ( udg_EPCaster, GetEnumUnit(), 100.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
    call SetUnitPositionLocFacingLocBJ( GetEnumUnit(), PolarProjectionBJ(udg_EPPoint[udg_EPPointNumber], 75.00, ( 180.00 + GetUnitFacing(GetEnumUnit()) )), udg_EPPoint[udg_EPPointNumber] )
    set udg_EPKnockedUnit[udg_EPKnockedUnitNumber] = GetEnumUnit()
endfunction

function Trig_EarthCompoundDamage_Actions takes nothing returns nothing
    set udg_EPPointNumber = ( udg_EPPointNumber + 1 )
    set udg_EPKnockedUnitNumber = ( udg_EPKnockedUnitNumber + 1 )
    set udg_EPPoint[udg_EPPointNumber] = PolarProjectionBJ(udg_EPPoint[1], ( 30.00 * I2R(udg_EPPointNumber) ), ( 30.00 * I2R(udg_EPPointNumber) ))
    call CreateNUnitsAtLoc( 1, 'h002', GetOwningPlayer(udg_EPCaster), udg_EPPoint[udg_EPPointNumber], bj_UNIT_FACING )
    call UnitApplyTimedLifeBJ( 2.00, 'BTLF', GetLastCreatedUnit() )
    call IssueImmediateOrderBJ( GetLastCreatedUnit(), "stomp" )
    call ForGroupBJ( GetUnitsInRangeOfLocMatching(250.00, udg_EPPoint[udg_EPPointNumber], Condition(function Trig_EarthCompoundDamage_Func010001003)), function Trig_EarthCompoundDamage_Func010A )
    call TerrainDeformationRippleBJ( 1.00, true, udg_EPPoint[udg_EPPointNumber], 270.00, 270.00, 64, 1, 250.00 )
    call AddSpecialEffectLocBJ( udg_EPPoint[udg_EPPointNumber], "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" )
    call AddSpecialEffectLocBJ( udg_EPPoint[udg_EPPointNumber], "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" )
endfunction

//===========================================================================
function InitTrig_EarthPressureDamage takes nothing returns nothing
    set gg_trg_EarthPressureDamage = CreateTrigger(  )
    call DisableTrigger( gg_trg_EarthPressureDamage )
    call TriggerRegisterTimerEventPeriodic( gg_trg_EarthPressureDamage, 0.25 )
    call TriggerAddAction( gg_trg_EarthPressureDamage, function Trig_EarthCompoundDamage_Actions )
endfunction

The ability does a knockback and here is the trigger
___________________________________________
JASS:
function Trig_EarthCompoundCrush_Actions takes nothing returns nothing
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 100
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call SetUnitPositionLoc( udg_EPKnockedUnit[GetForLoopIndexA()], PolarProjectionBJ(GetUnitLoc(udg_EPKnockedUnit[GetForLoopIndexA()]), 5.00, ( 180.00 + GetUnitFacing(udg_EPKnockedUnit[GetForLoopIndexA()]) )) )
        call AddSpecialEffectTargetUnitBJ( "origin", udg_EPKnockedUnit[GetForLoopIndexA()], "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction

//===========================================================================
function InitTrig_EarthPressureKnockback takes nothing returns nothing
    set gg_trg_EarthPressureKnockback = CreateTrigger(  )
    call DisableTrigger( gg_trg_EarthPressureKnockback )
    call TriggerRegisterTimerEventPeriodic( gg_trg_EarthPressureKnockback, 0.10 )
    call TriggerAddAction( gg_trg_EarthPressureKnockback, function Trig_EarthCompoundCrush_Actions )
endfunction

I try to make the knockback has a duration but the trigger seems does not work. Here's the trigger
_________________________________________
JASS:
function Trig_EarthCompoundCrushedUnit_Actions takes nothing returns nothing
    set udg_EPKnockedUnitNumber2 = ( udg_EPKnockedUnitNumber2 + 1 )
    set udg_EPKnockedUnit[udg_EPKnockedUnitNumber2] = null
endfunction

//===========================================================================
function InitTrig_EarthPressureKnockedUnit takes nothing returns nothing
    set gg_trg_EarthPressureKnockedUnit = CreateTrigger(  )
    call DisableTrigger( gg_trg_EarthPressureKnockedUnit )
    call TriggerRegisterTimerEventPeriodic( gg_trg_EarthPressureKnockedUnit, 1.00 )
    call TriggerAddAction( gg_trg_EarthPressureKnockedUnit, function Trig_EarthCompoundCrushedUnit_Actions )
endfunction

And here's the description of my ability.
Descriptions:
- Creates some earth stomps with a spiral form.
- Each stomp deals 100 damage to 250 AoE and stuns for 2 seconds.
- Move all enemy units in the AoE to the center of stomp.
- Knocks a random one enemy's unit back in the area of stomp for 0.1 - 10 seconds ( I write this bcoz i can't make a working duration trigger.)

You can download here.
http://www.hiveworkshop.com/forums/spells-569/earth-pressure-v0-1-a-205223/#post2025380

My Questions:
- What's BJ function.?
- My code has many "red color". What does it mean ?
 
Level 8
Joined
Jul 3, 2011
Messages
251
JASS is not like GUI, we put ALL of our code into one trigger (see my spells in my signature for an example) Bjs (the red lines) are generally avoid because they call other functions to do their job, they are slower than native functions and use up more than necessairy power, however there are SOME bjs you shouldn't avoid, a good example is
JASS:
call TriggerRegisterAnyUnitEventBJ
in GUI you use multiple triggers with the "every xx seconds of game time" event
JASS:
call TriggerRegisterTimerEventPeriodic( gg_trg_EarthPressureDamage, 0.25 )
SOME people use this in JASS, but i completely avoid them, and so do most JASS'ers, we use Timers, timers can repeat a function once or multiple times untill you destroy it, but note: destroying timers is buggy, you should use a timer recycler or pause it first, but id still suggest a timer recycler.
JASS:
set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 100
In JASS, we avoid bj_forLoopA, instead we use integers, and
JASS:
exitwhen integer1 == integer2
or some similar equation >= <= etc, also we dont use locations in JASS, not usually anyway. We prefer to use reals because a location calls other functions to get the reals, whats the point when we can just get the reals directly?
JASS:
local unit u = GetTriggerUnit
local real x = GetUnitX(u)
local real y = GetUnitY(u)
theres no need for all the conditions you have in different functions, you can just use
JASS:
if <condition here> then
  // Stuff here
<possible else here>
  // else stuff here
endif

EDIT: Also
JASS:
function Trig_EarthCompoundCast_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A000' ) ) then
        return false
    endif
    return true
endfunction
you can clean this up by doing this
JASS:
function Trig_EarthCompoundCast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction
you see,
JASS:
returns boolean
a boolean is just simply a true or false statement, when you put returns boolean, where you put
JASS:
returns
it will check that for a true or false statement, so since you put
JASS:
returns boolean
it will check if
JASS:
GetSpellAbilityId() == 'A000'
then return true or false.
 
Level 8
Joined
Jul 3, 2011
Messages
251
Not really sure lol, a guy named Spinnaker taught me the basics of what i needed to know then i started to learn the rest by myself and occasional questions to him, which now i offer the same to others :p

EDIT: Do not use
JASS:
call PolledWait( 10.00 )
waits of ANY kind will make spells unstable and possibly non-MUI. In JASS we use timers to make a wait, or to loop a spells effects over and over, or loop it with slight alterations using hashtables (see my divine halo spell in signature for a good example)
 
Last edited:
@crozzz, I'd recommend you read some Jass tutorials found in this subforum.

Those scripts look like they have been just converted from GUI. You need to learn a lot, and rewriting whole trigger by any of more experienced user will give you nothing that you could learn from. At first you have to understand the basic.

Waits aren't non-MUI; they are just inaccurate, duration of TriggerSleepActions depends highly on many differend circumstances, plus locals usage is required to avoid instance mess. Timers prove to be better in such case.
 
Level 8
Joined
Jul 3, 2011
Messages
251
Well Spinnaker they can be non-MUI if used in loops :p and Polledwait() isnt inaccurate since it uses game-time, but its still a wait so... yeah xD

And crozzz id recommend reading the tutorials in the subforum Spinnaker linked too.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well Spinnaker they can be non-MUI if used in loops :p

What ?!

and Polledwait() isnt inaccurate since it uses game-time, but its still a wait so... yeah xD

From Blizzard.j :

JASS:
function PolledWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        call DestroyTimer(t)
    endif
endfunction

Still innacurate because of the TSA, and we got an id leak, yeah.
Moar : it's even more innacurate that the TSA by itself, but because it's a part of timer, this part will be paused when the game is paused, just as a timer.
 
Status
Not open for further replies.
Top