- Joined
- Mar 25, 2008
- Messages
- 2,954
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
S&SMC#18 entry by palaslayer
Deep Crush and Thunder Storm
(the synergy can occur in real life, too, so be careful!)
Deep Crush [C]
Dives into the ground appearing at the target location and causing a huge water fountain to throw units in the area into the air, leaving them wet and slowed. Area, damage and percentage of slow increases each level.
Level 1 - 75 dmg, 300 area, 30%
Level 2 - 150 dmg, 400 area, 40%
Level 3 - 225 dmg. 500 area, 50%
Thunder Storm [T]
Calls down lightnings from the sky tearing apart every enemy close to the area hit. Wet enemies will be dealt extra damage and get stunned. Damage, stun duration and the number of lightnings increase with each level.
Level 1 - 100 damage, 4 lightnings
Level 2 - 150 damage, 6 lightnings
Level 3 - 200 damage, 8 lightnings
Removes the "Wet"-buff
A 100% Slow is making a unit attack at 50% speed. so he can attack![]()
The submissions can still be found herechangelog v1.1 said:*Changed Phoenix Strike's hotkey (thanks Bounty for spotting that out)
*Added cooldown to both spells (seems to not trigger the bug the Phoenix Strike has this way... however, be aware that the bug still exists.)
*Changed tooltips (thanks to PurplePoot for suggestions)
*Changed ability icons (thanks to -Berzeker- and OffGraphic for suggestions)
GetUnitAbilityLevelSwapped it is completely unneccesary, since it only calls the native.function GetUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
return GetUnitAbilityLevel(whichUnit, abilcode)
endfunction
CreateNUnitsAtLoc is pretty dull using as well ._.function CreateNUnitsAtLoc takes integer count, integer unitId, player whichPlayer, location loc, real face returns group
call GroupClear(bj_lastCreatedGroup)
loop
set count = count - 1
exitwhen count < 0
call CreateUnitAtLocSaveLast(whichPlayer, unitId, loc, face)
call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
endloop
return bj_lastCreatedGroup
endfunction
set d = CreateUnit(forWhichPlayer, unitid, x, y, facing)set d = CreateUnit(GetOwningPlayer(c), DUMMY_ID, GetUnitX(c), GetUnitY(c), bj_UNIT_FACING)Kingz, your spell looks cool, and seems original from my point of view. However, it gives an enourmous amount of lag when casting both of the spells at the same time. My fps dropped down to ~4. And since I really am pretty lousy judging GUI MUI spells (everything else I have no problems with^^) I recommend you a certain Paladon to judge your spell
Rmx, the tooltip could be better. You descibe both the spells in their tooltip, in one single sentence. Give us some breathing
The ideas are very cool tho, but definitly imbalaced^^. I vanished around 10 murlocs at once, and they never come back? However, since I didnt get any exp or bounty for it, I guess that nerfes it down alittle bit. Also, you should change the name to not be "just another warcraft map".
NiddHogg-kun, lovely idea tooAll of you three has done a really good job. This idea was very original (maybe not the tornado because I have seen those before) but the homing flame cannon was great. I would like the caster to play some kind of spell animation though. About your code, it looks Mui and everything like all three of yours, but Palason is still a good choice to ask^^.
Johnnny, where is your second spell :7? The time is running out.
Element of Water, where are both of yours :/?
15th March (Sunday), 00:00 GMT.
//**********************************************************************************************
//* By xD.Schurke (14.03.2009)
//*
//*
//* This is my entry for the current Spells&Systems Mini Contest 18 on hiveworkshop.com
//*
//* Version 1.2
//*
//* Changes:
//*
//* - Fixed some bugs with the second spell
//* - Reworked Effects of the second spell
//*
//*
//*
//*
//*
//*
//* xx xx DDDDD SSSS h k k EEEEE
//* xx xx DD DD SS h k k EE
//* xxxx DD DD SSS ccc hhh u u r rr ccc kk EEEE
//* xx xx DD DD _ SS cc h h u u rr cc k k EE
//* xx xx DDDDD |_| SSSS ccc h h uuuu r ccc k k EEEEE
//**********************************************************************************************
scope chargeSpell initializer chargeInt
globals
//Some variables are not private, because they are used in another scope again
//Rawcodes
constant integer dummyID = 'h000' //The rawcode of the dummyunit
constant integer chargeID = 'A002' //The rawcode of the charge spell
constant integer chargeBuffID = 'B001' //The rawcode of the charge spell debuff
constant integer flyID = 'Amrf' //The rawcode of the fly ability for spheres etc.
//Real Values
private constant real chargeDamage = 18.
private constant real chargeDamageInc = 5.
private constant real chargeDuration = 12.
private constant real chargeExtraChance = 25. //The percent chance
private constant real chargeDivisor = 45. //The divisor ==> higher = lower damage , lower = higher damage
private constant real Interval = 0.035 //The timer interval
private constant real damageInterval = 1/Interval //The 1 is 1 second
private constant real sphereDistance = 50.
private constant real angleSpeed = 10.
private constant real flySpeed = 5.
private constant real maxFlyHigh = 175.
private constant real sphereSize = 0.7
//Effect Strings
private constant string sfx = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
private constant string attach = "origin"
//Attack/Damage/Weapon Types => change for armor ignore etc.
constant attacktype atta = ATTACK_TYPE_NORMAL
constant damagetype dmg = DAMAGE_TYPE_NORMAL
constant weapontype weap = WEAPON_TYPE_WHOKNOWS
//Timer stacking issues
private timer Tim = CreateTimer()
private integer array Data
private integer Total = 0
endglobals
//Constant Functionts => Formuals for calculate damage
private constant function chargeDmg takes integer lvl returns real
return (chargeDamage+((lvl-1)*chargeDamageInc))/damageInterval
endfunction
private constant function chargeExtraDmg takes integer lvl, real time returns real
return (time*(chargeDamage+((lvl-1)*chargeDamageInc)))*(chargeDivisor/100)
endfunction
//The followning Struct is created for each 'Charge' effected unit
private struct chargeStruct
unit caster
unit target
real time = 0.
static method chargeDamageInterval takes nothing returns nothing
local chargeStruct dat
local integer i = 0
local texttag te
local real tmpReal = 0.
local real x = 0.
local real y = 0.
local real ang = 0.
local real fly = 0.
loop
exitwhen i >= Total
set dat = Data[i]
//the following if condition checks if the time is over or the debuff 'Charge' was removed from the unit and destroys the struct
if dat.time >= chargeDuration or GetUnitAbilityLevel(dat.target,chargeBuffID) <= 0 then
//the next part creates a chance to deal extra damage at the end of the spell or if the spell is removed from the target => with TextTag for showing the damage
if GetRandomReal(0,100) <= chargeExtraChance and GetUnitState(dat.target,UNIT_STATE_LIFE) > 0 then
set tmpReal = chargeExtraDmg(GetUnitAbilityLevel(dat.caster,chargeID),dat.time)
set te = CreateTextTag()
call SetTextTagText(te, I2S(R2I(tmpReal))+"!", 0.022)
call SetTextTagPos(te, GetUnitX(dat.target), GetUnitY(dat.target), 0.00)
call SetTextTagColor(te, 255, 255, 125, 155)
call SetTextTagVelocity(te, 0, 0.04)
call SetTextTagVisibility(te, true)
call SetTextTagFadepoint(te, 2)
call SetTextTagLifespan(te, 5)
call SetTextTagPermanent(te, false)
call UnitDamageTarget(dat.caster,dat.target,tmpReal,false,false,atta,dmg,weap)
endif
set Total = Total - 1
set Data[i] = Data[Total]
set i = i - 1
set dat.caster = null
set dat.target = null
call chargeStruct.destroy(dat)
else
//if the time isn't over yet the unit keeps being damaged
set dat.time = dat.time + Interval
call UnitDamageTarget(dat.caster,dat.target,chargeDmg(GetUnitAbilityLevel(dat.caster,chargeID)),false,false,atta,dmg,weap)
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
set te = null
endmethod
static method create takes nothing returns chargeStruct
local chargeStruct dat = chargeStruct.allocate()
if Total == 0 then
call TimerStart(Tim,Interval,true,function chargeStruct.chargeDamageInterval)
endif
set Data[Total] = dat
set Total = Total + 1
return dat
endmethod
endstruct
//standard initialization functions
private function chargeCondition takes nothing returns boolean
return GetSpellAbilityId() == chargeID
endfunction
private function chargeActions takes nothing returns nothing
local chargeStruct dat = chargeStruct.create()
local real x = 0
local real y = 0
set dat.caster = GetTriggerUnit()
set dat.target = GetSpellTargetUnit()
endfunction
private function chargeInt takes nothing returns nothing
local trigger int = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(int,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(int,Condition(function chargeCondition))
call TriggerAddAction(int,function chargeActions)
set int = null
endfunction
endscope
scope newElectroField initializer newInt
globals
//Rawcodes
private constant integer electroID = 'A001'
private constant integer overloadID = 'A000'
private constant integer timedLife = 'BTLF'
//Effect Strings
private constant string explusionSFX = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
private constant string fieldString = "Units\\NightElf\\Wisp\\WispExplode.mdl"
private constant string buffEffect = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldBuff.mdl"
private constant string missileSFX = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
//Action-Strings
private constant string attach = "origin"
private constant string overhead = "overhead"
private constant string purge = "purge"
//Real Values
private constant real dmgRadius = 45.
private constant real speed = 5.
private constant real speed2 = 15.
private constant real electroDamage = 7.
private constant real electroDamageInc = 2.
private constant real electroMisDamage = 75.
private constant real electroMisDamageInc = 50.
private constant real Interval = 0.035
private constant real duration = 5.
private constant real scale = 0.7
private constant real scale2 = 1.5
private constant real scaleInc = 0.01
private constant real flyHigh = 100.
private constant real degrees = 360.
private constant real maxDistance = 800.
private constant real fadeDistance = 85.
private constant real startDistance = 50.
//Integer Values
private constant integer missilesMax = 10
private constant integer missilesInc = 5
private constant integer color = 255
private constant integer alphaDec = 15
//Time Stacking issues => 2struct 2Timers
private timer Tim = CreateTimer()
private timer Tim2 = CreateTimer()
private timer Tim3 = CreateTimer()
private integer array Data
private integer array Data2
private integer array Data3
private integer Total = 0
private integer Total2 = 0
private integer Total3 = 0
//GroupIssues
private group tmpG = CreateGroup()
private player tmpP
private boolexpr Cond
endglobals
//Constant functions formulas + filter function for aoe damage in struct electroMainStruct
private constant function electroDmg takes integer lvl returns real
return (electroDamage+((lvl-1)*electroDamageInc))
endfunction
private constant function electroMisDmg takes integer lvl returns real
return electroMisDamage+((lvl-1)*electroMisDamageInc)
endfunction
private constant function missiles takes integer lvl returns integer
return missilesMax+((lvl-1)*missilesInc)
endfunction
private function filter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),tmpP) and (GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0) and (GetUnitTypeId(GetFilterUnit())!= dummyID)
endfunction
//The Overload-Struct
private struct overload
unit caster
unit missile
unit target
real time = 0.
real misScale = 0.
static method loopMethod takes nothing returns nothing
local overload dat
local integer i = 0
local unit dummy
loop
exitwhen i >= Total2
set dat = Data2[i]
set dat.time = dat.time - Interval
if dat.time <= 0 or GetUnitState(dat.target,UNIT_STATE_LIFE) <= 0 then
//if 5 seconds are over, the missile damages the target + effect
call DestroyEffect(AddSpecialEffect(fieldString,GetUnitX(dat.target),GetUnitY(dat.target)))
call DestroyEffect(AddSpecialEffect(explusionSFX,GetUnitX(dat.target),GetUnitY(dat.target)))
call UnitDamageTarget(dat.missile,dat.target,electroMisDmg(GetUnitAbilityLevel(dat.caster,electroID)),false,false,atta,dmg,weap)
call KillUnit(dat.missile)
set dummy = CreateUnit(GetOwningPlayer(dat.caster),dummyID,GetUnitX(dat.target),GetUnitY(dat.target),0)
call UnitAddAbility(dummy,overloadID)
call IssueTargetOrder(dummy,purge,dat.target)
call UnitApplyTimedLife(dummy,timedLife,1)
set Total2 = Total2 - 1
set Data2[i] = Data2[Total2]
set i = i - 1
else
set dat.misScale = dat.misScale + scaleInc
call SetUnitPosition(dat.missile,GetUnitX(dat.target),GetUnitY(dat.target))
call SetUnitScale(dat.missile,dat.misScale,dat.misScale,dat.misScale)
endif
set i = i + 1
endloop
if Total2 == 0 then
call PauseTimer(Tim2)
endif
set dummy = null
endmethod
static method create takes nothing returns overload
local overload dat = overload.allocate()
if Total2 == 0 then
call TimerStart(Tim2,Interval,true,function overload.loopMethod)
endif
set Data2[Total2] = dat
set Total2 = Total2 + 1
return dat
endmethod
endstruct
//missile struct, moves the missle and attaches it to a target with the charge debuff
private struct missileStruct
unit caster
unit missile
real x = 0.
real y = 0.
real angle = 0.
real distance = 0.
real time = 0.
integer alpha = 0
effect sfx
boolean bool = false
group g = CreateGroup()
static method move takes nothing returns nothing
local missileStruct dat
local overload data
local unit u
local integer i = 0
local real x = 0.
local real y = 0.
loop
exitwhen i >= Total
set dat = Data[i]
set dat.distance = dat.distance - speed
if (dat.distance <= 0 and dat.bool == false) or dat.time <= 0 then
set Total = Total - 1
set Data[i] = Data[Total]
set i = i - 1
call RemoveUnit(dat.missile)
call DestroyEffect(dat.sfx)
call DestroyGroup(dat.g)
set dat.g = null
set dat.missile = null
set dat.sfx = null
call missileStruct.destroy(dat)
elseif dat.distance <= fadeDistance and dat.bool == false then
set dat.alpha = dat.alpha - alphaDec
call SetUnitVertexColor(dat.missile,color,color,color,dat.alpha)
elseif dat.bool == false then
set x = dat.x + speed * Cos(dat.angle * bj_DEGTORAD)
set y = dat.y + speed * Sin(dat.angle * bj_DEGTORAD)
set dat.x = x
set dat.y = y
call SetUnitPosition(dat.missile,dat.x,dat.y)
set tmpP = GetOwningPlayer(dat.missile)
call GroupEnumUnitsInRange(tmpG,dat.x,dat.y,dmgRadius,Cond)
loop
set u = FirstOfGroup(tmpG)
exitwhen u == null
call UnitDamageTarget(dat.missile,u,electroDmg(GetUnitAbilityLevel(dat.caster,electroID)),false,false,atta,dmg,weap)
call DestroyEffect(AddSpecialEffectTarget(buffEffect,u,overhead))
if GetUnitAbilityLevel(u,chargeBuffID) > 0 and IsUnitInGroup(u,dat.g) != true then
set dat.bool = true
set data = overload.create()
set data.caster = dat.caster
set data.missile = dat.missile
set data.target = u
set data.time = duration
set data.misScale = scale
call GroupAddUnit(dat.g,u)
endif
call GroupRemoveUnit(tmpG,u)
endloop
else
set dat.time = dat.time - Interval
endif
set i = i + 1
endloop
set u = null
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
static method create takes nothing returns missileStruct
local missileStruct dat = missileStruct.allocate()
if Total == 0 then
call TimerStart(Tim,Interval,true,function missileStruct.move)
endif
set Data[Total] = dat
set Total = Total + 1
return dat
endmethod
endstruct
//the first missile
private struct startStruct
unit missile
unit caster
effect sfx
real x = 0.
real y = 0.
real distance = 0.
real angle = 0.
static method move takes nothing returns nothing
local startStruct dat
local missileStruct data
local integer i = 0
local integer p = 0
local real angle = 0.
local real x = 0.
local real y = 0.
loop
exitwhen i >= Total3
set dat = Data3[i]
set dat.distance = dat.distance - speed2
if dat.distance <= 0 then
set Total3 = Total3 - 1
set Data3[i] = Data3[Total3]
set i = i - 1
call DestroyEffect(AddSpecialEffect(fieldString,dat.x,dat.y))
call DestroyEffect(AddSpecialEffect(explusionSFX,dat.x,dat.y))
set p = missiles(GetUnitAbilityLevel(dat.caster,electroID))
set angle = degrees/p
loop
exitwhen p <= 0
set data = missileStruct.create()
set data.caster = dat.caster
set data.angle = angle*p
set x = dat.x + startDistance * Cos(data.angle * bj_DEGTORAD)
set y = dat.y + startDistance * Sin(data.angle * bj_DEGTORAD)
set data.missile = CreateUnit(GetOwningPlayer(dat.caster),dummyID,x,y,0)
set data.x = x
set data.y = y
set data.time = duration
set data.distance = maxDistance
set data.alpha = color
set data.sfx = AddSpecialEffectTarget(missileSFX,data.missile,attach)
call UnitAddAbility(data.missile,flyID)
call SetUnitFlyHeight(data.missile,flyHigh,0)
call UnitRemoveAbility(data.missile,flyID)
call SetUnitScale(data.missile,scale,scale,scale)
call SetUnitPathing(data.missile,false)
set p = p - 1
endloop
call KillUnit(dat.missile)
set dat.missile = null
set dat.caster = null
call DestroyEffect(dat.sfx)
set dat.sfx = null
call startStruct.destroy(dat)
else
set x = GetUnitX(dat.missile) + speed2 * Cos(dat.angle*bj_DEGTORAD)
set y = GetUnitY(dat.missile) + speed2 * Sin(dat.angle*bj_DEGTORAD)
call SetUnitPosition(dat.missile,x,y)
endif
set i = i + 1
endloop
if Total3 == 0 then
call PauseTimer(Tim3)
endif
endmethod
static method create takes nothing returns startStruct
local startStruct dat = startStruct.allocate()
if Total3 == 0 then
call TimerStart(Tim3,Interval,true,function startStruct.move)
endif
set Data3[Total3] = dat
set Total3 = Total3 + 1
return dat
endmethod
endstruct
//standard functions
private function newCondition takes nothing returns boolean
return GetSpellAbilityId() == electroID
endfunction
private function newAction takes nothing returns nothing
local startStruct dat = startStruct.create()
local location tmpLoc = GetSpellTargetLoc()
local real dx = GetLocationX(tmpLoc) - GetUnitX(GetTriggerUnit())
local real dy = GetLocationY(tmpLoc) - GetUnitY(GetTriggerUnit())
set dat.caster = GetTriggerUnit()
set dat.x = GetLocationX(tmpLoc)
set dat.y = GetLocationY(tmpLoc)
set dat.distance = SquareRoot(dx * dx + dy * dy)
set dat.angle = bj_RADTODEG * Atan2(dat.y - GetUnitY(dat.caster), dat.x - GetUnitX(dat.caster))
set dat.missile = CreateUnit(GetOwningPlayer(dat.caster),dummyID,GetUnitX(dat.caster),GetUnitY(dat.caster),0)
set dat.sfx = AddSpecialEffectTarget(missileSFX,dat.missile,attach)
call UnitAddAbility(dat.missile,flyID)
call SetUnitFlyHeight(dat.missile,flyHigh,0)
call UnitRemoveAbility(dat.missile,flyID)
call SetUnitScale(dat.missile,scale2,scale2,scale2)
call SetUnitPathing(dat.missile,false)
call RemoveLocation(tmpLoc)
set tmpLoc = null
endfunction
private function newInt takes nothing returns nothing
local trigger int = CreateTrigger()
local integer index = 0
local unit dummy = CreateUnit(Player(14),dummyID,9999999,9999999,0)
loop
call TriggerRegisterPlayerUnitEvent(int,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(int,Condition(function newCondition))
call TriggerAddAction(int,function newAction)
set int = null
set Cond = Condition(function filter)
call UnitAddAbility(dummy,overloadID)
call RemoveUnit(dummy)
call Preload(fieldString)
call Preload(explusionSFX)
call Preload(buffEffect)
call Preload(missileSFX)
call PreloadStart()
set dummy = null
endfunction
endscope
group g = CreateGroup()
