Spellpack Ragnarok Online Hero - Assassin

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
Out of pure boredom, I figured I might be able to quench my thirst for playing Ragnarok Online by simply making a few spells from the game, and this be the result.

The abilities I made are Thief/Assassin class abilities; Sonic Blow, Hide, Grimtooth and Venom Splasher.

Requirements: NewGen World Editor
GUI/JASS: JASS
Lagless: Yes
Leakless: Should be (might've missed something)

Note: Screenshots do not do these spells any justice. Try them out in game to see how they actually look like.

Sonic Blow (Description is shown in screenshot):

Assassin1.jpg

Code:

JASS:
scope SonicBlow initializer Init
    
    private keyword Data
    
    globals
        private constant integer SpellAID = 'A003'                //Rawcode of the Sonic Blow ability
        private constant integer StunAID = 'A004'                 //Rawcode of the stun ability
        private constant integer DummyID = 'u001'                 //Rawcode of your dummy unit
        private constant integer Strikes = 8                      //Amount of attacks dealt
        private constant real DelayBetweenStrikes = .25           //Interval in seconds between damage
        private constant real TotalDegreeSpin = 720.              //Total amount of degrees the target is turned during the spell
        private constant real Damage = 120.                       //Primary damage, deals this amount in level 1
        private constant real AddDamage = 80.                     //Additional damage per level above 1
        private constant real StunChance = 50.                    //Primary chance to stun, this applies on level 1
        private constant real AddStunChance = 25.                 //Additional chance to stun per level above 1
        private constant real AnimationSpeed = 5.                 //Animation speed percent (of default). 2. = 200% of default speed
        private constant real Interval = 0.03125                  //Timer interval, no reason at all to change this unless you experience great amounts of lag
        private constant string StunOrder = "thunderbolt"         //The order ID of your stun ability
        private constant string CastSFX = "Abilities\\Spells\\Items\\AIam\\AIamTarget.mdl"                             //Special effect applied on target on spellcast
        private constant string StrikeSFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"     //Special effect applied on target when the spell hits
        private constant attacktype AttackType = ATTACK_TYPE_NORMAL         //Attack type of the spell's damage
        private constant damagetype DamageType = DAMAGE_TYPE_UNIVERSAL      //Damage type of the spell's damage
        private constant weapontype WeaponType = WEAPON_TYPE_WHOKNOWS       //Weapon type of the spell's damage
        
        //Do not change anything below here unless you know what you're doing
        private Data array D
        
        private timer T = CreateTimer()
        private integer N = 0
    endglobals
    
    private function DamageCalc takes integer i returns real
        return Damage + AddDamage * (i - 1)
    endfunction
    
    private function StunChanceCalc takes integer i returns real
        return StunChance + AddStunChance * (i - 1)
    endfunction
    
    private struct Data
        unit caster
        unit target
        integer count
        real damage
        real ticks
        real angle
        real addangle
        static method create takes unit u, unit c returns Data
            local Data d = Data.allocate()
            local integer i = GetUnitAbilityLevel(u, SpellAID)
            local real r = StunChanceCalc(i)
            local real x = GetUnitX(c)
            local real y = GetUnitY(c)
            local unit dummy
            
            set d.caster = u
            set d.target = c
            set d.count = 0
            set d.damage = DamageCalc(i) / Strikes
            set d.ticks = 0.
            set d.angle = GetUnitFacing(c)
            set d.addangle = (TotalDegreeSpin / Strikes)
            
            call SetUnitTimeScale(d.caster, AnimationSpeed)
            call PauseUnit(d.target, true)
            call DestroyEffect(AddSpecialEffect(CastSFX, x, y))
            if GetRandomInt(1, 100) <= R2I(r) then
                set dummy = CreateUnit(GetOwningPlayer(u), DummyID, x, y, 0.)
                call UnitAddAbility(dummy, StunAID)
                call SetUnitAbilityLevel(dummy, StunAID, i)
                call IssueTargetOrder(dummy, StunOrder, c)
                call UnitApplyTimedLife(dummy, 'BTLF', 2.)
            endif
            
            set dummy = null
            
            return d
        endmethod
    endstruct
    
    private function Callback takes nothing returns nothing
        local integer i = N
        local real r
        local real x
        local real y
        local Data d
        loop
            exitwhen i <= 0
            set d = i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
            set d.ticks = d.ticks + Interval
            set x = GetUnitX(d.target)
            set y = GetUnitY(d.target)
            if d.ticks &gt; Strikes * DelayBetweenStrikes then
                call PauseUnit(d.target, false)
                call SetUnitTimeScale(d.caster, 1.)
                call d.destroy()
                set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                set N = N - 1
                if N == 0 then
                    call PauseTimer(T)
                endif
            else
                set r = d.ticks - I2R(R2I(d.ticks / DelayBetweenStrikes)) * DelayBetweenStrikes
                if r == 0 then
                    set d.count = d.count + 1
                    
                    call SetUnitFacing(d.target, d.angle - d.addangle * d.count)
                    if GetWidgetLife(d.target) &gt; .405 then
                        call UnitDamageTarget(d.caster, d.target, d.damage, true, false, AttackType, DamageType, WeaponType)
                        call DestroyEffect(AddSpecialEffect(StrikeSFX, x, y))
                    endif
                endif
            endif
            
            set i = i - 1
        endloop
    endfunction
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SpellAID
    endfunction
    
    private function Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local unit t = GetSpellTargetUnit()
        local Data d = Data.create(u, t)
        
        set N = N + 1
        set N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = d
        if N == 1 then
            call TimerStart(T, Interval, true, function Callback)
        endif
        
        set u = null
        set t = null
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig, Condition(function Conditions))
        call TriggerAddAction(trig, function Actions)
    endfunction
endscope

Hide (Description is shown in screenshot):

Assassin3.jpg

Code:

JASS:
scope Hide initializer Init
    
    private keyword Data
    
    globals
        private constant integer SpellAID = &#039;A001&#039;          //Rawcode of the Hide ability
        private constant real Duration = 20.                //Primary duration, also level 1 duration. If this together with &quot;AddDuration&quot; is set to 0 there will be no duration.
        private constant real AddDuration = 15.             //Additional duration per level above 1. If this together with &quot;Duration&quot; is set to 0 there will be no duration.
        private constant real CheckDist = 10.               //Amount of distance that cancels the effect. No need to change this unless you want the hero to be able to move slightly
        private constant real Interval = 0.03125            //The timer interval, no need to change this at all unless you experience lags
        
        //Do not change anything below here unless you know what you&#039;re doing
        private Data array D
        
        private timer T = CreateTimer()
        private trigger Tr = CreateTrigger()
        private group G = CreateGroup()
        private integer N = 0
    endglobals
    
    private function DurationCalc takes integer i returns real
        return Duration + AddDuration * (i - 1)
    endfunction
    
    private struct Data
        unit u
        real x
        real y
        real cdur
        real mdur
        static method create takes unit u returns Data
            local Data d = Data.allocate()
            
            set d.u = u
            set d.x = GetUnitX(u)
            set d.y = GetUnitY(u)
            set d.cdur = 0.
            set d.mdur = DurationCalc(GetUnitAbilityLevel(d.u, SpellAID))
            if d.mdur == 0 then
                set d.mdur = 0x100000
            endif
            
            call UnitAddAbility(d.u, AssassinSetup_HideInvisID)
            call GroupAddUnit(G, d.u)
            
            return d
        endmethod
        
        method onDestroy takes nothing returns nothing
            call UnitRemoveAbility(.u, AssassinSetup_HideInvisID)
            call GroupRemoveUnit(G, .u)
        endmethod
    endstruct
    
    private function TrigCallback takes nothing returns boolean
        local integer i = N
        local unit u = GetTriggerUnit()
        local Data d
        if IsUnitInGroup(u, G) == true and GetIssuedOrderId() != OrderId(AssassinSetup_GrimtoothOrder) then
            loop
                exitwhen i &lt;= 0
                set d = i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                if GetTriggerUnit() == d.u then
                    call d.destroy()
                    set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                    set N = N - 1
                    if N == 0 then
                        call PauseTimer(T)
                    endif
                endif
                
                set i = i - 1
            endloop
        endif
        
        return false
    endfunction
    
    private function Callback takes nothing returns nothing
        local integer i = N
        local real dx
        local real dy
        local Data d
        loop
            exitwhen i &lt;= 0
            set d = i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
            set d.cdur = d.cdur + Interval
            if d.cdur &lt; d.mdur then
                set dx = GetUnitX(d.u) - d.x
                set dy = GetUnitY(d.u) - d.y
                if SquareRoot(dx * dx + dy * dy) &gt;= CheckDist then
                    call d.destroy()
                    set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                    set N = N - 1
                    if N == 0 then
                        call PauseTimer(T)
                    endif
                endif
            else
                call d.destroy()
                set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                set N = N - 1
                if N == 0 then
                    call PauseTimer(T)
                endif
            endif
            
            set i = i - 1
        endloop
    endfunction
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SpellAID
    endfunction
    
    private function Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local Data d = Data.create(u)
        
        set N = N + 1
        set N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = d
        if N == 1 then
            call TimerStart(T, Interval, true, function Callback)
        endif
        
        set u = null
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig, Condition(function Conditions))
        call TriggerAddAction(trig, function Actions)
        
        call TriggerRegisterAnyUnitEventBJ(Tr, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
        call TriggerRegisterAnyUnitEventBJ(Tr, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
        call TriggerRegisterAnyUnitEventBJ(Tr, EVENT_PLAYER_UNIT_ISSUED_ORDER)
        call TriggerAddCondition(Tr, Condition(function TrigCallback))
    endfunction
endscope

Grimtooth (Description is shown in screenshot):

Assassin2.jpg

Code:

JASS:
scope Grimtooth initializer Init
    
    private keyword Data
    
    globals
        private constant integer SpellAID = &#039;A000&#039;              //Rawcode of the Grimtooth ability
        private constant real Damage = 35.                      //Primary damage, deals this amount in level 1
        private constant real AddDamage = 35.                   //Additional damage added per leve above 1
        private constant real AoE = 250.                        //The area of effect for the spell
        private constant real Interval = 0.03125                //The timer interval, no need to change this at all unless you experience lag
        private constant real SFXInterval = .1                  //The interval in seconds in which the spell moves forward, the lower the amount the faster the spell finishes
        private constant real DistBetweenSFX = 75.              //Distance between the effects
        private constant string SFX = &quot;Abilities\\Spells\\Undead\\Impale\\ImpaleMissTarget.mdl&quot;     //Special effects spawned during the spell
        private constant attacktype AttackType = ATTACK_TYPE_NORMAL     //Attack type of the spell&#039;s damage
        private constant damagetype DamageType = DAMAGE_TYPE_NORMAL     //Damage type of the spell&#039;s damage
        private constant weapontype WeaponType = WEAPON_TYPE_WHOKNOWS   //Weapon type of the spell&#039;s damage
        
        //Do not change anything below here unless you know what you&#039;re doing
        private Data array D
        
        private timer T = CreateTimer()
        private group G = CreateGroup()
        private integer N = 0
        private integer TempI
    endglobals
    
    private function DamageCalc takes integer i returns real
        return Damage + AddDamage * (i - 1)
    endfunction
    
    private struct Data
        unit caster
        integer count
        integer amount
        real x
        real y
        real cos
        real sin
        real check
        real tick
        real damage
        group safegroup
        static method create takes unit u, real x, real y returns Data
            local Data d = Data.allocate()
            local real ux = GetUnitX(u)
            local real uy = GetUnitY(u)
            local real dx = x - ux
            local real dy = y - uy
            local real angle = Atan2(y - uy, x - ux)
            
            set d.caster = u
            set d.count = 0
            set d.amount = R2I(SquareRoot(dx * dx + dy * dy) / DistBetweenSFX + .5)
            set d.x = ux
            set d.y = uy
            set d.cos = Cos(angle)
            set d.sin = Sin(angle)
            set d.check = SFXInterval / Interval
            set d.tick = 0.
            set d.damage = DamageCalc(GetUnitAbilityLevel(u, SpellAID))
            set d.safegroup = CreateGroup()
            
            return d
        endmethod
        method onDestroy takes nothing returns nothing
            call DestroyGroup(.safegroup)
        endmethod
    endstruct
    
    private function GroupFilter takes nothing returns boolean
        local unit u = GetFilterUnit()
        local Data d = TempI<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
        if IsUnitEnemy(u, GetOwningPlayer(d.caster)) == true and IsUnitType(u, UNIT_TYPE_STRUCTURE) != true and GetWidgetLife(u) &gt; .405 and IsUnitInGroup(u, d.safegroup) != true then
            call UnitDamageTarget(d.caster, u, d.damage, true, false, AttackType, DamageType, WeaponType)
            call GroupAddUnit(d.safegroup, u)
        endif
        
        set u = null
        
        return false
    endfunction
    
    private function Callback takes nothing returns nothing
        local integer i = N
        local real x
        local real y
        local Data d
        loop
            exitwhen i &lt;= 0
            set d = i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
            set d.tick = d.tick + 1
            if d.tick &gt;= d.check * (d.count + 1) then
                set d.count = d.count + 1
                set x = d.x + DistBetweenSFX * d.count * d.cos
                set y = d.y + DistBetweenSFX * d.count * d.sin
                set TempI = i
                
                call DestroyEffect(AddSpecialEffect(SFX, x, y))
                call GroupEnumUnitsInRange(G, x, y, AoE, Filter(function GroupFilter))
                if d.count &gt;= d.amount then
                    call d.destroy()
                    set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                    set N = N - 1
                    if N == 0 then
                        call PauseTimer(T)
                    endif
                endif
            endif
            
            set i = i - 1
        endloop
    endfunction
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SpellAID and GetUnitAbilityLevel(GetTriggerUnit(), AssassinSetup_HideInvisID) &gt; 0
    endfunction
    
    private function Actions takes nothing returns nothing
        local location l = GetSpellTargetLoc()
        local Data d = Data.create(GetTriggerUnit(), GetLocationX(l), GetLocationY(l))
        
        set N = N + 1
        set N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = d
        if N == 1 then
            call TimerStart(T, Interval, true, function Callback)
        endif
        
        call RemoveLocation(l)
        
        set l = null
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig, Condition(function Conditions))
        call TriggerAddAction(trig, function Actions)
    endfunction
endscope

Venom Splasher (Description is shown in screenshot):

Assassin4.jpg

Assassin5.jpg

Code:

JASS:
scope VenomSplasher initializer Init
    
    private keyword Data
    
    globals
        private constant integer SpellAID = &#039;A005&#039;              //Rawcode of the Venom Splasher ability
        private constant integer Delay = 5                      //Primary countdown, used on level 1
        private constant integer DelayReduct = 1                //Countdown reduction per level above 1
        private constant integer Red = 100                      //The Red value of the spawned text (ranges from 0 to 255)
        private constant integer Green = 0                      //The Green value of the spawned text (ranges from 0 to 255)
        private constant integer Blue = 175                     //The Blue value of the spawned text (ranges from 0 to 255)
        private constant integer Alpha = 0                      //The Alpha value of the spawned text (ranges from 0 to 255)
        private constant real TextSize = 20.                    //The size of the spawned text
        private constant real HealthLimit = 75.                 //The percentual amount of max health the target must be below for the effects to take place. Set this to 100. is you want the spell to work all the time
        private constant real AoE = 250.                        //The area of effect of the explosion damage
        private constant real Damage = 350.                     //Primary damage, deals this amount on level 1
        private constant real AddDamage = 150.                  //Additional damage per level above 1
        private constant real Interval = 0.03125                //Timer interval, no need to change this at all unless you experience lag
        private constant string ExplodeSFX = &quot;Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl&quot;       //The special effect spawned on explosion
        private constant attacktype AttackType = ATTACK_TYPE_NORMAL     //Attack type of the spell&#039;s damage
        private constant damagetype DamageType = DAMAGE_TYPE_POISON     //Damage type of the spell&#039;s damage
        private constant weapontype WeaponType = WEAPON_TYPE_WHOKNOWS   //Weapon type of the spell&#039;s damage
        
        //Do not change anything below here unless you know what you&#039;re doing
        private Data array D
        
        private timer T = CreateTimer()
        private group G = CreateGroup()
        private integer N = 0
        private integer TempI
        private integer C
    endglobals
    
    private function DelayCalc takes integer i returns integer
        return Delay - DelayReduct * (i - 1)
    endfunction
    
    private function DamageCalc takes integer i returns real
        return Damage + AddDamage * (i - 1)
    endfunction
    
    function QuickText takes unit u, string text, integer red, integer green, integer blue, integer alpha, real size returns nothing
        local texttag tag = CreateTextTag()
        call SetTextTagText(tag, text, size * 0.0023)
        call SetTextTagPosUnit(tag, u, 25.)
        call SetTextTagVisibility(tag, true)
        call SetTextTagColor(tag, red, green, blue, alpha)
        call SetTextTagVelocity(tag, 0, 0.04)
        call SetTextTagPermanent(tag, false)
        call SetTextTagFadepoint(tag, 0)
        call SetTextTagLifespan(tag, 4)
        
        set tag = null
    endfunction
    
    private struct Data
        unit caster
        unit target
        integer dur
        integer curdur
        real damage
        real ticks
        static method create takes unit u, unit c returns Data
            local Data d = Data.allocate()
            local integer i = GetUnitAbilityLevel(u, SpellAID)
            
            set d.caster = u
            set d.target = c
            set d.dur = DelayCalc(i)
            set d.curdur = d.dur
            set d.damage = DamageCalc(i)
            set d.ticks = 0.
            
            call QuickText(d.target, I2S(d.curdur), Red, Green, Blue, Alpha, TextSize)
            
            return d
        endmethod
    endstruct
    
    private function GroupFilter takes nothing returns boolean
        local unit u = GetFilterUnit()
        local Data d = TempI<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
        if IsUnitEnemy(u, GetOwningPlayer(d.caster)) == true and IsUnitType(u, UNIT_TYPE_STRUCTURE) != true and GetWidgetLife(u) &gt; .405 then
            set C = C + 1
            return true
        endif
        
        return false
    endfunction
    
    private function GroupCallback takes nothing returns nothing
        local Data d = TempI<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
        call UnitDamageTarget(d.caster, GetEnumUnit(), d.damage / C, true, false, AttackType, DamageType, WeaponType)
    endfunction
    
    private function Callback takes nothing returns nothing
        local integer i = N
        local real r
        local real x
        local real y
        local Data d
        loop
            exitwhen i &lt;= 0
            set d = i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
            set d.ticks = d.ticks + Interval
            set r = d.ticks - I2R(R2I(d.ticks / 1)) * 1
            if r &lt; 0 then
                set r = r + 1
            endif
            if r == 0 then
                set d.curdur = d.curdur - 1
                if d.curdur &gt; 0 then
                    call QuickText(d.target, I2S(d.curdur), Red, Green, Blue, Alpha, TextSize)
                else
                    set C = 0
                    set TempI = i
                    set x = GetUnitX(d.target)
                    set y = GetUnitY(d.target)
                    call GroupEnumUnitsInRange(G, x, y, AoE, Filter(function GroupFilter))
                    call ForGroup(G, function GroupCallback)
                    call GroupClear(G)
                    call DestroyEffect(AddSpecialEffect(ExplodeSFX, x, y))
                    call d.destroy()
                    set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
                    set N = N - 1
                    if N == 0 then
                        call PauseTimer(T)
                    endif
                endif
            endif
            
            set i = i - 1
        endloop
    endfunction
    
    private function Conditions takes nothing returns boolean
        local unit u = GetSpellTargetUnit()
        local real r = (GetUnitState(u, UNIT_STATE_LIFE) / GetUnitState(u, UNIT_STATE_MAX_LIFE)) * 100
        local boolean b = false
        if GetSpellAbilityId() == SpellAID and r &lt;= HealthLimit then
            set b = true
        endif
        
        set u = null
        
        return b
    endfunction
    
    private function Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local unit t = GetSpellTargetUnit()
        local Data d = Data.create(u, t)
        
        set N = N + 1
        set N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = d
        if N == 1 then
            call TimerStart(T, Interval, true, function Callback)
        endif
        
        set u = null
        set t = null
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig, Condition(function Conditions))
        call TriggerAddAction(trig, function Actions)
    endfunction
endscope
_______________________________________________________________

In b4 Flare:
JASS:
                    set i<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" /> = N<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />

Happy smiles :D
 

Attachments

  • RO Spellpack - Assassin v1.0 by Larcenist.w3x
    58.2 KB · Views: 314

Ryuu

I am back with Chocolate (:
Reaction score
64
Actually not, I was just commenting :p
These spells are quite good, because I can see the similarity in them and the original RO spells.

+rep
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
RO spells in general ain't that very complex, and I wanted to keep these as close to the originals as possible. I dare say the outcome is better than I expected (especially considering Sonic Blow).
 

Deviruchi

New Member
Reaction score
5
can u pls do wizard skills? like storm gust or jupitel thunder?

anyway nicely done on the assassin spells. :D
 

Flare

Stops copies me!
Reaction score
662
I see you updated to make your constant naming a bit more consistent :rolleyes:

JASS:
set d.mdur = 0x100000

1) Ahm... normal number for the normal peoples?
2) Constant?

JASS:
//
            local real dx = x - ux
            local real dy = y - uy
            local real angle = Atan2(y - uy, x - ux)

You have dx and dy, use them?

JASS:
//
    function QuickText takes unit u, string text, integer red, integer green, integer blue, integer alpha, real size returns nothing
        local texttag tag = CreateTextTag()
        call SetTextTagText(tag, text, size * 0.0023)
        call SetTextTagPosUnit(tag, u, 25.)
        call SetTextTagVisibility(tag, true)
        call SetTextTagColor(tag, red, green, blue, alpha)
        call SetTextTagVelocity(tag, 0, 0.04)
        call SetTextTagPermanent(tag, false)
        call SetTextTagFadepoint(tag, 0)
        call SetTextTagLifespan(tag, 4)
        
        set tag = null
    endfunction

No configurable properties?

JASS:
set r = d.ticks - I2R(R2I(d.ticks / 1)) * 1

What's the /1 and *1 for?

JASS:
//
        local unit u = GetTriggerUnit()
        local unit t = GetSpellTargetUnit()
        local Data d = Data.create(u, t)

Why declare locals for the units? You're only calling GetTriggerUnit and GetSpellTargetUnit once, so it's just additional unnecessary work for you


Hmmm, you should know by now Larcenist that I'm a b*tch when it comes to configurables :p

Happy smiles
*salutes Vexorian* Thank you, kind sir, for making our coding so much more amusing
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
>I see you updated to make your constant naming a bit more consistent

Because of your constant whining, yes :p

>1) Ahm... normal number for the normal peoples?
>2) Constant?


Same answer for both: Why on earth would that be of any use for anyone? It's supposed to act as an substitute for infinity, so unless you stay hidden in 291 hours it'll kind of last forever.

>You have dx and dy, use them?

Because I wrote half the code first and added them afterwards? :D

>No configurable properties?


It creates a text of chosen color and size over a unit with a velocity, adding constants for everything would bring more confusion than happiness.

>What's the /1 and *1 for?

Quick replacements of a .5 as dividend in the modulo function?

>Why declare locals for the units? You're only calling GetTriggerUnit and GetSpellTargetUnit once, so it's just additional unnecessary work for you


I didn't have in mind to do all things in the create methods at first, though it ended up this way, so I didn't bother replacing them.

>Hmmm, you should know by now Larcenist that I'm a b*tch when it comes to configurables

If by that you mean constant whining on xfire, then yes.
 

Flare

Stops copies me!
Reaction score
662
Same answer for both: Why on earth would that be of any use for anyone? It's supposed to act as an substitute for infinity, so unless you stay hidden in 291 hours it'll kind of last forever.
... perhaps people would like some sort of upper limit (even if they don't want a 'reasonable' limit) :)

Because I wrote half the code first and added them afterwards?
Then what was the point of adding them :confused:

It creates a text of chosen color and size over a unit with a velocity, adding constants for everything would bring more confusion than happiness.
Constants rule! Anyway, if people don't understand how to modify the value to best effect, they should just leave that constant alone, or change it back to the previous value :p

Quick replacements of a .5 as dividend in the modulo function?
Can't really remember what the modulo function looks like, but I'll take your word for it, until I ever get around to looking at the function. Won't you just end up getting a real value for d.ticks, ending in .000 either way? i.e.
JASS:
d.ticks - I2R (R2I (d.ticks))

Suppose it's something to play around with sometime, and see what I manage to break :p
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
>... perhaps people would like some sort of upper limit (even if they don't want a 'reasonable' limit)

JASS:
        private constant real Duration = 20.                //Primary duration, also level 1 duration. If this together with &quot;AddDuration&quot; is set to 0 there will be no duration.


That line is not there for nothing.

>Then what was the point of adding them

I use them for the distance between points check, which I added in after the angle part.

>Constants rule! Anyway, if people don't understand how to modify the value to best effect, they should just leave that constant alone, or change it back to the previous value

I can't seem to figure out why anyone would want to change these (considering it'd require constant testings of the spell in order to even see the outcode), but if it helps you sleep at night I'll add them tomorrow.

>Can't really remember what the modulo function looks like, but I'll take your word for it, until I ever get around to looking at the function. Won't you just end up getting a real value for d.ticks, ending in .000 either way? i.e.

ModuloReal would be:

JASS:
A - I2R(R2I(A / B)) * B


In your example:

JASS:
d.ticks - I2R (R2I (d.ticks))


Say d.ticks = 0.5, the formula would give:

0.5 - I2R(R2I(0.5)) = 0.5 - (I2R(0)) = 0.5 - 0 = 0.5

So no, it doesn't always return 0.000
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top