- Joined
- Jul 26, 2008
- Messages
- 1,009
I've been creating a starfall spell. So far it's graphically fine, but when it starts to damage targets there's a major issue with the innacurracy of the damage radius. The stars will land right on the enemy and won't hurt them. So other than general fine-tuning to fix this map, is there any way to make it so the area being damage is more accurate?
I'd assume it has to do with the D.x1 and y1 being set new before the damage occurs, though I have my doubts about that. Thanks.
I'd assume it has to do with the D.x1 and y1 being set new before the damage occurs, though I have my doubts about that. Thanks.
JASS:
scope Starfall initializer InitTrig_Starfall
globals
private constant integer SPELLID = 'StFa'
private constant real tick = 0.6
endglobals
private struct Data extends xedamage
unit c
real x
real y
real x1
real y1
static method Star takes nothing returns nothing
local xedamage d=xedamage.create()
local group g = NewGroup()
local timer tim = GetExpiredTimer()
local Data D = Data(GetTimerData(tim))
local integer lvl = GetUnitAbilityLevel(D.c, SPELLID)
local real dam = lvl*10+15+SpellStat(D.c, true)*(0.4+0.1*lvl)
call d.factor( UNIT_TYPE_STRUCTURE, 0.2 )
call d.atype( ATTACK_TYPE_NORMAL )
call d.dtype( DAMAGE_TYPE_MAGIC )
call d.damageAOE(D.c, D.x1, D.y1, 32, dam)
call ReleaseTimer(tim)
call d.destroy()
call D.destroy()
call ReleaseGroup(g)
endmethod
static method Timer takes nothing returns nothing
local xecast xc = xecast.createA()
local timer tim = GetExpiredTimer()
local timer tim1 = NewTimer()
local Data D = Data(GetTimerData(tim))
local integer lvl = GetUnitAbilityLevel(D.c, SPELLID)
local real ang = GetRandomReal(0,360)*bj_DEGTORAD
set D.x1 = D.x+GetRandomReal(50,400)*Cos(ang)
set D.y1 = D.y+GetRandomReal(50,400)*Sin(ang)
if GetUnitCurrentOrder(D.c) == OrderId("starfall") then
call DestroyEffect(AddSpecialEffect(GetAbilityEffectById(SPELLID, EFFECT_TYPE_MISSILE, 0), D.x1, D.y1))
call SetTimerData(tim1, D)
call TimerStart(tim1, 0.15, false, function Data.Star)
else
set D.c = null
call D.destroy()
call ReleaseTimer(tim)
endif
endmethod
static method create takes unit c, real x, real y, integer i returns Data
local Data D = Data.allocate()
local timer tim = NewTimer()
set D.c = c
set D.x = x
set D.y = y
call SetTimerData(tim,D)
call TimerStart(tim, 0.3*i+GetRandomReal(0.1,-0.1), true, function Data.Timer)
return D
endmethod
endstruct
private function Conditions takes nothing returns boolean
local integer i = 1
local integer lvl = GetUnitAbilityLevel(GetTriggerUnit(), SPELLID)
if GetSpellAbilityId() == SPELLID then
loop
call Data.create(GetTriggerUnit(), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), i)
exitwhen i > lvl*10+8
set i = i + 1
endloop
endif
return false
endfunction
//===========================================================================
public function InitTrig_Starfall takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
call TriggerAddCondition( t, function Conditions )
set t = null
call XE_PreloadAbility(SPELLID)
endfunction
endscope