Well, I'm choosing over a Moonmage, a Moonkin, an Ancient and a Wisp. Please help me.
What about Zoidberg?
Why not?
Haha
Well actually, why not give the Wisp a spotlight?
I agree with Almia.
You could name the wisp to something like Cosmic Soul or among those lines.
Ergh done as in done before this contest?
Nah, using Male Night Elf Names.
Hero Change; Gryphon Master
Q - Hammerfall
Throws a hammer to a target location, dealing 70/110/150 damage and slowing nearby enemies by 25/30/35% for 3 seconds. It remains on the ground afterwards for 3 seconds.
W - Cohesive Strike
Pulls enemies towards the Gryphon Master (or Hammerfall, if it is on the ground), allowing them to take 15/20/25% more damage for 3 seconds.
E - Shock Blast
Every 5 seconds, the Gryphon Master's attack becomes splash and deals 80/110/140% of Strength as bonus damage to the main target. The cooldown is reduced by attacks.
R - Skydive
Swoops to the ground below and takes flight once more, dragging enemies caught. Afterwards, the Gryphon Master gains 100% Attack Speed and a 20% damage resistance for 4 seconds.
Hero Change; Gryphon Master
Q - Hammerfall
Throws a hammer to a target location, dealing 70/110/150 damage and slowing nearby enemies by 25/30/35% for 3 seconds. It remains on the ground afterwards for 3 seconds.
W - Cohesive Strike
Pulls enemies towards the Gryphon Master (or Hammerfall, if it is on the ground), allowing them to take 15/20/25% more damage for 3 seconds.
E - Shock Blast
Every 5 seconds, the Gryphon Master's attack becomes splash and deals 80/110/140% of Strength as bonus damage to the main target. The cooldown is reduced by attacks.
R - Skydive
Swoops to the ground below and takes flight once more, dragging enemies caught. Afterwards, the Gryphon Master gains 100% Attack Speed and a 20% damage resistance for 4 seconds.
RESPONSE: So it's a flying hero? If so, I think that it would not fit into a basic Warcraft 3 hero criteria. That hero would be far to powerful at the start of the game. He would be able to easily harass enemy workers then hide in the trees before the enemy could even get the economy to make anti-air. Otherwise, I like the ideas of your abilities. I makes it more fast-paced, and really take advantage of the short time effects that are bestowed upon the hero and penalize the enemy. But the 3rd ability (Shock Blast) doesn't really fit in my opinion. The whole stat-based abilities are not something that the heroes should utilize in a vanilla game. |
Lol, well 'great minds think alike' I suppose.Well actually I was looking at the D3 Wizard kit when I worked on this
Maybe I could make it so Polymastery deals less damage, but reduces the armor of any unit caught in the AoE.
Well the Rule(s) were there somewhere (2nd post I believe?), but the "this is going to be the Contest Thread" part didn't show up until near the end. Still, to be fair, that was a couple weeks of waiting yet.Just remove the rule, it's that simple (I mean after you receive a response from whomever you asked). There's no need to "fix" the rule because it makes no sense in the first place. I don't recall seeing it in the year-long write-up. If I did, I would have warned you sooner.
I don't see why not. It already exists in the MPQs, right? If so, I think it'd be a nice creative choice to liven things up a bit. (Now, I don't know how you go about using it... Aside from importing it separately under the old texture's path??... I wonder if that should be Kosher...)good question, I could also use that beta Ranger skin found in War3.mpq to overwrite the present one. Can I do that?
Oh man, another Night Elf?? That's crazy; usually it's Orcs & Undead that get all the love. I'm excited for the challenge.Well, I'm choosing over a Moonmage, a Moonkin, an Ancient and a Wisp. Please help me.
Lawl.What about Zoidberg?
That's really interesting, & I'd love to see a good "Gryphon Rider" hero... However Wa666r has the right of it (on all counts); really can't have Flying Heroes. There's a reason (I believe) that Blizzard initially had them (flying PotM, flying Far Seer, etc), but then took them out.Hero Change; Gryphon Master
Q - Hammerfall
Throws a hammer to a target location, dealing 70/110/150 damage and slowing nearby enemies by 25/30/35% for 3 seconds. It remains on the ground afterwards for 3 seconds.
W - Cohesive Strike
Pulls enemies towards the Gryphon Master (or Hammerfall, if it is on the ground), allowing them to take 15/20/25% more damage for 3 seconds.
E - Shock Blast
Every 5 seconds, the Gryphon Master's attack becomes splash and deals 80/110/140% of Strength as bonus damage to the main target. The cooldown is reduced by attacks.
R - Skydive
Swoops to the ground below and takes flight once more, dragging enemies caught. Afterwards, the Gryphon Master gains 100% Attack Speed and a 20% damage resistance for 4 seconds.
I can't say that (not being a Judge). I would venture to say "No", or at least "Not Exactly"; if there's a better model you might get rated higher, but doing what you're doing won't necessarily rate you lower. At least I hope not.Anyways, Kyrbi0, will my score get reduced if I use a unit model for the same race?
Hmm... Close but thankfully not too close...Well im going with a Primal Druid thing of some sort, using the Druid of the Claw model.
So you're saying it shouldn't be fixed, simply removed. The result is anyone can use any system/spell/snippet/etc anywhere in existence, regardless of whether it has been created, submitted or approved before, during or after this Contest.
Then why even stop people from using Code they may have previously made?
Nor am I trying to argue; this is merely a good discussion (maybe 'debate'). : )I don't want to argue about this, but I'm just trying to say that you can't distinguish "systems" from "non-systems" with such fervor.
It looks like that's somewhere we can agree (cheaters being disqualified ('cheating' being defined as "using code written before the Contest").Cokemonkey11 said:People should be disqualified for cheating (writing spells before the contest starts), and that should be at the discretion of the judges in a logical way.
Umm, yes? Many times? Why?um have you people ever played a melle map without cheats?
RESPONSE:
So it's a flying hero? If so, I think that it would not fit into a basic Warcraft 3 hero criteria. That hero would be far to powerful at the start of the game. He would be able to easily harass enemy workers then hide in the trees before the enemy could even get the economy to make anti-air.
Otherwise, I like the ideas of your abilities. I makes it more fast-paced, and really take advantage of the short time effects that are bestowed upon the hero and penalize the enemy. But the 3rd ability (Shock Blast) doesn't really fit in my opinion. The whole stat-based abilities are not something that the heroes should utilize in a vanilla game.
A big possible problem of this contest is that people might think with DotA mind and not with melee mind. That means, low duration of negative buffs, focusing on damage and ultimates which deal damage (if you look well to most of the ultimates of melee heroes, they are either summoning an ultimate monster or an AoE non-damaging spell)
With that being said, I'm afraid some people might go off-course and forget that this hero should be made for melee game, not for an AoS or Hero Arena
i was talking about people who have submitted something it does not feel like melle its either too overpowered or too visually heavy
Well, here are my latest WIP's:![]()
![]()
![]()
![]()
![]()
Ranger abilities:
Flaming Arrows, Cold Arrows, Swiftness Aura and Black Arrow. (All from alpha)
PS: Some icons such as swiftness aura, black arrow are temporary.
lol, I think he is not being serious at allThe abilities are different so it's original.![]()
/*
* FROZEN SPELLPACK
* v1.0
* This spellpack cosists of 4 active spells.
* They are Cold Addict, Frostwave, Frost
* Phase, and Hailstorm (ultimate).
* Their codes are packed into one library
* means that they are requiring each other.
* !This spellpack requires JNGP to work!
* How to install:
* - Install and configure all external
* dependecies properly.
* - Copy all abilities (OE) in Undead group.
* - Copy dummy unit (OE) and it's model to
* your map.
* - Configure the spells.
* External Dependencies:
* Required:
* - CTL
* - Dummy
* - IsTerrainWalkable
* - WorldBounds
* - UnitIndexer
*
* Optional:
* - SpellEffectEvent
* - AutoFly
* Credits:
* - Nestharus
* - Bribe
* - Cokemonkey11
* - Magtheridon96
*/
scope FrozenSpellpack
/*
* CONFIGURATION
* Configuration is separated into several
* parts. Each part is reserved for one spell.
*/
/* A. Global */
globals
/* Dummy unit's rawcode at Object Editor */
private constant integer DUMMY_ID = 'h000'
/* General decay time for all created sfx */
private constant real SFX_DECAY_TIME = 2.0
endglobals
/* B. Slow */
private module SlowData
/* Slow ability's rawcode at Object Editor */
static constant integer SPELL_ID = 'A004'
/* Slow buff's rawcode at Object Editor */
static constant integer BUFF_ID = 'B001'
/* Slow order id */
static constant integer SLOW_ORDER = 852096 /* thunderclap */
/* Attached sfx on slow targets */
static constant string SLOW_SFX = "Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl"
static constant string SLOW_SFX_PT = "chest"
/* Duration is stackable */
static constant boolean STACKABLE = true
/* Will reset the duration if not stacked */
static constant boolean RESETABLE = false
endmodule
/* C. Freeze */
private module FreezeData
/* Freeze ability's rawcode at Object Editor */
static constant integer SPELL_ID = 'A008'
/* Freeze buff's rawcode at Object Editor */
static constant integer BUFF_ID = 'B000'
/* Freeze order id */
static constant integer FREEZE_ORDER = 852127 /* stomp */
/* Attached sfx on freeze targets */
static constant string FREEZE_SFX = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl"
static constant string FREEZE_SFX_PT = "origin"
/* Duration is stackable */
static constant boolean STACKABLE = false
/* Will reset the duration if not stacked */
static constant boolean RESETABLE = false
endmodule
/*
* COLD ADDICT
* Inflicts frost magic at a target, slowing
* it's movement and attack rate, and stopping
* any mana regeneration. All damages taken
* from caster's spell will be amplified.
*/
private module ColdAddictData
/* Main ability's rawcode at Object Editor */
static constant integer SPELL_ID = 'A001'
/* Attached sfx on targets */
static constant string TARGET_SFX = "Abilities\\Spells\\Items\\AIob\\AIobTarget.mdl"
static constant string TARGET_SFX_PT = "overhead"
/* Damage amplification is stackable */
static constant boolean STACKABLE_BUFF = false
/* Duration is stackable */
static constant boolean STACKABLE_DUR = false
/* Will reset the duration if not stacked */
static constant boolean RESETABLE = false
/* Damage amplification amount */
static constant method amount takes integer l returns real
return -5.0 + 15.0 * l
endmethod
/* Buff duration on normal units */
static constant method durationNormal takes integer l returns real
return 6.0
endmethod
/* Buff duration on hero units */
static constant method durationHero takes integer l returns real
return 4.0
endmethod
endmodule
/*
* FROSTWAVE
* Sends a lance of ice shards wave to the
* target point, dealing damage to land units
* in a line and slowing them for a short
* duration.
*/
private module FrostwaveData
/* Main ability's rawcode at Object Editor */
static constant integer SPELL_ID = 'A000'
/* Total of created missiles on every cast */
static constant integer SHARD_COUNT = 23
/* Normal height z for every missile */
static constant real LAUNCH_Z = 64.0
/* Initial speed of every missile */
static constant real SPEED_MIN = 20.0
/* Maximum speed of every missile */
static constant real SPEED_MAX = 40.0
/* Acceleration rate of every missile */
static constant real ACCELERATION = 0.25
/* Turning rate of every missile */
static constant real TURN_RATE = 12.5 * bj_DEGTORAD
/* Missile model path */
static constant string MISSILE_PATH = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl"
/* Attached sfx on targets */
static constant string TARGET_SFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
static constant string TARGET_SFX_PT = "origin"
/* Dealt damage configuration */
static constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
static constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
static constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
/* Max distance from missile to hits a target */
static constant method aoe takes integer l returns real
return 75.0
endmethod
/* Dealt damage amount */
static constant method damage takes integer l returns real
return 60.0 * l
endmethod
/* Travel distance of every missile */
static constant method distance takes integer l returns real
return 1000.0
endmethod
/* Slow duration for normal units */
static constant method durationNormal takes integer l returns real
return 2.75
endmethod
/* Slow duration for hero units */
static constant method durationHero takes integer l returns real
return 1.325
endmethod
/* Configure the targets */
static method filter takes unit u, player p returns boolean
return not(IsUnitAlly(u, p) or IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE))
endmethod
endmodule
/*
* FROST PHASE
* Instantly vanishes to the target point.
* Leaving ice explosion behind and at the
* target point. Freezes nearby enemy units
* for a short duration and deals minor damage
*/
private module FrostPhaseData
/* Main ability's rawcode at Object Editor */
static constant integer SPELL_ID = 'A007'
/* How often the spell will check terrain's pathability */
static constant real ACCURACY = 20.0 /* pixel */
/* Explosion sfx */
static constant real EXPLODE_SIZE = 2.0
static constant string EXPLODE_SFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
/* Only damage once for each target */
static constant boolean DAMAGE_ONCE = false
/* Dealt damage configuration */
static constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
static constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
static constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
/* Dealt damage amount */
static constant method damage takes integer l returns real
return 20.0 + 10.0 * l
endmethod
/* Max range from the center of explosion to hit a target */
static constant method aoe takes integer l returns real
return 250.0
endmethod
/* Max teleport distance */
static constant method distance takes integer l returns real
return 300.0 + 100.0 * l
endmethod
/* Freeze duration for normal units */
static constant method durationNormal takes integer l returns real
return 0.9 + 0.45 * l
endmethod
/* Freeze duration for hero units */
static constant method durationHero takes integer l returns real
return 0.45 + 0.225 * l
endmethod
/* Configure the targets */
static method filter takes unit u, player p returns boolean
return not(IsUnitAlly(u, p) or IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE))
endmethod
endmodule
private module HailstormData
static constant integer SPELL_ID = 'A003'
static constant real TARGET_Z = 350.0
static constant real LAUNCH_Z = 64.0
static constant boolean FAIL_STOP = false
static constant string MISSILE_PATH = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl"
static constant string CHANNEL_ORDER = "blizzard"
static constant method count takes integer l returns integer
return 1
endmethod
static constant method accuracy takes integer l returns real
return 4.5
endmethod
static constant method turning takes integer l returns real
return 5.0 * bj_DEGTORAD
endmethod
static constant method cdelay takes integer l returns real
return 0.2
endmethod
static constant method cdelayv takes integer l returns real
return 0.2
endmethod
static constant method cduration takes integer l returns real
return 10.0
endmethod
static constant method cradius takes integer l returns real
return 225.0
endmethod
static constant method fdamage takes integer l returns real
return 110.0
endmethod
static constant method faoe takes integer l returns real
return 75.0
endmethod
static constant method fdelay takes integer l returns real
return 0.1
endmethod
static constant method fduration takes integer l returns real
return 1.25
endmethod
endmodule
native UnitAlive takes unit id returns boolean
/* Function that returns distance between coordinates */
private function getDistance takes real x, real y, real xt, real yt returns real
return SquareRoot((xt - x) * (xt - x) + (yt - y) * (yt - y))
endfunction
/* Function that returns angle between coordinates */
private function getAngle takes real x, real y, real xt, real yt returns real
return Atan2(yt - y, xt - x)
endfunction
private function isInBound takes real x, real y returns boolean
return x >= WorldBounds.minX and x <= WorldBounds.maxX and y >= WorldBounds.minY and y <= WorldBounds.maxY
endfunction
private struct Slow extends array
implement SlowData
unit u
real d /* duration */
effect s
static unit c
static boolean array b
static thistype array dex
implement CTLExpire
if .d > 0 then
set .d = .d - .03125
if .d <= 0 or not UnitAlive(.u) then
call DestroyEffect(.s)
call UnitRemoveAbility(.u, BUFF_ID)
set b[GetUnitUserData(.u)] = false
call destroy()
endif
endif
implement CTLEnd
static method apply takes unit u, real d returns nothing
local thistype this
local integer i = GetUnitUserData(u)
if b[i] then
set this = dex[i]
/* Stack */
static if thistype.STACKABLE then
set .d = .d + d
else
/* Reset */
static if thistype.RESETABLE then
set .d = d
endif
endif
else
call SetUnitX(c, GetUnitX(u))
call SetUnitY(c, GetUnitY(u))
call IssueImmediateOrderById(c, SLOW_ORDER)
call SetUnitX(c, WorldBounds.maxX)
call SetUnitY(c, WorldBounds.maxY)
/* Check if the target is successfully buffed */
if GetUnitAbilityLevel(u, BUFF_ID) > 0 then
set this = create()
set .u = u
set .d = d
set .s = AddSpecialEffectTarget(SLOW_SFX, u, SLOW_SFX_PT)
set b[i] = true
set dex[i] = this
endif
endif
endmethod
static method onInit takes nothing returns nothing
set c = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
call UnitAddAbility(c, SPELL_ID)
endmethod
endstruct
private struct Freeze extends array
implement FreezeData
unit u
real d /* duration */
effect s
static unit c
static boolean array b
static thistype array dex
implement CTLExpire
if .d > 0 then
set .d = .d - .03125
if .d <= 0 or not UnitAlive(.u) then
call DestroyEffect(.s)
call UnitRemoveAbility(.u, BUFF_ID)
set b[GetUnitUserData(.u)] = false
call destroy()
endif
endif
implement CTLEnd
static method apply takes unit u, real d returns nothing
local thistype this
local integer i = GetUnitUserData(u)
if b[i] then
set this = dex[i]
/* Stack */
static if thistype.STACKABLE then
set .d = .d + d
else
/* Reset */
static if thistype.RESETABLE then
set .d = d
endif
endif
else
call SetUnitX(c, GetUnitX(u))
call SetUnitY(c, GetUnitY(u))
call IssueImmediateOrderById(c, FREEZE_ORDER)
call SetUnitX(c, WorldBounds.maxX)
call SetUnitY(c, WorldBounds.maxY)
/* Check if the target is successfully buffed */
if GetUnitAbilityLevel(u, BUFF_ID) > 0 then
set this = create()
set .u = u
set .d = d
set .s = AddSpecialEffectTarget(FREEZE_SFX, u, FREEZE_SFX_PT)
set b[i] = true
set dex[i] = this
endif
endif
endmethod
private static method onInit takes nothing returns nothing
set c = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
call UnitAddAbility(c, SPELL_ID)
endmethod
endstruct
/* Destroying Dummy after certain duration */
private struct RecycleBin extends array
real d /* duration */
Dummy u
implement CTLExpire
set .d = .d - .03125
if .d <= 0 then
call .u.destroy()
call destroy()
endif
implement CTLEnd
static method add takes Dummy u returns nothing
local thistype this = create()
set .d = SFX_DECAY_TIME
set .u = u
endmethod
endstruct
/* Cold Addict spell*/
scope ColdAddict
private struct ColdAddict extends array
implement ColdAddictData
unit u
real d /* duration */
real m /* mana */
effect s
static real array a /* amount */
static boolean array b
static thistype array dex
implement CTLExpire
set .d = .d - .03125
/* Stops mana regeneration */
call SetUnitState(.u, UNIT_STATE_MANA, .m)
if .d <= 0 or not UnitAlive(.u) then
call DestroyEffect(.s)
set b[GetUnitUserData(.u)] = false
call destroy()
endif
implement CTLEnd
static method onCast takes nothing returns boolean
local thistype this = create()
local unit t = GetSpellTargetUnit()
local integer i = GetUnitUserData(t)
local integer l = GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID)
if b[i] then
set this = dex[i]
static if thistype.STACKABLE_DUR then
if IsUnitType(t, UNIT_TYPE_HERO) then
set .d = .d + durationHero(l)
else
set .d = .d + durationNormal(l)
endif
/*
* Prevent slow buff from being removed before
* cold addict has expired
*/
if Slow.dex[i].d < .d then
set Slow.dex[i].d = .d
endif
else
static if thistype.RESETABLE then
if IsUnitType(t, UNIT_TYPE_HERO) then
set .d = .d + durationHero(l)
else
set .d = .d + durationNormal(l)
endif
/*
* Prevent slow buff from being removed before
* cold addict has expired
*/
if Slow.dex[i].d < .d then
set Slow.dex[i].d = .d
endif
endif
endif
/* Stack amplification amount */
static if thistype.STACKABLE_BUFF then
set a[i] = a[i] + amount(l)
endif
else
set this = create()
set .u = t
set .m = GetUnitState(.u, UNIT_STATE_MANA)
if IsUnitType(.u, UNIT_TYPE_HERO) then
set .d = .d + durationHero(l)
else
set .d = .d + durationNormal(l)
endif
set a[i] = amount(l)
set b[i] = true
set dex[i] = this
call Slow.apply(.u, .d)
set .s = AddSpecialEffectTarget(TARGET_SFX, .u, TARGET_SFX_PT)
endif
set t = null
return false
endmethod
static if not LIBRARY_SpellEffectEvent then
private static method check takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
call thistype.onCast()
endif
return false
endmethod
endif
static method onInit takes nothing returns nothing
local trigger t
static if LIBRARY_SpellEffectEvent then
call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast)
else
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.check))
endif
endmethod
endstruct
endscope
/* Frostwave spell*/
scope Frostwave
private struct data extends array
implement FrostwaveData
static constant real ANGLE_ADD = (bj_PI * 2)/data.SHARD_COUNT
endstruct
private module KillShard
call SetUnitX(i.m.u[j].unit, i.tX)
call SetUnitY(i.m.u[j].unit, i.tY)
call DestroyEffect(i.m.e[j])
call RecycleBin.add(i.m.u[j])
set i.m.e[j] = null
set i.m.b[j] = false
set i.m.c = i.m.c - 1
if i.m.c < 0 then
call i.m.destroy()
set b = true
endif
endmodule
private keyword Frostwave
private struct IceShard
integer c
real array a[data.SHARD_COUNT]
real array s[data.SHARD_COUNT]
real array x[data.SHARD_COUNT]
real array y[data.SHARD_COUNT]
Dummy array u[data.SHARD_COUNT]
boolean array b[data.SHARD_COUNT]
effect array e[data.SHARD_COUNT]
/* For FoG looping */
static group t = CreateGroup()
/* Function to compare two distances */
static method inRadius takes real x, real y, real xt, real yt, real r returns boolean
return (x - xt) * (x - xt) + (y - yt) * (y - yt) <= r * r
endmethod
static method move takes Frostwave i returns boolean
local integer j = 0
local boolean b = false
local real a
local unit u
loop
exitwhen j > data.SHARD_COUNT - 1
if i.m.b[j] then
set i.m.x[j] = i.m.x[j] + i.m.s[j] * Cos(i.m.a[j])
set i.m.y[j] = i.m.y[j] + i.m.s[j] * Sin(i.m.a[j])
if isInBound(i.m.x[j], i.m.y[j]) then
/* If has reached the destination */
if inRadius(i.m.x[j], i.m.y[j], i.tX, i.tY, i.m.s[j]) then
implement KillShard
else
set a = getAngle(i.m.x[j], i.m.y[j], i.tX, i.tY)
call SetUnitX(i.m.u[j].unit, i.m.x[j])
call SetUnitY(i.m.u[j].unit, i.m.y[j])
call SetUnitFacing(i.m.u[j].unit, i.m.a[j] * bj_RADTODEG)
call GroupEnumUnitsInRange(t, i.m.x[j], i.m.y[j], i.a, null)
loop
set u = FirstOfGroup(t)
exitwhen u == null
if UnitAlive(u) and not IsUnitInGroup(u, i.g) and data.filter(u, i.p) then
if IsUnitType(u, UNIT_TYPE_HERO) then
call Slow.apply(u, data.durationHero(i.l))
else
call Slow.apply(u, data.durationNormal(i.l))
endif
call UnitDamageTarget(i.c, u, i.d, false, false, data.ATTACK_TYPE, data.DAMAGE_TYPE, data.WEAPON_TYPE)
call DestroyEffect(AddSpecialEffectTarget(data.TARGET_SFX, u, data.TARGET_SFX_PT))
call GroupAddUnit(i.g, u)
endif
call GroupRemoveUnit(t, u)
endloop
/*
* Turn the missile slowly to face the target
* point based on TURN_RATE
*/
if data.TURN_RATE != 0 and Cos(i.m.a[j] - a) < Cos(data.TURN_RATE) then
if Sin(a - i.m.a[j]) >= 0 then
set i.m.a[j] = i.m.a[j] + data.TURN_RATE
else
set i.m.a[j] = i.m.a[j] - data.TURN_RATE
endif
else
set i.m.a[j] = a
/* Accelerate if has faced the target point correctly */
set i.m.s[j] = i.m.s[j] + data.ACCELERATION
if i.m.s[j] > data.SPEED_MAX then
set i.m.s[j] = data.SPEED_MAX
endif
endif
endif
else
implement KillShard
endif
endif
set j = j + 1
endloop
return b
endmethod
static method create takes real x, real y, real f returns thistype
local thistype this = allocate()
local integer i = 0
/* Determine the lowest angle */
set f = f - data.ANGLE_ADD * (data.SHARD_COUNT/2)
set .c = data.SHARD_COUNT - 1
loop
exitwhen i > .c
set .s[i] = data.SPEED_MIN
set .a[i] = f
set .b[i] = true
set .x[i] = x
set .y[i] = y
set .u[i] = Dummy.create(x, y, f * bj_RADTODEG)
set .e[i] = AddSpecialEffectTarget(data.MISSILE_PATH, .u[i].unit, "origin")
if not LIBRARY_AutoFly then
if UnitAddAbility(.u[i].unit, 'Amrf') and UnitRemoveAbility(.u[i].unit, 'Amrf') then
endif
endif
call SetUnitFlyHeight(.u[i].unit, data.LAUNCH_Z, 0)
set f = f + data.ANGLE_ADD
set i = i + 1
endloop
return this
endmethod
endstruct
private struct Frostwave extends array
real tX
real tY
real a /* AoE */
real d /* damage */
group g
player p
unit c
integer l /* level */
IceShard m /* missile */
implement CTL
local boolean b
implement CTLExpire
set b = IceShard.move(this)
if b then
call DestroyGroup(.g)
call destroy()
endif
implement CTLEnd
static method onCast takes nothing returns boolean
local thistype this = create()
local real a
local real x
local real y
set .c = GetTriggerUnit()
set .p = GetTriggerPlayer()
set .g = CreateGroup()
set x = GetUnitX(.c)
set y = GetUnitY(.c)
set .tX = GetSpellTargetX()
set .tY = GetSpellTargetY()
set .l = GetUnitAbilityLevel(.c, data.SPELL_ID)
/* If target point is the same as cast point */
if x == .tX and y == .tY then
set a = GetUnitFacing(.c) * bj_DEGTORAD
else
set a = getAngle(x, y, .tX, .tY)
endif
set .m = IceShard.create(x, y, a)
set .tX = x + data.distance(.l) * Cos(a)
set .tY = y + data.distance(.l) * Sin(a)
set .d = data.damage(.l)
set .a = data.aoe(.l)
return false
endmethod
static if not LIBRARY_SpellEffectEvent then
private static method check takes nothing returns boolean
if GetSpellAbilityId() == data.SPELL_ID then
call thistype.onCast()
endif
return false
endmethod
endif
static method onInit takes nothing returns nothing
local trigger t
static if LIBRARY_SpellEffectEvent then
call RegisterSpellEffectEvent(data.SPELL_ID, function thistype.onCast)
else
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.check))
endif
endmethod
endstruct
endscope
scope FrostPhase
private struct FrostPhase extends array
implement FrostPhaseData
real a /* AoE */
real r /* angle */
real d /* distance */
real dmg
real x
real y
group g
player p
unit c
integer l /* level */
static group t = CreateGroup()
implement CTL
local unit u
local unit d
local real c = 0
implement CTLExpire
/*
* Check terrain pathability between cast and
* target point
*/
set c = 0
loop
exitwhen c >= .d or not IsTerrainWalkable(.x, .y)
set .x = .x + ACCURACY * Cos(.r)
set .y = .y + ACCURACY * Sin(.r)
set c = c + ACCURACY
endloop
call SetUnitPosition(.c, .x, .y)
set .x = GetUnitX(.c)
set .y = GetUnitY(.c)
call GroupEnumUnitsInRange(t, .x, .y, .a, null)
loop
set u = FirstOfGroup(t)
exitwhen u == null
if UnitAlive(u) and filter(u, .p) then
if not IsUnitInGroup(u, .g) then
/* If only deal damage for once per unit*/
static if DAMAGE_ONCE then
call GroupAddUnit(.g, u)
endif
if IsUnitType(u, UNIT_TYPE_HERO) then
call Freeze.apply(u, durationHero(.l))
else
call Freeze.apply(u, durationNormal(.l))
endif
call UnitDamageTarget(.c, u, .dmg, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
endif
endif
call GroupRemoveUnit(t, u)
endloop
/* Create scaled sfx at target point */
set d = CreateUnit(.p, DUMMY_ID, .x, .y, 0)
call SetUnitScale(d, EXPLODE_SIZE, 1, 1)
call DestroyEffect(AddSpecialEffectTarget(EXPLODE_SFX, d, "origin"))
call UnitApplyTimedLife(d, 'BTLF', SFX_DECAY_TIME)
static if DAMAGE_ONCE then
call DestroyGroup(.g)
endif
call destroy()
set d = null
implement CTLEnd
static method onCast takes nothing returns boolean
local thistype this = create()
local integer l
local real xt
local real yt
local unit u
local unit d
set .c = GetTriggerUnit()
set .p = GetTriggerPlayer()
set .g = CreateGroup()
set .x = GetUnitX(.c)
set .y = GetUnitY(.c)
set xt = GetSpellTargetX()
set yt = GetSpellTargetY()
set .l = GetUnitAbilityLevel(.c, SPELL_ID)
set .r = getAngle(.x, .y, xt, yt)
set .d = getDistance(.x, .y, xt, yt)
if .d > distance(.l) then
set .d = distance(.l)
endif
set .dmg = damage(.l)
set .a = aoe(.l)
call GroupEnumUnitsInRange(t, .x, .y, .a, null)
loop
set u = FirstOfGroup(t)
exitwhen u == null
if UnitAlive(u) and filter(u, .p) then
if not IsUnitInGroup(u, .g) then
/* If only deal damage for once per unit*/
static if DAMAGE_ONCE then
call GroupAddUnit(.g, u)
endif
if IsUnitType(u, UNIT_TYPE_HERO) then
call Freeze.apply(u, durationHero(.l))
else
call Freeze.apply(u, durationNormal(.l))
endif
call UnitDamageTarget(.c, u, .dmg, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
endif
endif
call GroupRemoveUnit(t, u)
endloop
/* Create scaled sfx at cast point */
set d = CreateUnit(.p, DUMMY_ID, .x, .y, 0)
call SetUnitScale(d, EXPLODE_SIZE, 1, 1)
call DestroyEffect(AddSpecialEffectTarget(EXPLODE_SFX, d, "origin"))
call UnitApplyTimedLife(d, 'BTLF', SFX_DECAY_TIME)
set d = null
return false
endmethod
static if not LIBRARY_SpellEffectEvent then
private static method check takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
call thistype.onCast()
endif
return false
endmethod
endif
static method onInit takes nothing returns nothing
local trigger t
static if LIBRARY_SpellEffectEvent then
call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast)
else
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.check))
endif
endmethod
endstruct
endscope
scope Hailstorm
/*private struct Hailstorm extends array
static method onInit takes nothing returns nothing
local trigger t
static if LIBRARY_SpellEffectEvent then
call RegisterSpellEffectEvent(data.SPELL_ID, function thistype.onCast)
else
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.check))
endif
endmethod
endstruct*/
endscope
endscope
lol, I think he is not being serious at all
Anyway, I think this is the last WIP I will post here:
Still too lazy to work on the ultimate ability, it's gonna be quite complicatedJASS:/* * FROZEN SPELLPACK * v1.0 * This spellpack cosists of 4 active spells. * They are Cold Addict, Frostwave, Frost * Phase, and Hailstorm (ultimate). * Their codes are packed into one library * means that they are requiring each other. * !This spellpack requires JNGP to work! * How to install: * - Install and configure all external * dependecies properly. * - Copy all abilities (OE) in Undead group. * - Copy dummy unit (OE) and it's model to * your map. * - Configure the spells. * External Dependencies: * Required: * - CTL * - Dummy * - IsTerrainWalkable * - WorldBounds * - UnitIndexer * * Optional: * - SpellEffectEvent * - AutoFly * Credits: * - Nestharus * - Bribe * - Cokemonkey11 * - Magtheridon96 */ scope FrozenSpellpack /* * CONFIGURATION * Configuration is separated into several * parts. Each part is reserved for one spell. */ /* A. Global */ globals /* Dummy unit's rawcode at Object Editor */ private constant integer DUMMY_ID = 'h000' /* General decay time for all created sfx */ private constant real SFX_DECAY_TIME = 2.0 endglobals /* B. Slow */ private module SlowData /* Slow ability's rawcode at Object Editor */ static constant integer SPELL_ID = 'A004' /* Slow buff's rawcode at Object Editor */ static constant integer BUFF_ID = 'B001' /* Slow order id */ static constant integer SLOW_ORDER = 852096 /* thunderclap */ /* Attached sfx on slow targets */ static constant string SLOW_SFX = "Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl" static constant string SLOW_SFX_PT = "chest" /* Duration is stackable */ static constant boolean STACKABLE = true /* Will reset the duration if not stacked */ static constant boolean RESETABLE = false endmodule /* C. Freeze */ private module FreezeData /* Freeze ability's rawcode at Object Editor */ static constant integer SPELL_ID = 'A008' /* Freeze buff's rawcode at Object Editor */ static constant integer BUFF_ID = 'B000' /* Freeze order id */ static constant integer FREEZE_ORDER = 852127 /* stomp */ /* Attached sfx on freeze targets */ static constant string FREEZE_SFX = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl" static constant string FREEZE_SFX_PT = "origin" /* Duration is stackable */ static constant boolean STACKABLE = false /* Will reset the duration if not stacked */ static constant boolean RESETABLE = false endmodule /* * COLD ADDICT * Inflicts frost magic at a target, slowing * it's movement and attack rate, and stopping * any mana regeneration. All damages taken * from caster's spell will be amplified. */ private module ColdAddictData /* Main ability's rawcode at Object Editor */ static constant integer SPELL_ID = 'A001' /* Attached sfx on targets */ static constant string TARGET_SFX = "Abilities\\Spells\\Items\\AIob\\AIobTarget.mdl" static constant string TARGET_SFX_PT = "overhead" /* Damage amplification is stackable */ static constant boolean STACKABLE_BUFF = false /* Duration is stackable */ static constant boolean STACKABLE_DUR = false /* Will reset the duration if not stacked */ static constant boolean RESETABLE = false /* Damage amplification amount */ static constant method amount takes integer l returns real return -5.0 + 15.0 * l endmethod /* Buff duration on normal units */ static constant method durationNormal takes integer l returns real return 6.0 endmethod /* Buff duration on hero units */ static constant method durationHero takes integer l returns real return 4.0 endmethod endmodule /* * FROSTWAVE * Sends a lance of ice shards wave to the * target point, dealing damage to land units * in a line and slowing them for a short * duration. */ private module FrostwaveData /* Main ability's rawcode at Object Editor */ static constant integer SPELL_ID = 'A000' /* Total of created missiles on every cast */ static constant integer SHARD_COUNT = 23 /* Normal height z for every missile */ static constant real LAUNCH_Z = 64.0 /* Initial speed of every missile */ static constant real SPEED_MIN = 20.0 /* Maximum speed of every missile */ static constant real SPEED_MAX = 40.0 /* Acceleration rate of every missile */ static constant real ACCELERATION = 0.25 /* Turning rate of every missile */ static constant real TURN_RATE = 12.5 * bj_DEGTORAD /* Missile model path */ static constant string MISSILE_PATH = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl" /* Attached sfx on targets */ static constant string TARGET_SFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" static constant string TARGET_SFX_PT = "origin" /* Dealt damage configuration */ static constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL static constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL static constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS /* Max distance from missile to hits a target */ static constant method aoe takes integer l returns real return 75.0 endmethod /* Dealt damage amount */ static constant method damage takes integer l returns real return 60.0 * l endmethod /* Travel distance of every missile */ static constant method distance takes integer l returns real return 1000.0 endmethod /* Slow duration for normal units */ static constant method durationNormal takes integer l returns real return 2.75 endmethod /* Slow duration for hero units */ static constant method durationHero takes integer l returns real return 1.325 endmethod /* Configure the targets */ static method filter takes unit u, player p returns boolean return not(IsUnitAlly(u, p) or IsUnitType(u, UNIT_TYPE_FLYING) or IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) endmethod endmodule /* * FROST PHASE * Instantly vanishes to the target point. * Leaving ice explosion behind and at the * target point. Freezes nearby enemy units * for a short duration and deals minor damage */ private module FrostPhaseData /* Main ability's rawcode at Object Editor */ static constant integer SPELL_ID = 'A007' /* How often the spell will check terrain's pathability */ static constant real ACCURACY = 20.0 /* pixel */ /* Explosion sfx */ static constant real EXPLODE_SIZE = 2.0 static constant string EXPLODE_SFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" /* Only damage once for each target */ static constant boolean DAMAGE_ONCE = false /* Dealt damage configuration */ static constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL static constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL static constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS /* Dealt damage amount */ static constant method damage takes integer l returns real return 20.0 + 10.0 * l endmethod /* Max range from the center of explosion to hit a target */ static constant method aoe takes integer l returns real return 250.0 endmethod /* Max teleport distance */ static constant method distance takes integer l returns real return 300.0 + 100.0 * l endmethod /* Freeze duration for normal units */ static constant method durationNormal takes integer l returns real return 0.9 + 0.45 * l endmethod /* Freeze duration for hero units */ static constant method durationHero takes integer l returns real return 0.45 + 0.225 * l endmethod /* Configure the targets */ static method filter takes unit u, player p returns boolean return not(IsUnitAlly(u, p) or IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) endmethod endmodule private module HailstormData static constant integer SPELL_ID = 'A003' static constant real TARGET_Z = 350.0 static constant real LAUNCH_Z = 64.0 static constant boolean FAIL_STOP = false static constant string MISSILE_PATH = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl" static constant string CHANNEL_ORDER = "blizzard" static constant method count takes integer l returns integer return 1 endmethod static constant method accuracy takes integer l returns real return 4.5 endmethod static constant method turning takes integer l returns real return 5.0 * bj_DEGTORAD endmethod static constant method cdelay takes integer l returns real return 0.2 endmethod static constant method cdelayv takes integer l returns real return 0.2 endmethod static constant method cduration takes integer l returns real return 10.0 endmethod static constant method cradius takes integer l returns real return 225.0 endmethod static constant method fdamage takes integer l returns real return 110.0 endmethod static constant method faoe takes integer l returns real return 75.0 endmethod static constant method fdelay takes integer l returns real return 0.1 endmethod static constant method fduration takes integer l returns real return 1.25 endmethod endmodule native UnitAlive takes unit id returns boolean /* Function that returns distance between coordinates */ private function getDistance takes real x, real y, real xt, real yt returns real return SquareRoot((xt - x) * (xt - x) + (yt - y) * (yt - y)) endfunction /* Function that returns angle between coordinates */ private function getAngle takes real x, real y, real xt, real yt returns real return Atan2(yt - y, xt - x) endfunction private function isInBound takes real x, real y returns boolean return x >= WorldBounds.minX and x <= WorldBounds.maxX and y >= WorldBounds.minY and y <= WorldBounds.maxY endfunction private struct Slow extends array implement SlowData unit u real d /* duration */ effect s static unit c static boolean array b static thistype array dex implement CTLExpire if .d > 0 then set .d = .d - .03125 if .d <= 0 or not UnitAlive(.u) then call DestroyEffect(.s) call UnitRemoveAbility(.u, BUFF_ID) set b[GetUnitUserData(.u)] = false call destroy() endif endif implement CTLEnd static method apply takes unit u, real d returns nothing local thistype this local integer i = GetUnitUserData(u) if b[i] then set this = dex[i] /* Stack */ static if thistype.STACKABLE then set .d = .d + d else /* Reset */ static if thistype.RESETABLE then set .d = d endif endif else call SetUnitX(c, GetUnitX(u)) call SetUnitY(c, GetUnitY(u)) call IssueImmediateOrderById(c, SLOW_ORDER) call SetUnitX(c, WorldBounds.maxX) call SetUnitY(c, WorldBounds.maxY) /* Check if the target is successfully buffed */ if GetUnitAbilityLevel(u, BUFF_ID) > 0 then set this = create() set .u = u set .d = d set .s = AddSpecialEffectTarget(SLOW_SFX, u, SLOW_SFX_PT) set b[i] = true set dex[i] = this endif endif endmethod static method onInit takes nothing returns nothing set c = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 0) call UnitAddAbility(c, SPELL_ID) endmethod endstruct private struct Freeze extends array implement FreezeData unit u real d /* duration */ effect s static unit c static boolean array b static thistype array dex implement CTLExpire if .d > 0 then set .d = .d - .03125 if .d <= 0 or not UnitAlive(.u) then call DestroyEffect(.s) call UnitRemoveAbility(.u, BUFF_ID) set b[GetUnitUserData(.u)] = false call destroy() endif endif implement CTLEnd static method apply takes unit u, real d returns nothing local thistype this local integer i = GetUnitUserData(u) if b[i] then set this = dex[i] /* Stack */ static if thistype.STACKABLE then set .d = .d + d else /* Reset */ static if thistype.RESETABLE then set .d = d endif endif else call SetUnitX(c, GetUnitX(u)) call SetUnitY(c, GetUnitY(u)) call IssueImmediateOrderById(c, FREEZE_ORDER) call SetUnitX(c, WorldBounds.maxX) call SetUnitY(c, WorldBounds.maxY) /* Check if the target is successfully buffed */ if GetUnitAbilityLevel(u, BUFF_ID) > 0 then set this = create() set .u = u set .d = d set .s = AddSpecialEffectTarget(FREEZE_SFX, u, FREEZE_SFX_PT) set b[i] = true set dex[i] = this endif endif endmethod private static method onInit takes nothing returns nothing set c = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 0) call UnitAddAbility(c, SPELL_ID) endmethod endstruct /* Destroying Dummy after certain duration */ private struct RecycleBin extends array real d /* duration */ Dummy u implement CTLExpire set .d = .d - .03125 if .d <= 0 then call .u.destroy() call destroy() endif implement CTLEnd static method add takes Dummy u returns nothing local thistype this = create() set .d = SFX_DECAY_TIME set .u = u endmethod endstruct /* Cold Addict spell*/ scope ColdAddict private struct ColdAddict extends array implement ColdAddictData unit u real d /* duration */ real m /* mana */ effect s static real array a /* amount */ static boolean array b static thistype array dex implement CTLExpire set .d = .d - .03125 /* Stops mana regeneration */ call SetUnitState(.u, UNIT_STATE_MANA, .m) if .d <= 0 or not UnitAlive(.u) then call DestroyEffect(.s) set b[GetUnitUserData(.u)] = false call destroy() endif implement CTLEnd static method onCast takes nothing returns boolean local thistype this = create() local unit t = GetSpellTargetUnit() local integer i = GetUnitUserData(t) local integer l = GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID) if b[i] then set this = dex[i] static if thistype.STACKABLE_DUR then if IsUnitType(t, UNIT_TYPE_HERO) then set .d = .d + durationHero(l) else set .d = .d + durationNormal(l) endif /* * Prevent slow buff from being removed before * cold addict has expired */ if Slow.dex[i].d < .d then set Slow.dex[i].d = .d endif else static if thistype.RESETABLE then if IsUnitType(t, UNIT_TYPE_HERO) then set .d = .d + durationHero(l) else set .d = .d + durationNormal(l) endif /* * Prevent slow buff from being removed before * cold addict has expired */ if Slow.dex[i].d < .d then set Slow.dex[i].d = .d endif endif endif /* Stack amplification amount */ static if thistype.STACKABLE_BUFF then set a[i] = a[i] + amount(l) endif else set this = create() set .u = t set .m = GetUnitState(.u, UNIT_STATE_MANA) if IsUnitType(.u, UNIT_TYPE_HERO) then set .d = .d + durationHero(l) else set .d = .d + durationNormal(l) endif set a[i] = amount(l) set b[i] = true set dex[i] = this call Slow.apply(.u, .d) set .s = AddSpecialEffectTarget(TARGET_SFX, .u, TARGET_SFX_PT) endif set t = null return false endmethod static if not LIBRARY_SpellEffectEvent then private static method check takes nothing returns boolean if GetSpellAbilityId() == SPELL_ID then call thistype.onCast() endif return false endmethod endif static method onInit takes nothing returns nothing local trigger t static if LIBRARY_SpellEffectEvent then call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast) else set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t, Condition(function thistype.check)) endif endmethod endstruct endscope /* Frostwave spell*/ scope Frostwave private struct data extends array implement FrostwaveData static constant real ANGLE_ADD = (bj_PI * 2)/data.SHARD_COUNT endstruct private module KillShard call SetUnitX(i.m.u[j].unit, i.tX) call SetUnitY(i.m.u[j].unit, i.tY) call DestroyEffect(i.m.e[j]) call RecycleBin.add(i.m.u[j]) set i.m.e[j] = null set i.m.b[j] = false set i.m.c = i.m.c - 1 if i.m.c < 0 then call i.m.destroy() set b = true endif endmodule private keyword Frostwave private struct IceShard integer c real array a[data.SHARD_COUNT] real array s[data.SHARD_COUNT] real array x[data.SHARD_COUNT] real array y[data.SHARD_COUNT] Dummy array u[data.SHARD_COUNT] boolean array b[data.SHARD_COUNT] effect array e[data.SHARD_COUNT] /* For FoG looping */ static group t = CreateGroup() /* Function to compare two distances */ static method inRadius takes real x, real y, real xt, real yt, real r returns boolean return (x - xt) * (x - xt) + (y - yt) * (y - yt) <= r * r endmethod static method move takes Frostwave i returns boolean local integer j = 0 local boolean b = false local real a local unit u loop exitwhen j > data.SHARD_COUNT - 1 if i.m.b[j] then set i.m.x[j] = i.m.x[j] + i.m.s[j] * Cos(i.m.a[j]) set i.m.y[j] = i.m.y[j] + i.m.s[j] * Sin(i.m.a[j]) if isInBound(i.m.x[j], i.m.y[j]) then /* If has reached the destination */ if inRadius(i.m.x[j], i.m.y[j], i.tX, i.tY, i.m.s[j]) then implement KillShard else set a = getAngle(i.m.x[j], i.m.y[j], i.tX, i.tY) call SetUnitX(i.m.u[j].unit, i.m.x[j]) call SetUnitY(i.m.u[j].unit, i.m.y[j]) call SetUnitFacing(i.m.u[j].unit, i.m.a[j] * bj_RADTODEG) call GroupEnumUnitsInRange(t, i.m.x[j], i.m.y[j], i.a, null) loop set u = FirstOfGroup(t) exitwhen u == null if UnitAlive(u) and not IsUnitInGroup(u, i.g) and data.filter(u, i.p) then if IsUnitType(u, UNIT_TYPE_HERO) then call Slow.apply(u, data.durationHero(i.l)) else call Slow.apply(u, data.durationNormal(i.l)) endif call UnitDamageTarget(i.c, u, i.d, false, false, data.ATTACK_TYPE, data.DAMAGE_TYPE, data.WEAPON_TYPE) call DestroyEffect(AddSpecialEffectTarget(data.TARGET_SFX, u, data.TARGET_SFX_PT)) call GroupAddUnit(i.g, u) endif call GroupRemoveUnit(t, u) endloop /* * Turn the missile slowly to face the target * point based on TURN_RATE */ if data.TURN_RATE != 0 and Cos(i.m.a[j] - a) < Cos(data.TURN_RATE) then if Sin(a - i.m.a[j]) >= 0 then set i.m.a[j] = i.m.a[j] + data.TURN_RATE else set i.m.a[j] = i.m.a[j] - data.TURN_RATE endif else set i.m.a[j] = a /* Accelerate if has faced the target point correctly */ set i.m.s[j] = i.m.s[j] + data.ACCELERATION if i.m.s[j] > data.SPEED_MAX then set i.m.s[j] = data.SPEED_MAX endif endif endif else implement KillShard endif endif set j = j + 1 endloop return b endmethod static method create takes real x, real y, real f returns thistype local thistype this = allocate() local integer i = 0 /* Determine the lowest angle */ set f = f - data.ANGLE_ADD * (data.SHARD_COUNT/2) set .c = data.SHARD_COUNT - 1 loop exitwhen i > .c set .s[i] = data.SPEED_MIN set .a[i] = f set .b[i] = true set .x[i] = x set .y[i] = y set .u[i] = Dummy.create(x, y, f * bj_RADTODEG) set .e[i] = AddSpecialEffectTarget(data.MISSILE_PATH, .u[i].unit, "origin") if not LIBRARY_AutoFly then if UnitAddAbility(.u[i].unit, 'Amrf') and UnitRemoveAbility(.u[i].unit, 'Amrf') then endif endif call SetUnitFlyHeight(.u[i].unit, data.LAUNCH_Z, 0) set f = f + data.ANGLE_ADD set i = i + 1 endloop return this endmethod endstruct private struct Frostwave extends array real tX real tY real a /* AoE */ real d /* damage */ group g player p unit c integer l /* level */ IceShard m /* missile */ implement CTL local boolean b implement CTLExpire set b = IceShard.move(this) if b then call DestroyGroup(.g) call destroy() endif implement CTLEnd static method onCast takes nothing returns boolean local thistype this = create() local real a local real x local real y set .c = GetTriggerUnit() set .p = GetTriggerPlayer() set .g = CreateGroup() set x = GetUnitX(.c) set y = GetUnitY(.c) set .tX = GetSpellTargetX() set .tY = GetSpellTargetY() set .l = GetUnitAbilityLevel(.c, data.SPELL_ID) /* If target point is the same as cast point */ if x == .tX and y == .tY then set a = GetUnitFacing(.c) * bj_DEGTORAD else set a = getAngle(x, y, .tX, .tY) endif set .m = IceShard.create(x, y, a) set .tX = x + data.distance(.l) * Cos(a) set .tY = y + data.distance(.l) * Sin(a) set .d = data.damage(.l) set .a = data.aoe(.l) return false endmethod static if not LIBRARY_SpellEffectEvent then private static method check takes nothing returns boolean if GetSpellAbilityId() == data.SPELL_ID then call thistype.onCast() endif return false endmethod endif static method onInit takes nothing returns nothing local trigger t static if LIBRARY_SpellEffectEvent then call RegisterSpellEffectEvent(data.SPELL_ID, function thistype.onCast) else set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t, Condition(function thistype.check)) endif endmethod endstruct endscope scope FrostPhase private struct FrostPhase extends array implement FrostPhaseData real a /* AoE */ real r /* angle */ real d /* distance */ real dmg real x real y group g player p unit c integer l /* level */ static group t = CreateGroup() implement CTL local unit u local unit d local real c = 0 implement CTLExpire /* * Check terrain pathability between cast and * target point */ set c = 0 loop exitwhen c >= .d or not IsTerrainWalkable(.x, .y) set .x = .x + ACCURACY * Cos(.r) set .y = .y + ACCURACY * Sin(.r) set c = c + ACCURACY endloop call SetUnitPosition(.c, .x, .y) set .x = GetUnitX(.c) set .y = GetUnitY(.c) call GroupEnumUnitsInRange(t, .x, .y, .a, null) loop set u = FirstOfGroup(t) exitwhen u == null if UnitAlive(u) and filter(u, .p) then if not IsUnitInGroup(u, .g) then /* If only deal damage for once per unit*/ static if DAMAGE_ONCE then call GroupAddUnit(.g, u) endif if IsUnitType(u, UNIT_TYPE_HERO) then call Freeze.apply(u, durationHero(.l)) else call Freeze.apply(u, durationNormal(.l)) endif call UnitDamageTarget(.c, u, .dmg, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) endif endif call GroupRemoveUnit(t, u) endloop /* Create scaled sfx at target point */ set d = CreateUnit(.p, DUMMY_ID, .x, .y, 0) call SetUnitScale(d, EXPLODE_SIZE, 1, 1) call DestroyEffect(AddSpecialEffectTarget(EXPLODE_SFX, d, "origin")) call UnitApplyTimedLife(d, 'BTLF', SFX_DECAY_TIME) static if DAMAGE_ONCE then call DestroyGroup(.g) endif call destroy() set d = null implement CTLEnd static method onCast takes nothing returns boolean local thistype this = create() local integer l local real xt local real yt local unit u local unit d set .c = GetTriggerUnit() set .p = GetTriggerPlayer() set .g = CreateGroup() set .x = GetUnitX(.c) set .y = GetUnitY(.c) set xt = GetSpellTargetX() set yt = GetSpellTargetY() set .l = GetUnitAbilityLevel(.c, SPELL_ID) set .r = getAngle(.x, .y, xt, yt) set .d = getDistance(.x, .y, xt, yt) if .d > distance(.l) then set .d = distance(.l) endif set .dmg = damage(.l) set .a = aoe(.l) call GroupEnumUnitsInRange(t, .x, .y, .a, null) loop set u = FirstOfGroup(t) exitwhen u == null if UnitAlive(u) and filter(u, .p) then if not IsUnitInGroup(u, .g) then /* If only deal damage for once per unit*/ static if DAMAGE_ONCE then call GroupAddUnit(.g, u) endif if IsUnitType(u, UNIT_TYPE_HERO) then call Freeze.apply(u, durationHero(.l)) else call Freeze.apply(u, durationNormal(.l)) endif call UnitDamageTarget(.c, u, .dmg, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) endif endif call GroupRemoveUnit(t, u) endloop /* Create scaled sfx at cast point */ set d = CreateUnit(.p, DUMMY_ID, .x, .y, 0) call SetUnitScale(d, EXPLODE_SIZE, 1, 1) call DestroyEffect(AddSpecialEffectTarget(EXPLODE_SFX, d, "origin")) call UnitApplyTimedLife(d, 'BTLF', SFX_DECAY_TIME) set d = null return false endmethod static if not LIBRARY_SpellEffectEvent then private static method check takes nothing returns boolean if GetSpellAbilityId() == SPELL_ID then call thistype.onCast() endif return false endmethod endif static method onInit takes nothing returns nothing local trigger t static if LIBRARY_SpellEffectEvent then call RegisterSpellEffectEvent(SPELL_ID, function thistype.onCast) else set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t, Condition(function thistype.check)) endif endmethod endstruct endscope scope Hailstorm /*private struct Hailstorm extends array static method onInit takes nothing returns nothing local trigger t static if LIBRARY_SpellEffectEvent then call RegisterSpellEffectEvent(data.SPELL_ID, function thistype.onCast) else set t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t, Condition(function thistype.check)) endif endmethod endstruct*/ endscope endscope
![]()
No, it's not just you. No offense, but the behavior you described is exactly the kind of thing I want to stamp out for future Contests (this one included). Worry not; measures are being taken.EDIT:
Have just read the whole main post. Honestly, I never agreed with public poll. Not all users are able to give "precise" review and opinion, some will only vote based on their first impression. Just like me when voted at the past zephyr contest, Be My Angle by Bannar is the first entry I tried. And I'm quite impressed with it, and vote for him instantly without checking any other entries. Then after Dat-C3 asked me, have I tried his entry, I just answered yes whereas I haven't \o/
Then after that, I started to check every entry out :'D I'm not sure though, guess it's just me.
But I'm glad trigger/code gives a great score![]()
That is exactly what I have aimed to avoid in this Contest; past Contests did a poor job of indicating which was being made (seemingly accepting anything, from Melee to AoS to Hero Arena to TD...), and I feel that went a long way towards making those previous Contests fundamentally flawed (basically, "comparing apples to oranges"; see my posts on the Techtree Contest Submission thread for more of this).A big possible problem of this contest is that people might think with DotA mind and not with melee mind. That means, low duration of negative buffs, focusing on damage and ultimates which deal damage (if you look well to most of the ultimates of melee heroes, they are either summoning an ultimate monster or an AoE non-damaging spell)
With that being said, I'm afraid some people might go off-course and forget that this hero should be made for melee game, not for an AoS or Hero Arena
Unfortunately, probably not. Then again, that's just my two cents; we're not going to dictate matters of "Theme" so much; but expect to suffer in the Judging, plausibly.A warlock for the horde; does it fit or not? WC3 Horde is more on shamanism.
I would argue otherwise. Balance, if defined as "winning & losing roughly the same amount of matches/match-ups", has a lot to do with durations, cooldowns, and (mana?) costs. Imagine if Bash or Storm Bolt's stuns lasted for a full minute? Or if the Infernal could be summoned every 5 seconds? Or if Mana Burn costed 10 mana? Definitely problematic.Balance has very little to do with durations, cooldowns, and costs when it comes to design. You could easily make a wc3 hero with 3 passives and an autocast ability and make it balanced wrt the rest of wc3.
Don't make the mistake of producing a bad design just because you think it might feel more like a wc3 hero. On the other extreme, there are many pitfalls related to hero design between rts and moba genres.
Ooook... Well I tried to do a good job of warning people that "times change" (lol), but regardless... I'd really like to know where I have failed in communicating. I tried to strike a balance between the "bare essentials" to ensure a good, fair, fun Contest & providing reasonable explanations & examples in places. I also re-worked the Criteria to be more sensical (<- not a word but you get what I mean).Cokemonkey11 said:@kyrbi0: ... Looking back at the formal rules (which I didn't read before since rules are usually the same and I don't have time to analyze a wall of text), there are many issues.
Well we're all glad to have another Contestant, though I wish I could address your despondent attitude. :< Don't worry, if there's some "minutiae" you end up stumbling across people are here to help & point it out.Cokemonkey11 said:I've decided to just produce a hero, and if it gets disqualified over some minutiae, I'll have to just live with it.
We're gonna have to say "no", unfortunately.Anyways Kyrbi0 is it okay if we resize models by Y/Z in Model Editor? The Scaling Native does not allow Y/Z.
Hero Change for the fifth time. Damn, reusing some ability titles. I didn't even bother starting the last hero because of uncomfortability with the model.
Mystic Wyvern
Ah, I'm glad to see someone using the Ranger; looking cool. Also, glad to see someone deriving inspiration from Beta (you're not alone... >Well, here are my latest WIP's:![]()
![]()
![]()
![]()
![]()
Ranger abilities:
Flaming Arrows, Cold Arrows, Swiftness Aura and Black Arrow. (All from alpha)
PS: Some icons such as swiftness aura, black arrow are temporary.
Hrm...Still thinking about any sheep-related spells I can use for my Arcanists' ultimate.
Noice. I really wanted to do a Ranger hero (that & Garithos), so I'm glad to see someone handling it.I guess my idea isn't very original after all =/
My hero:
Blessed Ranger
Abilities:
Arcane Arrows, Forrestwalk, Holy Sigil, Pure Dexterity
more to come later :3
Very cool! Glad to see more WIPs, and glad to see someone using Garithos; I really wanted to use him as well.Ok, another WiP of his ulti in action. All his abilities are finished and I think he's finally balanced. Not much I know SFX wise but it's still useful.
I would argue otherwise. Balance, if defined as "winning & losing roughly the same amount of matches/match-ups", has a lot to do with durations, cooldowns, and (mana?) costs. Imagine if Bash or Storm Bolt's stuns lasted for a full minute? Or if the Infernal could be summoned every 5 seconds? Or if Mana Burn costed 10 mana? Definitely problematic.
I suppose it's possible (a Hero with 3 passives & an autocast (heck, the Tauren Chieftain has an astounding 2 passives, one of them even being his Ultimate!))... But I'd be really surprised to see that work. That strikes me as a Hero designed with a lot more passive-gameplay (no pun intended) in mind (or alternatively, one with tons of Macro & very little Micro; perhaps a TD or Hero Arena?), whereas true Melee involves a decent mix of both (strategy & tactics, macro & micro, etc).
Still have this idea and already making some of this spells
Shadow
Cunning hero, specializing in confusing enemy with illusion.
Shadow Blade
Slow the enemy and summon one illusion of Shadow to attack the enemy. Shadow Blade Illusion have Shadow Dodge ability.
Shadow Dodge
When Shadow attacked there is a 5/10/15% chance to summon an illusion of Shadow. Shadow Dodge illusions have Shadow Dodge Ability but only 2/4/6% and Shadow Grace ability but only 1/2/3% (i still think to remove this ability for its Shadow illusions). When Shadow has low health 100/125/150 hp and Shadow still have 100/80/60 mana then he will turn invisible. (still balancing this turning invisible thing i think i use it a lot to cheat death)
Shadow Grace
Give shadow a chance to do a critical strike or evade (still cant decide only one or both) and give him a chance to parry enemy attack with fan of knives 3/6/9% deal 50 damage up to 7?? nearby enemies.
Illusion Dance
Create 2 (or 3?) illusions of Shadow that have all Shadow abilities and deal 100% damage but receive 300% damage
Maybe you can give me some critics or comment how to balance this hero or improve it?