Spellpack Hero: Tiny, the Stone Giant

soulreaping

New Member
Reaction score
17
Hey,

Here is one of my favorite heroes in DotA Allstars, Tiny.

I wrote Avalanche, Craggy Exterior and Grow! scripts myself, though they are very simple.

Thanks for emjlr3 for approving me using his script here, big credit goes for him!

All triggers are leakless as far as I checked.

This requires TT system by cohadar imported to your map.
Also, this requires vJass (JASSHelper or NewGen).

So here they are:

BTNGolemStormBolt.gif


Avalanche

Bombards an area with rocks stunning and damaging enemy land units.

Level 1 - 100 damage.
Level 2 - 180 damage.
Level 3 - 260 damage.
Level 4 - 300 damage.

Screenshot:
tiny1jq6.jpg

Script:
JASS:

scope Avalanche

globals
    private constant integer abil_id = 'A000'
    private constant integer dum_id = 'u001'
    private constant integer dum_abil_id = 'A001'
endglobals

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

private function Actions takes nothing returns nothing
    local unit u
    local unit uu = GetTriggerUnit()
    local location loc = GetUnitLoc(uu)
    set u = CreateUnitAtLoc(GetOwningPlayer(uu), dum_id, loc, bj_UNIT_FACING)
    call RemoveLocation(loc)
    set loc = GetSpellTargetLoc()
    call UnitApplyTimedLife(u, 'BTLF', 5.)
    call UnitAddAbility(u,dum_abil_id)
    call SetUnitAbilityLevel(u, dum_abil_id, GetUnitAbilityLevel(uu, abil_id))
    call IssuePointOrderLoc(u, "clusterrockets", loc)
    call RemoveLocation(loc)
    set u = null
    set uu = null
    set loc = null
endfunction


public function InitTrig takes nothing returns nothing
    local trigger myTrig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(myTrig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(myTrig, Condition(function Conditions))
    call TriggerAddAction(myTrig, function Actions)
endfunction

endscope

BTNattackground.gif


Toss

JASS:

scope Toss

//******************************************************************************************
//*
//*  Toss - By emjlr3, Original seen in DotA Allstars
//*
//*  Toss a friend or foe from here to there by targeting on a unit, and grabbing
//*  a random target in the area, launching them towards the targeted area.
//* 
//*  Requires:
//*    - "TT" trigger copied to your map, if not already there
//*    - The "Toss" ability copied to your map
//*    - A vJASS Preprocessor
//*
//******************************************************************************************

globals
    // Config Globals:
    private constant integer abil_id = 'A002' // Toss ability rawcode
    private constant integer fly_id = 'Amrf' // Rawcode of ability to use for fly trick, if you have not touched Crow Form, this doesn't need changing
    private constant real impact_damage = .20 // Percent of toss damage dealt to tossed unit
    private constant real time = 1. // Flight time for tossed unit (seconds)
    private constant string end_sfx = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" // Effect created on target at end of toss
    private constant boolean kill_trees = true // Whether trees are destroyed upon target landing
    private constant attacktype attack_type = ATTACK_TYPE_NORMAL // Attack type used for damage
    private constant damagetype damage_type = DAMAGE_TYPE_DEMOLITION // Damage type used for damage
    
    // Needed Globals:
    private group G = CreateGroup()
    private unit U = null
    private rect R = null
    private location L = null
    public trigger Trigger = null // Output trigger will be Toss_Trigger, which can be used publically
endglobals
// Config. Functions:
private function Damage takes integer lvl returns real
    return 75.*lvl // Damage/lvl
endfunction
private function Area takes integer lvl returns real
    return 275. // Area within to grab units and damage units/lvl
endfunction

//========================================================================================
private struct data
    unit u
    unit targ
    player p
    real xt
    real yt
    real xl
    real yl
    real dist
    real ang
    real cos
    real sin
    real speed
    real hc
    integer lvl
    integer count = 1
    
    static method FiltIsEnemy takes nothing returns boolean
        return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>.405
    endmethod 
    static method DamageGroup takes unit damager, real radius, real x, real y, real amount returns nothing
        local unit u
    
        set bj_groupEnumOwningPlayer = GetOwningPlayer(damager)
        call GroupClear(G)
        call GroupEnumUnitsInRange(G, x, y, radius, Condition(function data.FiltIsEnemy)) 
        loop
            set u = FirstOfGroup(G)
            exitwhen u == null
            call GroupRemoveUnit(G,u)
            call UnitDamageTarget(damager,u,amount,false,false,attack_type,damage_type,null)
        endloop
    endmethod
    static method KillTrees_Child takes nothing returns nothing
        call KillDestructable(GetEnumDestructable())    
    endmethod
    static method KillTrees takes real x, real y, real radius returns nothing
        set R = Rect(x - radius,y - radius,x + radius,y + radius)
    
        call EnumDestructablesInRect(R,null,function data.KillTrees_Child)
        call RemoveRect(R)
        set R = null
    endmethod
    method onDestroy takes nothing returns nothing
        call SetUnitFlyHeight(.targ,GetUnitDefaultFlyHeight(.targ),0.)
		call PauseUnit(.targ,false)
		call SetUnitPathing(.targ,true)
        call UnitDamageTarget(.u,.targ,Damage(.lvl)*impact_damage,false,false,attack_type,damage_type,null)
		call DestroyEffect(AddSpecialEffectTarget(end_sfx,.targ,"origin"))
		call data.DamageGroup(.u,Area(.lvl),.xl,.yl,Damage(.lvl))
        if kill_trees then
            call data.KillTrees(.xl,.yl,Area(.lvl))
        endif
    endmethod
endstruct

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == abil_id
endfunction
private function Filt takes nothing returns boolean
    return GetFilterUnit()!=U and GetWidgetLife(GetFilterUnit())>.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)
endfunction
private function GetSpeed takes real dist returns real
    return dist/(1./TT_PERIOD)
endfunction
private function GetCountConversion takes integer count returns real
    return (50./(time/TT_PERIOD))*count
endfunction
private function Movement takes nothing returns boolean
    local data d = TT_GetData()
    local real conv
    local real height
	local real speed 
    local real x 
    local real y 
    
    if d.count<=time/TT_PERIOD then
        set conv = GetCountConversion(d.count)
        set height = (conv-25.)*(conv-25.)
        set speed = d.count*d.speed
        set x = d.xt+speed*d.cos
        set y = d.yt+speed*d.sin
        call SetUnitX(d.targ,x)
        call SetUnitY(d.targ,y)
		call SetUnitFlyHeight(d.targ,775.-height,0.)
		set d.count = d.count + 1
        return false
	else
        call d.destroy()
        return true
    endif
endfunction
private function Actions takes nothing returns nothing
    local data d = data.create()
    
    set d.u = GetTriggerUnit()
    set d.p = GetOwningPlayer(d.u)
    set d.lvl = GetUnitAbilityLevel(d.u,abil_id)
    
    call GroupClear(G)
    set U = d.u
    call GroupEnumUnitsInRange(G,GetUnitX(d.u),GetUnitY(d.u),Area(d.lvl),Condition(function Filt))
    set d.targ = GroupPickRandomUnit(G)
    if d.targ==null then
        call d.destroy()
        return
    endif
    
    set d.xt = GetUnitX(d.targ)
    set d.yt = GetUnitY(d.targ)
    set L = GetSpellTargetLoc()
    set d.xl = GetLocationX(L)
    set d.yl = GetLocationY(L)
    set d.ang = Atan2(d.yl-d.yt,d.xl-d.xt)
    set d.cos = Cos(d.ang)
    set d.sin = Sin(d.ang)
    set d.dist = SquareRoot((d.xt-d.xl)*(d.xt-d.xl) + (d.yt-d.yl)*(d.yt-d.yl))
    set d.speed = GetSpeed(d.dist)
    
    call PauseUnit(d.targ,true)
    call SetUnitPathing(d.targ,false)
    call UnitAddAbility(d.targ,fly_id)
    call UnitRemoveAbility(d.targ,fly_id)
    
    call TT_Start(function Movement,d)
    
    call RemoveLocation(L)
endfunction

//===========================================================================
public function InitTrig takes nothing returns nothing
    set Trigger = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( Trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( Trigger, Condition( function Conditions ) )
    call TriggerAddAction( Trigger, function Actions )
endfunction

endscope
Credit for emjlr3 for his script.

PASBTNResistantSkin.gif


Craggy Exterior

Tiny's body is made of solid granite, causing great pain to those who attack it. Whenever a melee unit attacks Tiny, there is a chance that they will be stunned for 1.2 seconds.

Level 1 - 6% chance, 25 stun damage.
Level 2 - 12% chance, 35 stun damage.
Level 3 - 18% chance, 45 stun damage.
Level 4 - 24% chance, 55 stun damage.

I can't really post a screenshot of that, sorry.

Script:
JASS:

scope CraggyExterior

globals
    private constant integer abil_id = 'A003'
    private constant integer dum_id = 'u001'
    private constant integer dum_abil_id = 'A004'
endglobals

private function Conditions takes nothing returns boolean
    return ((GetUnitAbilityLevel(GetTriggerUnit(), abil_id) > 0) and (IsUnitType(GetAttacker(), UNIT_TYPE_MELEE_ATTACKER) == true))
endfunction

private function Actions takes nothing returns nothing
    local integer i = GetRandomInt(0, 100)
    local unit u = GetTriggerUnit()
    local unit uu
    local location loc = GetUnitLoc(GetAttacker())
    local integer lvl = GetUnitAbilityLevel(u, abil_id)
    
    if (i <= 6 * lvl) then
        set uu = CreateUnitAtLoc(GetOwningPlayer(u), dum_id, loc, bj_UNIT_FACING)
        call UnitAddAbility(uu, dum_abil_id)
        call SetUnitAbilityLevel(uu, dum_abil_id, lvl)
        call UnitApplyTimedLife(uu, 'BTLF', 3.)
        call IssueTargetOrder(uu, "thunderbolt", GetAttacker())
    endif
    set u = null
    set uu = null
    call RemoveLocation(loc)
    set loc = null
endfunction

public function InitTrig takes nothing returns nothing
    local trigger myTrig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(myTrig, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddCondition(myTrig, Condition(function Conditions))
    call TriggerAddAction(myTrig, function Actions)
endfunction

endscope

PASBTNTinyGrow.gif


Grow!

Greatly increases Tiny's power and size, but does so at the cost of his attack speed. Improves toss damage and slightly increases move speed.

Level 1 - 40 bonus damage, 20% reduced attack speed.
Level 2 - 80 bonus damage, 35% reduced attack speed.
Level 3 - 120 bonus damage, 50% reduced attack speed.

Screenshot:
tiny3kn5.jpg

Script:
JASS:

scope Grow

globals
    private constant integer abil_id = 'A005'
    private constant integer upg_id = 'R000'
endglobals

struct Grow
    unit u
endstruct

private function Check takes nothing returns nothing
    local Grow g = Grow.create()
    local integer lvl = GetUnitAbilityLevel(g.u, abil_id)
    if (GetWidgetLife(g.u) > .405) then
        call SetUnitScale(g.u, .5 + .25*lvl, .5 + .25*lvl, .5 + .25*lvl)
    endif
    call g.destroy()
endfunction

private function Conditions takes nothing returns boolean
    return (GetLearnedSkill() == abil_id)
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local trigger myTrig = CreateTrigger()
    local integer lvl = GetUnitAbilityLevel(u, abil_id)
    local Grow g = Grow.create()
    call SetPlayerTechResearched(GetOwningPlayer(u), upg_id, lvl)
    call SetUnitScale(u, .5 + .25*lvl, .5 + .25*lvl, .5 + .25*lvl)
    if (lvl == 1) then
        set g.u = u
        call TriggerRegisterTimerEvent(myTrig, 1., true)
        call TriggerAddAction(myTrig, function Check)
    endif    
    set u = null
    call g.destroy()
endfunction

public function InitTrig takes nothing returns nothing
    local trigger myTrig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(myTrig, EVENT_PLAYER_HERO_SKILL)
    call TriggerAddCondition(myTrig, Condition(function Conditions))
    call TriggerAddAction(myTrig, function Actions)
endfunction

endscope

As you see, except Toss, the spells are pretty simple to code.

Have fun with it, and if you find any bug / leak I didn't, just post it here.

Thanks to Tinki3 for his spell template map.

Please comment.View attachment 14365
 

Attachments

  • TinyHero.w3x
    83.6 KB · Views: 736

Tom Jones

N/A
Reaction score
437
On attack if I'm not mistaken.

*Edit*
Locations should also be nulled.

Is that emilj3rs Toss? If so please respect the guideline/rule about not submitting other peoples work.

Keep it up.
 

hell_knight

Playing WoW
Reaction score
126
No , dota doesn't use an attack detection system it just uses the normal BJ where it gets whena unit is attacked.

Proof?
Spirit Breaker - Enpowering Haste - Damage done BEFORE you actually swing.
Ursa - Same story.
Craggy Exterior - same story
 

vypur85

Hibernate
Reaction score
803
I think for the Grow! ability, there is some periodic trigger (not sure) that makes sure that Tiny's size is correct. Because there is some bug that makes the Tiny's size reduced when being Frost Nova. Or when it dies and revived. Same applies to Phantom Assassin's Blur. But I say this from my observation when playing DotA, I'm not really sure about it trigger-wise.
 

emjlr3

Change can be a good thing
Reaction score
395
my spell is here, without permission....even though credit is given, that is not right
 

Tom Jones

N/A
Reaction score
437
No , dota doesn't use an attack detection system it just uses the normal BJ where it gets whena unit is attacked.

Proof?
Spirit Breaker - Enpowering Haste - Damage done BEFORE you actually swing.
Ursa - Same story.
Craggy Exterior - same story
Not true, and the swing in Empowering Haste is triggered. Dota does indeed use a damage detection system, think of Impetus, Arcane Orb, Glaives of Wisdom, etc.
 

--Thanatos--

New Member
Reaction score
33
But Jones, yeah, Impetus, Arcane Orb, Glaives of Wisdom, and etc. you said uses damage detection system. However, it wasn't for Backstab and Greater Bash.
IceFrog uses Damage Detection System only for Orb Abilities.
 

soulreaping

New Member
Reaction score
17
Ok a few clarifications here:

1 - Craggy prevents the entire attack, from my experience with Tiny so I coded it that way.
2 - emjlr3, since you published it I thought it was ok, it's just another way to sort of advertise your spell. If you are not right with that, I'll remove it.
3 - About the Grow!, there is sense in what you are saying, vypur85, I'll update that.
 

soulreaping

New Member
Reaction score
17
Ok so I removed the Toss ability, and I added the Grow! suggestion for the periodic trigger.

And sorry emjlr3 for not asking for permission.
 

waaaks!

Zinctified
Reaction score
256
So where is ur own made toss ability

also...all the spells can be made in GUI....and more people like GUI than jass
and also, u used vjass for it, which makes people need to use newgen pack just to use the scripts

i suggest making it WE friendly scripts
 

soulreaping

New Member
Reaction score
17
My own Toss ability will come when I'll have the time.

I made it JASS because I hate GUI. It uses all those nasty BJs which we should all try to avoid.

I know most of the people here are GUIers, but JASS is so much better and flexible, and because these spells are pretty simple, it's good to learn from them.

And if people do use these spells, means they do use JASS and should have JASSHelper since it's much better than the WE normal compiler.
 

Cohadar

master of fugue
Reaction score
209
Dota does indeed use a damage detection system, think of Impetus, Arcane Orb, Glaives of Wisdom, etc.

nope, there is no such thing in dota.
I have looked at unprotected dota code and all those spells register unit_damaged event on cast.
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
>>Dota does indeed use a damage detection system, think of Impetus, Arcane Orb, Glaives of Wisdom, etc.
>>and all those spells register unit_damaged event on cast.
Aren't they are mostly same? It just need to trigger the trigger when a unit is damaged. (Or maybe attacked...when damaged is dealt)
 

emjlr3

Change can be a good thing
Reaction score
395
you can use Toss, just don't make assumptions next time around, the Tiny hero is not exactly completel without Toss is he
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      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