- Joined
- Jul 26, 2008
- Messages
- 1,009
Uses AutoIndex, TimerUtils, xe 0.8
Alright so I have a skill called poison daggers. It throws knives out in a fan shape over an area. Problem is it works like a shotgun. Up close it does ridiculous damage, but far away it's near useless.
I wanted to remedy that by making the spell only hit units at max twice. So I decided to use AutoIndex to help count how many times a unit has been hit by a knife and stop it at two. Well, now the spell doesn't work at all. :\ I kept my attempt in, and will have to revert back to an earlier version of the spell til I can figure it out. I'm having a similar problem with another spell where I want to limit the number of times a unit can be hit.
Alright so I have a skill called poison daggers. It throws knives out in a fan shape over an area. Problem is it works like a shotgun. Up close it does ridiculous damage, but far away it's near useless.
I wanted to remedy that by making the spell only hit units at max twice. So I decided to use AutoIndex to help count how many times a unit has been hit by a knife and stop it at two. Well, now the spell doesn't work at all. :\ I kept my attempt in, and will have to revert back to an earlier version of the spell til I can figure it out. I'm having a similar problem with another spell where I want to limit the number of times a unit can be hit.
JASS:
scope PoisonDaggers initializer init
globals
private constant integer SPELLID = 'afok'
private constant real tick = 1
endglobals
public struct Data extends xecollider
unit caster
unit t
// group g
timer tim
real dur
integer array counted[8194]
/* static method empty takes nothing returns nothing//Was thinking of grouping units and setting their variable to 0 when the struct ended.
local unit e = GetEnumUnit()
set .counted[GetUnitId(e)] = 0
endmethod*/
static method Timer takes nothing returns nothing//This one does the poison damage over time
local thistype this = GetTimerData(GetExpiredTimer())
local xedamage d= xedamage.create()
local integer lvl = GetUnitAbilityLevel(.caster, SPELLID)
local real dam = 2+3*lvl
set .dur = .dur + tick
if .dur <= 5 and not IsUnitType(.t, UNIT_TYPE_DEAD ) then
call d.useSpecialEffect(GetAbilityEffectById(SPELLID, EFFECT_TYPE_AREA_EFFECT, 1),"origin")
set d.dtype = DAMAGE_TYPE_POISON
set d.atype = ATTACK_TYPE_NORMAL
call d.damageTarget(.caster,.t, dam)
else
set .caster = null
set .t = null
call ReleaseTimer(.tim)
call .terminate()
endif
call d.destroy()
endmethod
/* method onDestroy takes nothing returns nothing//Was thinking of grouping then calling forgroup at the end of the struct
call ForGroup(.g, function thistype.empty)
endmethod*/
method onUnitHit takes unit target returns nothing
local xedamage d= xedamage.create()
local Data D
local integer id = GetUnitId(target)
local integer lvl = GetUnitAbilityLevel(.caster, SPELLID)
local real dam = (GetHeroAgi(.caster,true)*0.1)*(9+4*lvl)
set .counted[id] = 1
// set .counted[id] = .counted[id] + 1//This is where the issue takes place, I was trying to use an if statement for this but it wouldn't work
if IsUnitEnemy(target, GetOwningPlayer(.caster)) and not IsUnitType(target,UNIT_TYPE_STRUCTURE) then
call DestroyEffect(AddSpecialEffectTarget(GetAbilityEffectById(SPELLID, EFFECT_TYPE_AREA_EFFECT, 0), target, "origin"))
// call GroupAddUnit(this.g, target)
set d.dtype = DAMAGE_TYPE_POISON
set d.atype = ATTACK_TYPE_NORMAL
call d.damageTarget(this.caster,target, dam)
call d.destroy()
set .t = target
set .tim = NewTimer()
call SetTimerData(.tim,this)
call TimerStart(.tim, tick, true, function Data.Timer)//call the poison on damage on targets
call .hiddenDestroy()//Hidden destroy, so I do not terminate the struct and cause issues.
endif
endmethod
static method Actions takes nothing returns nothing
local unit c = GetTriggerUnit()
local integer i = 0
local integer lvl = GetUnitAbilityLevel(c, SPELLID)
local real angle = bj_RADTODEG*Atan2( GetSpellTargetY() - GetUnitY(c) , GetSpellTargetX() - GetUnitX(c) ) + (15+10*lvl)/2
local real cone = (15+10*lvl)/(1+lvl)
local Data xc
loop
exitwhen i == 2+lvl
set xc = Data.create( GetUnitX(c), GetUnitY(c), bj_DEGTORAD*(angle - cone*i) )
set xc.caster = c
set xc.fxpath = GetAbilityEffectById(SPELLID, EFFECT_TYPE_MISSILE, 0)
set xc.speed = 900
set xc.expirationTime = 1.
set xc.collisionSize = 32
set xc.dur = 0
set i = i + 1
endloop
set c = null
endmethod
static method Conditions takes nothing returns boolean
if GetSpellAbilityId() == SPELLID then
call thistype.Actions()
endif
return false
endmethod
endstruct
//===========================================================================
public function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, function Data.Conditions )
call XE_PreloadAbility(SPELLID)
set t = null
endfunction
endscope