| 12-24-2009, 10:52 PM | #1 | |||||||
Well, heres a little spellpack i started 12 hours before the deadline of the fourth hero contest. Needless to say that i didnt finish until today. Its still missing the item, but whatever. I am proud to present to you the Disciple of Life, a supporting hero with a bit of a nuke side. The spells themselves are rather unoriginal, i admit. Then again, i havent seen many submissions using DamageModifiers yet, so these may be a good demonstration. First off: I used custom icons, because none of the Blizzard ones fit decently (imo). One of those icons is from WoW, i take permission as a given for that icon. As for the other three icons, heres the permission: These spells use:
And here are the spells: Seed of Life
Spell Code:library SeedOfLife initializer Init uses GroupUtils, DamageModifiers, SpellEvent, AutoIndex, IntuitiveBuffSystem, optional TimedHandles private keyword Data // DO NOT TOUCH! globals private constant integer AID = 'A001' // ability triggering this. Any unit targeting ability is fine. Used Bloodlust private constant integer BUFF_PLACER_AID = 'A004' // Ability placing BID on the unit this ability is added to. Based off of Slow Aura (Tornado). private constant integer BID = 'B000' // buff placed by BUFF_PLACER_AID on the target unit private constant string FX = "Abilities\\Spells\\Human\\Heal\\HealTarget.mdl" // displayed on the target unit when the effect of this ability is triggered. private constant string FX_ATTPT = "origin" private constant real FX_DURATION = 1.833 // 0 or less only plays the death animation // ignored if TimedHandles is not present in the map private constant string TARGET_FX = "" // displayed on the target of this spell private constant string TARGET_FX_ATTPT = "" // where to display the effect on the target of this spell private constant integer PRIORITY = 0 // when to trigger the effects of an instance of this spell when a unit receives damage // refer to DamageModifiers documentation private real array DURATION // how long does the buff last? private real array AOE // Heals all units around the damaged target in this area private real array CHANCE // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% private integer array MAX_HEALINGS // heal at most this many times // zero or less for no limit endglobals // how long does the buff last? private function Duration takes integer level returns real return DURATION[level] endfunction // Heals all units around the damaged target in this area private function Aoe takes integer level returns real return AOE[level] endfunction // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% private function Chance takes integer level returns real return CHANCE[level] endfunction // heal at most this many times // zero or less for no limit private function Max_Healings takes integer level returns integer return MAX_HEALINGS[level] endfunction private function SetUpSpellData takes nothing returns nothing // how long does the buff last? set DURATION[1]=7 set DURATION[2]=7 set DURATION[3]=7 // Heals all units around the damaged target in this area set AOE[1]=200 set AOE[2]=275 set AOE[3]=350 // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% set CHANCE[1]=1 set CHANCE[2]=1 set CHANCE[3]=1 // heal at most this many times // zero or less for no limit set MAX_HEALINGS[1]=0 set MAX_HEALINGS[2]=0 set MAX_HEALINGS[3]=0 endfunction // if you want to get the targets current HP, use GetUnitLife(whichUnit) // damage dealt to a unit with this buff active needs to be greater than what this function returns to be blocked private function Minimum_Damage takes integer level, unit target returns real return 0. endfunction // how much damage to block private function Damage_Blocked takes integer level, unit target, real damage returns real return 0. endfunction // how much health to restore after blocking private function Health_Restored takes integer level, unit target, real damage returns real return 10.+level*10. endfunction // how much health to heal units in the area private function Aoe_Heal takes integer level, unit target, real damage returns real return 10.+level*5. endfunction // only units matching these criteria will get healed private function ValidTarget takes unit u, unit caster returns boolean return IsUnitAlly(u, GetOwningPlayer(caster))/* */ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/* */ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/* */ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/* */ endfunction // globals private integer BuffType endglobals private struct Data extends DamageModifier unit caster unit target effect targetFx integer level integer healings=0 static thistype Tmps static real CurrentDamage static thistype array Instance private method onDestroy takes nothing returns nothing set Instance[GetUnitId(.target)]=0 set .caster=null set .target=null if TARGET_FX!="" then call DestroyEffect(.targetFx) set .targetFx=null endif endmethod private static method AoeHealEnum takes nothing returns boolean local unit u=GetFilterUnit() if u!=.Tmps.target and ValidTarget(u, .Tmps.caster) then call SetUnitLife(u, GetUnitLife(u)+Aoe_Heal(.Tmps.level, .Tmps.target, .CurrentDamage)) static if LIBRARY_TimedHandles then if FX_DURATION>0 then call DestroyEffectTimed(AddSpecialEffectTarget(FX, u, FX_ATTPT), FX_DURATION) else call DestroyEffect(AddSpecialEffectTarget(FX, u, FX_ATTPT)) endif else call DestroyEffect(AddSpecialEffectTarget(FX, u, FX_ATTPT)) endif endif set u=null return false endmethod private method onDamageTaken takes unit origin, real damage returns real local real blocked=0 if GetRandomReal(0,1)<=Chance(.level) and damage+0.406>=Minimum_Damage(.level, .target) then if ValidTarget(.target, .caster) then call SetUnitLife(.target, GetUnitLife(.target)+Health_Restored(.level, .target, damage)) static if LIBRARY_TimedHandles then if FX_DURATION>0 then call DestroyEffectTimed(AddSpecialEffectTarget(FX, .target, FX_ATTPT), FX_DURATION) else call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT)) endif else call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT)) endif set blocked=Damage_Blocked(.level, .target, damage) endif if Aoe(.level)>0. then set .Tmps=this set .CurrentDamage=damage call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(.target), GetUnitY(.target), Aoe(.level), Condition(function thistype.AoeHealEnum)) endif set .healings=.healings+1 if Max_Healings(.level)>0 and .healings>=Max_Healings(.level) then call UnitRemoveBuff(.target, BuffType) endif return -blocked endif return 0. endmethod static method create takes unit caster, unit target returns thistype local thistype s=Instance[GetUnitId(target)] if s==0 then set s=.allocate(target, PRIORITY) set s.caster=caster set s.target=target if TARGET_FX!="" then set s.targetFx=AddSpecialEffectTarget(TARGET_FX, target, TARGET_FX_ATTPT) endif set s.level=GetUnitAbilityLevel(caster, AID) set Instance[GetUnitId(target)]=s else if s.level<GetUnitAbilityLevel(caster, AID) then set s.caster=caster set s.healings=0 set s.level=GetUnitAbilityLevel(caster, AID) endif endif set UnitAddBuff(caster, target, BuffType, Duration(s.level), s.level).data=s return s endmethod static method BuffRemoved takes nothing returns nothing call thistype(GetEventBuff().data).destroy() endmethod endstruct private function CastResponse takes nothing returns nothing call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetUnit) endfunction private function Init takes nothing returns nothing call RegisterSpellEffectResponse(AID, CastResponse) set BuffType=DefineBuffType(BUFF_PLACER_AID, BID, 0, false, true, 0,0,Data.BuffRemoved) call SetUpSpellData() endfunction endlibrary Prolonged Life
Spell Code:library ProlongedLife initializer Init uses GroupUtils, DamageModifiers, SpellEvent, AutoIndex, IntuitiveBuffSystem, optional TimedHandles private keyword Data // DO NOT TOUCH! globals private constant integer AID = 'A000' // ability triggering this. Any unit targeting ability is fine. Used Channel private constant integer BUFF_PLACER_AID = 'A005' // Ability placing BID on the unit this ability is added to. Based off of Slow Aura (Tornado). private constant integer BID = 'B001' // buff placed by BUFF_PLACER_AID on the target unit private constant string FX = "Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl" // displayed on the target unit when the effect of this ability is triggered. private constant string FX_ATTPT = "origin" private constant real FX_DURATION = 0. // 0 or less only plays the death animation // ignored if TimedHandles is not present in the map private constant string TARGET_FX = "Abilities\\Spells\\Items\\HealingSalve\\HealingSalveTarget.mdl" // displayed on the target of this spell private constant string TARGET_FX_ATTPT = "head" // where to display the effect on the target of this spell private constant integer PRIORITY = 0 // when to trigger the effects of an instance of this spell when a unit receives damage // refer to DamageModifiers documentation private real array DURATION // how long does the buff last? private real array AOE // Heals all units around the damaged target in this area private real array CHANCE // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% private integer array MAX_HEALINGS // heal at most this many times // zero or less for no limit endglobals // how long does the buff last? private function Duration takes integer level returns real return DURATION[level] endfunction // Heals all units around the damaged target in this area private function Aoe takes integer level returns real return AOE[level] endfunction // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% private function Chance takes integer level returns real return CHANCE[level] endfunction // heal at most this many times // zero or less for no limit private function Max_Healings takes integer level returns integer return MAX_HEALINGS[level] endfunction private function SetUpSpellData takes nothing returns nothing // how long does the buff last? set DURATION[1]=8 set DURATION[2]=8 set DURATION[3]=8 // Heals all units around the damaged target in this area set AOE[1]=0 set AOE[2]=0 set AOE[3]=0 // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% set CHANCE[1]=1 set CHANCE[2]=1 set CHANCE[3]=1 // heal at most this many times // zero or less for no limit set MAX_HEALINGS[1]=1 set MAX_HEALINGS[2]=1 set MAX_HEALINGS[3]=1 endfunction // if you want to get the targets current HP, use GetUnitLife(whichUnit) // damage dealt to a unit with this buff active needs to be greater than what this function returns to be blocked private function Minimum_Damage takes integer level, unit target returns real return GetUnitLife(target) endfunction // how much damage to block private function Damage_Blocked takes integer level, unit target, real damage returns real return damage endfunction // how much health to restore after blocking private function Health_Restored takes integer level, unit target, real damage returns real return GetUnitLife(target)*0.1*level endfunction // how much health to heal units in the area private function Aoe_Heal takes integer level, unit target, real damage returns real return 0. endfunction // only units matching these criteria will get healed private function ValidTarget takes unit u, unit caster returns boolean return IsUnitAlly(u, GetOwningPlayer(caster))/* */ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/* */ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/* */ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/* */ endfunction // globals private integer BuffType endglobals private struct Data extends DamageModifier unit caster unit target effect targetFx integer level integer healings=0 static thistype Tmps static real CurrentDamage static thistype array Instance private method onDestroy takes nothing returns nothing set Instance[GetUnitId(.target)]=0 set .caster=null set .target=null if TARGET_FX!="" then call DestroyEffect(.targetFx) set .targetFx=null endif endmethod private static method AoeHealEnum takes nothing returns boolean local unit u=GetFilterUnit() if u!=.Tmps.target and ValidTarget(u, .Tmps.caster) then call SetUnitLife(u, GetUnitLife(u)+Aoe_Heal(.Tmps.level, .Tmps.target, .CurrentDamage)) static if LIBRARY_TimedHandles then if FX_DURATION>0 then call DestroyEffectTimed(AddSpecialEffectTarget(FX, u, FX_ATTPT), FX_DURATION) else call DestroyEffect(AddSpecialEffectTarget(FX, u, FX_ATTPT)) endif else call DestroyEffect(AddSpecialEffectTarget(FX, u, FX_ATTPT)) endif endif set u=null return false endmethod private method onDamageTaken takes unit origin, real damage returns real local real blocked=0 if GetRandomReal(0,1)<=Chance(.level) and damage+0.406>=Minimum_Damage(.level, .target) then if ValidTarget(.target, .caster) then call SetUnitLife(.target, GetUnitLife(.target)+Health_Restored(.level, .target, damage)) static if LIBRARY_TimedHandles then if FX_DURATION>0 then call DestroyEffectTimed(AddSpecialEffectTarget(FX, .target, FX_ATTPT), FX_DURATION) else call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT)) endif else call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT)) endif set blocked=Damage_Blocked(.level, .target, damage) endif if Aoe(.level)>0. then set .Tmps=this set .CurrentDamage=damage call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(.target), GetUnitY(.target), Aoe(.level), Condition(function thistype.AoeHealEnum)) endif set .healings=.healings+1 if Max_Healings(.level)>0 and .healings>=Max_Healings(.level) then call UnitRemoveBuff(.target, BuffType) endif return -blocked endif return 0. endmethod static method create takes unit caster, unit target returns thistype local thistype s=Instance[GetUnitId(target)] if s==0 then set s=.allocate(target, PRIORITY) set s.caster=caster set s.target=target if TARGET_FX!="" then set s.targetFx=AddSpecialEffectTarget(TARGET_FX, target, TARGET_FX_ATTPT) endif set s.level=GetUnitAbilityLevel(caster, AID) set Instance[GetUnitId(target)]=s else if s.level<GetUnitAbilityLevel(caster, AID) then set s.caster=caster set s.healings=0 set s.level=GetUnitAbilityLevel(caster, AID) endif endif set UnitAddBuff(caster, target, BuffType, Duration(s.level), s.level).data=s return s endmethod static method BuffRemoved takes nothing returns nothing call thistype(GetEventBuff().data).destroy() endmethod endstruct private function CastResponse takes nothing returns nothing call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetUnit) endfunction private function Init takes nothing returns nothing call RegisterSpellEffectResponse(AID, CastResponse) set BuffType=DefineBuffType(BUFF_PLACER_AID, BID, 0, false, true, 0,0,Data.BuffRemoved) call SetUpSpellData() endfunction endlibrary Smiting Zeal
Spell Code:library SmitingZeal initializer Init uses SpellEvent, GroupUtils globals private constant integer AID = 'A002' // any passive ability should do fine, preferably one that doesnt place a buff. private constant string DAMAGE_FX = "Abilities\\Spells\\Human\\Feedback\\SpellBreakerAttack.mdl" // effect displayed when a unit gets damaged by this ability private constant string DAMAGE_FX_ATTPT = "overhead" // where to display the effect private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC // what type of damage is dealt to enemy units surrounding the caster (magic, physical, pure, ...) private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC // what type of damage is dealt to enemy units surrounding the caster (magic, physical, pure, ...) private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS // sound played when a unit is damaged by this ability, WHOKNOWS or null for no sound. private real array AOE // enemy units within this radius get damaged private real array MANA_COST // this ability drains this much additional mana from the caster, values >0 but <1 are values relative to the maximum mana of the caster private constant boolean ENFORCE_MANA_COST = false // if true, the effects of this ability will only be triggered if the hero has enough mana, // if false, it will be triggered whether or not the caster has enough mana, and if he doesnt, // it will subtract the remaining mana points endglobals private function Aoe takes integer level returns real return AOE[level] endfunction private function Mana_Cost takes integer level returns real return MANA_COST[level] endfunction private function Damage takes unit caster, integer level returns real return GetHeroInt(caster, true)*(1.+level) endfunction private function SetUpSpellData takes nothing returns nothing set AOE[1]=300. set AOE[2]=375. set AOE[3]=450. set MANA_COST[1]=20. set MANA_COST[2]=20. set MANA_COST[3]=20. endfunction private function ValidateTarget takes unit u, unit caster returns boolean return IsUnitEnemy(u, GetOwningPlayer(caster))/* */ and IsUnitType(u, UNIT_TYPE_DEAD)==false/* */ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/* */ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/* */ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/* */ and IsUnitVisible(u, GetOwningPlayer(caster))/* */ endfunction // globals private boolexpr DamageFilter private real tmpdam endglobals private function DamageFilterFunc takes nothing returns boolean local unit u=GetFilterUnit() if ValidateTarget(u, SpellEvent.CastingUnit) then call UnitDamageTarget(SpellEvent.CastingUnit, u, tmpdam, true, true, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call DestroyEffect(AddSpecialEffectTarget(DAMAGE_FX, u, DAMAGE_FX_ATTPT)) endif set u=null return false endfunction private function CastResponse takes nothing returns nothing local integer level = GetUnitAbilityLevel(SpellEvent.CastingUnit, AID) local real cost=0 if level>0 then if Mana_Cost(level)>=1 then set cost=Mana_Cost(level) elseif Mana_Cost(level)>0 then set cost=Mana_Cost(level)*GetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA) endif if not ENFORCE_MANA_COST or GetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA)>=cost then call SetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA, RMaxBJ(GetUnitState(SpellEvent.CastingUnit, UNIT_STATE_MANA)-Mana_Cost(level), 0)) set tmpdam=Damage(SpellEvent.CastingUnit, level) call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(SpellEvent.CastingUnit), GetUnitY(SpellEvent.CastingUnit), Aoe(level), DamageFilter) endif endif endfunction private function Init takes nothing returns nothing call RegisterSpellEffectResponse(0, CastResponse) set DamageFilter=Condition(function DamageFilterFunc) call SetUpSpellData() endfunction endlibrary Reverse Damage
Spell Code:library ReverseDamage initializer Init uses GroupUtils, DamageModifiers, SpellEvent, AutoIndex, IntuitiveBuffSystem, optional TimedHandles private keyword Data // DO NOT TOUCH! globals private constant integer AID = 'A003' // ability triggering this. Any unit targeting ability is fine. Used Bloodlust private constant integer BUFF_PLACER_AID = 'A006' // Ability placing BID on the unit this ability is added to. Based off of Slow Aura (Tornado). private constant integer BID = 'B002' // buff placed by BUFF_PLACER_AID on the target unit private constant string FX = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl" // displayed on the target unit when the effect of this ability is triggered. private constant string FX_ATTPT = "head" private constant real FX_DURATION = 0. // 0 or less only plays the death animation // ignored if TimedHandles is not present in the map private constant string TARGET_FX = "Abilities\\Spells\\Items\\HealingSalve\\HealingSalveTarget.mdl" // displayed on the target of this spell private constant string TARGET_FX_ATTPT = "head" // where to display the effect on the target of this spell private constant integer PRIORITY = 0 // when to trigger the effects of an instance of this spell when a unit receives damage // refer to DamageModifiers documentation private real array DURATION // how long does the buff last? private real array AOE // Heals all units around the damaged target in this area private real array CHANCE // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% private integer array MAX_HEALINGS // heal at most this many times // zero or less for no limit endglobals // how long does the buff last? private function Duration takes integer level returns real return DURATION[level] endfunction // Heals all units around the damaged target in this area private function Aoe takes integer level returns real return AOE[level] endfunction // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% private function Chance takes integer level returns real return CHANCE[level] endfunction // heal at most this many times // zero or less for no limit private function Max_Healings takes integer level returns integer return MAX_HEALINGS[level] endfunction private function SetUpSpellData takes nothing returns nothing // how long does the buff last? set DURATION[1]=5 set DURATION[2]=5 set DURATION[3]=5 // Heals all units around the damaged target in this area set AOE[1]=0 set AOE[2]=0 set AOE[3]=0 // Chance to trigger this ability // 1.0 = 100% // 0.0 = 0% set CHANCE[1]=1 set CHANCE[2]=1 set CHANCE[3]=1 // heal at most this many times // zero or less for no limit set MAX_HEALINGS[1]=1 set MAX_HEALINGS[2]=1 set MAX_HEALINGS[3]=1 endfunction // if you want to get the targets current HP, use GetUnitLife(whichUnit) // damage dealt to a unit with this buff active needs to be greater than what this function returns to be blocked private function Minimum_Damage takes integer level, unit target returns real return 20. endfunction // how much damage to block private function Damage_Blocked takes integer level, unit target, real damage returns real return RMinBJ(damage, 100.) endfunction // how much health to restore after blocking private function Health_Restored takes integer level, unit target, real damage returns real return RMinBJ(damage, 100.) endfunction // how much health to heal units in the area private function Aoe_Heal takes integer level, unit target, real damage returns real return 0. endfunction // only units matching these criteria will get healed private function ValidTarget takes unit u, unit caster returns boolean return IsUnitAlly(u, GetOwningPlayer(caster))/* */ and IsUnitType(u, UNIT_TYPE_MECHANICAL)==false/* */ and IsUnitType(u, UNIT_TYPE_STRUCTURE)==false/* */ and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)==false/* */ endfunction // globals private integer BuffType endglobals private struct Data extends DamageModifier unit caster unit target effect targetFx integer level integer healings=0 static thistype Tmps static real CurrentDamage static thistype array Instance private method onDestroy takes nothing returns nothing set Instance[GetUnitId(.target)]=0 set .caster=null set .target=null if TARGET_FX!="" then call DestroyEffect(.targetFx) set .targetFx=null endif endmethod private static method AoeHealEnum takes nothing returns boolean local unit u=GetFilterUnit() if u!=.Tmps.target and ValidTarget(u, .Tmps.caster) then call SetUnitLife(u, GetUnitLife(u)+Aoe_Heal(.Tmps.level, .Tmps.target, .CurrentDamage)) static if LIBRARY_TimedHandles then if FX_DURATION>0 then call DestroyEffectTimed(AddSpecialEffectTarget(FX, u, FX_ATTPT), FX_DURATION) else call DestroyEffect(AddSpecialEffectTarget(FX, u, FX_ATTPT)) endif else call DestroyEffect(AddSpecialEffectTarget(FX, u, FX_ATTPT)) endif endif set u=null return false endmethod private method onDamageTaken takes unit origin, real damage returns real local real blocked=0 if GetRandomReal(0,1)<=Chance(.level) and damage+0.406>=Minimum_Damage(.level, .target) then if ValidTarget(.target, .caster) then call SetUnitLife(.target, GetUnitLife(.target)+Health_Restored(.level, .target, damage)) static if LIBRARY_TimedHandles then if FX_DURATION>0 then call DestroyEffectTimed(AddSpecialEffectTarget(FX, .target, FX_ATTPT), FX_DURATION) else call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT)) endif else call DestroyEffect(AddSpecialEffectTarget(FX, .target, FX_ATTPT)) endif set blocked=Damage_Blocked(.level, .target, damage) endif if Aoe(.level)>0. then set .Tmps=this set .CurrentDamage=damage call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(.target), GetUnitY(.target), Aoe(.level), Condition(function thistype.AoeHealEnum)) endif set .healings=.healings+1 if Max_Healings(.level)>0 and .healings>=Max_Healings(.level) then call UnitRemoveBuff(.target, BuffType) endif return -blocked endif return 0. endmethod static method create takes unit caster, unit target returns thistype local thistype s=Instance[GetUnitId(target)] if s==0 then set s=.allocate(target, PRIORITY) set s.caster=caster set s.target=target if TARGET_FX!="" then set s.targetFx=AddSpecialEffectTarget(TARGET_FX, target, TARGET_FX_ATTPT) endif set s.level=GetUnitAbilityLevel(caster, AID) set Instance[GetUnitId(target)]=s else if s.level<GetUnitAbilityLevel(caster, AID) then set s.caster=caster set s.healings=0 set s.level=GetUnitAbilityLevel(caster, AID) endif endif set UnitAddBuff(caster, target, BuffType, Duration(s.level), s.level).data=s return s endmethod static method BuffRemoved takes nothing returns nothing call thistype(GetEventBuff().data).destroy() endmethod endstruct private function CastResponse takes nothing returns nothing call Data.create(SpellEvent.CastingUnit, SpellEvent.TargetUnit) endfunction private function Init takes nothing returns nothing call RegisterSpellEffectResponse(AID, CastResponse) set BuffType=DefineBuffType(BUFF_PLACER_AID, BID, 0, false, true, 0,0,Data.BuffRemoved) call SetUpSpellData() endfunction endlibrary |
| 12-25-2009, 01:28 AM | #2 |
Nice spells, I like the idea of a support damage hero. The seed of life was my favorite. |
| 12-28-2009, 02:00 PM | #3 |
Version 1.0.1 Just noticed that another extension to the Hero Contest was granted. This is really unfortunate. |
| 02-04-2010, 08:22 PM | #4 |
All/most spells:
Seed of Life:
Prolonged Life:
Smiting Zeal:
Reverse damage:
|
| 02-04-2010, 09:50 PM | #5 | ||||||
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
@Smiting Zeal: Ill see what i can do to improve it. Thanks for the review. |
| 01-25-2011, 12:37 PM | #6 |
Version 1.1.0 |
| 01-25-2011, 08:41 PM | #7 |
Seed of life
Prolonged Life
Smiting Zeal
Reverse Damage
Reverse Damage, Prolonged Life and to a lesser extent Seed of Life are very similar spells. This is more of a hero design issue than a problem for a spell submission; after all, we accept single spells, so a spellpack with multiple similar spells is fine. Still, I wish the spells were a bit more diverse, if not in their default setups then at least in what their calibration sections allow you to do with them. For example, with a bit more calibration options, Reverse Damage and Prolong Life could be the same spell. You'd just need a constant to tell if the spell should only trigger on lethal damage or not, another to determine the damage reduction percentage (so you can just block damage or fully reverse it or anything in between) in addition to the calibration values of the existing two spells. A single spell like that (you could still have two separate spells in the map to showcase the flexibility of the code) would be worth more than those two spells currently are. Since these are meant to be buff spells, they should support dispel functionality. I realize the old periodic checks in combination with buff spells did this already, but that's a bad solution for multiple reasons: the periodic checks are wasteful and each such spell must be based on a different base spell (the number of which is limited) because buff spells based on the same spell don't stack. The latter is a problem even if you don't intend to support dispel, so instead, since you're already triggering large portions of the spell, it would be easy to use a self-targetting aura (auras, unlike buff spells, do stack even when based on the same ability) to display the buff. That still leaves the problem of detecting dispel, though, which could be solved by using a buff system like ABuff or IBS. Another thing that comes to mind (and I am getting slightly off-topic here) is that there is use for a healing library. With a healing event, we could make more interesting spells for a healer-type hero. There's this, but it's terribly old and should be replaced by something newer. |
| 01-28-2011, 04:01 PM | #8 |
Version 1.2.0 This should fix almost every issue you brought up, Anitarf. The only one it doesnt, is using a library dedicated to healing. And currently, i dont think i need to submit another library. |
| 01-28-2011, 08:59 PM | #9 | |
Quote:
Approved. |
| 01-28-2011, 11:22 PM | #10 |
There was a fourth spell contest? |
| 02-08-2011, 03:17 PM | #11 |
Version 1.2.1 Yes, i believe it was dropped though because only two people or so managed to submit an entry. |
