- Joined
- May 28, 2007
- Messages
- 365
JASS:
scope Cleave initializer Init
private struct data
unit target = null
unit caster = null
group knockGroup = null
real v = 0.
real angle = 0.
endstruct
globals
private boolexpr filter = null
private data tempData
endglobals
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00N'
endfunction
private function Filt takes nothing returns boolean
local unit t = GetFilterUnit()
if( IsUnitEnemy(t,GetOwningPlayer(tempData.caster)) and GetWidgetLife(t)>0.405 and not IsUnitType(t, UNIT_TYPE_MECHANICAL)and not IsUnitInGroup(t, tempData.knockGroup) ) then
call GroupAddUnit(tempData.knockGroup, t)
call UnitAddAbility(t, 'A00O')
endif
return FALSE
endfunction
private function KnockbackGroup takes nothing returns nothing
local unit u = GetEnumUnit()
local real dx = 0.
local real dy = 0.
set dx = PolarProjectionX(GetUnitX(u), tempData.v, tempData.angle)
set dy = PolarProjectionY(GetUnitY(u), tempData.v, tempData.angle)
if IsTerrainWalkable(dx, dy) then
call SetUnitX(u, dx)
call SetUnitY(u, dy)
endif
endfunction
private function Callback takes nothing returns nothing
local timer myTimer = GetExpiredTimer()
local data d = GetTimerData(myTimer)
local unit target = null
set d.v = d.v*0.925
set tempData = d
// Enum and add new units to the knockback group
call GroupEnumUnitsInRange(tempGroup, GetUnitX(d.target), GetUnitY(d.target), 125, filter)
// Knockback the entire group
call ForGroup(d.knockGroup, function KnockbackGroup)
if d.v <= 5 then
loop
set target = FirstOfGroup(d.knockGroup)
exitwhen target == null
call UnitRemoveAbility(target, 'A00O')
call GroupRemoveUnit(d.knockGroup, target)
endloop
call ReleaseGroup(d.knockGroup)
call ReleaseTimer(myTimer)
call d.destroy()
endif
endfunction
private function Actions takes nothing returns nothing
local timer myTimer = NewTimer()
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local real amount = 50+GetHeroLevel(u)*10+GetUnitStat(u, ATTACK_POWER)*0.4*BarbarianDamageModifier(u,t)
local data d = data.create()
set d.caster = u
set d.target = t
set d.knockGroup = NewGroup()
set d.angle = AngleBetweenPointsXY(GetUnitX(u), GetUnitY(u), GetUnitX(t), GetUnitY(t))
set d.v = 40.
call GroupAddUnit(d.knockGroup, t)
call UnitAddAbility(t, 'A00O')
call UnitDamage(u, t, PHYSICAL, amount)
call SetTimerData(myTimer, d)
call TimerStart(myTimer, 0.03, true, function Callback)
endfunction
function Init takes nothing returns nothing
local trigger t = CreateTrigger()
set filter = Condition(function Filt)
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Conditions ) )
call TriggerAddAction( t, function Actions )
set t = null
endfunction
endscope
So this is my code for a spell. When used, it seems to work fine. However, the spell starts to crash after a certain time. I'm not sure if it's based on how many times the spell was used, or if it has to do with the maps game time.
The crash is unrelated to the custom functions that are being used such as UnitDamage, which is why I didn't post the code for those functions.
I once commented out the timer and the struct, and the crashes stopped.
Is there something I'm doing wrong?
I'm also attaching this, because I think this is the problem.
l
JASS:
ibrary IsTerrainWalkable initializer Init
//*****************************************************************
//* IsTerrainWalkable
//*
//* rewritten in vJass by: Anitarf
//* original implementation: Vexorian
//*
//* A function for checking if a point is pathable for ground
//* units (it does so by attempting to move an item there and
//* checking where it ended up), typically used to stop sliding
//* units before they end up stuck in trees. If the point is not
//* pathable, the function will also determine the nearest point
//* that is (the point where the item ends up).
//*****************************************************************
globals
// this value is how far from a point the item may end up for the point to be considered pathable
private constant real MAX_RANGE = 10.0
// the following two variables are set to the position of the item after each pathing check
// that way, if a point isn't pathable, these will be the coordinates of the nearest point that is
public real X = 0.0
public real Y = 0.0
// END OF CALIBRATION SECTION
// ================================================================
private rect r
private item check
private item array hidden
private integer hiddenMax = 0
endglobals
private function Init takes nothing returns nothing
set check = CreateItem('ciri',0,0)
call SetItemVisible(check,false)
set r = Rect(0.0,0.0,128.0,128.0)
endfunction
private function HideBothersomeItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set hidden[hiddenMax]=GetEnumItem()
call SetItemVisible(hidden[hiddenMax],false)
set hiddenMax=hiddenMax+1
endif
endfunction
// ================================================================
function IsTerrainWalkable takes real x, real y returns boolean
// first, hide any items in the area so they don't get in the way of our item
call MoveRectTo(r, x,y)
call EnumItemsInRect(r,null,function HideBothersomeItem)
// try to move the check item and get it's coordinates
call SetItemPosition(check,x,y)//this unhides the item...
set X = GetItemX(check)
set Y = GetItemY(check)
call SetItemVisible(check,false)//...so we must hide it again
// before returning, unhide any items that got hidden at the start
loop
exitwhen hiddenMax<=0
set hiddenMax=hiddenMax-1
call SetItemVisible(hidden[hiddenMax],true)
set hidden[hiddenMax]=null
endloop
// return pathability status
return (x-X)*(x-X)+(y-Y)*(y-Y) < MAX_RANGE*MAX_RANGE
endfunction
endlibrary
Last edited: