• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Fire Geysers v1.5

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
FIRE GEYSERS

My first spell... :p
Go nuts on the critique but also tell me what to change & improve this is my first vJASS spell...
Credits to redscores for his spell template map.

vJASS, MUI, Leakless, & Lagless

''Technical' description'': creates X amount of fire special effects at random points around the caster, dealing Y damage to all units within range of any of those effects. Every Z seconds for A times, random fire effects will be created at random points around the caster, damaging all units within range.
X, Y, Z, A are all configurable variables.

Could probably look a lot better with more fire effects, but now you can configure that, too.

Code:
JASS:
scope FireGeysers initializer Init

globals
    private constant integer SPELLID = 'A000' //ABILITY RAWCODE
    private constant string EFFECT = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" //FIRE EFFECT

    private constant integer EFFECTAMOUNT = 3 //HOW MANY FIRE GEYSERS ARE CREATED DURING A PERIOD
    private constant integer AMOUNT = 3 //HOW MANY TIMES THE EFFECT OCCURS IN TOTAL. TO FIND OUT HOW LONG THE SPELL WILL LAST IN SECONDS: AMOUNT * PERIOD
    
    private constant real PERIOD = 2.0 //HOW OFTEN THE EFFECT OCCURS
    private constant real DAMAGE = 50.0 //DAMAGE DONE BY EACH FIRE GEYSER PER LEVEL
    private constant real RNDMIN = 300.0 //MINIMUM DISTANCE THE EFFECT WILL OCCUR FROM THE CASTER
    private constant real RNDMAX = 600.0 //MINIMUM DISTANCE THE EFFECT WILL OCCUR FROM THE CASTER
    
    private constant attacktype ATTACKTYPE = ATTACK_TYPE_MAGIC //THE TYPE OF ATTACK (MAGIC, HERO, CHAOS, ETC.)
    private constant damagetype DAMAGETYPE = DAMAGE_TYPE_FIRE //THE TYPE OF DAMAGE.
    private constant weapontype WEAPONTYPE = WEAPON_TYPE_WHOKNOWS //FOR DIFFERENT TYPES OF WEAPONS. DON'T RECOMMAND YOU CHANGE IT.
    
    //DON'T CHANGE ANYTHING AFTER THIS POINT UNLESS YOU KNOW WHAT YOU'RE DOING!
    private group TEMPGROUP = CreateGroup()
endglobals

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELLID
endfunction

private struct data
    unit u = null
    real ux = 0.0
    real uy = 0.0
    integer lvl = 0
    integer count = 0

    static method create takes unit u returns data
        local data d = data.allocate()
        set d.u = u
        set d.ux = GetUnitX(u)
        set d.uy = GetUnitY(u)
        set d.lvl = GetUnitAbilityLevel(u, SPELLID)
        return d
    endmethod
endstruct

globals
    private data TEMPSTRUCT
endglobals

private function Damage takes nothing returns boolean
    call UnitDamageTarget(TEMPSTRUCT.u, GetFilterUnit(), DAMAGE * TEMPSTRUCT.lvl, false, false, ATTACKTYPE, DAMAGETYPE, WEAPONTYPE)
    return false
endfunction

private function Periodic takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local real rndx = 0.0
    local real rndy = 0.0
    local real angle = 0.0
    local integer i = 0

    if d.count < AMOUNT then
        loop
            set rndx = d.ux + GetRandomReal(RNDMIN, RNDMAX) * Cos(GetRandomReal(0.00,57.29))
            set rndy = d.uy + GetRandomReal(RNDMIN, RNDMAX) * Sin(GetRandomReal(0.00,57.29))
            call DestroyEffect(AddSpecialEffect(EFFECT, rndx, rndy))
            call GroupEnumUnitsInRange(TEMPGROUP, rndx, rndy, 200.0, Condition(function Damage))
        set i = i + 1
        exitwhen i == EFFECTAMOUNT
        endloop
        set d.count = d.count + 1
    else
        call ReleaseTimer(GetExpiredTimer())
        call d.destroy()
    endif
endfunction

private function Actions takes nothing returns nothing
    local timer t = NewTimer()
    call SetTimerData(t, data.create(GetTriggerUnit()))
    call TimerStart(t, PERIOD, true, function Periodic)
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 Conditions))
    call TriggerAddAction(t, function Actions)
endfunction
endscope

Changelog:
v1.5
- Fixed a bug where incorrect units would be damaged.
- Further randomized effects.
v1.4
- Added weapontype, damagetype, and attacktype configurables.
- Made code easier to read.
- Optimized code.
v1.3
- Inlined damage.
v1.2
- Further optimized code.
v1.1
- Optimized code.
- Damage, amount of fire effects, amount of times the spell will run for can now all be easily modified.


Keywords:
fire, geysers, spell, ability
Contents

Fire Geysers v1.5 (Map)

Reviews
10:17, 20th Dec 2009 TriggerHappy: Review for Spell I don't think I can approve this based on the simplicity of the spell. Status Feel free to message me here if you have any issues with my review or if you have updated your...

Moderator

M

Moderator

10:17, 20th Dec 2009
TriggerHappy:

Review for Spell

I don't think I can approve this based on the simplicity of the spell.

Status

Feel free to message me here if you have any issues with
my review or if you have updated your resource and want it reviewed again.

Rejected
 
Level 31
Joined
May 3, 2008
Messages
3,155
JASS:
private function Init takes nothing returns nothing    local trigger t = CreateTrigger()    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)    call TriggerAddCondition(t, Condition(function Conditions))    call TriggerAddAction(t, function Actions)endfunction

if my memory serves me right, here could be improve.
 
Level 6
Joined
Jul 8, 2008
Messages
150
JASS:
private function Init takes nothing returns nothing    local trigger t = CreateTrigger()    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)    call TriggerAddCondition(t, Condition(function Conditions))    call TriggerAddAction(t, function Actions)endfunction

if my memory serves me right, here could be improve.

I don't know lol. The only thing I see is that I could remove the BJ but then it would look awefully messy. :(

EDIT: Btw, xxdingo93xx, I meant critique the code, not the actual spell. lol :p
 
Tiny code o_O

  • You may want to think of only using a condition thread instead of combining actions/conditions. It creates one less thread and saves a function call. Like this;
    JASS:
    private function Actions takes nothing returns boolean
        if YOUR_CONDITION then
            // Do actions
        endif
        return false
    endfunction
    
    private function onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterSomeEvent(t)
        call TriggerAddCondition(t, Condition(function Actions))
    endfunction
  • In your struct, I'm pretty sure all of the default values are these when uninitialized; Initializing them just makes your allocate function slower.
    JASS:
        unit u = null
        real ux = 0.0
        real uy = 0.0
        integer lvl = 0
        integer count = 0
 
Top