| 06-14-2006, 07:51 PM | #1 |
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) 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) 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) 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 |
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. 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 |
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 |
Why dont you try something like this? 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 |
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 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: 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 |
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: 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 |
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. 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 |
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 |
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 |
