• 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 help with spell code and effects

Status
Not open for further replies.
Level 3
Joined
Jun 6, 2007
Messages
48
Spell description:

The earthfather links to a unit through nature taking 70% of the damage the unit receives whilst linked.


JASS:
globals
    unit Earthfather = GetSpellAbilityUnit()
    unit G_Unit = GetSpellTargetUnit()
    boolean G_Protect = false
    // local buff G_Buff
    lightning G_Effect
    location G_Start = GetUnitLoc(Earthfather)
    location G_Finish = GetSpellTargetUnit()
endglobals

function GuardianJ_Conditions takes nothing returns boolean
    if ( not ( 'A007' == GetSpellAbilityId() ) ) then
        return false
    endif
    return true
endfunction

function GuardianJ_Actions takes nothing returns nothing
        
    if ( IsUnitAliveBJ(G_Unit) == true  ) then
    
        // For testing
        call DisplayTextToForce( GetPlayersAll(), "Spell Reset" )
        
        // Disable current casting
        set G_Protect = false
        call DestroyLightningBJ( G_Effect )
        set G_Effect = null
        call UnitRemoveBuffBJ( 'B002', G_Unit )
        
        // Set current casting
        call AddLightningLoc( "DRAL", G_Start, G_Finish )
        set G_Effect = GetLastCreatedLightningBJ()
    else
        call DisplayTextToForce(GetPlayersAll(), "First time cast")
        call AddLightningLoc( "DRAL", G_Start, G_Finish )
        set G_Effect = GetLastCreatedLightningBJ()
    endif
endfunction

function GuardianP_Conditions takes nothing returns boolean
    if ( not ( GetAttackedUnitBJ() == G_Unit ) ) then
        return false
    endif
    if ( not ( IsUnitEnemy(GetAttacker(), GetOwningPlayer(GetAttackedUnitBJ())) == true ) ) then
        return false
    endif
    if ( not ( UnitHasBuffBJ(GetAttackedUnitBJ(), 'B002') == true ) ) then
        return false
    endif
    return true
endfunction

function GuardianP_Actions takes nothing returns nothing
    call SetUnitLifeBJ( G_Unit, ( GetUnitStateSwap(UNIT_STATE_LIFE, G_Unit) + ( GetEventDamage() * 0.70 ) ) )
    call UnitDamageTargetBJ( GetEventDamageSource(), Earthfather, ( GetEventDamage() * 0.70 ), ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
endfunction

function GuardianE_Conditions takes nothing returns boolean
    if ( not ( UnitHasBuffBJ(G_Unit, 'B002') == true ) ) then
        return false
    endif
    return true
endfunction

function GuardianE_Actions takes nothing returns nothing
    call MoveLightningLoc(G_Effect, G_Start, G_Finish)
endfunction

//===========================================================================
function InitTrig_GuardianJass takes nothing returns nothing
    local trigger GuardianJass = CreateTrigger(  )
    local trigger GuardianProtect = CreateTrigger(  )
    local trigger GuardianEffect = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( GuardianJass, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( GuardianJass, Condition( function GuardianJ_Conditions ) )
    call TriggerAddAction( GuardianJass, function GuardianJ_Actions )
    
    call TriggerRegisterUnitEvent( GuardianProtect, G_Unit, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition( GuardianProtect, Condition( function GuardianP_Conditions ) )
    call TriggerAddAction( GuardianProtect, function GuardianP_Actions )
    
    call TriggerRegisterTimerEventPeriodic( GuardianEffect, 0.01 )
    call TriggerAddCondition( GuardianEffect, Condition( function GuardianE_Conditions ) )
    call TriggerAddAction( GuardianEffect, function GuardianE_Actions )

endfunction


What happens:

Earthfather casts the spell on a target unit.

Unit has buff effect
Unit does not have a lightning effect linked between it and the Earthfather
Unit takes full damage when attacked (Not ment to happen)

Things to do:

Add a distance that the link will work and will cancel out if too far away
Touch up possible leaks
Improve code if possible

If anyone can help me out with this spell whether it be editing the code for me or pointing out what's going wrong would be a great help.
 
Level 22
Joined
Dec 31, 2006
Messages
2,216
You should replace all the BJ's with natives. You should also compress you conditions to 1 line.
Change this:
JASS:
function GuardianE_Conditions takes nothing returns boolean
    if ( not ( UnitHasBuffBJ(G_Unit, 'B002') == true ) ) then
        return false
    endif
    return true
endfunction
To this:
JASS:
function GuardianE_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(G_UNIT, 'B002') > 0
endfunction
And this:
JASS:
function GuardianP_Conditions takes nothing returns boolean
if ( not ( GetAttackedUnitBJ() == G_Unit ) ) then
        return false
    endif
    if ( not ( IsUnitEnemy(GetAttacker(), GetOwningPlayer(GetAttackedUnitBJ())) == true ) ) then
        return false
endif
    if ( not ( UnitHasBuffBJ(GetAttackedUnitBJ(), 'B002') == true ) ) then
        return false
    endif
    return true
endfunction
To this:
JASS:
function GuardianP_Conditions takes nothing returns boolean
    return GetTriggerUnit() == G_Unit and IsUnitEnemy(GetAttacker(), GetOwningPlayer(G_UNIT)) and GetUnitAbilityLevel(G_UNIT, 'B002') > 0
endfunction
 
Level 3
Joined
Jun 6, 2007
Messages
48
code

When i change UnitDamageTargetBJ to UnitDamageTarget:

JASS:
function GuardianP_Actions takes nothing returns nothing
    call SetUnitLifeBJ( G_Unit, ( GetUnitStateSwap(UNIT_STATE_LIFE, G_Unit) + ( GetEventDamage() * 0.70 ) ) )
    call UnitDamageTargetBJ( GetEventDamageSource(), Earthfather, ( GetEventDamage() * 0.70 ), ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
endfunction
to
JASS:
function GuardianP_Actions takes nothing returns nothing
    call SetUnitLifeBJ( G_Unit, ( GetUnitStateSwap(UNIT_STATE_LIFE, G_Unit) + ( GetEventDamage() * 0.70 ) ) )
    call UnitDamageTarget( GetEventDamageSource(), Earthfather, ( GetEventDamage() * 0.70 ), ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
endfunction

It says:

Line 47: Cannot convert attacktype to boolean
Line 47: Cannot convert damagetype to boolean
Line 47: Not enough arguments passed to function

And for say SetUnitLifeBJ, in the Function list theres not SetUnitLife, is there a page i've missed where it states BJ and there respective natives?

Also, why does my lightning (Link effect) not appear when it has:

JASS:
        call AddLightningLoc( "DRAL", G_Start, G_Finish )

I'm 99% certain that i've defined G_Start and G_Finish correctly.

I've only been learning Jass for 4 days so please excuse the mountain of questions, i gave you +rep for already helping me a bunch. After this i just gotta work on the damage transfer part of it.
 
Level 5
Joined
Nov 14, 2007
Messages
161
if your not using JASSCRAFT, i recommend it, it is very very helpful about BJs etc. if you see a BJ, double click it on your code and at the bottom it lists out the function calls etc. you can see the function and double click on that to know the exact order a unit etc gets called.

what BJs do are re-arrange stuff so the order of GUI makes sense when you read it, but by doing so it adds repetitive function calls.
commonly the non-BJ is the same thing just re-arranged the order the function takes params.

JASS:
function SetUnitLifeBJ takes unit whichUnit, real newValue returns nothing
    call SetUnitState(whichUnit, UNIT_STATE_LIFE, RMaxBJ(0,newValue))
endfunction

JASS:
function UnitDamageTargetBJ takes unit whichUnit, unit target, real amount, attacktype whichAttack, damagetype whichDamage returns boolean
    return UnitDamageTarget(whichUnit, target, amount, true, false, whichAttack, whichDamage, WEAPON_TYPE_WHOKNOWS)
endfunction

JASS:
function UnitRemoveBuffBJ takes integer buffcode, unit whichUnit returns boolean
    return UnitRemoveAbility(whichUnit, buffcode)
endfunction

JASS:
function DestroyLightningBJ takes lightning whichBolt returns boolean
    return DestroyLightning(whichBolt)
endfunction

and the funny ones:
JASS:
function IsUnitAliveBJ takes unit whichUnit returns boolean
    return not IsUnitDeadBJ(whichUnit)
endfunction
another function call...
JASS:
function IsUnitDeadBJ takes unit whichUnit returns boolean
    return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
endfunction
could simply be:
JASS:
GetUnitState(whichUnit, UNIT_STATE_LIFE) > 0

all copy/paste from jasscraft. hope it helps you out.

YO_MA_MA

EDIT: try changing:
JASS:
unit Earthfather = GetSpellAbilityUnit()
to
JASS:
unit Earthfather = GetTriggerUnit()
GetTriggerUnit() is ur friend ;)

EDIT2:
and
JASS:
location G_Finish = GetSpellTargetUnit()
is trying to save a unit to a location,
try changing to:
JASS:
location G_Finish = GetUnitLoc(G_unit)
 
Level 3
Joined
Jun 6, 2007
Messages
48
More help :(

Thanks for the help and the program, it does help alot, i've changed my code heaps using that program. New Code:

JASS:
globals
    unit Earthfather = GetTriggerUnit()
    unit G_Unit = GetSpellTargetUnit()
    boolean G_Protect = false
    lightning G_Effect
    location G_Start = GetUnitLoc(Earthfather)
    location G_Finish = GetUnitLoc(G_Unit)
endglobals

function GuardianJ_Conditions takes nothing returns boolean
    if ( not ( 'A007' == GetSpellAbilityId() ) ) then
        return false
    endif
    return true
endfunction

function GuardianJ_Actions takes nothing returns nothing
                
    if ( GetUnitState(G_Unit, UNIT_STATE_LIFE) > 0  ) then
    
        // For testing
        call DisplayTextToForce( GetPlayersAll(), "Spell Reset" )
        
        // Disable current casting
        set G_Protect = false
        call DestroyLightning( G_Effect )
        set G_Effect = null
        call UnitRemoveAbility(G_Unit, 'B002')
        
        // Set current casting
        set G_Protect = true
        call AddLightningLoc( "DRAL", G_Start, G_Finish )
        set G_Effect = GetLastCreatedLightningBJ()
    else
        set G_Protect = true
        call DisplayTextToForce(GetPlayersAll(), "First time cast")
        // call AddLightningLoc( "DRAL", GetUnitLoc(Earthfather), GetUnitLoc(G_Unit) )
        call AddLightningEx("DRAL", true, GetLocationX(G_Start), GetLocationY(G_Start), GetLocationZ(G_Start), GetLocationX(G_Finish), GetLocationY(G_Finish), GetLocationZ(G_Finish))
        set G_Effect = GetLastCreatedLightningBJ()
    endif
endfunction

function GuardianP_Conditions takes nothing returns boolean
    return IsUnitEnemy(GetAttacker(), GetOwningPlayer(G_Unit)) and GetUnitAbilityLevel(G_Unit, 'B002') > 0
endfunction

function GuardianP_Actions takes nothing returns nothing
    call SetUnitState(G_Unit, UNIT_STATE_LIFE, RMaxBJ(0, ( GetUnitStateSwap(UNIT_STATE_LIFE, G_Unit) + ( GetEventDamage() * 0.70 ) )))
    call UnitDamageTarget(GetEventDamageSource(), Earthfather, ( GetEventDamage() * 0.70 ), true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
endfunction

function GuardianE_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(G_Unit, 'B002') > 0
endfunction

function GuardianE_Actions takes nothing returns nothing
    call MoveLightningLoc(G_Effect, G_Start, G_Finish)
endfunction

//===========================================================================
function InitTrig_GuardianJass takes nothing returns nothing
    local trigger GuardianJass = CreateTrigger(  )
    local trigger GuardianProtect = CreateTrigger(  )
    local trigger GuardianEffect = CreateTrigger(  )

    call TriggerRegisterAnyUnitEventBJ( GuardianJass, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( GuardianJass, Condition( function GuardianJ_Conditions ) )
    call TriggerAddAction( GuardianJass, function GuardianJ_Actions )
    
    call TriggerRegisterUnitEvent( GuardianProtect, G_Unit, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition( GuardianProtect, Condition( function GuardianP_Conditions ) )
    call TriggerAddAction( GuardianProtect, function GuardianP_Actions )
    
    call TriggerRegisterTimerEventPeriodic( GuardianEffect, 0.01 )
    call TriggerAddCondition( GuardianEffect, Condition( function GuardianE_Conditions ) )
    call TriggerAddAction( GuardianEffect, function GuardianE_Actions )

endfunction

Is there any possibility that the globals arn't working?

JASS:
globals
    unit Earthfather = GetTriggerUnit()
    unit G_Unit = GetSpellTargetUnit()
    boolean G_Protect = false
    lightning G_Effect
    location G_Start = GetUnitLoc(Earthfather)
    location G_Finish = GetUnitLoc(G_Unit)
endglobals

Cause the GuardianJ_Actions works cause it says First Cast when i cast it but the lightning doesn't and neither does the damage redirection part (Both use G_Unit, Earthfather, G_Start/Finish)

Syntax Checker in both JassCraft and JassNewGen World Editor say my code has 0 Errors yet the Lightning effect doesn't work and the target unit still takes 100% damage. :cry:


EDIT: When i add DisplayTexttoForce(GetPlayersAll(), GetUnitName(G_Unit)) it only says "First Time Cast", does that mean it's not storing the units and locations of units in the Globals?
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
Of course the globals don't work.
They are all based on trigger output and they have nothing to do with any trigger.
What you meant to do was something like this

JASS:
globals
    unit Earthfather
    unit G_Unit
    boolean G_Protect = false
    lightning G_Effect
    location G_Start
    location G_Finish
endglobals

function GuardianJ_Actions takes nothing returns nothing

    set Earthfather = GetTriggerUnit()
    set G_Unit = GetSpellTargetUnit()
    set G_Start = GetUnitLoc(Earthfather)
    set G_Finish = GetUnitLoc(G_Unit)

    ...

endfunction
 
Level 3
Joined
Jun 6, 2007
Messages
48
vJass

EDIT: Omfg i found out why it was crashing...

I had setup the Globals as normal but in my main Jass function i had

JASS:
set G_Protect = false

as soon as i removed that it worked perfectly.

Setting a boolean up when it's already setup must crash Wc3. >_>

+rep to all that helped me.
 
Last edited:
Status
Not open for further replies.
Top