| 10-24-2008, 06:07 AM | #1 |
this library is basically an arrow collision but it seems to be having problems with handle count when used a lot if you need clarification, ask me JASS:library CAS requires CSData,CSSafety,HandyFunctions globals private constant real Start = 50.00 private constant real Scale = 1.00 private constant real Fly_height = 60.00 private constant attacktype A = ATTACK_TYPE_CHAOS private constant damagetype D = DAMAGE_TYPE_UNIVERSAL private unit Caster = null endglobals private function FilterIsEnemyAlive takes nothing returns boolean return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster))) and (GetWidgetLife(GetFilterUnit())>0.405) endfunction private function FilterIsEnemyAlive2 takes nothing returns boolean return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster))) and (GetWidgetLife(GetFilterUnit())>0.405) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)) endfunction //======================================================================= struct Arrow //! runtextmacro PUI() unit u unit d unit a real moved real cd real maxd real dmg real angle real anglechange real r real plx real ply real bases group g timer t integer aid boolean spell string sfx string as boolean grav real csd real acceleration static method create takes integer ut, unit u, integer lvl, real cx, real cy, real tx, real ty, real period, real r, real moved, real bases, real acceleration, real maxd, real dmg, integer items returns Arrow //ut = UnitTypeIdOfDummyUnit, u = Caster, lvl = abilityLvl, cx = CasterX, cy = CasterY, tx = TargetX, ty = TargetY, period = timer interval, r = radius of arrow, moved = starting move speed, bases = max speed of arrow, acceleration = speed accelerated per interval, maxd = arrow range, dmg = damage, items = check if items should be given to dummy local integer index local item indexItem local integer lvl2 = GetUnitAbilityLevel(u,'A01X') local integer i local real angle = AngleXY(cx,cy,tx,ty) local unit arrow = CreateUnit(GetOwningPlayer(u),ut, PolarProjectionX (cx, Start, angle), PolarProjectionY (cy, Start, angle) , Rad2Deg(angle)) local Arrow d = Arrow.allocate() set Arrow[arrow] = d set d.t = NewTimer() set d.u = u set d.cd = Start set d.csd = 0 set d.maxd = maxd set d.angle = angle set d.dmg = dmg set d.g = NewGroup() set d.r = r set d.d = arrow set d.plx = GetUnitX(d.d) set d.ply = GetUnitY(d.d) set d.acceleration = acceleration call GroupAddUnit(Arrows,d.d) call SetUnitMoveSpeed(d.d, moved) set d.bases = bases set d.moved = moved set d.a = null set d.aid = 0 set d.spell = false set d.sfx = null set d.as = null set d.spell = false set d.anglechange = 0 if lvl2 == 1 then set d.grav = true else set d.grav = false endif if items == 1 then set index = 0 loop exitwhen index > 5 set indexItem = UnitItemInSlot(u, index) if indexItem != null then if GetItemTypeId(indexItem) == 'I00G' or GetItemTypeId(indexItem) == 'I00M' then set i = GetRandomInt(1, 100) if i <= 15 then call UnitAddItemById(d.d,'I00V') endif endif if GetItemTypeId(indexItem) == 'I00J' or GetItemTypeId(indexItem) == 'I00M' then set i = GetRandomInt(1 , 100) if i <= 15 then call UnitAddItemById(d.d,'I00X') endif endif if GetItemTypeId(indexItem) == 'I00F' or GetItemTypeId(indexItem) == 'I00M' then set i = GetRandomInt(1 , 100) if i <= 17 then call UnitAddItemById(d.d, 'I00W') endif endif if GetItemTypeId(indexItem) == 'I007' then set i = GetRandomInt(1 , 100) if i <= 10 then call UnitAddItemById(d.d, 'I007') endif endif if GetItemTypeId(indexItem) == 'I006' then set i = GetRandomInt(1 , 100) if i <= 15 then call UnitAddItemById(d.d, 'I006') endif endif if GetItemTypeId(indexItem) == 'I008' then set i = GetRandomInt(1 , 100) if i <= 20 then call UnitAddItemById(d.d, 'I008') endif endif endif set index = index + 1 endloop set indexItem = null endif set Caster = u if GetUnitTypeId(d.d) == 'h00K' then set d.spell = true set d.aid = 'A00A' set d.as = "flamestrike" set d.a = CreateUnit(GetOwningPlayer(u),'h000',cx,cy,0) call UnitAddAbility(d.a,'A00A') call SetUnitAbilityLevel(d.a,'A00A',lvl) call UnitApplyTimedLife(d.a,'BTLF',60) set d.sfx = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl" endif if d.grav == true then if GetUnitState( u, UNIT_STATE_MANA) >= 1 then call SetUnitState( u, UNIT_STATE_MANA, GetUnitState( u, UNIT_STATE_MANA) - 1) set d.moved = d.moved - 7 set d.bases = d.bases - 7 endif endif call SetUnitPathing(d.d,false) call SetUnitScale(d.d,Scale,Scale,Scale) call SetUnitFlyHeight(d.d,Fly_height,0.00) call TimerStart(d.t,period,true,function Arrow.Execute) call SetCSData(d.t,d) set arrow = null return Arrow[d.d] endmethod public static method SA takes integer ut, unit u, integer lvl, real cx, real cy, real tx, real ty, real period, real r, real moved, real bases, real acceleration, real maxd, real dmg, integer items returns nothing call Arrow.create(ut,u,lvl,cx,cy,tx,ty,period,r,moved,bases,acceleration,maxd,dmg,items) endmethod static method Execute takes nothing returns nothing local real x local real y local real cx local real cy local real tx local real ty local real x2 local real y2 local real a local unit u local group g local group g2 local group g3 local real dist local real rdist local real angle local integer lvl local integer lvl2 local integer lvl3 local unit FoG local integer i = 0 local TargetStruct e local Arrow d = GetCSData(GetExpiredTimer()) set lvl3 = GetUnitAbilityLevel(d.u,'A02C') set lvl2 = 0 set Caster = d.u set x = GetUnitX(d.d) set y = GetUnitY(d.d) set rdist = DistanceXY( x, y, d.plx, d.ply) set d.cd = d.cd + rdist set d.plx = x set d.ply = y if GetUnitState(d.d,UNIT_STATE_LIFE) < .405 then set d.grav = false call d.release() return endif if d.cd >= d.maxd then set g3 = NewGroup() if GetUnitAbilityLevel(d.u, 'A023') > 0 then call DestroyEffect(AddSpecialEffect("war3mapImported\\NewGroundEX.mdl", x, y)) call GroupEnumUnitsInRange(g3,x,y,200,Condition(function FilterIsEnemyAlive)) loop // and deals damage to each enemy in the area. // set FoG = FirstOfGroup(g3) exitwhen FoG == null call GroupRemoveUnit(g3,FoG) call UnitDamageTarget(d.d,FoG,(GetUnitAbilityLevel(d.u, 'A023') * 25) + 100,false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,null) endloop if lvl3 == 1 then if GetUnitTypeId(d.d) != 'h00N' then set i = 0 loop exitwhen i == 5 set angle = GetRandomReal(0, 6.28318531) set cx = x set cy = y set tx = PolarProjectionX(x,200,angle) set ty = PolarProjectionY(y,200,angle) call Arrow.SA('h00N',d.u,1,cx,cy,tx,ty,0.03,60,33,33,0.3,400,100,0) set i = i + 1 endloop endif endif endif call ReleaseGroup(g3) set g3 = null set d.grav = false call d.release() return endif call SetUnitFacing(d.d,GetUnitFacing(d.d) + d.anglechange) set d.anglechange = 0 set d.angle = Deg2Rad(GetUnitFacing(d.d)) set x = PolarProjectionX(x, d.moved, d.angle) set y = PolarProjectionY(y, d.moved, d.angle) if x > GMaxX or x < GMinX or y > GMaxY or y < GMinY then set g3 = NewGroup() if GetUnitAbilityLevel(d.u, 'A023') > 0 then call DestroyEffect(AddSpecialEffect("war3mapImported\\NewGroundEX.mdl", x, y)) call GroupEnumUnitsInRange(g3,x,y,200,Condition(function FilterIsEnemyAlive)) loop // and deals damage to each enemy in the area. // set FoG = FirstOfGroup(g3) exitwhen FoG == null call GroupRemoveUnit(g3,FoG) call UnitDamageTarget(d.d,FoG,(GetUnitAbilityLevel(d.u, 'A023') * 25) + 100,false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,null) endloop if lvl3 == 1 then if GetUnitTypeId(d.d) != 'h00N' then set i = 0 loop exitwhen i == 5 set angle = GetRandomReal(0, 6.28318531) set cx = x set cy = y set tx = PolarProjectionX(x,200,angle) set ty = PolarProjectionY(y,200,angle) call Arrow.SA('h00N',d.u,1,cx,cy,tx,ty,0.03,60,33,33,0.3,400,100,0) set i = i + 1 endloop endif endif endif call ReleaseGroup(g3) set g3 = null set d.grav = false call d.release() return endif call SetUnitX(d.d, x) call SetUnitY(d.d, y) if d.moved < d.bases then set d.moved = d.moved + d.acceleration endif set g = NewGroup() set g2 = NewGroup() call GroupEnumUnitsInRange(g,x,y,d.r,Condition(function FilterIsEnemyAlive)) call GroupEnumUnitsInRange(g2,x,y,100,Condition(function FilterIsEnemyAlive2)) call GroupAddGroupAdv(g2,g) set lvl = GetUnitAbilityLevel(d.u,'A029') set u = FirstOfGroup(g) if u == null then call GroupClear(d.g) else loop set u = FirstOfGroup(g) exitwhen u == null if not(IsUnitInGroup(u,d.g)) then call GroupAddUnit(d.g,u) set e = TargetStruct[u] if e != 0 then if GetOwningPlayer(d.d) == GetOwningPlayer(e.trigunit) then set lvl2 = e.lvl endif endif call UnitDamageTarget(d.d,u,d.dmg + ((d.cd/100)*lvl) + (20*lvl2),false,false,A,D,null) endif call GroupRemoveUnit(g,u) endloop endif call ReleaseGroup(g) set g = null if GetUnitState(d.d, UNIT_STATE_LIFE) > .405 then set d.csd = d.csd + rdist if d.csd >= 250 then set d.csd = 0 call IssuePointOrder(d.a, d.as, x, y) call DestroyEffect(AddSpecialEffect( d.sfx, x, y )) endif endif if d.grav == true then set g = NewGroup() call GroupEnumUnitsInRange(g,x,y,600,Condition(function FilterIsEnemyAlive)) call GroupAddGroupAdv(Arrows, g) loop set u = FirstOfGroup(g) if u == d.d then call GroupRemoveUnit(g,u) set u = FirstOfGroup(g) endif exitwhen u == null set x2 = GetUnitX(u) set y2 = GetUnitY(u) set dist = DistanceXY(x,y,x2,y2) if dist <= 600 then set a = AngleXY(x2,y2,x,y) if 400/dist <= dist then set x2 = SafeX(PolarProjectionX(x2,(d.moved/(dist/d.moved*2)),a)) set y2 = SafeY(PolarProjectionY(y2,(d.moved/(dist/d.moved*2)),a)) endif call SetUnitX(u,x2) call SetUnitY(u,y2) endif call GroupRemoveUnit(g,u) endloop set u = null call ReleaseGroup(g) set g = null call ReleaseGroup(g2) set g2 = null endif endmethod method onDestroy takes nothing returns nothing call RemoveUnit(.d) call RemoveUnit(.a) set .u = null set .d = null set .a = null call GroupRemoveUnit(Arrows,.d) call ReleaseGroup(.g) set .g = null call ReleaseTimer(.t) set .spell = false set .grav = false set .sfx = null set .as = null endmethod endstruct endlibrary i have no idea what im missing but using this library about 600 times (at once) causes the message to show up (Max handle count). and after the 600 structs are destroyed, it still says the max handle count is reached. am i leaking structs? (this library uses CSSafety,CSData, and HandyFunctions (shown below) and PUI) JASS:library HandyFunctions initializer Init globals // CONFIGURABLES: private constant integer FlyTrick = 'Amrf' // Raw code of Crow Form private constant integer Dummy_id = 'n000' // Raw code of your maps dummy unit // DON'T NEED TO BE CHANGED: private timer gametime = null private rect Trees_in_rect = null private real Game_maxX private real Game_maxY private real Game_minX private real Game_minY private unit Caster private group Damage_group = CreateGroup() private group AddGroup private integer i = 0 endglobals // Returns a safe X location, so units do not go outside map bounds function SafeX takes real x returns real if x<Game_minX then return Game_minX elseif x>Game_maxX then return Game_maxX endif return x endfunction // Returns a safe Y location, so units do not go outside map bounds function SafeY takes real y returns real if y<Game_minY then return Game_minY elseif y>Game_maxY then return Game_maxY endif return y endfunction // Creates a dummy caster needed for Preload (below) function CreateCaster takes real x, real y returns unit set Caster = CreateUnit(Player(15),Dummy_id,x,y,0.00) call UnitAddAbility(Caster,FlyTrick) call UnitRemoveAbility(Caster,FlyTrick) call UnitApplyTimedLife(Caster,'BTLF',5.00) return Caster endfunction // Preloads an ability, reduces lag function PreLoadAbil takes integer abil returns nothing set Caster = CreateCaster(0.00,0.00) call UnitAddAbility(Caster,abil) endfunction // Angle between co-ordinates function AngleXY takes real x, real y, real xx, real yy returns real return Atan2((yy-y),(xx-x)) endfunction // Distance between co-ordinates function DistanceXY takes real x1, real y1, real x2, real y2 returns real return SquareRoot((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)) endfunction // Used with below function function KillEnumDestructable takes nothing returns nothing call KillDestructable(GetEnumDestructable()) endfunction // Kills trees/destructables function KillTrees takes real x, real y, real radius returns nothing set Trees_in_rect = Rect(x-radius,y-radius,x+radius,y+radius) call EnumDestructablesInRect(Trees_in_rect,null,function KillEnumDestructable) call RemoveRect(Trees_in_rect) endfunction // Checks for pathability (very basic) function Pathability takes real x, real y returns boolean return IsTerrainPathable(x,y, PATHING_TYPE_WALKABILITY) endfunction // Used with below function function IsPointWater takes real x, real y returns boolean return IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) and not(IsTerrainPathable(x,y,PATHING_TYPE_AMPHIBIOUSPATHING)) endfunction // Checks if point is water function IsPointWaterLoc takes location loc returns boolean return IsPointWater(GetLocationX(loc),GetLocationY(loc)) endfunction // filters for enemies, who are alive and are not structures function FilterIsEnemyAliveNotStructure takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer) and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>.405 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false endfunction // Damages an area, uses the above filter function DamageArea takes unit Damager, real Area, real x, real y, real Dmg, attacktype Attacktype, damagetype Damagetype returns nothing local unit FoG set bj_groupEnumOwningPlayer = GetOwningPlayer(Damager) call GroupClear(Damage_group) call GroupEnumUnitsInRange(Damage_group, x, y, Area, Condition(function FilterIsEnemyAliveNotStructure)) // Function that loops through the CreateGroup() loop // and deals damage to each enemy in the area. // set FoG = FirstOfGroup(Damage_group) exitwhen FoG == null call GroupRemoveUnit(Damage_group,FoG) call UnitDamageTarget(Damager,FoG,Dmg,false,false,Attacktype,Damagetype,null) endloop endfunction // Adds Text tags over a unit function TextTagUnit takes string text, unit targ, integer red, integer green, integer blue, integer alpha, real velocity, real duration returns nothing local texttag t = CreateTextTag() call SetTextTagText(t, text, 0.025) call SetTextTagPosUnit(t, targ,15) call SetTextTagColor(t, red, green, blue, alpha) call SetTextTagVelocity(t, 0, velocity) call SetTextTagVisibility(t, true) call SetTextTagFadepoint(t, 2) call SetTextTagLifespan(t, duration) call SetTextTagPermanent(t, false) set t = null endfunction function PolarProjectionX takes real x, real distance, real angle returns real return x + distance * Cos(angle) endfunction function PolarProjectionY takes real y, real distance, real angle returns real return y + distance * Sin(angle) endfunction // Better alternative to PolledWait() function PolledWait2 takes real duration returns nothing local real timeRemaining local real st = TimerGetElapsed(gametime) if duration > 0. then loop set timeRemaining = duration - TimerGetElapsed(gametime) + st exitwhen timeRemaining <= 0 if timeRemaining > 2.00 then call TriggerSleepAction(0.1 * timeRemaining) else call TriggerSleepAction(0.0) endif endloop endif endfunction // Replicates a sim error function SimError takes player ForPlayer, string msg returns nothing local sound error = CreateSoundFromLabel("InterfaceError",false,false,false,10,10) if (GetLocalPlayer() == ForPlayer) then call ClearTextMessages() call DisplayTimedTextToPlayer(ForPlayer,0.52,-1.00,2.00,"|cffffcc00"+msg+"|r") call StartSound(error) endif call KillSoundWhenDone(error) set error=null endfunction function Add takes nothing returns nothing call GroupAddUnit(AddGroup, GetEnumUnit()) endfunction function GroupAddGroupAdv takes group sourceGroup, group destGroup returns group set AddGroup = null set AddGroup = destGroup call ForGroup(sourceGroup, function Add) return AddGroup endfunction function CountPlayers takes nothing returns nothing set i = i + 1 endfunction function CountPlayersInForce takes force Players returns integer set i = 0 call ForForce(Players, function CountPlayers) return i endfunction // Starts the game timer, and sets boundaries private function Init takes nothing returns nothing set gametime = CreateTimer() call TimerStart(gametime,1000000.00,false,null) set Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea)-50.00 set Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea)-50.00 set Game_minX = GetRectMinX(bj_mapInitialPlayableArea)+50.00 set Game_minY = GetRectMinY(bj_mapInitialPlayableArea)+50.00 endfunction function ItemCheck takes unit u, integer itemid returns integer local integer index local item indexItem local integer n = 0 set index = 0 loop exitwhen index > 5 set indexItem = UnitItemInSlot(u, index) if indexItem != null then if GetItemTypeId(indexItem) == itemid then set n = n + 1 endif endif set index = index + 1 endloop return n endfunction endlibrary |
| 10-24-2008, 09:52 AM | #2 |
can you post a map? I can't figure it out with code alone lol. |
| 10-25-2008, 12:10 AM | #3 |
sure here it is. wait, if your going to play the game, type -units to spawn the units and -set level to make hero level rise by 1 each time. |
| 10-25-2008, 04:31 AM | #4 |
Arrow[arrow] = d
Is this PUI usage? I haven't used it so I don't know. EDIT Try nulling all handles on method Execute, I think the handles you used there aren't being nulled effectively. |
| 10-25-2008, 05:02 AM | #5 |
yes thats PUI edit: a recheck through excute and saw that g2 (group) was not being released or nulled. is this enough to go over handle id in 2000 uses? (it seems like it, the group is created every .03 seconds..not being released or nulled) but theres one more issue on this library, using it 2000 times or so causes one of the dummy arrows to get stuck..is it simply because there are too many arrows? also. using this handle counter JASS:scope HC initializer Init globals private leaderboard udg_HandleBoard endglobals private function L2I takes location P returns integer return P return 0 endfunction private function Update takes nothing returns nothing local integer i = 0 local integer id local location array P local real result=0 loop exitwhen i >= 50 set i = i + 1 set P[i] = Location(0,0) set id = L2I(P[i]) set result = result + (id-0x100000) endloop set result = result/i-i/2 loop call RemoveLocation(P[i]) set P[i] = null exitwhen i <= 1 set i = i - 1 endloop call LeaderboardSetItemValue(udg_HandleBoard,0,R2I(result)) endfunction private function Actions takes nothing returns nothing set udg_HandleBoard = CreateLeaderboard() call LeaderboardSetLabel(udg_HandleBoard, "Handle Counter") call PlayerSetLeaderboard(GetLocalPlayer(),udg_HandleBoard) call LeaderboardDisplay(udg_HandleBoard,true) call LeaderboardAddItem(udg_HandleBoard,"Handles",0,Player(0)) call LeaderboardSetSizeByItemCount(udg_HandleBoard,1) call Update() call TimerStart(GetExpiredTimer(),0.05,true,function Update) endfunction function Init takes nothing returns nothing debug call TimerStart(CreateTimer(),0,false,function Actions) endfunction endscope it goes up by 20 each time i use CAS |
| 10-25-2008, 01:44 PM | #6 |
structs have nothing to do with handle count. You have exceeded the handle count limit for CSdata and that's 400000 handles, you must have a very bad memory leak elsewhere. |
| 10-25-2008, 08:49 PM | #7 |
how does that explain the increase of handles when using it though? JASS:scope SA initializer Init private function Damage takes integer i returns real return 133.33+(66.66*i) + 0.5 endfunction private function MaxDist takes integer i returns real return 333.33+(666.66*i) endfunction //======================================================================= private function Actions takes nothing returns nothing local unit u = GetTriggerUnit() local unit t = GetSpellTargetUnit() local location l = GetSpellTargetLoc() local integer i = GetUnitAbilityLevel(u,GetSpellAbilityId()) local real cx = GetUnitX(u) local real cy = GetUnitY(u) local real tx local real ty if t != null then set tx = GetUnitX(t) set ty = GetUnitY(t) else set tx = GetLocationX(l) set ty = GetLocationY(l) endif call Arrow.SA('h00J',u,i,cx,cy,tx,ty,0.03,60,33,33,0.3,MaxDist(i),Damage(i),1) set u = null set t = null call RemoveLocation(l) set l = null endfunction //======================================================================= private function Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A011' or GetSpellAbilityId() == 'A017' endfunction //======================================================================= private function Init takes nothing returns nothing local trigger trig = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(trig,Condition(function Conditions)) call TriggerAddAction(trig,function Actions) endfunction endscope this is the function that uses it |
| 10-29-2008, 05:56 AM | #8 |
bump |
| 10-29-2008, 12:47 PM | #9 | |
Quote:
No, the problem is not with the function that uses it, it is with your whole map, you got a tough leak somewhere. |
