Spellpack Assorted Diablo Spells

emootootoo

Top Banana
Reaction score
51
Spellpack includes:
  • Blessed Hammer
  • Hurricane
  • Poison Javelin
  • Iron Maiden

These spells require:
Newgen - includes JassHelper compiler (vjass): http://www.thehelper.net/forums/showthread.php?t=73936

The descriptions are in the top of the code boxes for the spells. :)

Name: Blessed Hammer

MUI: Yes
Leakless: Yes

BlessedHammer.jpg


Code:
JASS:
//=====================================================================//
//                             Blessed Hammer                          //
//=====================================================================//
//by emootootoo                                                        //
//                                                                     //
// Requires: vJass, CSData, CSSafety                                   //
//                                                                     //
// Things you need to copy:                                            //
// Abilities: Blessed Hammer                                           //
// Units: BlessedHammerDummy                                           //
// Sound: gg_snd_bolthammercast                                        //
//                                                                     //
// Description: Summons a magical hammer that spirals outwards from    //
// the caster damaging any enemies it hits.                            //
//=====================================================================//

scope BlessedHammer

globals // Configuration

    private integer spellID='A001'
    //Blessed Hammer Ability ID
    private integer DummyID='h002'
    //Blessed Hammer Dummy Unit ID
    private integer bhDamage=40
    //Damage per level (eg: 40*level)
    private integer bhSpeed=190
    //Higher number = Faster
    private real bhDistance=1440
    //How many revolutions, 360 = 1, 1080 = 3
    private integer bhRadius=500
    // The radius in which the hammers spirals fit into
    private integer DmgRadius=120
    // The radius the hammer has to hit a unit
    private string HitArt="Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
    // Art used for when the projectile hits a unit
    
endglobals // End Configuration

//Code =====================================================================

struct BHData
    public unit BH
    public integer count
    public integer slvl
    public real BHangle
    public real BHradius
    public location BHloc
    public group BHgroup
    public unit BHcaster
endstruct

function Trig_BlessedHammer_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==spellID
endfunction

function BlessedHammerTimer takes nothing returns nothing
    //gets struct number from the expiring timer
    local BHData BHD = GetCSData(GetExpiredTimer())
    local location HammerLoc =GetUnitLoc(BHD.BH)
    
    //gets the distance between hammer and cast point
    local real dx=GetLocationX(HammerLoc)-GetLocationX(BHD.BHloc)
    local real dy=GetLocationY(HammerLoc)-GetLocationY(BHD.BHloc)
    local real distance=SquareRoot(dx*dx+dy*dy)
    
    //gets the new angle and radius from caster for the hammer to move
    local real anglediff=(10/(distance))*bhSpeed
    local real angle=BHD.BHangle-anglediff
    local real radius=BHD.BHradius+((I2R(bhRadius))/(bhDistance/(anglediff)))
    
    //sets new position for hammer to move to
    local real x=GetLocationX(BHD.BHloc)+radius*Cos(angle*bj_DEGTORAD)
    local real y=GetLocationY(BHD.BHloc)+radius*Sin(angle*bj_DEGTORAD)
    
    local group g=CreateGroup()
    local group g2=CreateGroup()
    local unit u 
    local effect sfx

    //damages enemy units in range of the hammer
    call GroupEnumUnitsInRange(g,x,y,DmgRadius,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        if IsUnitEnemy(u,GetOwningPlayer(BHD.BH))==true and IsUnitInGroup(u,BHD.BHgroup)==false and IsUnitType(u,UNIT_TYPE_STRUCTURE)==false and GetUnitState(u,UNIT_STATE_LIFE)>0 then
            call UnitDamageTarget(BHD.BHcaster,u,bhDamage*BHD.slvl,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
            call GroupAddUnit(BHD.BHgroup,u) //adds damaged unit to the struct group
            call DestroyEffect(AddSpecialEffectTarget(HitArt,u,"chest"))
        endif
        call GroupRemoveUnit(g,u)
    endloop
    call DestroyGroup(g)
    set g = null
    
    //puts units that are already in the struct group that are still
    // in range of the hammer into a temp group
    loop
        set u = FirstOfGroup(BHD.BHgroup)
        exitwhen u == null
        if IsUnitInRangeXY(u,x,y,DmgRadius)==true then
            call GroupAddUnit(g2,u)
        endif
        call GroupRemoveUnit(BHD.BHgroup,u)
    endloop
    
    //puts all units in the temp group back into the struct group
    //this makes it so the hammer can damage the same unit more than once,
    //as long as it goes out of the damage range of the hammer first
    loop
        set u = FirstOfGroup(g2)
        exitwhen u == null
        call GroupAddUnit(BHD.BHgroup,u)
        call GroupRemoveUnit(g2,u)
    endloop
    call DestroyGroup(g2)
    set g2 = null
    
    
    //checks if the hammer has reached its max range
    //if it hasnt, moves it, if it has, finishes the spell
    if distance<=bhRadius then
        set BHD.count=BHD.count+1
        call SetUnitPosition(BHD.BH,x,y)
        set BHD.BHangle=angle
        set BHD.BHradius=radius
    else
        call RemoveLocation(BHD.BHloc)
        call DestroyGroup(BHD.BHgroup)
        set BHD.BHgroup=null
        call BHD.destroy()
        call ReleaseTimer(GetExpiredTimer())
        call RemoveUnit(BHD.BH) 
    endif

    
    call RemoveLocation(HammerLoc)
    
    //nulling handles
    set HammerLoc=null
    set sfx=null
    set u=null
endfunction

function Trig_BlessedHammer_Actions takes nothing returns nothing
    local BHData BHD=BHData.create()
    local unit caster=GetTriggerUnit()
    local real angle=GetUnitFacing(caster)
    local real x=GetUnitX(caster)+100*Cos(angle*bj_DEGTORAD)
    local real y=GetUnitY(caster)+100*Sin(angle*bj_DEGTORAD)
    local timer t = NewTimer()
    local unit BHammer=CreateUnit(GetOwningPlayer(caster),DummyID,x,y,angle-90)
    local sound soundfx=CreateSound("war3mapImported\\bolthammercast.wav",false,true,true,10,10," ")
    //gg_snd_bolthammercast
    
    //sound effect
    call AttachSoundToUnit(soundfx,caster)
    call SetSoundVolume(soundfx,127)
    call StartSound(soundfx)
    call KillSoundWhenDone(soundfx)
    
    //sets struct data
    set BHD.count=0
    set BHD.slvl=GetUnitAbilityLevel(caster,spellID)
    set BHD.BH=BHammer
    set BHD.BHcaster=caster
    set BHD.BHangle=angle
    set BHD.BHradius=40
    set BHD.BHloc=Location(GetUnitX(caster),GetUnitY(caster))
    set BHD.BHgroup=CreateGroup()
    call SetUnitUserData(BHammer, BHD)
    
    //sets timer
    call SetCSData(t,BHD)
    call TimerStart(t,0.03,true,function BlessedHammerTimer)
    
    set soundfx=null
    set t=null
    set caster=null
    set BHammer=null
endfunction

endscope
//===========================================================================
function InitTrig_BlessedHammer takes nothing returns nothing
    set gg_trg_BlessedHammer = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_BlessedHammer, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_BlessedHammer, Condition( function Trig_BlessedHammer_Conditions ) )
    call TriggerAddAction( gg_trg_BlessedHammer, function Trig_BlessedHammer_Actions )
endfunction


Name: Hurricane

MUI: Yes
Leakless: Yes

Hurricane-1.jpg


Code:
JASS:
//=====================================================================//
//                             Hurricane                               //
//=====================================================================//
//by emootootoo                                                        //
//                                                                     //
// Requires: vJass, CSData, CSSafety                                   //
//                                                                     //
// Things you need to copy:                                            //
// Abilities: Hurricane, HurricaneDummySpell                           //
// Units: HurricaneDummy, DummyCaster                                  //
// Buffs: Chilled                                                      //
//                                                                     //
// Description: Summons a hurricane around the caster that damages and //
// slows enemy units that come within.                                 //
//=====================================================================//

scope Hurricane

globals // Configuration

    private integer spellID='A000'
    //Hurricane Ability ID
    private integer dummycasterID='h003'
    //The DummyCaster unit's ID
    private integer dummyunitID='h000'
    //The HurricaneDummy unit's ID
    private real hInterval=0.5
    //Time between damaging units in the hurricane (eg. 1.0 damages every 1 second)
    //Note: Only use intervals of multiples of 0.05 (0.05, 0.4, 1.65, etc)
    private real hDuration=10.0
    //Duration of the spell
    private real hRadius=500
    //Radius of the Hurricane spell
    private real hDamage=25
    //Damage per level. Deals damage per interval to anyone in the huricane (eg. 50*lvl)
    private real hDistanceInterval=150
    //How far gusts of wind are apart from each other (max of 6 circles of wind around caster)
    //The circles are determined starting from the max radius inwards to keep it accurate
    
endglobals // End Configuration

//Code =====================================================================

struct hData
    public unit array hUnit[12]
    public real array hAngle[12]
    public real array hDist[12]
    public unit hCaster
    public integer  hNumber
    public integer count
    public integer slvl
endstruct

function Trig_Hurricane_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==spellID
endfunction

function HurricaneTimer takes nothing returns nothing
    local hData hD = GetCSData(GetExpiredTimer())
    local group g=CreateGroup()
    local unit u
    local unit tempu
    local real x
    local real y
    local location loc=GetUnitLoc(hD.hCaster)
    local integer intcount=R2I(hInterval/0.05)
    local integer tempint=0
    local integer int=0
    
    
    if GetUnitState(hD.hCaster,UNIT_STATE_LIFE)>0 then
    else
        set hD.count=R2I(hDuration/0.05)+1
    endif
    
        
    if hD.count<=R2I(hDuration/0.05) then
        set hD.count=hD.count+1
        loop
        exitwhen tempint>hD.hNumber
            set tempint=tempint+1
            set hD.hAngle[tempint]=hD.hAngle[tempint]+8
            set x=GetLocationX(loc)+hD.hDist[tempint]*Cos(hD.hAngle[tempint]*bj_DEGTORAD)
            set y=GetLocationY(loc)+hD.hDist[tempint]*Sin(hD.hAngle[tempint]*bj_DEGTORAD)
            call SetUnitPosition(hD.hUnit[tempint],x,y)
        endloop

        
        if ModuloInteger(hD.count,intcount)==0 then
            call GroupEnumUnitsInRange(g,GetUnitX(hD.hCaster),GetUnitY(hD.hCaster),hRadius,null)
            loop
                set u = FirstOfGroup(g)
                exitwhen u==null
                    if IsUnitEnemy(u,GetOwningPlayer(hD.hCaster))==true and IsUnitType(u,UNIT_TYPE_STRUCTURE)==false and GetUnitState(u,UNIT_STATE_LIFE)>0 then
                        call UnitDamageTarget(hD.hCaster,u,hDamage*hD.slvl,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,null)
                        set tempu=CreateUnit(GetOwningPlayer(hD.hCaster),dummycasterID,GetUnitX(u),GetUnitY(u),0)
                        call IssueTargetOrder(tempu,"slow",u)
                        call UnitApplyTimedLife(tempu,'BTLF',0.75)
                    endif
                call GroupRemoveUnit(g,u)
            endloop
            call DestroyGroup(g)
            set g = null
        endif
    else
        call hD.destroy()
        call ReleaseTimer(GetExpiredTimer())
        loop
            exitwhen int>hD.hNumber
                set int=int+1
                call RemoveUnit(hD.hUnit[int])
                set hD.hUnit[int]=null
        endloop
    endif
    
    call RemoveLocation(loc)
    set loc=null
    set u=null
    set tempu=null
endfunction

function Trig_Hurricane_Actions takes nothing returns nothing
    local hData hD=hData.create()
    local unit caster=GetTriggerUnit()
    local real angle=GetUnitFacing(caster)
    local real tempangle
    local location cloc=GetUnitLoc(caster)
    local location tloc=null
    local timer t = NewTimer()
    local real x
    local real y
    local integer radnum=R2I((hRadius*2)/hDistanceInterval)
    local integer tempint=2
    local integer int=0
    local integer bsint=0
    
    if radnum<1 then
        set radnum=1
    endif
    if radnum>12 then
        set radnum=12
    endif
    
    loop
        exitwhen int>radnum
            loop
                exitwhen tempint<1
                if tempint==2 then
                    set tempangle=angle-90
                else
                    set tempangle=angle+90
                endif
                set int=int+1 
                set tloc=GetUnitLoc(caster)
                set x=GetLocationX(tloc)+(hRadius-(bsint*hDistanceInterval))*Cos(tempangle*bj_DEGTORAD)
                set y=GetLocationY(tloc)+(hRadius-(bsint*hDistanceInterval))*Sin(tempangle*bj_DEGTORAD)
                set hD.hUnit[int]=CreateUnit(GetOwningPlayer(caster),dummyunitID,x,y,0)
                call RemoveLocation(tloc)
                set tloc=Location(x,y)
                call SetUnitVertexColor(hD.hUnit[int],255,255,255,0)
                set hD.hAngle[int]=tempangle
                set hD.hDist[int]=DistanceBetweenPoints(cloc,tloc)
                set tempint=tempint-1
                call RemoveLocation(tloc)
            endloop
        set bsint=bsint+1
        set tempint=2            
    endloop
    

    set hD.count=0
    set hD.slvl=GetUnitAbilityLevel(caster,spellID)
    set hD.hCaster=caster
    set hD.hNumber=int
    call SetUnitUserData(hD.hUnit[hD.hNumber], hD)
    
    call SetCSData(t,hD)
    call TimerStart(t,0.05,true,function HurricaneTimer)
    
    set caster=null
    call RemoveLocation(cloc)
    set cloc=null
    set tloc=null
    set t=null
endfunction

endscope
//===========================================================================
function InitTrig_Hurricane takes nothing returns nothing
    set gg_trg_Hurricane = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Hurricane, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Hurricane, Condition( function Trig_Hurricane_Conditions ) )
    call TriggerAddAction( gg_trg_Hurricane, function Trig_Hurricane_Actions )
endfunction


Name: Poison Javelin

MUI: Yes
Leakless: Yes

PoisonJavelin.jpg


Code:
JASS:
//=====================================================================//
//                             Poison Javelin                          //
//=====================================================================//
//by emootootoo                                                        //
//                                                                     //
// Requires: vJass, CSData, CSSafety                                   //
//                                                                     //
// Things you need to copy:                                            //
// Abilities: Poison Javelin, PjavPoisonCloud                          //
// Units: JavelinDummy, Poison Cloud                                   //
// Buffs: Poisoned                                                     //
//                                                                     //
// Description: Throws a poisonous javelin that leaves a trail of      //
// poison, poisoning enemies in it. When the javelin hits an enemy,    //
// it stops and deals damage to them.                                  //
//=====================================================================//

scope PoisonJavelin

globals // Configuration

    private integer spellID='A004'
    //'Poison Javelin' Ability ID
    private integer PJcloudID='A003'
    //'PJavPoisonCloud' Ability ID
    private integer dummyjavID='h005'
    //The 'JavelinDummy' unit's ID
    private integer dummycloudID='h004'
    //The 'Poison Cloud' unit's ID
    private string HitArt="Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
    //The art on the unit that gets hit by the javelin
    private real hSpeed=0.03
    //Speed javelin travels
    private real jDistance=1000
    //Distance the Javelin travels
    private real jCloudTime=5.
    //Amount of time poison clouds stay on the groudn before being removed
    private real jDamage=25
    //Damage per level of Impact Damage (not poison damage)
    //Note: Poison Damage and duration are altered in the ability 'PJavPoisonCloud'
    
endglobals // End configuration

//Code =====================================================================

struct jData
    public unit jUnit
    public unit jCaster
    public integer count
    public integer slvl
endstruct

function Trig_PoisonJavelin_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==spellID
endfunction

function PoisonJavelinTimer takes nothing returns nothing
    local jData jD = GetCSData(GetExpiredTimer())
    local group g=CreateGroup()
    local unit u
    local unit tempu
    local integer tempint=0
    local location dummypos=GetUnitLoc(jD.jUnit)
    local real x=GetLocationX(dummypos)+20*Cos(GetUnitFacing(jD.jUnit)*bj_DEGTORAD)
    local real y=GetLocationY(dummypos)+20*Sin(GetUnitFacing(jD.jUnit)*bj_DEGTORAD)
    
    if jD.count<=jDistance/20 then
        call SetUnitPosition(jD.jUnit,x,y)
        set jD.count=jD.count+1
        if ModuloInteger(jD.count,2)==0 then
            set tempu=CreateUnit(GetOwningPlayer(jD.jCaster),dummycloudID,x,y,0)
            call UnitAddAbility(tempu,PJcloudID)
            call SetUnitAbilityLevel(tempu,PJcloudID,jD.slvl)
            call UnitApplyTimedLife(tempu,'BTLF',jCloudTime)
        endif
    else
        call jD.destroy()
        call ReleaseTimer(GetExpiredTimer())
        call RemoveUnit(jD.jUnit)
    endif
    
    
    call GroupEnumUnitsInRange(g,GetUnitX(jD.jUnit),GetUnitY(jD.jUnit),90,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u==null
        if IsUnitEnemy(u,GetOwningPlayer(jD.jCaster))==true and IsUnitType(u,UNIT_TYPE_STRUCTURE)==false and GetUnitState(u,UNIT_STATE_LIFE)>0 then
            set tempint=tempint+1
            call UnitDamageTarget(jD.jCaster,u,jDamage*jD.slvl,true,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_NORMAL,null)
            call AddSpecialEffectTarget(HitArt,u,"chest")
        endif
        call GroupRemoveUnit(g,u)
    endloop
    call DestroyGroup(g)
    set g = null
    
    if tempint>0 then
        set jD.count=R2I((jDistance/20))+1
    endif
    
    call RemoveLocation(dummypos)
    set dummypos=null
    set tempu=null
endfunction

function Trig_PoisonJavelin_Actions takes nothing returns nothing
    local jData jD=hData.create()
    local unit caster=GetTriggerUnit()
    local location tpoint=GetSpellTargetLoc()
    local location castpos=GetUnitLoc(caster)
    local real angle=bj_RADTODEG * Atan2(GetLocationY(tpoint) - GetLocationY(castpos), GetLocationX(tpoint) - GetLocationX(castpos))
    local timer t = NewTimer()
    local real x=GetLocationX(castpos)+50*Cos(angle*bj_DEGTORAD)
    local real y=GetLocationY(castpos)+50*Sin(angle*bj_DEGTORAD)
    local unit u=CreateUnit(GetOwningPlayer(caster),dummyjavID,x,y,angle)
    

    set jD.count=0
    set jD.slvl=GetUnitAbilityLevel(caster,spellID)
    set jD.jCaster=caster
    set jD.jUnit=u
    call SetUnitUserData(jD.jUnit, jD)
    
    call SetCSData(t,jD)
    call TimerStart(t,hSpeed,true,function PoisonJavelinTimer)
    
    set caster=null
    set u=null
    call RemoveLocation(tpoint)
    set tpoint=null
    call RemoveLocation(castpos)
    set castpos=null
    set t=null
endfunction

endscope
//===========================================================================
function InitTrig_PoisonJavelin takes nothing returns nothing
    set gg_trg_PoisonJavelin = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_PoisonJavelin, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_PoisonJavelin, Condition( function Trig_PoisonJavelin_Conditions ) )
    call TriggerAddAction( gg_trg_PoisonJavelin, function Trig_PoisonJavelin_Actions )
endfunction


Name: Iron Maiden

MUI: Yes
Leakless: Yes

IronMaiden.jpg


Code:
JASS:
//=====================================================================//
//                             Iron Maiden                             //
//=====================================================================//
//by emootootoo                                                        //
//                                                                     //
// Requires: vJass                                                     //
//                                                                     //
// Things you need to copy:                                            //
// Abilities: Iron Maiden                                              //
// Units: DummyCaster                                                  //
// Buffs: Iron Maiden                                                  //
//                                                                     //
// Description: Curses units in an AoE making them do a % of the damage//
// they deal to to enemies, back to themselves, lasts a few seconds.   //
//=====================================================================//

scope IronMaiden

globals // Configuration Continued

    private integer spellID='A005'
    //'Iron Maiden' Ability ID
    private integer dummyID='A006'
     //'IronMaidenLvl' Ability rawcode (note: item ability)
     //Note: Make sure this ability has the same amount of levels as the real ability
     // as it is used to keep track of the level of the curse on units.     
    private integer buffID='B002'
    //rawcode for the 'Iron Maiden' buff     
    private real damageReturn=1.
    //Damage return per level (ie damageReturn*level)    
    private integer AoE=200
    //The AoE the same as the level 1 AoE in the 'Iron Maiden' ability (make same as 'Iron Maid' ability)    
    private integer AoEIncrease=50
    //The amount of AoE added per level (make same as 'Iron Maid' ability)
    private string HitArt="Abilities\\Weapons\\FlyingMachine\\FlyingMachineImpact.mdl"
    //Art when they damage themselves
    
    //Note: Most of the Data for the spell (including duration) is set in the ability 'Iron Maiden'
    
endglobals // End Configuration

function Trig_IronMaiden_Actions takes nothing returns nothing
    if GetUnitAbilityLevel(GetTriggerUnit(),'Aloc')==0 then // locust
        call TriggerRegisterUnitEvent(gg_trg_IronMaiden,GetTriggerUnit(),EVENT_UNIT_DAMAGED)
    endif
endfunction



function Trig_IronMaiden_Cast_Conditions takes nothing returns boolean
    return GetSpellAbilityId()==spellID
endfunction

function Trig_IronMaiden_Cast_Actions takes nothing returns nothing
    local location tloc=GetSpellTargetLoc()
    local group g=CreateGroup()
    local unit u
    
    call GroupEnumUnitsInRange(g,GetLocationX(tloc),GetLocationY(tloc),AoE+(AoEIncrease*GetUnitAbilityLevel(GetTriggerUnit(),spellID)),null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u==null
        if IsUnitEnemy(u,GetOwningPlayer(GetTriggerUnit()))==true and IsUnitType(u,UNIT_TYPE_STRUCTURE)==false and GetUnitState(u,UNIT_STATE_LIFE)>0 then
            call UnitAddAbility(u,dummyID)
            call SetUnitAbilityLevel(u,dummyID,GetUnitAbilityLevel(GetTriggerUnit(),spellID))
        endif
            call GroupRemoveUnit(g,u)
    endloop
    call DestroyGroup(g)
    set g = null
    set u=null
    call RemoveLocation(tloc)
    set tloc=null
endfunction



function Trig_IronMaiden_Mapstart_Actions takes nothing returns nothing
    local unit u
    local group g=CreateGroup()
    
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u==null
        if IsUnitType(u,UNIT_TYPE_STRUCTURE)==false and GetUnitState(u,UNIT_STATE_LIFE)>0 then
            call TriggerRegisterUnitEvent(gg_trg_IronMaiden,u,EVENT_UNIT_DAMAGED)
        endif
        call GroupRemoveUnit(g,u)
    endloop
    
    call DestroyGroup(g)
    set g = null
endfunction



function Trig_IronMaiden_Dmg_Conditions takes nothing returns boolean
    return GetUnitAbilityLevel(GetEventDamageSource(),buffID)>0 and GetOwningPlayer(GetEventDamageSource())!=GetOwningPlayer(GetTriggerUnit())
endfunction

function Trig_IronMaiden_Dmg_Actions takes nothing returns nothing
    call UnitDamageTarget(GetEventDamageSource(),GetEventDamageSource(), GetEventDamage()*(damageReturn*GetUnitAbilityLevel(GetEventDamageSource(),dummyID)),true,false,ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL,null)  
    call AddSpecialEffectTarget(HitArt,GetEventDamageSource(),"chest")
endfunction

endscope

function InitTrig_IronMaiden takes nothing returns nothing
    local trigger gg_trg_IronMaiden_Events=CreateTrigger()
    local trigger gg_trg_IronMaiden_Cast=CreateTrigger()
    local trigger gg_trg_IronMaiden_Mapstart=CreateTrigger()
    set gg_trg_IronMaiden=CreateTrigger(  )
    call TriggerAddCondition( gg_trg_IronMaiden, Condition( function Trig_IronMaiden_Dmg_Conditions ) )
    call TriggerAddAction( gg_trg_IronMaiden, function Trig_IronMaiden_Dmg_Actions )
    call TriggerRegisterEnterRectSimple( gg_trg_IronMaiden_Events, GetPlayableMapRect() )
    call TriggerAddAction( gg_trg_IronMaiden_Events, function Trig_IronMaiden_Actions )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_IronMaiden_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_IronMaiden_Cast, Condition( function Trig_IronMaiden_Cast_Conditions ) )
    call TriggerAddAction( gg_trg_IronMaiden_Cast, function Trig_IronMaiden_Cast_Actions )
    call TriggerRegisterTimerEventSingle( gg_trg_IronMaiden_Mapstart, 1 )
    call TriggerAddAction( gg_trg_IronMaiden_Mapstart, function Trig_IronMaiden_Mapstart_Actions )
    set gg_trg_IronMaiden_Events=null
    set gg_trg_IronMaiden_Cast=null
    set gg_trg_IronMaiden_Mapstart=null
endfunction


Map is now updated with all spells in JESP standard.
 

Attachments

  • Diablo Spellpack.w3x
    77.7 KB · Views: 742

Doom-Angel

Jass User (Just started using NewGen)
Reaction score
167
nice job though as far as i remember Iron maiden was the paladin's skill which caused like a lightning to come up from the sky isn't it like that?
anyway +Rep

Edit: sorry i can't....
 

hell_knight

Playing WoW
Reaction score
126
nice job though as far as i remember Iron maiden was the paladin's skill which caused like a lightning to come up from the sky isn't it like that?
anyway +Rep

Edit: sorry i can't....

IronMaiden was a badass necro curse that reflected damage you did.
Nice spells +rep

The paladin one ,was somethin else cant even remember its name
 

Cohadar

master of fugue
Reaction score
209
Did you post this spells before at some place?
I think this is not the first time I saw that Poison Javelin.
 

emootootoo

Top Banana
Reaction score
51
as far as i remember Iron maiden was the paladin's skill which caused like a lightning to come up from the sky

Fist of Heavens! That ability that no-one ever uses because they either make a hammerdin or smiter. :(

Did you post this spells before at some place?
I think this is not the first time I saw that Poison Javelin.

Yeah I was posting them up in JASS help, asking how they can be improved.
 

Doom-Angel

Jass User (Just started using NewGen)
Reaction score
167
oh right it was Fist of Heavens....
well i guess everyone makes mistake :p
 

Sim

Forum Administrator
Staff member
Reaction score
534
Nice work!

There are a few issues though, but generally speaking these spells are almost worthy of approval. ;)

Blessed Hammer:

None of the following changes are obligatory, though they would definitely improve the spell ;)

  • The hammers should last longer. In Diablo 2 they rotate for a much longer period of time.
  • Try to get the song of a Blessed Hammer summon in Diablo 2 and implement it. It would really reproduce the spell perfectly! Shouldn't be too hard to get with an MPQ Extractor. If it works with Starcraft it must work with Diablo 2.

Hurricane:

  • I believe in Diablo 2 there's no tornadoes turning around :p What you could do is to create several trails of wind instead, as in D2 there are trails all around the hero, not just at the end of the Area of effect.
  • The damage should be done differently. Instead of say, 200 damage per second, it should be, say, 20 damage every 0.10 second. The total will remain 200 per second, though more... constant :)

Poison Javelin:

  • It always deals 10 damage per second, no matter the level. Should be 10x level.
  • Sometimes the unit isn't being poisoned. Especially when the target is close to the caster.

Iron Maiden:

  • If your goal is to recreate Diablo 2 spells, then the levels going up should increase the redirected damage, not the duration :)
  • In any case though, duration should be increased. (Balancing issues are not of concern though... Do this at the end or not at all)

Well, these spells are great anyhow, it's just that if want to recreate diablo 2 spells, then recreate them for real ;)

Three cheers!
 

emootootoo

Top Banana
Reaction score
51
Blessed Hammer:
The hammers should last longer. In Diablo 2 they rotate for a much longer period of time.
I admit, they do. But I personally prefer them not lasting as long. I'll increase it a tiny bit just for you though. :p (i figured people would just change the butt-load of constants I made for them which gives tonnes of freedom with changing the spell, it's basically a template!)
Try to get the song of a Blessed Hammer summon in Diablo 2 and implement it. It would really reproduce the spell perfectly! Shouldn't be too hard to get with an MPQ Extractor. If it works with Starcraft it must work with Diablo 2.
Good idea, I'll do that now, it'll probably add like 30kb to the map though. :(

Hurricane:
[*]I believe in Diablo 2 there's no tornadoes turning around :p What you could do is to create several trails of wind instead, as in D2 there are trails all around the hero, not just at the end of the Area of effect.
Uh.. Mr. perfectionist. If you make me a model that does that I'll be happy to add it. :) (the twisters are what make the circle of wind lol)

[*]The damage should be done differently. Instead of say, 200 damage per second, it should be, say, 20 damage every 0.10 second. The total will remain 200 per second, though more... constant :)
In D2 I remember it damaging every 1 second or so... maybe I'm wrong? But anyway, they can just change the periodic global to any multiple of 0.05 and the damage global if they are desperate. (i'll make it 0.5)

Poison Javelin:
[*]It always deals 10 damage per second, no matter the level. Should be 10x level.
Thanks for pointing that out, completely forgot about the poison damage leveling lol.

[*]Sometimes the unit isn't being poisoned. Especially when the target is close to the caster.
Righto, I'll make the javelin start closer and make the clouds AoE bigger.

Iron Maiden:
If your goal is to recreate Diablo 2 spells, then the levels going up should increase the redirected damage, not the duration :)
[Solved in Post #9]I would love to make it level but, I don't have any idea how to do that with the way I set up the triggers. I can't attach a struct to affected units with the ability level, because it may intefere with existing unit data. I also don't know of any ways to get an ability level based off a buff. So really.. I have no idea, if you have one I'd be happy to add this.

[*]In any case though, duration should be increased. (Balancing issues are not of concern though... Do this at the end or not at all)
Yeah, you do that in the actual ability.[/QUOTE]

Well, these spells are great anyhow, it's just that if want to recreate diablo 2 spells, then recreate them for real ;)
Three cheers!

Thanks, I'll add an edit to the top of my first post once I've updated the spellpack.

To sum it up (this is what is in the update):

CAN:
  • Make hammers last longer
  • Add hammer sound
  • Make Hurricane periodic faster
  • Fix poison javelin poison leveling
  • Fix poison hitting
  • Iron Maiden Level-up - doing right now
  • Make Hurricane wind effects without twisters

CAN'T:
  • This list is gone now :)
 

Somatic

You can change this now in User CP.
Reaction score
84
Iron maiden % can be up if you were to attach a dummy ability which reflects the caster's level of iron maiden when cast. And check for the ability of that dummy ability, and you can easily remove the ability when the duration is up.

None the less, good Spell pack +rep =)
 

emootootoo

Top Banana
Reaction score
51
Iron maiden % can be up if you were to attach a dummy ability which reflects the caster's level of iron maiden when cast. And check for the ability of that dummy ability, and you can easily remove the ability when the duration is up.

None the less, good Spell pack +rep =)

You rock. I'll do that right now. I don't think the 3 hours sleep has helped my brain come up with an idea like that. :p

Edit: OK, added it and updated the first post :)
 

Sim

Forum Administrator
Staff member
Reaction score
534
> i figured people would just change the butt-load of constants I made for them which gives tonnes of freedom

My mistake. Don't bother doing it, although make sure that changing those constants actually work.

> Uh.. Mr. perfectionist. If you make me a model that does that I'll be happy to add it. :) (the twisters are what make the circle of wind lol)

It's not a matter of perfection, it's a matter of recreation.

Do you want real feedbacks? You just had to tell if you didn't, heh ;)

Now, there is a way. Plus, no need to make a model!

Here's a simple line of code to further explain my thoughts...

JASS:
call SetUnitVertexColor( tempu[0], 255, 255, 255, 0 )


Here's what it becomes when added into your trigger:

JASS:
    set x=GetLocationX(GetUnitLoc(caster))+hRadius*Cos(angle-90*bj_DEGTORAD)
    set y=GetLocationY(GetUnitLoc(caster))+hRadius*Sin(angle-90*bj_DEGTORAD)
    set tempu[0]=CreateUnit(GetOwningPlayer(caster),dummyunitID,x,y,0)
    call SetUnitVertexColor( tempu[0], 255, 255, 255, 0 )
    set hD.hUnit[0]=tempu[0]
    set hD.hAngle[0]=angle-90

    set x=GetLocationX(GetUnitLoc(caster))+hRadius*Cos(angle+90*bj_DEGTORAD)
    set y=GetLocationY(GetUnitLoc(caster))+hRadius*Sin(angle+90*bj_DEGTORAD)
    set tempu[1]=CreateUnit(GetOwningPlayer(caster),dummyunitID,x,y,0)
    call SetUnitVertexColor( tempu[1], 255, 255, 255, 0 )
    set hD.hUnit[1]=tempu[1]
    set hD.hAngle[1]=angle+90


No more tornado. Only a gust of wind will appear!

Now, to make it look further more like in D2...

Add more invisible tornadoes turning around the hero, so it becomes a real hurricane. I'd say make a total of 6 tornadoes around the hero, 3 per "level".

2 tornadoes at 200 range, 2 more at 350 range and the final 2s at 500 range.

Or something like that.

Or, even better, make the number of tornadoes spawning based upon the area of effect constant? It would further improve the customization of the spell.

> In D2 I remember it damaging every 1 second or so... maybe I'm wrong?

Even if they did, when you can "optimize" something... why not do it? ;)

------

Do the changes in your list, plus the one under "CAN'T", and I will approve this spellpack.

I must say once again that these are well done. Keep it up!
 

emootootoo

Top Banana
Reaction score
51
No more tornado. Only a gust of wind will appear!

Done

Or, even better, make the number of tornadoes spawning based upon the area of effect constant? It would further improve the customization of the spell.

and done.

First post updated.
 

Kenny

Back for now.
Reaction score
202
first off, these skills are almost dead on, they are amazing, i especially love the new hurricane, after those last few changes you made.

one thing i need to point out, the blessed hammer was so good that it made me want to spam the ability, so i did. then i realised after a little while of spamming that some of the hammers froze when the spell was cast. The rest of the hammers were as normal but the hammer that were created from the last use of the spell sometimes from and used constantly. It is easy to see if you spam the hammer ability on both heroes at the same time.

Hope that isn't just my imagination. :p

anyway these spells are awesome, very detailed and very precise. good work.

-kenny-
 

emootootoo

Top Banana
Reaction score
51
one thing i need to point out, the blessed hammer was so good that it made me want to spam the ability, so i did. then i realised after a little while of spamming that some of the hammers froze when the spell was cast. The rest of the hammers were as normal but the hammer that were created from the last use of the spell sometimes from and used constantly. It is easy to see if you spam the hammer ability on both heroes at the same time.

Yeah, I just tested that out. Seems like if a crapload of hammers are made at once it starts bugging, but gets back on track again if you wait for a couple of hammers to finish spinning.

I really don't have a clue why that is happening. Maybe because it's a spell with a 0.1 cooldown that uses timers? Maybe someone like Dax with a lot more experience than me can explain this? :p

I've done some testing and figured out the problem is with the unitdata not attaching or something weird like that.

I just made a post in the JASS Help forum so hopefully I can get a solution.

http://www.thehelper.net/forums/showthread.php?t=76339
 

Technomancer

New Member
Reaction score
14
I was running into the same problem when testing TTS. My issue was that some of my attached structs were being destroyed in my timer function, I forgot the particulars, therefore resulting in everything in that struct returning 0.

local real distance=DistanceBetweenPoints(HammerLoc,BHD.BHloc); check BHloc to make sure that there is a valid location there.


I remember now. My remove function was using a counter for my arrays, and I was using Num_Units, instead of Num_Units - 1, to get the last item in the array. Obviously, might not be the same for you, but if it is then pwnsauce.
 

emootootoo

Top Banana
Reaction score
51
I'm using CSData and structs though, and it works most of the time, until there are like over 30 hammers spinning around.

So I can't really see that being the problem :(
 

Doom-Angel

Jass User (Just started using NewGen)
Reaction score
167
i don't think that in the original diablo you could have reached 30 hammers in a row and even if you had high cast rate you still would be able to reach 20 hammers mabye you should have made a higher cooldown
 

emootootoo

Top Banana
Reaction score
51
With the basic values I put in for the spell, a unit can only get like 10 hammers at most going at once, if that.

But if you have like 3 heroes all doing it at the same time non-stop it will probably still bug at some point.. or if someone decides to make the hammers last twice as long as they do now.

It wouldn't be a problem if only one hero used it with the values that are already set or close to them.

Edit: The_Kingpin solved my problem for me in the Jass Help forums, I wasn't nulling all my handles. I will now update every spell in the pack and when this is complete I will update the first post of this thread.

Edit2: First post is now updated with changes
 

emjlr3

Change can be a good thing
Reaction score
395
neat spells, I like, seems like coding issues are under control here, so I will not review it
 
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