• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece!🔗 Click here to enter!

[JASS] Detect magic immunity and wait time in chain spell

Status
Not open for further replies.
Level 12
Joined
Apr 29, 2005
Messages
999
Two questions:

1. Magic immunity
Let's say that you have a JASS spell that deals damage to a unit by using the command "UnitDamageTargetBJ". A problem is that you don't want the spell to damage the target if it is immune to magic. Is there any good way to do that without testing if the unit has any of all abilities in the map that grants spell immunity?

2. Wait correct amount of time between chain effects
I have made a chain spell that works perfectly except that the time between each dummy casting the effecting spell is not correct. How to fix that? I have tried (distance between target N and N+1)/(missile speed) but the wait time still isn't the correct. Here is the code, under the first line in the first loop you find my try to get the correct amount of time. 750 is the missile speed.

JASS:
//EVENT CONDITION
//================================================================================================
function Trig_Chain_Lightning_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A005' ) ) then
        return false
    endif
    return true
endfunction
//================================================================================================

function Trig_Chain_Lightning_Actions takes nothing returns nothing
 local unit CV_Caster
 local unit CV_Target
 local unit CV_First
 local unit CV_Matching
 local unit CV_Dummy
 local player CV_Player
 local location CV_TargetPoint
 local location CV_MatchingPoint
 local group CV_Group1
 local group CV_Group2
 local integer CV_Tests
 local integer CV_MaxTargets
 local real CV_Distance
 set CV_Caster = GetSpellAbilityUnit()
 set CV_Target = null
 set CV_Player = GetOwningPlayer(CV_Caster)
 set CV_Matching = GetSpellTargetUnit()
 set CV_TargetPoint = GetUnitLoc(CV_Caster)
 set CV_Group1 = GetUnitsInRangeOfLocAll(400, CV_TargetPoint) 
 set CV_Group2 = CreateGroup()
 set CV_Tests = CountUnitsInGroup(CV_Group1)
 set CV_First = FirstOfGroup(CV_Group1) 
 set CV_MaxTargets = 5
 set CV_Matching = GetSpellTargetUnit()
 set CV_MatchingPoint = GetUnitLoc(CV_Matching)
 
 call GroupAddUnit(CV_Group2, CV_Matching)
 call DisplayTimedTextToForce(GetPlayersAll(), 2, "Variables set.")  
 call CreateTextTagUnitBJ( "Matching" + I2S(CV_Tests), CV_Matching, 100, 10, 0, 100, 0, 0)
 
 loop
   if (CV_Matching != null) then
     call TriggerSleepAction(DistanceBetweenPoints(CV_MatchingPoint, CV_TargetPoint)/(750))
     call DisplayTimedTextToForce(GetPlayersAll(), 2, "Distance:" + R2S(DistanceBetweenPoints(CV_MatchingPoint, CV_TargetPoint)/(750))) 
     call CreateNUnitsAtLocFacingLocBJ(1, 'h000', CV_Player, CV_TargetPoint, CV_MatchingPoint) 
     set CV_Dummy = GetLastCreatedUnit()
     call SetUnitAbilityLevelSwapped('A001', CV_Dummy, 1)
     call IssueTargetOrderBJ(CV_Dummy, "thunderbolt", CV_Matching)
     call UnitApplyTimedLifeBJ(2, 'BTLF', CV_Dummy)
     set CV_Dummy = null
     set CV_MatchingPoint = GetUnitLoc(CV_Matching)
     set CV_MaxTargets = CV_MaxTargets - 1  
   else
     set CV_MaxTargets = 0
   endif  
 exitwhen (CV_MaxTargets == 0)
   set CV_Matching = null
   set CV_TargetPoint = CV_MatchingPoint
   set CV_Group1 = GetUnitsInRangeOfLocAll(400, CV_MatchingPoint)
   set CV_Tests = CountUnitsInGroup(CV_Group1)
   loop
     exitwhen (CV_Tests == 0 or CV_Matching == CV_First)
     set CV_First = FirstOfGroup(CV_Group1)
     call CreateTextTagUnitBJ( "Tested" + I2S(CV_Tests), CV_First, 10, 10, 100, 100, 100, 0)
     if (IsUnitEnemy(CV_First, CV_Player) and IsUnitAliveBJ(CV_First) and not(IsUnitInGroup(CV_First, CV_Group2))) then
       set CV_Matching = CV_First
       set CV_MatchingPoint = GetUnitLoc(CV_Matching)
       call GroupAddUnit(CV_Group2, CV_First)
       call CreateTextTagUnitBJ( "Matching" + I2S(CV_Tests), CV_Matching, 100, 10, 0, 100, 0, 0)
       set CV_Tests = 0 
     else
       set CV_Tests = CV_Tests - 1
       set CV_Matching = null
     endif
     call GroupRemoveUnit(CV_Group1, CV_First)
     call DisplayTimedTextToForce(GetPlayersAll(), 2, "Secondary loop executed once.") 
   endloop
   set CV_Target = CV_Matching
   call DisplayTimedTextToForce(GetPlayersAll(), 2, "Primary loop executed once.")
 endloop


 call DisplayTimedTextToPlayer(CV_Player, -1, -1, 2, "Variables being destroyed")
 call RemoveLocation(CV_TargetPoint)
 call RemoveLocation(CV_MatchingPoint)
 call DestroyGroup(CV_Group1)
 call DestroyGroup(CV_Group2)
 set CV_Caster = null
 set CV_Target = null
 set CV_First = null
 set CV_Matching = null
 set CV_TargetPoint = null
 set CV_MatchingPoint = null
 set CV_Group1 = null

 set CV_Group2 = null
 set CV_Player = null
 call DisplayTimedTextToForce(GetPlayersAll(), 2, "Chain Lightning Completed")  
endfunction

//EVENT
//================================================================================================
function InitTrig_Chain_Lightning takes nothing returns nothing
    set gg_trg_Chain_Lightning = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Chain_Lightning, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Chain_Lightning, Condition( function Trig_Chain_Lightning_Conditions ) )
    call TriggerAddAction( gg_trg_Chain_Lightning, function Trig_Chain_Lightning_Actions )
endfunction
//================================================================================================
 
Level 8
Joined
Nov 27, 2004
Messages
251
. Magic immunity
A problem is that you don't want the spell to damage the target if it is immune to magic. Is there any good way to do that without testing if the unit has any of all abilities in the map that grants spell immunity?

you can use this

JASS:
UnitDamageTarget(WhichUnit,WhichTarget,Amount,true,true,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS)

as you see you say to the unit to damage via magic attack and will deal no damage to magic immune units

in the other case you may use this to flilter magic immune units

JASS:
IsUnit(WhichUnit,UNIT_TYPE_MAGIC_IMMUNE)

Wait correct amount of time between chain effects

Waits or TriggerSleepAction(X) and PolledWait(X) arent accurate,use Timers wich may solve your problem.
 
Status
Not open for further replies.
Top