• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] t3h Shadow oooff..... DEEEEAAAAAAATTHHHH !!!!

Status
Not open for further replies.
Level 19
Joined
Aug 24, 2007
Messages
2,888
[JASS="Shadow of Death"]
scope ShadowOfDeath // Must be same with trigger name
globals
private real DamageInterval
private real Damage
private real MaximumRange
private real SpreadRange
private real AttackInterval
private real SpreadInterval
private real ShadowArea
private real DissapearInterval
private integer FL = 5
private integer IPL = 3

//! -------------- SETUP STARTS --------------

// Spell raw code in object editor
private constant integer SpellId = 'A00B'
// Trigger Preloads spell in how many seconds (-1 = no preload, 0 = preload in loading, x>0 preload after game start)
private constant real preloaddelay = -1
// Shadow Model
private constant string FXshadow = "war3mapImported\\Shadow of Death.mdl"
// Damage Model
private constant string FXdamage = "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl"
// Preload (see the "Advanced")
private constant real PreloadAfter = 0.
endglobals

private function Setup takes integer ability_level,integer hero_level, integer str,integer agi,integer int returns nothing
// Damage dealt per second
set Damage = 50. + ability_level*25. +hero_level*0+ str*0 + agi*0 + int*0
// Maximum spread range
set MaximumRange = 400.0 + ability_level*200.0 +hero_level*0+ str*0 + agi*0 + int*0
// Damage interval of shadow
set DamageInterval = 0.75 + ability_level*0.0 +hero_level*0+ str*0 + agi*0 + int*0
// Effect area of one piece of shadow
set ShadowArea = 100. + ability_level*20.
// Distance between shadow levels
set SpreadRange = ShadowArea*0.8
// Interval between shadows to get created
set SpreadInterval = 0.25
// Dissapear interval after finishing
set DissapearInterval = 0.05
endfunction

// ability_level = Ability Level of the Spell
// hero_level = Level of Casting Hero
// seconds_charged = How many seconds caster channeled the orb
// str = Strenght of Casting Hero
// agi = Agility of Casting Hero
// int = Intelligence of Casting Hero

//! -------------- SETUP ENDS --------------

public function PreloadSpell takes nothing returns nothing
call Preload(FXdamage)
call Preload(FXshadow)
endfunction

private struct SpreadS
timer T
unit C
real SX
real SY
real MR
real array X[150]
real array Y[150]
real R
real INT
effect array E[150]
integer array TABLE[50]
integer Level
integer NumberOfShadows //Strange... I tried to set it to 1 here and got some problems
integer CC
boolean REV = false
method LetsBegin takes nothing returns nothing
local integer a2 = 0
local integer i1
local integer i2
local integer i3
set .X[0] = .SX
set .Y[0] = .SY
set .E[0] = AddSpecialEffect(FXshadow,.SX,.SY)
set .NumberOfShadows = 1
set .Level = 1
loop
exitwhen a2 == FL
set .TABLE[a2] = a2
set a2 = a2 +1
endloop
set a2 = 0
loop
exitwhen a2 == FL*2
set i1 = GetRandomInt(0,FL-1)
set i2 = GetRandomInt(0,FL-1)
set i3 = .TABLE[i1]
set .TABLE[i1] = .TABLE[i2]
set .TABLE[i2] = i3
set a2 = a2+1
endloop
endmethod
endstruct

private struct DamageS
group G1 = CreateGroup()
group G2 = CreateGroup()
SpreadS S
real D
real A
endstruct

private function DamageTimer takes nothing returns nothing
local DamageS s1 = GetData(GetExpiredTimer())
local SpreadS s2 = s1.S
local unit u
local integer i = 0
if s2.NumberOfShadows == 0 then
call DestroyTimer(s2.T)
call DestroyTimer(GetExpiredTimer())
call DestroyGroup(s1.G1)
call DestroyGroup(s1.G2)
call s2.destroy()
call s1.destroy()
set u = null
return
endif

loop
exitwhen i == s2.NumberOfShadows
call GroupEnumUnitsInRange(s1.G2,s2.X,s2.Y,s1.A,nullfilter)
loop
set u = FirstOfGroup(s1.G2)
exitwhen u == null
if IsUnitEnemy(u,GetOwningPlayer(s2.C)) and GetWidgetLife(u) > 0 and (IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u,UNIT_TYPE_STRUCTURE) or IsUnitInGroup(u,s1.G1)) == false then
call UnitDamageTarget(s2.C,u,s1.D,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffectTarget(FXdamage,u,"chest"))
call GroupAddUnit(s1.G1,u)
endif
call GroupRemoveUnit(s1.G2,u)
endloop
set i = i+1
endloop
call GroupClear(s1.G1)
set u = null
endfunction

private function SpreadTimer takes nothing returns nothing
local SpreadS s1 = GetData(GetExpiredTimer())
local integer i1
local integer i2
local integer i3
local integer a1 = 0
local integer a2 = 1
local integer a3 = 0
if s1.NumberOfShadows == 0 or (s1.R*s1.Level > s1.MR and not s1.REV) then
return
endif

if not (IfChanneling(s1.C,s1.CC) or s1.REV) then
set s1.REV = true
call TimerStart(GetExpiredTimer(),s1.INT,true,function SpreadTimer)
endif

if not s1.REV then
set a1 = s1.Level*FL+1
set a3 = (s1.Level-1)*FL+1
loop
exitwhen a2 == s1.Level+1
set a1 = a1 + (a2-1)*IPL
set a3 = a3 + (a2-2)*IPL
set a2 = a2+1
endloop
if s1.Level == 1 then
set i1 = s1.NumberOfShadows-1
else
set i1 = s1.NumberOfShadows - a3 -IPL
endif
set s1.X[s1.NumberOfShadows] = s1.SX+s1.R*s1.Level*Cos((I2R(s1.TABLE[i1])/I2R(FL+IPL*(s1.Level-1)-1))*(2.*bj_PI))
set s1.Y[s1.NumberOfShadows] = s1.SY+s1.R*s1.Level*Sin((I2R(s1.TABLE[i1])/I2R(FL+IPL*(s1.Level-1)-1))*(2.*bj_PI))
set s1.E[s1.NumberOfShadows] = AddSpecialEffect(FXshadow,s1.X[s1.NumberOfShadows],s1.Y[s1.NumberOfShadows])
set s1.NumberOfShadows = s1.NumberOfShadows+1
if s1.NumberOfShadows == a1 then
set s1.Level = s1.Level+1
set a2 = 0
loop
exitwhen a2 == FL + s1.Level*IPL
set s1.TABLE[a2] = a2
set a2 = a2+1
endloop
set a2 = 0
loop
exitwhen a2 == (FL+IPL*(s1.Level-1)-1)*2
set i1 = GetRandomInt(0,FL+IPL*(s1.Level-1)-1)
set i2 = GetRandomInt(0,FL+IPL*(s1.Level-1)-1)
set i3 = s1.TABLE[i1]
set s1.TABLE[i1] = s1.TABLE[i2]
set s1.TABLE[i2] = i3
set a2 = a2+1
endloop
endif
else
set s1.NumberOfShadows = s1.NumberOfShadows-1
call DestroyEffect(s1.E[s1.NumberOfShadows])
endif
endfunction

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SpellId
endfunction

private function SpellCast takes nothing returns nothing
local unit caster = GetTriggerUnit()
local integer level = GetUnitAbilityLevel(caster,GetSpellAbilityId())
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local integer agi = GetHeroAgi(caster,true)
local integer int = GetHeroInt(caster,true)
local integer str = GetHeroStr(caster,true)
local integer hlevel = GetHeroLevel(caster)
local timer t = CreateTimer()
local SpreadS s1 = SpreadS.create()
local DamageS s2 = DamageS.create()
call Setup(level,hlevel,str,agi,int)
set s1.CC = StartChanneling(caster)
set s2.S = s1
set s1.R = SpreadRange
set s1.SX = x
set s1.SY = y
set s1.T = t
set s1.C = caster
set s2.D = Damage
set s2.A = ShadowArea
set s1.MR = MaximumRange
set s1.INT = DissapearInterval
call s1.LetsBegin()
call SetData(t,s1)
call TimerStart(t,DamageInterval,true,function DamageTimer)
set t = CreateTimer()
call SetData(t,s2)
call TimerStart(t,SpreadInterval,true,function SpreadTimer)
// My part
set t = null
set caster = null
endfunction

public function InitTrig takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, nullfilter)
set index = index + 1
exitwhen index == 16
endloop
set index = 0
call TriggerAddAction( trig, function SpellCast)
call TriggerAddCondition( trig, Filter(function Conditions) )
if PreloadAfter >= 0 then
call TimerStart(CreateTimer(),PreloadAfter,false,function PreloadSpell)
elseif PreloadAfter == -1 then
call PreloadSpell()
endif
endfunction

endscope[/code]


Problems:
-Sometimes it spreads the shadows with same interval it destroys
-Sometimes it doesnt destroy shadows

Everything else seems fine

Solution ?

Also I attached the map so you wont need to implement

Thanks for incoming replies
 
Last edited:
Level 19
Joined
Aug 24, 2007
Messages
2,888
Anyway I think I found a solution to fix both problems

So you may delete

Edit: Yea it worked and fixed
 
Last edited:
Level 19
Joined
Aug 24, 2007
Messages
2,888
@PaF:less function executions (about localling struct vars)
hey at least I dont do local unit c = s1.c

@HT:
cause gray looks sexier than green?
you are the man

@noone: TABLE[] guy is my favourite

@Poot: keep winning
 
Status
Not open for further replies.
Top