Spell Hammerblow

Trollvottel

never aging title
Reaction score
262
Description:
A fun spell, i made it when i had nothing to do and i wanted to test the timer ticker system
Throws a hammer at the target location. Units in range will be damaged and knockbacked.
GUI/Jass: Jass
vJass: yes (so it requires newgen)
Uses Timer Ticker system.

Hard to take a screenshot...

but here are some screenshots:
Throws the hammer overhead:
neubitmapof2.jpg
Throws it again:
neubitmap2vb9.jpg
Now you see the eruption (or not) and the knockback
neubitmap2ap1.jpg

Now the Code (I hope it is leakless):
JASS:

scope hammerblow
    // //================================================================\\
    // || How to implement:                                              ||
    // || 1. copy the dummy and the spell                                ||
    // || 2. copy the spellcode and if necessary the time ticker system  ||
    // || 3. change the values below and have fun                        ||
    // \\================================================================//
    globals
        private constant integer rawid = 'A000' // spell rawcode
        private constant integer dummyraw = 'h000' // dummy rawcode
        private constant real knockdis = 400 // distance of knockback
        private constant real knockspeed = 20 // knockback speed
        private constant real radius = 400 // radius of damage and knockback
        private constant real damage = 150 // damage per level
    endglobals
    globals 
        private constant string lightningcode = "LEAS"
        //Now the Red/Green/Blue/Alpha values of the lightning. 1.00 = 100%
        private constant real red = 1
        private constant real green = 1
        private constant real blue = 1
        private constant real alpha = 1.00
    endglobals

    private function Trig_Spell_Conditions takes nothing returns boolean
        return GetSpellAbilityId() == rawid
    endfunction


    //Knockback
    private struct s
        unit u
        real dis
        real speed
        real angle
        effect e
    endstruct

    private function knock_child takes nothing returns boolean
        local s dat = TT_GetData()
        set dat.dis = dat.dis - dat.speed
        if dat.dis >= 0 then
            call SetUnitFacing(dat.u, GetUnitFacing(dat.u) + 10 )
            call SetUnitPosition(dat.u, GetUnitX(dat.u) + dat.speed * Cos(dat.angle * bj_DEGTORAD), GetUnitY(dat.u) + dat.speed * Sin(dat.angle * bj_DEGTORAD))
        else
            call DestroyEffect(dat.e)
            call SetUnitPathing(dat.u, true)
            call dat.destroy()
            return true
        endif
        return false
    endfunction

    function knockback takes unit u, real dis, real speed, real angle returns nothing
        local s dat = s.create()
        call SetUnitPathing(u, false)
        set dat.u = u
        set dat.dis = dis
        set dat.speed = speed
        set dat.angle = angle
        set dat.e = AddSpecialEffectTarget("Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl", dat.u, "origin")
        call TT_Start(function knock_child, dat)
    endfunction

    //Spell


    private struct hammer
        unit caster
        unit dummy
        real dis
        real angle
        real targx
        real targy
        real curx
        real cury
        real height    = 0
        real minus     = 0
        real curdis
        lightning light

            method onDestroy takes nothing returns nothing
                call RemoveUnit(this.dummy)
                call DestroyLightning(this.light)
            endmethod
    endstruct


    private function periodic takes nothing returns boolean
        local hammer dat = TT_GetData()
        local group g 
        local unit u
        local terraindeformation t
        set dat.curx = dat.curx + dat.dis / 10 * Cos(dat.angle * bj_DEGTORAD)
        set dat.cury = dat.cury + dat.dis / 10 * Sin(dat.angle * bj_DEGTORAD)

        set dat.minus = dat.minus + 1.00
        if dat.minus > 10 then
            set dat.height = dat.height - dat.curdis / 10
        else
            set dat.height = dat.height + dat.curdis / 10
        endif
        
        call SetUnitPosition(dat.dummy, dat.curx,dat.cury)
        call SetUnitFlyHeight(dat.dummy, dat.height, 0)
        
        call MoveLightningEx(dat.light, false,  GetUnitX(dat.caster), GetUnitY(dat.caster), 40, dat.curx, dat.cury, dat.height)
       
        set dat.curdis = SquareRoot((GetUnitX(dat.caster) - dat.curx ) * (GetUnitX(dat.caster) - dat.curx ) + (GetUnitY(dat.caster) - dat.cury ) * (GetUnitY(dat.caster) - dat.cury ))
        if dat.curdis  >= dat.dis then
        
            call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", dat.curx, dat.cury))
            set t = TerrainDeformCrater(dat.curx, dat.cury, radius, 80, R2I(200), false)
            
            set g = CreateGroup()
            call GroupEnumUnitsInRange(g, dat.curx, dat.cury, radius, null)
            loop
                set u = FirstOfGroup(g)
                call GroupRemoveUnit(g,u)
                exitwhen u == null
                if GetUnitState(u, UNIT_STATE_LIFE) > 0 and IsUnitEnemy(u, GetOwningPlayer(dat.caster)) then
                    call UnitDamageTarget(dat.caster, u, damage * GetUnitAbilityLevel(dat.caster, rawid), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    call knockback(u, knockdis, knockspeed, bj_RADTODEG * Atan2(GetUnitY(u) - dat.cury, GetUnitX(u) - dat.curx ))
                endif
            endloop
            
            call DestroyGroup(g)
            call dat.destroy()
            set g = null
            set u = null
            set t = null
            return true
        endif
        return false
    endfunction

    private function Trig_Spell_Actions takes nothing returns nothing
        local hammer dat = hammer.create()
        local location loc = GetSpellTargetLoc()
        set dat.targx    = GetLocationX(loc)
        set dat.targy    = GetLocationY(loc)
        call RemoveLocation(loc)
        set dat.caster   = GetTriggerUnit()
        set dat.angle    = bj_RADTODEG * Atan2(dat.targy - GetUnitY(dat.caster), dat.targx - GetUnitX(dat.caster))
        set dat.dis      = SquareRoot((GetUnitX(dat.caster) - dat.targx ) * (GetUnitX(dat.caster) - dat.targx ) + (GetUnitY(dat.caster) - dat.targy ) * (GetUnitY(dat.caster) - dat.targy ))
        set dat.curx     = GetUnitX(dat.caster) - dat.dis  * Cos(dat.angle * bj_DEGTORAD)
        set dat.cury     = GetUnitY(dat.caster) - dat.dis  * Sin(dat.angle * bj_DEGTORAD)
        set dat.light    = AddLightning(lightningcode, false, GetUnitX(dat.caster), GetUnitY(dat.caster), dat.curx, dat.cury)
        call SetLightningColor(dat.light, red, green, blue, alpha)
        set dat.dummy    = CreateUnit(GetOwningPlayer(dat.caster), dummyraw, dat.curx, dat.cury, dat.angle)
        call TT_Start( function periodic, dat)
        set loc = null
    endfunction

    //===========================================================================
    function InitTrig_Spell takes nothing returns nothing
        set gg_trg_Spell = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
        call TriggerAddCondition( gg_trg_Spell, Condition( function Trig_Spell_Conditions ) )
        call TriggerAddAction( gg_trg_Spell, function Trig_Spell_Actions )
    endfunction


endscope
 

Attachments

  • Spell - Hammer blow.w3x
    23.3 KB · Views: 709

Hatebreeder

So many apples
Reaction score
380
Well...
No Map is attached =)
While looking though your Code, I noticed this:
JASS:
//call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Naga\\NagaBlood\\NagaBloodWindserpent.mdl", GetUnitX(dat.u), GetUnitY(dat.u)))


If you don't use this, maybe it's better to remove it completly ;)
Other than that, I can't seem to find any leaks...
Well done =)
 

Cohadar

master of fugue
Reaction score
209
I noticed you declared knockspeed constant but you are not using it.
And the fact that TT_PERIOD is not showing anywhere tells me this is not independent of period, if someone changed their TT to use 0.03 instead of default 0.04 it would change speeds in your spell.

You should learn how to make spells period independent.
 

gref

New Member
Reaction score
33
Couple of comments: A: the name of the map you upoaded is Hammeblow, not Hammer blow.
B: It would be better if you made it easier to stop channeling -- (Ie. turn the disable other abilities bit in the channel spell off).
C: The tooltip needs work. I wanted to just press a key on my keyboard to use it and there wasn't one.
Finally: Maybe for the test you should make the hero level 10, or make a trigger that restores his health to full periodically (Or just make is regen 99999) because he died in about a second... which stopped me testing the spell because I'm lazy.

All in all, it looks pretty good. It would be really cool if you get a model that didn't resize so badly, but obviously that's hard to do. If you just improve those things which make your map easier to test, then people probably will...
 

Trollvottel

never aging title
Reaction score
262
Finally: Maybe for the test you should make the hero level 10, or make a trigger that restores his health to full periodically (Or just make is regen 99999) because he died in about a second... which stopped me testing the spell because I'm lazy.

just press esc... ^^

all in all, it looks pretty good. It would be really cool if you get a model that didn't resize so badly, but obviously that's hard to do.

thank you.
i think everyone has to choose this own hammer model, maybe ill add a function to change the lighnings color and art.
 

Trollvottel

never aging title
Reaction score
262
well in the next release the armor is on 3000 so the unit wont take damage

ok ive edited it a bit
 

The Undaddy

Creating with the power of rage
Reaction score
55
Haven't looked through the code but when you cast the hammer on 'self' it usually stays flying until you move.It's nice,overall.
Also,I don't like spells which pause the unit so that it can always cast the spell
 

gref

New Member
Reaction score
33
Well the effect certainly is better. I see you've changed it from unit target to point target, which is probably a good thing. Also the push back seems bigger.
As far as I can see it's looking pretty good.
Knowing the moderators around here, I'd guess that they'd still want you to make a clone of a normal tootip: Ie. have yellow letter for hotkey instead of [e] or whatever it was.
Good spell.
I don't like channelling spells as a personal thing, but I can almost get past that with this :p.
 

rodead

Active Member
Reaction score
42
well i got a question how can i make your spell damage buildings but not knockback them ( i am not an expirienced Jasser but i can read it)
 

Trollvottel

never aging title
Reaction score
262
no problem.
find this:
JASS:

               if GetUnitState(u, UNIT_STATE_LIFE) > 0 and IsUnitEnemy(u, GetOwningPlayer(dat.caster)) then
                    call UnitDamageTarget(dat.caster, u, damage * GetUnitAbilityLevel(dat.caster, rawid), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    call knockback(u, knockdis, knockspeed, bj_RADTODEG * Atan2(GetUnitY(u) - dat.cury, GetUnitX(u) - dat.curx ))
                endif

and change it to this:
JASS:
                if GetUnitState(u, UNIT_STATE_LIFE) > 0 and IsUnitEnemy(u, GetOwningPlayer(dat.caster)) then
                    call UnitDamageTarget(dat.caster, u, damage * GetUnitAbilityLevel(dat.caster, rawid), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    if IsUnitType(u, UNIT_TYPE_STRUCTURE) != true then
                        call knockback(u, knockdis, knockspeed, bj_RADTODEG * Atan2(GetUnitY(u) - dat.cury, GetUnitX(u) - dat.curx ))
                    endif
                endif
 

Komaqtion

You can change this now in User CP.
Reaction score
469
This spell works with the newest patches, but (This is a very small tweak) it could use the new [ljass]GetSpellTargetX/Y[/ljass] natives, instead of using a location...

Just for some small efficiency gain XD
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    I ordered like five blocks for 15 dollars. They're just little aluminum blocks with holes drilled into them
  • Varine Varine:
    They are pretty much disposable. I have shitty nozzles though, and I don't think these were designed for how hot I've run them
  • Varine Varine:
    I tried to extract it but the thing is pretty stuck. Idk what else I can use this for
  • Varine Varine:
    I'll throw it into my scrap stuff box, I'm sure can be used for something
  • Varine Varine:
    I have spare parts for like, everything BUT that block lol. Oh well, I'll print this shit next week I guess. Hopefully it fits
  • Varine Varine:
    I see that, despite your insistence to the contrary, we are becoming a recipe website
  • Varine Varine:
    Which is unique I guess.
  • The Helper The Helper:
    Actually I was just playing with having some kind of mention of the food forum and recipes on the main page to test and see if it would engage some of those people to post something. It is just weird to get so much traffic and no engagement
  • The Helper The Helper:
    So what it really is me trying to implement some kind of better site navigation not change the whole theme of the site
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top