Those of you who downloaded this spell before and on 2010-15-02, download it again. Last version of the map was called v1.01x and is corrupted.
The current version is 1.01
Thank you!
Yeah well, let's continue, this is my second spell submitted this year. And it is once again an interpretation of a diablo 2 spell.
Coalesces a frozen orb from the air, shredding an area with freezing bolts, damaging nearby enemy ground units. A unit caught dying by a bolt may shatter, leaving no corpse behind.
Level 1 - 20 damage per bolt, 8% chance to shatter.
Level 2 - 30 damage per bolt, 12% chance to shatter.
Level 3 - 40 damage per bolt, 16% chance to shatter.
Level 4 - 50 damage per bolt, 20% chance to shatter.
Slows units for 2 seconds.
Previews
Introduction
Jass:
// 'Introduction'//// The reason why I did this spell is because I have not// seen yet any frozen orb spell which is properly// functional, or that I think does not look diablo 2'ish// enough (Vexorian made a frozen orb spell, I know, but// it isn't working at all anymore. This spell was indeed// an interpretation of the sorceress' spell Frozen Orb// in Diablo 2.//// A small note before I continue, due to some// complications with vJass I did not manage certain// things I had in mind in the beginning. The code may// indeed (the callback especially) be written in// another way, and I tried that, and failed.// Suggestions are welcome.//// A second note is that, frozen orb by default demands// some attention in the memory. Casting this multiply// times in a row without a cooldown, is going to have// some consequences. This is nothing I can change.// Adapt the XE_ANIMATION_PERIOD if needed.//// Third note is, you will not be able to control the// amount of bolts spawned while the orb is alive. These// are only depending on the animation period. This is// also how Diablo 2 handles Frozen Orb. Each bolt is// released each frame until the orb vanishes.
Implementation
Jass:
// First of all, you will need this library and the// xebasic library. Copy these to your map.//// Second, you need the Universal Dummy unit found in the// unit editor. Don't forget to import the dummy.mdx and// set the dummy to use it as a model.//// Important: In order to apply the slow// buff to the affected unit, make sure the universal// dummy has:// A cooldown time > 0// Damage base != 0 (default -1)// Damage die > 0 (default 1)// A fast projectile speed// A decent range// Targets allowed - At least 'ground'// Weapon type - missile// Attack 1 enabled// (if the unit does not have a movement speed, add it)// And the usual stuff//// Next copy the ability which will cast the spell, and// the ability which will apply the buff, and modify the// rawcode id's in the constants below. Don't forget to// make sure the dummy unit id in the xebasic library is// set right as well.
Credits
Jass:
// Vexorian - JassHelper, xebasic// PitzerMike & MindWorX - JNGP// Blizzard - Once again for some tooltip inspiration.
Code
Jass:
library FrozenOrb initializer Init requires xebasic
//------------------------------------------------------<>// 'FROZEN ORB'//// Submitted by Eccho 2010-02-05 (1.0)// 2010-02-15 (1.01)// Changelog can be found at the official submission post// at// http://www.hiveworkshop.com/forums/spells-569/frozen-orb-v1-0-a-158026///// Give credits if used!!//------------------------------------------------------<>//------------------------------------------------------<>// 'Native including'//// If you have this in your code somewhere else,// make sure to not double define it.//------------------------------------------------------<>native UnitAlive takesunit id returnsboolean//------------------------------------------------------<>// 'Configuration section'//// Change the spell to fit your needs.//------------------------------------------------------<>globalsprivateconstantinteger ABILITY_ID ='A000'//The ability triggering the spellprivateconstantinteger FROST_SLOW_ID ='A001'//The ability containing the frost attack. It the duration isn't altered of the already existing one in wc3, use that id instead.privateconstantinteger FROST_SLOW_BUFF ='Bfro'//The buff which is used in the slow attack ability//Art of the main orb unitprivateconstantstring ORB_ART ="Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"privateconstantinteger ORB_SPEED =800//Max travel speedprivateconstantinteger ORB_RANGE =900//Max travel distanceprivateconstantinteger ORB_RADIUS =32//The radius the orb has. It is required as a polar projection offset when the orb explodes in the endprivateconstantinteger ORB_HEIGHT =48//The z-height from the ground the orb will travelprivateconstantreal ORB_SCALE =1.0//The size/scaling of the orb (I believe the current model have some issues here, but it works with other models)//Art of the released bolts. The bolts released when the orb explodes uses this art too.privateconstantstring MISSILE_ART ="Abilities\\Weapons\\LichMissile\\LichMissile.mdl"privateconstantinteger MISSILE_SPEED =450//...privateconstantinteger MISSILE_RANGE =400//...privateconstantinteger MISSILE_RADIUS =32//Bolt radius. It is used to check the collision of which enemies the bolts will hit and damage.privateconstantinteger MISSILE_HEIGHT =48//...privateconstantreal MISSILE_SCALE =0.5//...privateconstantreal MISSILE_RAD_OFFSET =3*bj_PI/5//Each bolt is released with a certain angle offset (in radians), and is defined by this constant. Each bolt is added this constant + the previous angle.privateconstantinteger MISSILE_AMOUNT_MAX =100//Keep this constant at a secure amount. The spell could go very wrong if this value is less than the maximum amount of bolts released. 100 is used by default.privateconstantinteger ORB_EXPLODE_AMOUNT =12//Amount of bolts released when the orb explodesprivateconstantinteger ORB_EXPLODE_SPEED =500//Special bolt travel speedprivateconstantinteger ORB_EXPLODE_RANGE =400//Special bolt travel distance//If a unit shatters, this effect will be created at it's positionprivateconstantstring IMPACT_SHATTER_ART ="Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"privateconstantinteger IMPACT_SHATTER_PER_BASE =8//Percental base chance to shatter a unit which dies from the spellprivateconstantinteger IMPACT_SHATTER_PER_INC =4//Percental increament chance per level to shatter a unit which dies from the spell (example, if base is 8 and incr is 4, each level adds 4 chance)privateconstantinteger IMPACT_DAMAGE_BASE =20//Base damageprivateconstantinteger IMPACT_DAMAGE_INC =10//Increamental damage (works in the same way as the shatter base/incr fields)//Self-explanatoryprivateconstantattacktype ATTACK_TYPE =ATTACK_TYPE_MAGICprivateconstantdamagetype DAMAGE_TYPE =DAMAGE_TYPE_UNIVERSALprivateconstantweapontype WEAPON_TYPE =WEAPON_TYPE_WHOKNOWSendglobals//------------------------------------------------------<>// 'Damage filter'//// Add more options as desired.// Some info: It is used as a condition not a boolexpr,// thus, not going to give any issue with IsUnitType.//------------------------------------------------------<>privatefunction TargetFilter takesunit enemy,player caster,real x,real y returnsbooleanreturn UnitAlive(enemy)andIsUnitEnemy(enemy, caster)andIsUnitType(enemy,UNIT_TYPE_GROUND)andIsUnitInRangeXY(enemy, x, y, MISSILE_RADIUS)endfunction//------------------------------------------------------<>// 'Shatter filter'//// Add more options as desired.// It determines the units which may shatter// The filter does not need to contain the same context// as the damage filter. It is only potentially ran after// the target filter have became true.//------------------------------------------------------<>privatefunction ShatterFilter takesunit enemy returnsbooleanreturnnotIsUnitType(enemy,UNIT_TYPE_MECHANICAL)andnotIsUnitType(enemy,UNIT_TYPE_HERO)andnotIsUnitType(enemy,UNIT_TYPE_MAGIC_IMMUNE)endfunction//------------------------------------------------------<>// 'Other constants'//// These should not be altered by default, but if you// know what you are doing, or see a way to use other// constants instead, feel free.//------------------------------------------------------<>globalsprivateconstantreal ORB_TMAX =1.0*ORB_RANGE/ORB_SPEED
privateconstantreal MISSILE_TMAX =1.0*MISSILE_RANGE/MISSILE_SPEED
privateconstantreal EXPLODE_TMAX =1.0*ORB_EXPLODE_RANGE/ORB_EXPLODE_SPEED
privateconstantreal RAD_BETWEEN_EXPL =bj_PI*2/ORB_EXPLODE_AMOUNT
privateconstantgroup ENUM_GROUP =CreateGroup()privateconstanttimer ANIM_TIMER =CreateTimer()endglobals//------------------------------------------------------<>// 'Spell code'//// If you even think up of an optimize fully working// version, tell me about it.//------------------------------------------------------<>privatestruct missile
unit obj
effect art
real sx
real sy
real xvel
real yvel
staticmethod create takesstring art,player p,real x,real y,real z,real rad,integer speed,real scale returnsthistypelocalthistypethis=thistype.allocate()setthis.obj=CreateUnit(p, XE_DUMMY_UNITID, x, y, rad*bj_RADTODEG)callUnitAddAbility(this.obj, XE_HEIGHT_ENABLER)callUnitRemoveAbility(this.obj, XE_HEIGHT_ENABLER)callSetUnitFlyHeight(this.obj, z,0)callSetUnitScale(this.obj, scale, scale, scale)callSetUnitAnimationByIndex(this.obj,90)callUnitRemoveAbility(this.obj,'Aatk')setthis.art=AddSpecialEffectTarget(art,this.obj,"origin")setthis.sx= x
setthis.sy= y
setthis.xvel= speed*Cos(rad)setthis.yvel= speed*Sin(rad)returnthisendmethodmethod clear takesnothingreturnsnothingcallDestroyEffect(this.art)callKillUnit(this.obj)setthis.art=nullsetthis.obj=nullendmethodendstructprivatestruct spell
missile orb
real otick
missile array mis[MISSILE_AMOUNT_MAX]realarray mtick[MISSILE_AMOUNT_MAX]integer mcount
integer mtot
missile array xpl[ORB_EXPLODE_AMOUNT]real xtick //All exploding missiles have the same tickoffsetplayer owner
integer damage
integer chance
staticthistypearray tta
staticinteger tot =0staticmethod callback takesnothingreturnsnothinglocalthistypethislocal missile m
localinteger i =0localinteger j
localinteger k
localreal x
localreal y
localunit u
localunit v
loopexitwhen(i >=thistype.tot)setthis=thistype.tta[i]//Bolts goes hereset j =0loopexitwhen(j >=this.mtot)if(this.mis[j].obj!=null)thensetthis.mtick[j]=this.mtick[j]+XE_ANIMATION_PERIOD
set x =this.mis[j].sx+this.mis[j].xvel*this.mtick[j]set y =this.mis[j].sy+this.mis[j].yvel*this.mtick[j]callGroupEnumUnitsInRange(ENUM_GROUP, x, y, XE_MAX_COLLISION_SIZE+MISSILE_RADIUS,null)loopset u =FirstOfGroup(ENUM_GROUP)exitwhen(u ==null)callGroupRemoveUnit(ENUM_GROUP, u)exitwhen(TargetFilter(u,this.owner, x, y))endloop//A nice BJ, wrapped anywayif(this.mtick[j]<= MISSILE_TMAX andRectContainsCoords(bj_mapInitialPlayableArea, x, y)and u ==null)thencallSetUnitX(this.mis[j].obj, x)callSetUnitY(this.mis[j].obj, y)elseif(u !=null)thencallUnitDamageTarget(this.mis[j].obj, u,this.damage,true,false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)if(UnitAlive(u))thenif(GetUnitAbilityLevel(u, FROST_SLOW_BUFF)==0)thenset v =CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), XE_DUMMY_UNITID, x, y,0)callUnitAddAbility(v, FROST_SLOW_ID)callUnitApplyTimedLife(v,'BTLF',1.0)callIssueTargetOrder(v,"attackonce", u)endifelseif(GetRandomInt(0,100)<=this.chanceand ShatterFilter(u))thencallDestroyEffect(AddSpecialEffect(IMPACT_SHATTER_ART, x, y))callRemoveUnit(u)endifendif//A note - instances are not destroyed until the end of the spell, when all instances are properly cleared.callthis.mis[j].clear()setthis.mcount=this.mcount-1endifendifset j = j+1endloop//Orb goes hereif(this.orb.obj!=null)thensetthis.otick=this.otick+XE_ANIMATION_PERIOD
set x =this.orb.sx+this.orb.xvel*this.otickset y =this.orb.sy+this.orb.yvel*this.otickif(this.otick< ORB_TMAX andRectContainsCoords(bj_mapInitialPlayableArea, x, y))thencallSetUnitX(this.orb.obj, x)callSetUnitY(this.orb.obj, y)setthis.mis[this.mtot]= missile.create(MISSILE_ART,this.owner, x, y, MISSILE_HEIGHT,this.mtot*MISSILE_RAD_OFFSET, MISSILE_SPEED, MISSILE_SCALE)setthis.mtick[this.mtot]=0setthis.mcount=this.mcount+1setthis.mtot=this.mtot+1else//Clears the orbcallthis.orb.clear()//Proceeds with creating special bolts, aka bolts released when the orb vanishes.set j =0loopexitwhen(j >= ORB_EXPLODE_AMOUNT)setthis.xpl[j]= missile.create(MISSILE_ART,this.owner, x+ORB_RADIUS*Cos(j*RAD_BETWEEN_EXPL), y+ORB_RADIUS*Sin(j*RAD_BETWEEN_EXPL), MISSILE_HEIGHT, j*RAD_BETWEEN_EXPL+bj_PI*0.25, ORB_EXPLODE_SPEED, MISSILE_SCALE)set j = j+1endloopsetthis.xtick=0endifelse//Special bolt stuff goes heresetthis.xtick=this.xtick+XE_ANIMATION_PERIOD
set j =0loopexitwhen(j >= ORB_EXPLODE_AMOUNT)if(this.xpl[j].obj!=null)thenset x =this.xpl[j].sx+this.xpl[j].xvel*this.xtickset y =this.xpl[j].sy+this.xpl[j].yvel*this.xtickcallGroupEnumUnitsInRange(ENUM_GROUP, x, y, XE_MAX_COLLISION_SIZE+MISSILE_RADIUS,null)loopset u =FirstOfGroup(ENUM_GROUP)exitwhen(u ==null)callGroupRemoveUnit(ENUM_GROUP, u)exitwhen(TargetFilter(u,this.owner, x, y))endloopif(this.xtick< EXPLODE_TMAX andRectContainsCoords(bj_mapInitialPlayableArea, x, y)and u ==null)thencallSetUnitX(this.xpl[j].obj, x)callSetUnitY(this.xpl[j].obj, y)elseif(u !=null)thencallUnitDamageTarget(this.xpl[j].obj, u,this.damage,true,false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)if(UnitAlive(u))thenif(GetUnitAbilityLevel(u, FROST_SLOW_BUFF)==0)thenset v =CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), XE_DUMMY_UNITID, x, y,0)callUnitAddAbility(v, FROST_SLOW_ID)callUnitApplyTimedLife(v,'BTLF',1.0)callIssueTargetOrder(v,"attackonce", u)endifelseif(GetRandomInt(0,100)<=this.chanceand ShatterFilter(u))thencallDestroyEffect(AddSpecialEffect(IMPACT_SHATTER_ART, x, y))callRemoveUnit(u)endifendif//Clears a special boltcallthis.xpl[j].clear()endifendifset j = j+1endloopendif//Completely destroys the spell and all instancesif(this.mcount==0andthis.orb.obj==nullandthis.xtick>= ORB_TMAX)thenset j =0loopexitwhen(j >=this.mcount)callthis.mis[j].destroy()set j = j+1endloopset j =0loopexitwhen(j >= ORB_EXPLODE_AMOUNT)callthis.xpl[j].destroy()set j = j+1endloopcallthis.orb.destroy()callthis.destroy()setthistype.tot=thistype.tot-1setthistype.tta[i]=thistype.tta[thistype.tot]if(thistype.tot==0)thencallPauseTimer(ANIM_TIMER)endifelseset i = i+1endifendloopset v =nullendmethodstaticmethod create takesunit su,real tx,real ty returnsthistypelocalthistypethis=thistype.allocate()localreal x =GetUnitX(su)localreal y =GetUnitY(su)localinteger level =GetUnitAbilityLevel(su, ABILITY_ID)setthis.owner=GetOwningPlayer(su)setthis.orb= missile.create(ORB_ART,this.owner, x, y, ORB_HEIGHT,Atan2(ty-y, tx-x), ORB_SPEED, ORB_SCALE)setthis.otick=0setthis.mcount=0setthis.mtot=0setthis.damage= IMPACT_DAMAGE_BASE+IMPACT_DAMAGE_INC*(level-1)setthis.chance= IMPACT_SHATTER_PER_BASE+IMPACT_SHATTER_PER_INC*(level-1)setthistype.tta[thistype.tot]=thisif(thistype.tot==0)thencallTimerStart(ANIM_TIMER, XE_ANIMATION_PERIOD,true,functionthistype.callback)endifsetthistype.tot=thistype.tot+1returnthisendmethodendstructprivatefunction Evaluate takesnothingreturnsbooleanif(GetSpellAbilityId()== ABILITY_ID)thencall spell.create(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY())endifreturnfalseendfunctionprivatefunction Init takesnothingreturnsnothinglocaltrigger t =CreateTrigger()callTriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)callTriggerAddCondition(t,Filter(function Evaluate))endfunctionendlibrary
changelog
<> v1.01 Added a "shatter filter" to prevent issues such as removing a hero from the game.
More coming soon I think.
Do not forget to give credits if this is used!!
~Eccho~
Rating - 4.50 (4 votes)
(Hover and click)
Moderator Comments
Not Rated
10:14, 5th Feb 2010
TriggerHappy:
The only thing I would suggest doing is recycling the missiles, it would be extremely easy in your scenario.
oh my days, this is good, really good but it is such a waste that WC3 lacks of a real frozen orb model and those icey shards (as the shards are now to "dark blueish")
As my code experience in vJass isn't the best I better leave my comments but I know a thing and another you can do so :)
Hey eccho now you made this and Charged Bolt. Those are really useful to me since im recreating Diablo II in Warcraft 3. Could you make blizzard like in Diablo II?
__________________
I hate people who call warcraft stuff for "sexy" or "hot".
crap, this spell has been done over and over again and we dont need the version number 9000, and vexorian made a better one ...
read the introduction
Quote:
(Vexorian made a frozen orb spell, I know, but
// it isn't working at all anymore. This spell was indeed
// an interpretation of the sorceress' spell Frozen Orb
// in Diablo 2.
// The reason why I did this spell is because I have not
// seen yet any frozen orb spell which is properly
// functional, or that I think does not look diablo 2'ish
// enough (Vexorian made a frozen orb spell, I know, but
// it isn't working at all anymore. This spell was indeed
// an interpretation of the sorceress' spell Frozen Orb
// in Diablo 2.
//
Please, link me to a fully working jass frozen orb. Vexorians may have been good back in the days he made it, but the script is old, and definitly not compatiable with wc3 anymore. Give me sources instead of dropping by and just tell me "oh just some new oldfag crap" more or less.