HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell Attaching Variables problem

06-14-2006, 07:51 PM#1
The)TideHunter(
Ok, so im making another spell.
It gives a bonus to the caster (done not by triggers but base ability).
If the unit dies it heals all enemies around him for 250 damage.
The spell lasts for 30 seconds.

What i did, because you cant check for HasUnitGotBuff when its dead, so i attached a boolean for 30 sec (with a timer which the 30 runs with).
If the boolean is true, it will heal enemies, if it is false it wont.

Heres the code:
Trigger 1: (Cast)
Collapse JASS:
function Spell_SealOfTheUnderworld_Finish takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit Caster = CF_GetAttachedUnit("Spell_SealOfTheUnderworld_Caster", t)
    call CF_AttachBoolean(false, "Spell_SealOfTheUnderworld_Active", Caster)
    call CF_DestroyTimer(t)
    set t = null
endfunction

function Trig_Seal_of_the_Underworld_Cast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Trig_Seal_of_the_Underworld_Cast_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    call CF_AttachBoolean(true, "Spell_SealOfTheUnderworld_Active", GetSpellAbilityUnit())
    call CF_AttachHandle(GetSpellAbilityUnit(), "Spell_SealOfTheUnderworld_Caster", t)
    call TimerStart(t, 30., false, function Spell_SealOfTheUnderworld_Finish)
endfunction

//===========================================================================
function InitTrig_Seal_of_the_Underworld_Cast takes nothing returns nothing
    set gg_trg_Seal_of_the_Underworld_Cast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Seal_of_the_Underworld_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Seal_of_the_Underworld_Cast, Condition( function Trig_Seal_of_the_Underworld_Cast_Conditions ) )
    call TriggerAddAction( gg_trg_Seal_of_the_Underworld_Cast, function Trig_Seal_of_the_Underworld_Cast_Actions )
endfunction


Trigger 2: (Death)

Collapse JASS:
function Trig_Seal_of_the_Underworld_Death_Conditions takes nothing returns boolean
    return CF_GetAttachedBoolean("Spell_SealOfTheUnderworld_Active", GetDyingUnit())
endfunction

function Trig_Seal_of_the_Underworld_Death_Func002002003 takes nothing returns boolean
    return ( IsPlayerEnemy(GetOwningPlayer(GetDyingUnit()), GetOwningPlayer(GetFilterUnit())) == true )
endfunction

function Trig_Seal_of_the_Underworld_Death_Func003A takes nothing returns nothing
    call SetUnitLifeBJ( GetEnumUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetEnumUnit()) + 250.00 ) )
    call CF_CreateAttachedUnitEffect(GetEnumUnit(), "Abilities\\Spells\\Other\\Parasite\\ParasiteTarget.mdl", "chest", 2.5)
endfunction

function Trig_Seal_of_the_Underworld_Death_Actions takes nothing returns nothing
    set udg_TempPoint = GetUnitLoc(GetDyingUnit())
    set udg_TempGroup = GetUnitsInRangeOfLocMatching(600.00, udg_TempPoint, Condition(function Trig_Seal_of_the_Underworld_Death_Func002002003))
    call ForGroupBJ( udg_TempGroup, function Trig_Seal_of_the_Underworld_Death_Func003A )
    call CF_AttachBoolean(false, "Spell_SealOfTheUnderworld_Active", GetDyingUnit())
endfunction

//===========================================================================
function InitTrig_Seal_of_the_Underworld_Death takes nothing returns nothing
    set gg_trg_Seal_of_the_Underworld_Death = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Seal_of_the_Underworld_Death, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Seal_of_the_Underworld_Death, Condition( function Trig_Seal_of_the_Underworld_Death_Conditions ) )
    call TriggerAddAction( gg_trg_Seal_of_the_Underworld_Death, function Trig_Seal_of_the_Underworld_Death_Actions )
endfunction


Problem: It heals enemies if its true or false

And yes, i set TempPoint and TempGroup and dident destroy them, i will do that later.

EDIT: Sorry forgot some of the custom functions that are not there.
Here they are(btw its my usual casual functions, dont bother to read it all :D)
Collapse JASS:
globals
    gamecache udg_GC = null
endglobals

// Casual Functions Engine
// Created and Updated by The)TideHunter(
// Creation Began: 28/05/06
// Last Updated: 13/06/06

// Game Cache Return Function
function CF_GC takes nothing returns gamecache
    if(udg_GC == null) then
        call FlushGameCache(InitGameCache("GC"))
        set udg_GC = InitGameCache("GC")
    endif
    return udg_GC
endfunction

// Constants
constant function CF_MaxProjectileCollisionRange takes nothing returns real
    return 10.
endfunction
// Rawcodes
constant function CF_DummyRawcode takes nothing returns integer
    return '????'
endfunction

// Handle Variables
function CF_H2I takes handle H returns integer
    return H
    return 0
endfunction

function CF_C2I takes code C returns integer
    return C
    return 0
endfunction

function CF_I2Unit takes integer I returns unit
    return I
    return null
endfunction

function CF_I2Effect takes integer I returns effect
    return I
    return null
endfunction

function CF_I2Group takes integer I returns group
    return I
    return null
endfunction

function CF_I2Sound takes integer I returns sound
    return I
    return null
endfunction

function CF_I2Dialog takes integer I returns dialog
    return I
    return null
endfunction

function CF_I2Button takes integer I returns button
    return I
    return null
endfunction

function CF_I2Player takes integer I returns player
    return I
    return null
endfunction

function CF_I2Timer takes integer I returns timer
    return I
    return null
endfunction

function CF_I2Rect takes integer I returns rect
    return I
    return null
endfunction

function CF_I2Trigger takes integer I returns trigger
    return I
    return null
endfunction

function CF_I2Code takes integer I returns code
    return I
    return null
endfunction

// Attach Variables
function CF_StoreInt takes integer whichInt, string label returns nothing
    if(whichInt == 0) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreInteger(CF_GC(), "Integer", label, whichInt)
    endif
endfunction
function CF_StoreString takes string whichString, string label returns nothing
    if(whichString == null) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreString(CF_GC(), "String", label, whichString)
    endif
endfunction
function CF_StoreReal takes real whichReal, string label returns nothing
    if(whichReal == 0) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreReal(CF_GC(), "Real", label, whichReal)
    endif
endfunction
function CF_StoreBoolean takes boolean whichBoolean, string label returns nothing
    if(whichBoolean == false) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreBoolean(CF_GC(), "Boolean", label, whichBoolean)
    endif
endfunction
function CF_StoreCode takes code whichCode, string label returns nothing
    if(whichCode == null) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreInteger(CF_GC(), "Code", label, CF_C2I(whichCode))
    endif
endfunction
function CF_StoreHandle takes handle whichHandle, string label, string handleType returns nothing
    if(whichHandle == null) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreInteger(CF_GC(), handleType, label, CF_H2I(whichHandle))
    endif
endfunction

function CF_AttachInt takes integer whichInt, string label, handle attachToWhichHandle returns nothing
    if(attachToWhichHandle == null) or (whichInt == 0) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreInteger(CF_GC(), I2S(CF_H2I(attachToWhichHandle)), label, whichInt)
    endif
endfunction
function CF_AttachString takes string whichString, string label, handle attachToWhichHandle returns nothing
    if(attachToWhichHandle == null) or (whichString == null) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreString(CF_GC(), I2S(CF_H2I(attachToWhichHandle)), label, whichString)
    endif
endfunction
function CF_AttachReal takes real whichReal, string label, handle attachToWhichHandle returns nothing
    if(attachToWhichHandle == null) or (whichReal == 0) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreReal(CF_GC(), I2S(CF_H2I(attachToWhichHandle)), label, whichReal)
    endif
endfunction
function CF_AttachBoolean takes boolean whichBoolean, string label, handle attachToWhichHandle returns nothing
    if(attachToWhichHandle == null) or (whichBoolean == false) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreBoolean(CF_GC(), I2S(CF_H2I(attachToWhichHandle)), label, whichBoolean)
    endif
endfunction
function CF_AttachCode takes code whichCode, string label, handle attachToWhichHandle returns nothing
    if(attachToWhichHandle == null) or (whichCode == null) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreInteger(CF_GC(), I2S(CF_H2I(attachToWhichHandle)), label, CF_C2I(whichCode))
    endif
endfunction
function CF_AttachHandle takes handle whichHandle, string label, handle attachToWhichHandle returns nothing
    if(attachToWhichHandle == null) or (whichHandle == null) then
        call FlushStoredMission(CF_GC(), label)
    else
        call StoreInteger(CF_GC(), I2S(CF_H2I(attachToWhichHandle)), label, CF_H2I(whichHandle))
    endif
endfunction

function CF_GetStoredInt takes string label returns integer
    return GetStoredInteger(CF_GC(), "Integer", label)
endfunction
function CF_GetStoredString takes string label returns string
    return GetStoredString(CF_GC(), "String", label)
endfunction
function CF_GetStoredReal takes string label returns real
    return GetStoredReal(CF_GC(), "Real", label)
endfunction
function CF_GetStoredBoolean takes string label returns boolean
    return GetStoredBoolean(CF_GC(), "Boolean", label)
endfunction
function CF_GetStoredCode takes string label returns code
    return CF_I2Code(GetStoredInteger(CF_GC(), "Code", label))
endfunction

function CF_GetStoredUnit takes string label returns unit
    return CF_I2Unit(GetStoredInteger(CF_GC(), "Unit", label))
endfunction
function CF_GetStoredEffect takes string label returns effect
    return CF_I2Effect(GetStoredInteger(CF_GC(), "Effect", label))
endfunction
function CF_GetStoredGroup takes string label returns group
    local integer i = GetStoredInteger(CF_GC(), "Group", label)
    if(i != 0) then
        return CF_I2Group(i)
    endif
    return CreateGroup()
endfunction
function CF_GetStoredSound takes string label returns sound
    return CF_I2Sound(GetStoredInteger(CF_GC(), "Sound", label))
endfunction
function CF_GetStoredDialog takes string label returns dialog
    return CF_I2Dialog(GetStoredInteger(CF_GC(), "Dialog", label))
endfunction
function CF_GetStoredButton takes string label returns button
    return CF_I2Button(GetStoredInteger(CF_GC(), "Button", label))
endfunction
function CF_GetStoredPlayer takes string label returns player
    return CF_I2Player(GetStoredInteger(CF_GC(), "Player", label))
endfunction
function CF_GetStoredTimer takes string label returns timer
    local integer i = GetStoredInteger(CF_GC(), "Timer", label)
    if(i != 0) then
        return CF_I2Timer(i)
    endif
    return CreateTimer()
endfunction
function CF_GetStoredRect takes string label returns rect
    return CF_I2Rect(GetStoredInteger(CF_GC(), "Rect", label))
endfunction
function CF_GetStoredTrigger takes string label returns trigger
    local integer i = GetStoredInteger(CF_GC(), "Trigger", label)
    if(i != 0) then
        return CF_I2Trigger(i)
    endif
    return CreateTrigger()    
endfunction

function CF_GetAttachedInt takes string label, handle attachedHandle returns integer
    return GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
endfunction
function CF_GetAttachedString takes string label, handle attachedHandle returns string
    return GetStoredString(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
endfunction
function CF_GetAttachedReal takes string label, handle attachedHandle returns real
    return GetStoredReal(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
endfunction
function CF_GetAttachedBoolean takes string label, handle attachedHandle returns boolean
    return GetStoredBoolean(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
endfunction
function CF_GetAttachedCode takes string label, handle attachedHandle returns code
    return CF_I2Code(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction

function CF_GetAttachedUnit takes string label, handle attachedHandle returns unit
    return CF_I2Unit(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedEffect takes string label, handle attachedHandle returns effect
    return CF_I2Effect(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedGroup takes string label, handle attachedHandle returns group
    local integer i = GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
    if(i != 0) then
        return CF_I2Group(i)
    endif
    return CreateGroup()
endfunction
function CF_GetAttachedSound takes string label, handle attachedHandle returns sound
    return CF_I2Sound(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedDialog takes string label, handle attachedHandle returns dialog
    return CF_I2Dialog(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedButton takes string label, handle attachedHandle returns button
    return CF_I2Button(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedPlayer takes string label, handle attachedHandle returns player
    return CF_I2Player(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedTimer takes string label, handle attachedHandle returns timer
    local integer i = GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
    if(i != 0) then
        return CF_I2Timer(i)
    endif
    return CreateTimer()
endfunction
function CF_GetAttachedRect takes string label, handle attachedHandle returns rect
    return CF_I2Rect(GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label))
endfunction
function CF_GetAttachedTrigger takes string label, handle attachedHandle returns trigger
    local integer i = GetStoredInteger(CF_GC(), I2S(CF_H2I(attachedHandle)), label)
    if(i != 0) then
        return CF_I2Trigger(i)
    endif
    return CreateTrigger()
endfunction

function CF_RemoveAttachments takes handle attachedHandle returns nothing
    call FlushStoredMission(CF_GC(), I2S(CF_H2I(attachedHandle)))
endfunction

// Common Functions
function CF_IsXSafe takes real X returns boolean
    local rect SafeRect = bj_mapInitialPlayableArea
    local real MinSafeX = GetRectMinX(SafeRect)
    local real MaxSafeX = GetRectMaxX(SafeRect)
    if(MinSafeX < X) and (MaxSafeX > X) then
        return true
    endif
    call RemoveRect(SafeRect)
    set SafeRect = null
    return false
endfunction

function CF_IsYSafe takes real Y returns boolean
    local rect SafeRect = bj_mapInitialPlayableArea
    local real MinSafeY = GetRectMinY(SafeRect)
    local real MaxSafeY = GetRectMaxY(SafeRect)
    if(MinSafeY < Y) and (MaxSafeY > Y) then
        return true
    endif
    call RemoveRect(SafeRect)
    set SafeRect = null
    return false
endfunction

function CF_IsLocSafe takes real X, real Y returns boolean
    if(CF_IsXSafe(X) == true) and (CF_IsYSafe(Y) == true) then
        return true
    endif
    return false
endfunction

function CF_IsLocSafeEx takes location whichLocation returns boolean
    return CF_IsLocSafe(GetLocationX(whichLocation), GetLocationY(whichLocation))
endfunction

function CF_GetHost takes nothing returns player
    local player Host
    if(CF_GetStoredPlayer("CF_EXTRA_GAMEHOST") == null) then
        call StoreInteger(CF_GC(), "missionKey", "key", GetPlayerId(GetLocalPlayer()) + 1)
        call TriggerSyncStart()
        call SyncStoredInteger(CF_GC(), "missionKey", "key")
        call TriggerSyncReady()
        set Host = Player(GetStoredInteger(CF_GC(), "missionKey", "key") - 1)
        call CF_StoreHandle(Host, "CF_EXTRA_GAMEHOST", "Player")
        return Host
    endif
    set Host = null
    return CF_GetStoredPlayer("CF_EXTRA_GAMEHOST")
endfunction        

function CF_GetPlayerLookingX takes player whichPlayer returns real
    if(GetLocalPlayer() == whichPlayer) then
        return GetCameraTargetPositionX()
    endif
    return 0.
endfunction

function CF_GetPlayerLookingY takes player whichPlayer returns real
    if(GetLocalPlayer() == whichPlayer) then
        return GetCameraTargetPositionY()
    endif
    return 0.
endfunction

function CF_GetPlayerLookZ takes player whichPlayer returns real
    if(GetLocalPlayer() == whichPlayer) then
        return GetCameraTargetPositionZ()
    endif
    return 0.
endfunction

function CF_GetPlayerLookingLoc takes player whichPlayer returns location
    return Location(CF_GetPlayerLookingX(whichPlayer), CF_GetPlayerLookingY(whichPlayer))
endfunction

function CF_SayMessage takes player whichPlayer, string msg, real duration returns nothing
    local integer loopN = 0
    if(msg != null) then
        if(whichPlayer == null) then
            loop
                exitwhen loopN == 11
                call DisplayTimedTextToPlayer(Player(loopN), 0., 0., duration, msg)
                set loopN = loopN + 1
            endloop
        else
            call DisplayTimedTextToPlayer(whichPlayer, 0., 0., duration, msg)
        endif
    endif
endfunction

function CF_IsUnitEnemy takes unit whichUnit, unit source returns boolean
    return IsPlayerEnemy(GetOwningPlayer(source), GetOwningPlayer(whichUnit))
endfunction

function CF_DestroyTimer takes timer whichTimer returns nothing
    call CF_RemoveAttachments(whichTimer)
    call DestroyTimer(whichTimer)
endfunction

function CF_UnitDamageUnit takes unit credit, unit target, real amount, integer attackIndex, integer damageIndex returns nothing
    call UnitDamageTarget(credit, target, amount, true, false, ConvertAttackType(attackIndex), ConvertDamageType(damageIndex), ConvertWeaponType(0))
endfunction

function CF_UnitDamageLoc takes unit credit, real amount, real X, real Y, real radius, integer attackIndex, integer damageIndex, boolean effectEnemies, boolean effectAllies returns nothing
    local location centerPoint = Location(X, Y)
    local group targets = GetUnitsInRangeOfLocAll(radius, centerPoint)
    local unit CurrentUnit
    loop
        set CurrentUnit = FirstOfGroup(targets)
        exitwhen (CurrentUnit == null)
        if(CF_IsUnitEnemy(credit, CurrentUnit) == true) and (effectEnemies == true) or (CF_IsUnitEnemy(credit, CurrentUnit) == false) and (effectAllies == true) then
            call CF_UnitDamageUnit(credit, CurrentUnit, amount, attackIndex, damageIndex)
        endif
        call GroupRemoveUnit(targets, CurrentUnit)
    endloop
    call RemoveLocation(centerPoint)
    call DestroyGroup(targets)
    set centerPoint = null
    set targets = null
endfunction
        
function CF_UnitSpellDamageUnit takes unit credit, unit target, real amount returns nothing
    call CF_UnitDamageUnit(credit, target, amount, 4, 8)  
endfunction

function CF_GetADummy takes real X, real Y returns unit
    local unit u = CreateUnit(Player(15), CF_DummyRawcode(), X, Y, 0.)
    call UnitAddAbility(u, 'Avul')
    call UnitAddAbility(u, 'Aloc')
    call UnitAddAbility(u, 'Amph')
    call UnitRemoveAbility(u, 'Amph')
    return u
endfunction 

// Extended Creation Functions
// Effect
function CF_CreateGroundEffect takes real X, real Y, real Z, string modelPath returns effect
    local unit CarryingUnit
    local effect NewEffect
    local destructable Height
    if(CF_IsLocSafe(X, Y) == true) then
        set Height = CreateDestructableZ('OTip', X, Y, Z, 0.00, 1, 0)
        set CarryingUnit = CF_GetADummy(X, Y)
        set NewEffect = AddSpecialEffectTarget(modelPath, CarryingUnit, "origin")
        call CF_AttachHandle(CarryingUnit, "Effect_CarryingUnit", NewEffect)
        call CF_AttachReal(X, "Effect_CoordX", NewEffect)
        call CF_AttachReal(Y, "Effect_CoordY", NewEffect)
        call CF_AttachReal(Z, "Effect_CoordZ", NewEffect)
        call CF_AttachString(modelPath, "Effect_ModelPath", NewEffect)
        call CF_StoreHandle(NewEffect, "LastCreatedEffect", "Effect")
        call RemoveDestructable(Height)
        return NewEffect
    endif
    set CarryingUnit = null
    set NewEffect = null
    set Height = null
    return null
endfunction

function CF_CreateAttachedUnitEffect_End takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local effect e = CF_GetAttachedEffect("Timer_TempEffect", t)
    call CF_DestroyTimer(t)
    call DestroyEffect(e)    
    set t = null
    set e = null
endfunction

function CF_CreateAttachedUnitEffect takes unit whichUnit, string modelPath, string attachPoint, real duration returns effect
    local effect NewEffect = AddSpecialEffectTarget(modelPath, whichUnit, attachPoint)
    local timer t = CreateTimer()
    call CF_AttachHandle(NewEffect, "Timer_TempEffect", t)
    call TimerStart(t, duration, false, function CF_CreateAttachedUnitEffect_End)
    return NewEffect
endfunction 

function CF_GetEffectCarryingUnit takes effect whichEffect returns unit
    return CF_GetAttachedUnit("Effect_CarryingUnit", whichEffect)
endfunction

function CF_GetEffectX takes effect whichEffect returns real
    return CF_GetAttachedReal("Effect_CoordX", whichEffect)
endfunction

function CF_GetEffectY takes effect whichEffect returns real
    return CF_GetAttachedReal("Effect_CoordY", whichEffect)
endfunction

function CF_GetEffectZ takes effect whichEffect returns real
    return CF_GetAttachedReal("Effect_CoordZ", whichEffect)
endfunction

function CF_GetEffectLoc takes effect whichEffect returns location
    return Location(CF_GetEffectX(whichEffect), CF_GetEffectY(whichEffect))
endfunction

function CF_GetEffectModelPath takes effect whichEffect returns string
    return CF_GetAttachedString("Effect_ModelPath", whichEffect)
endfunction

function CF_GetLastCreatedEffect takes nothing returns effect
    return CF_GetStoredEffect("LastCreatedEffect")
endfunction

function CF_SetEffectX takes effect whichEffect, real X returns nothing
    if(CF_IsXSafe(X) == true) then
        call SetUnitX(CF_GetEffectCarryingUnit(whichEffect), X)
        call CF_AttachReal(X, "Effect_CoordX", whichEffect)
    endif
endfunction

function CF_SetEffectY takes effect whichEffect, real Y returns nothing
    if(CF_IsYSafe(Y) == true) then
        call SetUnitY(CF_GetEffectCarryingUnit(whichEffect), Y)
        call CF_AttachReal(Y, "Effect_CoordY", whichEffect)
    endif
endfunction

function CF_SetEffectLoc takes effect whichEffect, real X, real Y returns nothing
    if(CF_IsLocSafe(X, Y) == true) then
        call CF_SetEffectX(whichEffect, X)
        call CF_SetEffectY(whichEffect, Y)
    endif
endfunction

function CF_SetEffectLocEx takes effect whichEffect, location whichLoc returns nothing
    call CF_SetEffectLoc(whichEffect, GetLocationX(whichLoc), GetLocationY(whichLoc))
endfunction

function CF_MakeEffectFaceAngle takes effect whichEffect, real angle returns nothing
    call SetUnitFacing(CF_GetEffectCarryingUnit(whichEffect), angle)
endfunction

function CF_MakeEffectFaceAngleOverTime takes effect whichEffect, real angle, real duration returns nothing
    call SetUnitFacingTimed(CF_GetEffectCarryingUnit(whichEffect), angle, duration)
endfunction

function CF_MoveEffectFacingAngle takes effect whichEffect, real angle, real X, real Y returns nothing
    call CF_SetEffectLoc(whichEffect, X, Y)
    call CF_MakeEffectFaceAngle(whichEffect, angle)
endfunction

function CF_MoveEffectFacingAngleOverTime takes effect whichEffect, real angle, real X, real Y, real duration returns nothing
    call CF_SetEffectLoc(whichEffect, X, Y)
    call CF_MakeEffectFaceAngleOverTime(whichEffect, angle, duration)
endfunction     

function CF_CopyEffect takes effect whichEffect returns effect
    return CF_CreateGroundEffect(CF_GetEffectX(whichEffect), CF_GetEffectY(whichEffect), CF_GetEffectZ(whichEffect), CF_GetEffectModelPath(whichEffect))
endfunction

function CF_CopyEffectNewLoc takes effect whichEffect, real X, real Y returns effect
    local effect NewEffect = CF_CopyEffect(whichEffect)
    call CF_SetEffectLoc(NewEffect, X, Y)
    return NewEffect
endfunction

function CF_CopyEffectNewLocEx takes effect whichEffect, location whichLoc returns effect
    return CF_CopyEffectNewLoc(whichEffect, GetLocationX(whichLoc), GetLocationY(whichLoc))
endfunction

function CF_DestroyEffect takes effect whichEffect returns nothing
    local unit CarryingUnit = CF_GetEffectCarryingUnit(whichEffect)
    call CF_RemoveAttachments(whichEffect)
    call DestroyEffect(whichEffect)
    call RemoveUnit(CarryingUnit)
    set CarryingUnit = null
endfunction

function CF_DestroyTempEffect takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local effect DestroyingEffect = CF_GetAttachedEffect("Timer_TempEffect", t)
    call CF_DestroyEffect(DestroyingEffect)
    call CF_DestroyTimer(t)
    set t = null
    set DestroyingEffect = null
endfunction

function CF_CreateTempEffect takes real X, real Y, real Z, string modelPath, real duration returns effect
    local timer t = CreateTimer()
    local effect NewEffect = CF_CreateGroundEffect(X, Y, Z, modelPath)
    call CF_AttachHandle(NewEffect, "Timer_TempEffect", t)
    call TimerStart(t, duration, false, function CF_DestroyTempEffect)
    return NewEffect
endfunction

function CF_CreateTempEffectLoc takes location whichLoc, real Z, string modelPath, real duration returns effect
    return CF_CreateTempEffect(GetLocationX(whichLoc), GetLocationY(whichLoc), Z, modelPath, duration)
endfunction
   
function CF_CopyTempEffect takes effect whichEffect, real duration returns effect
    local timer t = CreateTimer()
    local effect NewEffect = CF_CopyEffect(whichEffect)
    call CF_AttachHandle(NewEffect, "Timer_TempEffect", t)
    call TimerStart(t, duration, false, function CF_DestroyTempEffect)
    return NewEffect
endfunction

function CF_CopyTempEffectLoc takes effect whichEffect, real X, real Y, real duration returns effect
    local timer t = CreateTimer()
    local effect NewEffect = CF_CopyEffectNewLoc(whichEffect, X, Y)
    call CF_AttachHandle(NewEffect, "Timer_TempEffect", t)
    call TimerStart(t, duration, false, function CF_DestroyTempEffect)
    return NewEffect
endfunction

function CF_CopyTempEffectLocEx takes effect whichEffect, location whichLoc, real duration returns effect
    local timer t = CreateTimer()
    local effect NewEffect = CF_CopyEffectNewLocEx(whichEffect, whichLoc)
    call CF_AttachHandle(NewEffect, "Timer_TempEffect", t)
    call TimerStart(t, duration, false, function CF_DestroyTempEffect)
    return NewEffect
endfunction

// Main Functions
// Target Projectile
function CF_LaunchTargetProjectile_Update takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local effect Projectile = CF_GetAttachedEffect("Projectile_Effect", t)
    local unit credit = CF_GetAttachedUnit("Projectile_Credit", t)
    local unit target = CF_GetAttachedUnit("Projectile_Target", t)
    local real DamageAmount = CF_GetAttachedReal("Projectile_Damage", t)
    local real CurrentX = CF_GetEffectX(Projectile)
    local real CurrentY = CF_GetEffectY(Projectile)
    local real TargetX = GetUnitX(target)               
    local real TargetY = GetUnitY(target)
    local real angle = bj_RADTODEG * Atan2(TargetY - CurrentY, TargetX - CurrentX)
    local real speed = CF_GetAttachedReal("Projectile_Speed", t)
    local real distance = SquareRoot((TargetX - CurrentX) * (TargetX - CurrentX) + (TargetY - CurrentY) * (TargetY - CurrentY))
    local real time = distance / speed
    local real MovingDistance = CF_GetAttachedReal("Projectile_MovingDistance", t)
    local real NewX
    local real NewY
    local trigger CallBack = CF_GetAttachedTrigger("Projectile_CallBack", t)
    local integer attackIndex = CF_GetAttachedInt("Projectile_AttackIndex", t)
    local integer damageIndex = CF_GetAttachedInt("Projectile_DamageIndex", t)
    local boolean FirstRun = CF_GetAttachedBoolean("Projectile_FirstRun", t)
    if(FirstRun == true) then
        set MovingDistance = distance / (time / 0.01)
        call CF_AttachReal(MovingDistance, "Projectile_MovingDistance", t)
        call CF_AttachBoolean(false, "Projectile_FirstRun", t)
    endif
    set NewX = CurrentX + MovingDistance * Cos(angle * bj_DEGTORAD)
    set NewY = CurrentY + MovingDistance * Sin(angle * bj_DEGTORAD) 
    if(distance < CF_MaxProjectileCollisionRange()) then
        call CF_UnitDamageUnit(credit, target, DamageAmount, attackIndex, damageIndex)
        call CF_DestroyEffect(Projectile)
        call CF_DestroyTimer(t)
        call TriggerExecute(CallBack)
    else
        call CF_MoveEffectFacingAngle(Projectile, angle, NewX, NewY) 
        call TimerStart(t, 0.01, false, function CF_LaunchTargetProjectile_Update)
    endif         
endfunction

function CF_LaunchTargetProjectile_Begin takes unit credit, unit target, real startX, real startY, real Z, real damage, string modelPath, real speed, code callBack, integer attackIndex, integer damageIndex returns nothing
    local timer t = CreateTimer()
    local effect ProjectileEffect = CF_CreateGroundEffect(startX, startY, Z, modelPath)
    local trigger callBackTrigger = CreateTrigger()
    call TriggerAddAction(callBackTrigger, callBack)
    call CF_AttachHandle(credit, "Projectile_Credit", t)
    call CF_AttachHandle(target, "Projectile_Target", t)
    call CF_AttachHandle(ProjectileEffect, "Projectile_Effect", t)
    call CF_AttachReal(damage, "Projectile_Damage", t)
    call CF_AttachReal(speed, "Projectile_Speed", t)
    call CF_AttachBoolean(true, "Projectile_FirstRun", t)
    call CF_AttachReal(0., "Projectile_MovingDistance", t)
    call CF_AttachInt(attackIndex, "Projectile_AttackIndex", t)
    call CF_AttachInt(damageIndex, "Projectile_DamageIndex", t)
    call CF_AttachHandle(credit, "Trigger_ProjectileCredit", callBackTrigger)
    call CF_AttachHandle(target, "Trigger_ProjectileTarget", callBackTrigger)
    call CF_AttachReal(damage, "Trigger_ProjectileDamage", callBackTrigger)
    call CF_AttachReal(speed, "Trigger_ProjectileSpeed", callBackTrigger)
    call CF_AttachHandle(callBackTrigger, "Projectile_CallBack", t)
    call TimerStart(t, 0.01, false, function CF_LaunchTargetProjectile_Update)
endfunction

// Location Projectile
function CF_LaunchLocationProjectile_Update takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local effect Projectile = CF_GetAttachedEffect("Projectile_Effect", t)
    local unit credit = CF_GetAttachedUnit("Projectile_Credit", t)
    local unit target = CF_GetAttachedUnit("Projectile_Target", t)
    local real DamageAmount = CF_GetAttachedReal("Projectile_Damage", t)
    local real Radius = CF_GetAttachedReal("Projectile_Radius", t)
    local real CurrentX = CF_GetEffectX(Projectile)
    local real CurrentY = CF_GetEffectY(Projectile)
    local real TargetX = CF_GetAttachedReal("Projectile_DestinationX", t)               
    local real TargetY = CF_GetAttachedReal("Projectile_DestinationY", t)
    local real angle = bj_RADTODEG * Atan2(TargetY - CurrentY, TargetX - CurrentX)
    local real speed = CF_GetAttachedReal("Projectile_Speed", t)
    local real distance = SquareRoot((TargetX - CurrentX) * (TargetX - CurrentX) + (TargetY - CurrentY) * (TargetY - CurrentY))
    local real time = distance / speed
    local real MovingDistance = CF_GetAttachedReal("Projectile_MovingDistance", t)
    local real NewX
    local real NewY
    local boolean effectAllies = CF_GetAttachedBoolean("Projectile_EffectAllies", t)
    local boolean effectEnemies = CF_GetAttachedBoolean("Projectile_EffectEnemies", t)
    local trigger CallBack = CF_GetAttachedTrigger("Projectile_CallBack", t)
    local integer attackIndex = CF_GetAttachedInt("Projectile_AttackIndex", t)
    local integer damageIndex = CF_GetAttachedInt("Projectile_DamageIndex", t)
    local boolean FirstRun = CF_GetAttachedBoolean("Projectile_FirstRun", t)
    if(FirstRun == true) then
        set MovingDistance = distance / (time / 0.01)
        call CF_AttachReal(MovingDistance, "Projectile_MovingDistance", t)
        call CF_AttachBoolean(false, "Projectile_FirstRun", t)
    endif
    set NewX = CurrentX + MovingDistance * Cos(angle * bj_DEGTORAD)
    set NewY = CurrentY + MovingDistance * Sin(angle * bj_DEGTORAD) 
    if(distance < CF_MaxProjectileCollisionRange()) then
        call CF_UnitDamageLoc(credit, DamageAmount, TargetX, TargetY, Radius, attackIndex, damageIndex, effectEnemies, effectAllies)
        call CF_DestroyEffect(Projectile)
        call CF_DestroyTimer(t)
        call TriggerExecute(CallBack)
    else
        call CF_MoveEffectFacingAngle(Projectile, angle, NewX, NewY) 
        call TimerStart(t, 0.01, false, function CF_LaunchTargetProjectile_Update)
    endif         
endfunction

function CF_LaunchLocationProjectile_Begin takes unit credit, real startX, real startY, real Z, real destX, real destY, real damage, real radius, string modelPath, real speed, boolean effectAllies, boolean effectEnemies, code callBack, integer attackIndex, integer damageIndex returns nothing
    local timer t = CreateTimer()
    local effect ProjectileEffect = CF_CreateGroundEffect(startX, startY, Z, modelPath)
    local trigger callBackTrigger = CreateTrigger()
    call TriggerAddAction(callBackTrigger, callBack)
    call CF_AttachHandle(credit, "Projectile_Credit", t)
    call CF_AttachHandle(ProjectileEffect, "Projectile_Effect", t)
    call CF_AttachReal(destX, "Projectile_DestinationX", t)
    call CF_AttachReal(destY, "Projectile_DestinationY", t)
    call CF_AttachReal(damage, "Projectile_Damage", t)
    call CF_AttachReal(speed, "Projectile_Speed", t)
    call CF_AttachReal(radius, "Projectile_Radius", t)
    call CF_AttachBoolean(effectAllies, "Projectile_EffectAllies", t)
    call CF_AttachBoolean(effectEnemies, "Projectile_EffectEnemies", t)
    call CF_AttachBoolean(true, "Projectile_FirstRun", t)
    call CF_AttachReal(0., "Projectile_MovingDistance", t)
    call CF_AttachInt(attackIndex, "Projectile_AttackIndex", t)
    call CF_AttachInt(damageIndex, "Projectile_DamageIndex", t)
    call CF_AttachHandle(credit, "Trigger_ProjectileCredit", callBackTrigger)
    call CF_AttachReal(destX, "Trigger_ProjectileDestinationX", callBackTrigger)
    call CF_AttachReal(destY, "Trigger_ProjectileDestrinationY", callBackTrigger)
    call CF_AttachReal(damage, "Trigger_ProjectileDamage", callBackTrigger)
    call CF_AttachReal(speed, "Trigger_ProjectileSpeed", callBackTrigger)
    call CF_AttachHandle(callBackTrigger, "Projectile_CallBack", t)
    call TimerStart(t, 0.01, false, function CF_LaunchTargetProjectile_Update)
endfunction
06-15-2006, 12:12 AM#2
Rising_Dusk
The entire death function is just converted from GUI, so it's a bit weird.
I took the liberty of optimizing and correcting it.

It healed enemies because your boolexpr in the GroupEnum..() returned true if the FilterUnit() was an enemy and false if it was an ally.

Collapse JASS:
function Seal_of_the_Underworld_Death_Conditions takes nothing returns boolean
    return CF_GetAttachedBoolean("Spell_SealOfTheUnderworld_Active", GetDyingUnit())
endfunction

function Seal_of_the_Underworld_Death_Check takes nothing returns boolean
    return IsPlayerAlly(GetOwningPlayer(GetDyingUnit()), GetOwningPlayer(GetFilterUnit()))
endfunction

function Seal_of_the_Underworld_Death_GroupStuff takes nothing returns nothing
    local unit u = GetEnumUnit()
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + 250.00)
    call CF_CreateAttachedUnitEffect(u, "Abilities\\Spells\\Other\\Parasite\\ParasiteTarget.mdl", "chest", 2.5)
    set u = null
endfunction

function Seal_of_the_Underworld_Death_Actions takes nothing returns nothing
    local unit d = GetDyingUnit()
    local real x = GetUnitX(d)
    local real y = GetUnitY(d)
    local group g = CreateGroup()
    local boolexpr b = Condition(function Seal_of_the_Underworld_Death_Check)
    
    call GroupEnumUnitsInRange(g, x, y, 600.0, b)
    call ForGroup(udg_TempGroup, function Seal_of_the_Underworld_Death_GroupStuff)
    call CF_AttachBoolean(false, "Spell_SealOfTheUnderworld_Active", GetDyingUnit())
    
    call GroupClear(g)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set d = null
    set g = null
    set b = null
endfunction

//===========================================================================
function InitTrig_Seal_of_the_Underworld_Death takes nothing returns nothing
    set gg_trg_Seal_of_the_Underworld_Death = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Seal_of_the_Underworld_Death, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition(gg_trg_Seal_of_the_Underworld_Death, Condition(function Seal_of_the_Underworld_Death_Conditions))
    call TriggerAddAction(gg_trg_Seal_of_the_Underworld_Death, function Seal_of_the_Underworld_Death_Actions)
endfunction
06-15-2006, 04:02 AM#3
Naakaloh
I believe he wants it to heal enemies, but instead of healing them when a unit with the buff dies, it heals them when ever the unit dies, with or without the buff. At least that's what it seems like his situation is.
06-15-2006, 06:37 AM#4
sheep.spirit
Why dont you try something like this?

Collapse JASS:
function buff_tester takes nothing returns nothing
  local timer t = GetExpiredTimer()
  local unit u =  CF_GetAttachedUnit("Spell_SealOfTheUnderworld_Caster", t)
  local real r = CF_GetAttachedReal(r, t)
   if  GetWidgetLife(u) < 0.405 then 
  call ExecuteFunc("Function_for_after_death_with_buff")
  call DestroyTimer(t)
   elseif r == 30. then
   call DestroyTimer(t)
   elseif GetUnitAbilityLevel(u, 'B000') ==0 then
 call CF_AttachReal(30., "r",t)
   else
 call CF_AttachReal(r+0.01, "r",t)
  endif
set u = null
endfunction
 
function this_is_an_extra_function_for_testing takes nothing returns nothing
  local timer t = CreateTimer()
  local unit u = GetTriggerUnit()
  
    call CF_AttachHandle(u, "Spell_SealOfTheUnderworld_Caster", t)
    call TimerStart(t,0.01, true, function buff_tester)
set u = null
endfunction

This functions tests whether the unit has the buff every 0.01 sec. If has no buff, then set to 50 which just destroys the timer without doing anything. If the unit dies in the middle, which is GetWidgetLife < 0.405 then u execute the function.
06-15-2006, 06:55 AM#5
Naakaloh
That seems a little excessive, a trigger firing every 0.01 seconds for 30 seconds. That's up to 3000 times instead of simply firing twice. Imagine if this spell were cast on 10 different units, that would make it worse. I think his method is fine, but there may be something with returning the GetAttachedBoolean, since it seems to always return true regardless of whether the buff is applied or not. (At least, that's what I'm gathering from his post.)
06-15-2006, 07:06 AM#6
The)TideHunter(
The problem was i cant check dead units for buffs, so i attached a boolean to the unit for 30 seconds, which was instead of checking for the buff. If the unit dies it will heal enemies.

I dont understand why it heals enemies when its true OR false. which checks if it is in this line:

Collapse JASS:
function Trig_Seal_of_the_Underworld_Death_Conditions takes nothing returns boolean
    return CF_GetAttachedBoolean("Spell_SealOfTheUnderworld_Active", GetDyingUnit())
endfunction

EDIT: Yes they have BJ's and some are useless, i converted to text because im lazy looking on JassCraft for the variable order of functions, and because it saved time. I would change them to there natives and optimize it once it works
06-15-2006, 03:48 PM#7
Naakaloh
I don't really see what's wrong. I'm guesing you have tried displaying the value of the boolean to the play and it does correctly show as true or false? If so, maybe it's just a peculiarity of the World Editor, and you might have to try something like, but that's just a random though:

Collapse JASS:
function Trig_Seal_of_the_Underworld_Death_Conditions takes nothing returns boolean
    if(CF_GetAttachedBoolean("Spell_SealOfTheUnderworld_Active", GetDyingUnit()))
        return true
    endif
    return false
endfunction
06-16-2006, 01:37 AM#8
sheep.spirit
Why is it excessive? You could easily change the 0.01 in the functions to 1. or 0.1
It prevents any bugs from occuring like dispell. Boolean attaching is assuming that the buff stays there for the whole duration. Let me try to fix the function optimised by Rising_Dusk into my functions.

Collapse JASS:
function Function_for_after_death_with_buff takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit d =  CF_GetAttachedUnit("Spell_SealOfTheUnderworld_Caster", t)
    local real x = GetUnitX(d)
    local real y = GetUnitY(d)
    local group g = CreateGroup()
    local unit f
    
    call GroupEnumUnitsInRange(g, x, y, 600.0, null)
    loop 
    set f = FirstOfGroup(g)
    exitwhen f == null
     if IsPlayerEnemy(GetOwningPlayer(d), GetOwningPlayer(f)) then
         call SetUnitState(f, UNIT_STATE_LIFE, GetUnitState(f, UNIT_STATE_LIFE) + 250.00)
    call CF_CreateAttachedUnitEffect(f, "Abilities\\Spells\\Other\\Parasite\\ParasiteTarget.mdl", "chest", 2.5)
      endif
   call GroupRemoveUnit(g, f)
endloop
    
     call DestroyGroup(g)
    set d = null
    set g = null
    set f = null
endfunction

function buff_tester takes nothing returns nothing
  local timer t = GetExpiredTimer()
  local unit u =  CF_GetAttachedUnit("Spell_SealOfTheUnderworld_Caster", t)
  local real r = CF_GetAttachedReal(r, t)
   if  GetWidgetLife(u) < 0.405 then 
  call ExecuteFunc("Function_for_after_death_with_buff")
  call DestroyTimer(t)
   elseif r == 30. then
   call DestroyTimer(t)
   elseif GetUnitAbilityLevel(u, 'B000') ==0 then
 call CF_AttachReal(30., "r",t)
   else
 call CF_AttachReal(r+1., "r",t)
  endif
set u = null
endfunction
 
function this_is_an_extra_function_for_testing takes nothing returns nothing
  local timer t = CreateTimer()
  local unit u = GetTriggerUnit()
  
    call CF_AttachHandle(u, "Spell_SealOfTheUnderworld_Caster", t)
    call TimerStart(t,1., true, function buff_tester)
set u = null
endfunction

This should do the job, instead of splitting it into 2 triggers. However, if you really want to use your original functions, then i suggest you put a == true behind your conditions. Do not alweays assume that putting nothing behind is == true, cause if i am not wrong, IsUnitType also always rturn true of something.
06-16-2006, 02:57 AM#9
Rising_Dusk
Just a readability thing, Sheep, but I recommend watching your indents.
If you keep indents together, it makes it much easier to follow.

And if you would Tide, could you post the functions you are currently at (I think the first post is a bit outdated for now). Or if it isn't, then cool. I'll plug the functions into a testmap and make it work.

Also, explain again what you want this spell to do.
Heal enemies on death and not allies? Or the other way around?
06-16-2006, 04:15 AM#10
sheep.spirit
It buffs the caster alot, but if u die when the buff is on you, you heal enemies, this is presummably the cost of accquiring the power. is it correct? tt's what i think the spell does