HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Tormental Wrath

08-07-2009, 07:48 AM#1
Komaqtion
Hi!

I'm kinda new to this forum (Though have looked around in it for some time now, without posting) and I thought I'd post a spell I've made here.

Tormental Wrath
Any name ideas are welcome, though might not use them XD

This is actually the very first vJASS/JASS spell I've ever made (Yay me XD) so hope you like it :D

MUI/MPI: MUI
GUI/JASS/vJASS: vJASS

Requires: The spell-trigger itself
the XEbasic, XEfx, XEcollider and XEdamage libraries
the BoundSentinel library
JASS Newgen Pack version 5d
And finally, the patch 1.23b, or higher, for Warcraft 3.

Here are some screenshots :D

Screenies!







A small description of the spell:
Description

The hero will create a series of explosion around himself, before letting out small "balls" of fire, tumbling and dealing damage to enemies they come across! As a finish, explosions will appear when the balls get destroyed.

Level 1 - 75 damage on first explosion, 20 damage per second at the fire balls and lastly, 100 damage on the final explosion.

Level 2 - 100 damage on first explosion, 40 damage per second at the fire balls and lastly, 150 damage on the final explosion.

Level 3 - 125 damage on first explosion, 60 damage per second at the fire balls and lastly, 200 damage on the final explosion.




And here's the spells code:

Expand Tormental Wrath:

Please give much feedback, and tips both for this spell and future stuff :D

Changelog!


V 1.00 - Initial release!

V 1.10
¤ Changed "Range functions" to return real values instead of using I2R.
¤ Added a new constant, ANGLES, which configures how many angles the effects will show at.
¤ Added some new comments on the constants.
¤ Removed nulling triggers.

v 1.15
¤ Split the global block into two.
¤ Added constants for attack-type and damage-type.
¤ Added a constant to decide how many angles the effects will be created at.

V 1.20 - Major Update!
¤ New library replaces "Timed Handles".(Named "EAE" by kingkingyyk3, Thanks ALOT !!!)
¤ Now destroys dummy and special effect together, instead of the dummy had timed life.
¤ Using the new "EAE" library, now creates the last special effect at the right point.
¤ Fixed the spell not doing any damage, because the constants "LEVEL" didn't get set before the function for the damage and range. XD
¤ Instead of creating 16 groups inside the loop, it now creates 1 group each outside the loop in the 3 functions using them.
¤ Added/Changed some comments.

V 1.20b
¤ Fixed it to use the constant ANGLES correctly.

V 1.21
¤ DAMAGE_FACTOR is now a real.
¤ Uses global group instead of many local ones.
¤ Added another constant, "SLIDE_SPEED". Determines how much the moving effect is moved each 0.05 seconds.

V 1.22
¤ Updated Key Timers 2 to the latest version.
¤ Changed a typo in credits. Sorry, Jesus4Lyf XD

V 1.23
¤ Updated Key Timers to 1.7.0. :D
¤ Reduced the map size to half, lol.

V 1.23b
¤ Updated Key Timer 2 again. XD

V 1.24
¤ Fixed a bug where the dummies didn't get destroyed and stopped by using Timer Ticker instead of Key Timers 2.
¤ Changed some comments a bit.

V 1.25
¤ Added levels to the actual ability, as it didn't have it before.
¤ Changed name to "Tormental Wrath"!
¤ Changed a commonly used local unit variable to a global instead.
¤ Kingkingyyk3 updated the EAE library to be more efficient!

V 1.30
¤ Big rewrite of the spell's script! (Thanks to Kingkingyyk3!!!!)
¤ Now only needs the system Timer Ticker. (No more EAE that is :D)
¤ Fixed a bug where the dummy projectiles went further with higher speed than the others!
¤ Now completely MUI!!
¤ Made some adjustments to the comments.
¤ Balanced the damage slightly, reduced the damage by 40%!

V 1.31
¤ Added a couple of constants: Weapontype, attach point, slide interval!
¤ Changed weapontype to WEAPON_TYPE_WHOKNOWS :D

V 1.4
¤ Added 2 configurables. DISTANCE and TIME.
¤ Added "some" more comments on some configurables.
¤ Removed a struct member, now uses locals instead.
¤ Switched from using TT (Timer Ticker) to using KT2 (Key Timers 2) ... Again!
¤ Some minor tweaks.

V 1.41
¤ Did some major balancing, as it was way too overpowered before!
¤ Changed the tooltip of the spell, quite a bit!
¤ Added a configurable, EXPLOSION_OFFSET, which determines how much offset the first explosions will be.
¤ A few more minor tweaks to the code.

V 1.5
¤ Added a TimerUtils version of the spell, as it can't be approved at WC3C.net if it doesn't use it.
¤ Made some minor changes in the documentation.

V 1.51
¤ The spell now uses GroupUtils!
¤ Changed the spell to correctly use the ANGLE constant!
¤ Changed from using FirstOfGroup, to use ForGroup calls.
¤ Changed the constant SLIDE_SPEED to be Units/Second instead of Units/Interval.
¤ Some slight changes in the documentation.

V 2.00
¤ Complete rewrite of the entire code !
¤ Now uses only the xe libraries, and BoundSentinel !
¤ Added more constants !
¤ And many, many more changes !

Attached Files
File type: w3xTormental Wrath, by Komaqtion!.w3x (71.8 KB)
08-07-2009, 08:16 AM#2
Rising_Dusk
You credit some Jesus4Lyf character for KeyTimers, but it is not approved here, so it follows that this spell in its current form cannot be approved here. You should use TimerUtils instead.
08-07-2009, 08:24 AM#3
Komaqtion
I can't use systems from another forum in order to get approval here ? :S

Well, ok then... I'll just have to do a TimerUtils version of it too then :(

EDIT: Can't honestly seem to get it working with Timerutils :(
This gives the "Unexpected: "requires Timerutils"":
Collapse JASS:
scope Dummy initializer Init requires TimerUtils

Why won't it compile ?
08-07-2009, 09:32 AM#4
Pyrogasm
Scopes require all libraries by default, so you don't need to state it.
It might be good practice to get in the habit of doing stuff like this, though:
Collapse JASS:
scope EclipseOfSanity initializer Init //requires LinkedList, TimedLoop, xebasic, xepreload, xefx 
08-07-2009, 10:53 AM#5
Komaqtion
Now it compiles at least :D But there is some serious lag now :(

Here's the new code:
Hidden information:
Collapse JASS:
scope Dummy initializer Init
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***********************************************************************************************************//
//@@//////////////////////////////////Tormental Wrath, Made by Komaqtion///////////////////////////////////@@//
//@@                                        TimerUtils Version                                             @@//
//@@                                          How to import:                                               @@//
//@@                                                                                                       @@//
//@@        ¤ First copy the ability "Tormental Wrath" and the unit "Dummy" and change the ID's in the     @@//
//@@        constants below to the new ones. Then you need to import Vexorian's dummy.mdx file from        @@//
//@@        this map, or another, and change "Dummy" unit's model to this one. Then, of course, you        @@//
//@@        need to import the triggers, which are in the categories "The Spell" and                       @@//
//@@        "Required Systems". Then you're free to change any of the given global constants to suit       @@//
//@@        your needs.                                                                                    @@//
//@@                                                                                                       @@//
//@@                                           Requirements:                                               @@//
//@@        ¤ Patch 1.23b or newer.                                                                        @@//
//@@        ¤ JASS Newgen Pack, version 5c or newer.                                                       @@//
//@@        ¤ This spell, of course !                                                                      @@//
//@@        ¤ TimerUtils, made by Vexorian :D                                                              @@//
//@@        ¤ The dummy.mdx, made by Vexorian !                                                            @@//
//@@                                                                                                       @@//
//@@        ¤ Credits to:                                                                                  @@//
//@@          * Vexorian, for the dummy.mdx file and TimerUtils                                            @@//
//@@          * Kingkingyyk3 (@ TheHelper.net), for his wonderfull help on this spell,!                    @@//
//@@                                                                                                       @@//
//@@          And, of course, so many thanks to all of the many helpfull people at TheHelper.net           @@//
//@@          who has helped get is spell working! (kingkingyyk3 and WolfieNoCT especially :D)             @@//
//@@                                                                                                       @@//
//@@                                                                                                       @@//
//@@        Note: This is my very first fully working, and quite good, spell made completely in vJASS.     @@//
//@@                                                                                                       @@//
//@@        So much feedback, and suggestions are very much welcome, and maybe some tips to make it        @@//
//@@        even better would be nice :D                                                                   @@//
//@@                                                                                                       @@//
//@@///////////////////////////////////////////////////////////////////////////////////////////////////////@@//
//***********************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
globals

    // Effects! Change as you'd like ;)\\
    
    private constant string EFFECT_C = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl"                // Effect on the caster!
    private constant string EFFECT_1 = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl"              // Effect 200 range from the caster!
    private constant string EFFECT_2 = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"                      // Effect at the end!
    private constant string DUMMY_EFFECT = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"  // Effect on the moving dummy!
    private constant string ATTACH_POINT = "origin"                                                                // The attach point of the dummy effect!
    
    // ID's! Change to the ID's on your map :D\\
    
    private constant integer SPELL_ID = '0000'          // ID of the spell!
    private constant integer DUMMY_ID = 'h000'          // ID of the dummy unit!
    private constant integer LOCUST = 'Aloc'            // ID of the "Locust" ability! (Might not need changing)
    private constant integer BUFF_ID = 'BTLF'           // ID of the expiration buff on the dummy!
    
    // Other constant integers! Change at will :P\\
    
    private constant real DAMAGE_FACTOR = 1.                     // Just a simple real to make it easy to change the damage!
    private constant real RANGE_FACTOR = 15.                      // Just a simple real to make it easy to change the range!
    private constant integer ANGLES = 16                          // The number of agles the effects will show at! (360/ANGLES)
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL  // Explains itself i think XD
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL  // Same here :P
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here :D
    private constant real SLIDE_SPEED = 10.                       // How much the dummy effect moves each interval!
    private constant real SLIDE_INTERVAL = .05                    // How long an interval is!
    private constant real TIME = 2.5                              // How long it takes for the spell to complete!
    private constant integer DISTANCE = R2I(TIME/SLIDE_INTERVAL)  // How long the dummy effects will travel!
    private constant real EXPLOSION_OFFSET = 200                  // How much range the first explosions are offset the casters porition!
    
endglobals

    // Damage functions!\\

private function Damage_Small takes integer lv returns real
    return DAMAGE_FACTOR * lv
endfunction

private function Damage_Medium takes integer lv returns real   
    return 50 + lv * DAMAGE_FACTOR * 25
endfunction

private function Damage_High takes integer lv returns real
    return 50 + lv * DAMAGE_FACTOR * 50
endfunction

    // Range functions!\\

private function Range_Small takes nothing returns real
    return RANGE_FACTOR * 5
endfunction

private function Range_Medium takes nothing returns real
    return RANGE_FACTOR * 10
endfunction

private function Range_High takes nothing returns real
    return RANGE_FACTOR * RANGE_FACTOR
endfunction

        // End of Configuration!\\
        
globals
    
    private integer TempStructIndex
    private group Temp = CreateGroup()
    private unit temp = null
    private timer t// = NewTimer()

endglobals
        
private struct Data
    unit array du [ANGLES]
    unit cs
    boolean b = false
    player p
    group g = CreateGroup()
    integer lvl
    effect array e [ANGLES]
    integer ticks
    
    static method create takes unit u returns Data
        local Data a = Data.allocate()
        set a.cs = u
        set a.p = GetOwningPlayer(u)
        set a.lvl = GetUnitAbilityLevel(a.cs,SPELL_ID)
        return a
    endmethod
    
endstruct

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

private function GroupEm takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), Data(TempStructIndex).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(), Data(TempStructIndex).g) == false
endfunction

private function Smaller_GroupEm takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), Data(TempStructIndex).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

private function Move_Dummy takes nothing returns nothing
    local Data a = GetTimerData(GetExpiredTimer())
    local real xd
    local real yd
    local real xd2
    local real yd2
    local integer i = 1
    set TempStructIndex = a
    if a.ticks > 0 then
        set a.ticks = a.ticks - 1
        loop
            exitwhen i>=ANGLES
            set xd = GetUnitX(a.du[i])
            set yd = GetUnitY(a.du[i])
            set xd2 = xd+SLIDE_SPEED*Cos(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
            set yd2 = yd+SLIDE_SPEED*Sin(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
            call GroupEnumUnitsInRange(Temp, xd2, yd2, Range_Small(), Condition(function Smaller_GroupEm))
            loop
                set temp = FirstOfGroup(Temp)
            exitwhen temp == null
                call UnitDamageTarget(a.cs, temp, Damage_Small(a.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
                call GroupAddUnit(a.g,temp)
                call GroupRemoveUnit(Temp,temp)
            endloop
            call SetUnitX(a.du[i],xd2)
            call SetUnitY(a.du[i],yd2)
            set i = i+1
        endloop
    else
        loop
        exitwhen i >=ANGLES
            set xd = GetUnitX(a.du[i])
            set yd = GetUnitY(a.du[i])
            call DestroyEffect(a.e[i])
            call DestroyEffect(AddSpecialEffect(EFFECT_2,xd,yd))
            call GroupEnumUnitsInRange(Temp, xd, yd, Range_High(), Condition(function Smaller_GroupEm))
            loop
                set temp = FirstOfGroup(Temp)
            exitwhen temp == null
                call UnitDamageTarget(a.cs, temp, Damage_High(a.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
                call GroupRemoveUnit(Temp,temp)
            endloop
            call RemoveUnit(a.du[i])
            set i = i+1
        endloop
        call a.destroy()
        call ReleaseTimer(t)
    endif
endfunction

private function Effects takes nothing returns nothing
    local Data a = Data.create(GetTriggerUnit())
    local real xu = GetUnitX(a.cs)
    local real yu = GetUnitY(a.cs)
    local real dx
    local real dy
    local integer i = 1
    set t = NewTimer()
    call DestroyEffect(AddSpecialEffect(EFFECT_C,xu,yu))
    loop
        exitwhen i>=ANGLES
        set dx = xu+EXPLOSION_OFFSET*Cos(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
        set dy = yu+EXPLOSION_OFFSET*Sin(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
        set TempStructIndex = a
        call DestroyEffect(AddSpecialEffect(EFFECT_1, dx, dy))
        call GroupEnumUnitsInRange(Temp, dx, dy,Range_Medium(), Condition(function GroupEm))
        loop
            set temp = FirstOfGroup(Temp)
        exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, Damage_Medium(a.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(Temp,temp)
        endloop
        set a.du[i] = CreateUnit(a.p,DUMMY_ID,xu,yu,bj_RADTODEG*Atan2(dy-yu,dx-xu))
        call UnitAddAbility(a.du[i],LOCUST)
        set a.e[i] = AddSpecialEffectTarget(DUMMY_EFFECT,a.du[i],ATTACH_POINT)
        set i = i+1
    endloop
    set a.ticks = DISTANCE
    call SetTimerData(t,a)
    call TimerStart(t, SLIDE_INTERVAL, true, function Move_Dummy)
    call GroupClear(a.g)
    call GroupClear(Temp)
endfunction

private function Init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Spell_Check))
    call TriggerAddAction(t,function Effects)
endfunction

endscope


And btw, I'm using TimerUtils Blue flavor, don't know if this is too fast for it or something, but just wanted to let you know :D
08-07-2009, 08:49 PM#6
Computer(Insane)
Haha you post it here as well. Nice spell and that name where did you get it
08-07-2009, 09:15 PM#7
Gtam
Why would you want a new name its cool and nice spell
08-08-2009, 09:26 AM#8
Komaqtion
Working now! :D
08-09-2009, 11:22 AM#9
Komaqtion
Updated it now to use TimerUtils :D

Anything else needed for approval ? :o
08-09-2009, 01:22 PM#10
Anitarf
Quote:
Originally Posted by Komaqtion
Anything else needed for approval ? :o
  • A preview image.
  • A proper scope name.
  • Removal of the unapprovable version of the spell from the post.
  • Removal of links to offsite images (we have the file attachment feature for a reason).
  • It needs to pass a more detailed review of the code that will come after the above conditions are satisfied.
08-09-2009, 02:40 PM#11
Komaqtion
How do I add the Preview image ??? :S
And what size does it need to be ?

All changes made exept the preview image :D
08-09-2009, 07:03 PM#12
Pyrogasm
Just a 100x100 image that is displayed next to th thread in the spells forum.
08-09-2009, 07:08 PM#13
Komaqtion
Yeah, but how do I add it ? :S
08-09-2009, 07:23 PM#14
Pyrogasm
Edit post > go advanced > attachments
08-09-2009, 07:31 PM#15
Komaqtion
Done now :D