Is this spell MUI/MPI/Leakless? (Death-Grip)

LearningCode

New Member
Reaction score
24
Yea, I normally wouldn't be so fussy about this..
(Unless the spell does not work at all =x)
But this spell is not for me, it's for a User named Bananarama1

The spell basically goes like this:
1) Hero casts Death Grip
2) Red Lightning chains hero and targeted unit
3) Targeted unit is dragged towards hero
4) Targeted unit is stunned and damaged

The spell works fine, but I'd like to know if it leaks or isn't MUI and MPI.

There's also one thing I'd like to change but cannot figure out.
If the targeted unit is, say, 600pixels away, the spell takes 0.6 seconds to drag the targeted unit to the hero. (Just an imaginary time)
But when the targeted unit is 50pixels away, the spell will still take 0.6 seconds to drag the targeted unit to the hero.

It's a bit irritating when you cast the spell from close range, lol.
How would I go about making this spell drag enemy units at a constant speed? o.0

This spell isn't my idea, some other guy thought of it first, I don't know who, lol

The gripping spell:
JASS:
// ===============================
// How the idea for this spell was conceived:
// This spell is not my idea.
// I just made a JASS version of a spell Bananarama1 wanted 
// Someone else made a GUI version of this spell
// But the spell could not be targeted on enemy units except for neutral hostile
// The spell also makes the target unit move INSTANTLY to the caster
// Bananarama1 wanted it targetable on any enemy unit and the targeted unit to be 'pulled'
// ===============================
// I looked at the GUI triggers and, yea, it looked like something I could 'simplify'
// But, I'm not sure if this spell in MUI, MPI and leakless
// Could you guys check it out for me? o.0
// ===============================
// Spell name: Death Grip
// Effect: Enemy units targeted are drawn towards the caster and are stunned and damaged
// ===============================
// Question:
// ~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~
// How do I make it such that the targeted unit moves at a constant rate towards the caster?
// The targeted unit takes 0.625 seconds to move to the caster, Regardless of initial distance
// ~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~


scope DGPull initializer InitTrig

   globals
      private constant integer DGID = 'A000'
      //The raw-code of the Death-Grip Spell
      
      private constant integer DummyID = 'nzin'
      //The raw-code of the dummy summoned to stun the enemy
      
      private constant integer StormID = 'A001'
      //The raw-code of the StormBolt spell that the dummy will cast
      
      private constant integer TickAmount = 20
      //The number of ticks, more ticks mean a longer spell duration.
      
      private constant string WarCry = "COME OVER HERE!"
      //What you want the Floating Text Message to say
   endglobals

   private struct DG
      private static DG data = 0
      private static hashtable ht = InitHashtable()
      unit caster
      unit target
      timer t
      real uX
      real uY
      real uZ
      real cX
      real cY
      real cZ
      real distance
      real radian
      lightning Bzzt
      real movement
      integer ticks = 0
      trigger trig
      integer DGLevel
      real damage
      
      static method DGStun takes nothing returns nothing
         local DG d = DG.data
         local unit dummy
         
         set dummy = CreateUnit(GetOwningPlayer(d.caster), DummyID, d.cX, d.cY, bj_UNIT_FACING)
         call UnitAddAbility(dummy, StormID)
         call IssueTargetOrder(dummy, "thunderbolt", d.target)
         call UnitApplyTimedLife(dummy, 'BTLF', 1.00)
         set dummy = null
         
         call DestroyEffect(AddSpecialEffect("NewGroundEX.mdx", d.uX, d.uY))
         call PauseUnit(d.caster, false)
         call PauseUnit(d.target, false)
         call UnitDamageTarget(d.caster, d.target, d.damage, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
         
         call d.destroy()
      endmethod
      
      
      static method DGTimer takes nothing returns nothing
         local DG d = LoadInteger(DG.ht, GetHandleId(GetExpiredTimer()), 0)
         local real moveit = d.distance - (d.ticks * d.movement)
         
         if d.ticks < TickAmount then
            set d.uX = GetUnitX(d.target)
            set d.uY = GetUnitY(d.target)
            set d.uZ = GetUnitFlyHeight(d.target)
            set d.cX = GetUnitX(d.caster)
            set d.cY = GetUnitY(d.caster)
            set d.cZ = GetUnitFlyHeight(d.caster)
            set d.uX = d.cX + (moveit) * Cos(d.radian)
            set d.uY = d.cY + (moveit) * Sin(d.radian)
            
            call SetUnitX(d.target, d.uX)
            call SetUnitY(d.target, d.uY)
            call MoveLightningEx(d.Bzzt, true, d.cX, d.cY, d.cZ, d.uX, d.uY, d.uZ)
            
            set d.ticks = d.ticks + 1
         
         else
            set DG.data = d
            call DG.DGStun()
         endif
      endmethod
      
      static method DGAct takes nothing returns nothing
         local DG d = DG.allocate()
         local texttag tag
         set d.trig = GetTriggeringTrigger()
         call DisableTrigger(d.trig)
         set d.caster = GetTriggerUnit()
         set d.target = GetSpellTargetUnit()
         set d.t = CreateTimer()
         set d.uX = GetUnitX(d.target)
         set d.uY = GetUnitY(d.target)
         set d.uZ = GetUnitFlyHeight(d.target)
         set d.cX = GetUnitX(d.caster)
         set d.cY = GetUnitY(d.caster)
         set d.cZ = GetUnitFlyHeight(d.caster)
         set d.radian = Atan2((d.uY - d.cY), (d.uX - d.cX))
         set d.distance = (d.uX - d.cX) / Cos(d.radian)
         set d.movement = d.distance / TickAmount
         set d.DGLevel = GetUnitAbilityLevel(d.caster, DGID)
         set d.damage = d.DGLevel * 125
         
         
         call PauseUnit(d.caster, true)
         call PauseUnit(d.target, true)
         call SetUnitPathing(d.target, false)
         set tag = CreateTextTagUnitBJ( WarCry, d.caster, 0, 14.00, 100.00, 0.00, 0.00, 0 )
         call SetTextTagPermanent( tag, false )
         call SetTextTagLifespan( tag, (TickAmount * 0.03125) )
         set d.Bzzt = AddLightningEx("AFOD", true, d.cX, d.cY, d.cZ, d.uX, d.uY, d.uZ)
         
         call TimerStart(d.t, 0.03125, true, function DG.DGTimer)
         call SaveInteger(d.ht, GetHandleId(d.t), 0, d)
         set tag = null
      endmethod
      
      
      method onDestroy takes nothing returns nothing
         call EnableTrigger(.trig)
         set .caster = null
         set .target = null
         call PauseTimer(.t)
         call DestroyTimer(.t)
         set .t = null
         call DestroyLightning(.Bzzt)
         set .Bzzt = null
         set .trig = null
      endmethod
   endstruct

   private function DGCond takes nothing returns boolean
      return GetSpellAbilityId() == DGID
   endfunction
   
   private function InitTrig takes nothing returns nothing
      local trigger t = CreateTrigger()
      local integer i = 0
      
      loop
      exitwhen i == 8
         call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
      set i = i+1
      endloop
      
      call TriggerAddCondition(t, Condition(function DGCond))
      call TriggerAddAction(t, function DG.DGAct)
   endfunction


endscope

The Remove Dummy Trigger:
JASS:
scope Dead initializer RemoveDummy
   
   globals
      private constant integer DummyID = 'nzin' 
      //The raw-code of the dummy summoned to stun the enemy
   endglobals
   
   private struct Dead
      private static Dead data = 0
      unit u
      
      static method DeadAct takes nothing returns nothing
         local Dead d = Dead.data
         call RemoveUnit(d.u)
         call d.destroy()
      endmethod
      
      static method DeadCond takes nothing returns boolean
         local Dead d = Dead.allocate()
         set d.u = GetTriggerUnit()
         set Dead.data = d
         if GetUnitTypeId(d.u) == DummyID then
            return true
         else
            call d.destroy()
            return false
         endif
      endmethod
      
      method onDestroy takes nothing returns nothing
         set .u = null
      endmethod
   
   endstruct
   
   private function RemoveDummy takes nothing returns nothing
      local trigger t = CreateTrigger()
      local integer i = 0
      
      loop
      exitwhen i == 12
         call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
      set i = i+1
      endloop
      call TriggerAddCondition(t, Condition(function Dead.DeadCond))
      call TriggerAddAction(t, function Dead.DeadAct)
   endfunction

endscope

[EDIT]
Wtf, the Spoilers don't work =/
 

Attachments

  • SS1.png
    SS1.png
    75.6 KB · Views: 176
  • SS2.png
    SS2.png
    52.6 KB · Views: 131
  • SS3.png
    SS3.png
    132.2 KB · Views: 158
  • SS4.png
    SS4.png
    207.6 KB · Views: 168
  • Death Grip JASSified.w3x
    23.5 KB · Views: 126

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
You can throw away the dummy removal trigger. Death units are auto removed after their death time.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
It looks Mui and Leakless.

Thought, you should use TimerUtils or KT (Timer Systems) instead of using Hashtables.
 

LearningCode

New Member
Reaction score
24
If I use a timer system, the dude Bananarama1 will have to import 2 triggers for one spell =/

Lol, I'll just make a 2nd version and make it available as an option xD
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top