- Joined
- Sep 5, 2015
- Messages
- 369
I am really interested in learning more about triggers and novice level coding finally so im trying to learn as much as I can as i build this map, and after finding this ability i feel it is fairly simple (compared to other stuff i've seen on here...(>o.o<)) and would make a good learning stepping stone for me
p.s. first time ive posted triggers/script so forgive me if this is inefficient or a wrong way of posting
(QUESTION)
I downloaded blessed hammer ability (--> Blessed Hammer 1.11 ) And it runs fine
but I want to change some features about it:
the base damage it does, -> (i got a good idea how this works)
changing the scaling with damage based on amount of strength, -> (can't figure out how to scale it up per level:
level 1=2. level2=2.2. level3= 2.35. level4= 2.5 etc)
and removing the bonus damage to undead units -> (i got a good idea how this works)
the hitbox of the hammers, -> (i got NO clue how to even look for this one in the code)
just to make sure I dont screw up the entire spell and potentially break my map I would like some confirmation on what i think i need to do. I don't know really anything about coding but with my limited experience, for example, i can see that-> private constant real Hammer_Damage_Range = 128.0 might potentially be the "hitbox" of the hammers because they seem about as big as that. but i also think thats the distance inbetween the hammers themself? also there is code->
set damage = 25.0 + 25.0*h.abi_lvl
set damage = damage + 2.0 * GetHeroStr(h.caster, /include_bonuses:/ true)
if IsUnitType(target, UNIT_TYPE_UNDEAD) then
// evil beware!
set damage = 2.0 * damage
endif
which gives bonus damage (2 x str level) and i assume if i were to change that to say 1? it would be an easy adjust? also i also see set damage = 25.0+25.0*h.abi lvl (the first level is 50 damage so i assume that line would change the base damage, example, 50 + 25*h.abi lvl would make the first level deal 75 damage. 25*h.abi lvl simply means 25 x the ability level correct? so at level 4 it should be 200? this works when ive tried it so im running with it. but again i dont want it to like crash later on or something? lol
Thanks,
code below and link again: Blessed Hammer 1.11
p.s. first time ive posted triggers/script so forgive me if this is inefficient or a wrong way of posting
(QUESTION)
I downloaded blessed hammer ability (--> Blessed Hammer 1.11 ) And it runs fine
but I want to change some features about it:
the base damage it does, -> (i got a good idea how this works)
changing the scaling with damage based on amount of strength, -> (can't figure out how to scale it up per level:
level 1=2. level2=2.2. level3= 2.35. level4= 2.5 etc)
and removing the bonus damage to undead units -> (i got a good idea how this works)
the hitbox of the hammers, -> (i got NO clue how to even look for this one in the code)
just to make sure I dont screw up the entire spell and potentially break my map I would like some confirmation on what i think i need to do. I don't know really anything about coding but with my limited experience, for example, i can see that-> private constant real Hammer_Damage_Range = 128.0 might potentially be the "hitbox" of the hammers because they seem about as big as that. but i also think thats the distance inbetween the hammers themself? also there is code->
set damage = 25.0 + 25.0*h.abi_lvl
set damage = damage + 2.0 * GetHeroStr(h.caster, /include_bonuses:/ true)
if IsUnitType(target, UNIT_TYPE_UNDEAD) then
// evil beware!
set damage = 2.0 * damage
endif
which gives bonus damage (2 x str level) and i assume if i were to change that to say 1? it would be an easy adjust? also i also see set damage = 25.0+25.0*h.abi lvl (the first level is 50 damage so i assume that line would change the base damage, example, 50 + 25*h.abi lvl would make the first level deal 75 damage. 25*h.abi lvl simply means 25 x the ability level correct? so at level 4 it should be 200? this works when ive tried it so im running with it. but again i dont want it to like crash later on or something? lol
Thanks,
code below and link again: Blessed Hammer 1.11
vJASS:
library Hammer initializer init
globals
private constant real Tau = 6.283185
private constant integer Ability_Id = 'A000'
private constant integer Dummy_Id = 'e000'
private constant real Dt = 1.0 / 32.0
private constant real Hammer_Duration = 6.0 // in seconds
private constant real Hammer_Rot_Speed = Tau / 1.65 // in radians per second
private constant real Hammer_Outward_Speed = 112.0 // in units per second
private constant real Hammer_Damage_Range = 128.0
private constant real Hammer_Damage_Again_Delay = 0.85
private constant string Hammer_On_Hit_Effect_Model = "Abilities\\Weapons\\GryphonRiderMissile\\GryphonRiderMissile.mdl"
private constant real Hammer_Fly_Height = 96.0
endglobals
private struct Hammer
Hammer prev
Hammer next
integer abi_lvl
unit du
unit caster
player caster_owner
real start_pos_x
real start_pos_y
real pos_x
real pos_y
real outward_radius
real rot_dir
integer duration // in ticks per second
endstruct
native UnitAlive takes unit u returns boolean
private function target_allowed takes unit target, Hammer h returns boolean
return UnitAlive(target) and IsUnitEnemy(target, h.caster_owner)
endfunction
private function hammer_damage_target takes Hammer h, unit target returns nothing
local boolean melee_attack = false
local boolean range_attack = true
local attacktype attack_type = ATTACK_TYPE_NORMAL // spell
local damagetype damage_type = DAMAGE_TYPE_UNIVERSAL // ignore armor value
local weapontype weapon_type = WEAPON_TYPE_WHOKNOWS
local real damage
set damage = 25.0 + 25.0*h.abi_lvl
set damage = damage + 2.0 * GetHeroStr(h.caster, /[I]include_bonuses:[/I]/ true)
if IsUnitType(target, UNIT_TYPE_UNDEAD) then
// evil beware!
set damage = 2.0 * damage
endif
call UnitDamageTarget(h.caster, target, damage, melee_attack, range_attack, attack_type, damage_type, weapon_type)
endfunction
// These should suffice, but we should probably use a dummy recycling library instead.
//
globals
private unit dummy_spawn_result
endglobals
private function dummy_spawn takes player caster_owner, real start_pos_x, real start_pos_y returns unit
set dummy_spawn_result = CreateUnit(caster_owner, Dummy_Id, start_pos_x, start_pos_y, 0.0)
call SetUnitFlyHeight(dummy_spawn_result, Hammer_Fly_Height, 0.0)
return dummy_spawn_result
endfunction
private function dummy_remove takes unit dummy returns nothing
call RemoveUnit(dummy)
endfunction
// We need to save the time when a unit was last damaged by a hammer.
//
globals
private hashtable ht = InitHashtable()
endglobals
private function unit_get_last_time_damaged_by_hammer takes unit u, Hammer hammer returns real
return LoadReal(ht, integer(hammer), GetHandleId(u))
endfunction
private function unit_set_last_time_damaged_by_hammer takes unit u, Hammer hammer, real value returns nothing
call SaveReal(ht, integer(hammer), GetHandleId(u), value)
endfunction
private function hammer_clear_units_last_damaged_times takes Hammer hammer returns nothing
call FlushChildHashtable(ht, integer(hammer))
endfunction
private function hammer_spawn takes unit caster returns Hammer
local Hammer h = Hammer.create() // Hammer.allocate()
local real start_pos_x = GetUnitX(caster)
local real start_pos_y = GetUnitY(caster)
set h.abi_lvl = GetUnitAbilityLevel(caster, Ability_Id)
set h.caster = caster
set h.caster_owner = GetOwningPlayer(caster)
set h.du = dummy_spawn(h.caster_owner, start_pos_x, start_pos_y)
set h.start_pos_x = start_pos_x
set h.start_pos_y = start_pos_y
set h.pos_x = start_pos_x
set h.pos_y = start_pos_y
set h.outward_radius = 0.0
set h.rot_dir = 0.0
set h.duration = R2I(Hammer_Duration * (1.0 / Dt))
return h
endfunction
private function hammer_remove takes Hammer h returns nothing
set h.caster = null
call dummy_remove(h.du)
call hammer_clear_units_last_damaged_times(h)
call h.destroy() // h.deallocate()
endfunction
globals
private real now = 0.0
endglobals
private function update_now takes nothing returns nothing
set now = now + 0.03125 // 1.0 / 32.0
endfunction
globals
private group targets = CreateGroup()
endglobals
private function deal_damage_in_range takes Hammer h, real range returns nothing
local unit u
local real t
call GroupEnumUnitsInRange(targets, h.pos_x, h.pos_y, 192.0 + Hammer_Damage_Range, /[I]filter:[/I]/ null)
call GroupRemoveUnit(targets, h.caster)
loop
set u = FirstOfGroup(targets)
exitwhen u == null
call GroupRemoveUnit(targets, u)
if IsUnitInRangeXY(u, h.pos_x, h.pos_y, Hammer_Damage_Range) and target_allowed(u, h) then
set t = unit_get_last_time_damaged_by_hammer(u, h)
if now - t >= Hammer_Damage_Again_Delay then
call unit_set_last_time_damaged_by_hammer(u, h, now)
call hammer_damage_target(h, u)
if UnitAlive(u) then
call DestroyEffect(AddSpecialEffectTarget(Hammer_On_Hit_Effect_Model, u, "head"))
else
call DestroyEffect(AddSpecialEffect(Hammer_On_Hit_Effect_Model, GetUnitX(u), GetUnitY(u)))
endif
endif
endif
endloop
endfunction
globals
// the sentinel node of the doubly linked list of all hammers
private Hammer hammers = Hammer(0)
// implicitly we have
// hammers.prev = hammers
// hammers.next = hammers
private timer ticker = CreateTimer()
endglobals
private function hammer_do_every_tick takes Hammer h returns nothing
set h.pos_x = h.start_pos_x + Dt * h.outward_radius * Cos(h.rot_dir)
set h.pos_y = h.start_pos_y + Dt * h.outward_radius * Sin(h.rot_dir)
set h.rot_dir = h.rot_dir + Dt * Hammer_Rot_Speed
set h.outward_radius = h.outward_radius + Hammer_Outward_Speed
call SetUnitX(h.du, h.pos_x)
call SetUnitY(h.du, h.pos_y)
call SetUnitFacing(h.du, h.rot_dir * 57.295779 + 90.0)
call deal_damage_in_range(h, Hammer_Damage_Range)
endfunction
private function hammers_do_every_tick takes nothing returns nothing
local Hammer h
local Hammer next
set h = hammers.next
if h == hammers then
call PauseTimer(ticker)
return
endif
loop
exitwhen h == hammers
if h.duration == 0 then
set next = h.next
set h.prev.next = h.next
set h.next.prev = h.prev
call hammer_remove(h)
set h = next
else
set h.duration = h.duration - 1
call hammer_do_every_tick(h)
set h = h.next
endif
endloop
endfunction
private function on_spell_effect takes nothing returns nothing
local Hammer h
if Ability_Id != GetSpellAbilityId() then
return
endif
set h = hammer_spawn(GetTriggerUnit())
set h.prev = hammers.prev
set h.next = hammers
set h.prev.next = h
set h.next.prev = h
call hammer_do_every_tick(h)
if h.prev == hammers then
call TimerStart(ticker, Dt, true, function hammers_do_every_tick)
endif
endfunction
private function init takes nothing returns nothing
local trigger t
call TimerStart(CreateTimer(), Dt, true, function update_now)
// should probably use a "better" on ability spell effect dispatch mechanism
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function on_spell_effect)
endfunction
endlibrary
Last edited by a moderator: