| 02-01-2009, 10:01 PM | #1 |
Hello there, I'm currently working on fine-tuning my motion system. Currently it runs quite smoothly but there's a few kinks it has. Namely, my boolexpr function I'm passing is not working correctly. I'm also looking for ways to increase functionality if at all possible. Snippit of boolexpr being passed: BoolExpr Example:function KillExpir takes nothing returns boolean local unit u = GetFilterUnit() if(IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(CALLBACK_MOTION.rotating))) and (GetWidgetLife(u) > .405)then return true endif return false endfunction // local MotionFunction mz = KillCollision // call m.SetCollisionEvent(64, mz, false, Condition(function KillExpir)) I'm not sure what's up with the expr, but it's grouping allied units ? Anyways, it's impossible to determine without the system: JASS:library MotionLib globals timer MotionTimer = CreateTimer() integer NMotionObjects = 0 Motion array MotionObjects Motion CALLBACK_MOTION group CollisionGroup = CreateGroup() endglobals function TrigMotion takes nothing returns nothing local Motion m local integer I = NMotionObjects - 1 loop set m = MotionObjects[i] set m.dur = m.dur - update set m.rots = m.rots + 1 call SetUnitX(m.rotating, GetUnitX(m.rotating) + Cos(m.xtheta + m.x*m.rots) * m.incr) call SetUnitY(m.rotating, GetUnitY(m.rotating) + Sin(m.ytheta + m.y*m.rots) * m.incr) set m.z = m.z+m.ztheta call SetUnitFlyHeight(m.rotating, m.z, .01) if(m.collisionevent == true)then call GroupClear(CollisionGroup) call GroupEnumUnitsInRange(CollisionGroup, GetUnitX(m.rotating), GetUnitY(m.rotating), m.colsize, m.filter) if(FirstOfGroup(CollisionGroup) != null)then set CALLBACK_MOTION = m if(m.coldeath == true)then set m.dur = 600 set NMotionObjects = NMotionObjects - 1 set MotionObjects[i] = MotionObjects[NMotionObjects] endif call m.oncollide.evaluate() endif endif if(m.dur <= 0)then set CALLBACK_MOTION = m call m.callback.evaluate() set NMotionObjects = NMotionObjects - 1 set MotionObjects[i] = MotionObjects[NMotionObjects] endif exitwhen(I == 0) set I = I - 1 endloop if(NMotionObjects == 0)then call PauseTimer(MotionTimer) endif endfunction function interface MotionFunction takes nothing returns nothing struct Motion unit rotating real xorig real yorig real x real y real z real xtheta real ytheta real ztheta real incr real dur integer rots = 0 MotionFunction callback boolean collisionevent = false real colsize boolean coldeath = false boolexpr filter MotionFunction oncollide method AddNewMotion takes unit moving, real dur, real incr, real x, real y, real z, real xtheta, real ytheta, real ztheta, MotionFunction callback returns nothing set .rotating = moving set .dur = dur set .x = x set .y = y set .z = z set .xtheta = xtheta set .ytheta = ytheta set .ztheta = ztheta set .incr = incr set .callback = callback endmethod method SetOrigin takes real xorig, real yorig returns nothing set .xorig = xorig set .yorig = yorig endmethod method SetCollisionEvent takes real colsize, MotionFunction callback, boolean dies, boolexpr filter returns nothing set .collisionevent = true set .coldeath = dies set .colsize = colsize set .oncollide = callback set .filter = filter endmethod method Start takes nothing returns nothing set MotionObjects[NMotionObjects] = this if(NMotionObjects == 0)then call TimerStart(MotionTimer, update, true, function TrigMotion) endif set NMotionObjects = NMotionObjects + 1 endmethod endstruct endlibrary Code Example:function ExpireFunc takes nothing returns nothing local Motion m = CALLBACK_MOTION call RemoveUnit(m.rotating) call m.destroy() endfunction function KillExpir takes nothing returns boolean local unit u = GetFilterUnit() if(IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(CALLBACK_MOTION.rotating))) and (GetWidgetLife(u) > .405)then return true endif return false endfunction function Really takes nothing returns nothing local Motion m = CALLBACK_MOTION local MotionFunction expire = ExpireFunc local real angle = Atan2(m.yorig-GetUnitY(m.rotating), m.xorig-GetUnitX(m.rotating)) set m.rots = 0 call m.AddNewMotion(m.rotating, 1.5, m.incr, .025, .025, 0, angle, angle, 0, expire) call m.Start() endfunction function EndCollision takes nothing returns nothing local Motion m = CALLBACK_MOTION call PauseUnit(m.rotating, false) call SetUnitVertexColor(m.rotating, 255, 0, 0, 50) call m.destroy() endfunction function KillCollision takes nothing returns nothing local Motion m = CALLBACK_MOTION local Motion m2 local MotionFunction mf = EndCollision local unit u = null local real x = GetUnitX(m.rotating) local real y = GetUnitY(m.rotating) local real r local group g = CollisionGroup loop set u = FirstOfGroup(g) exitwhen(u == null) call GroupRemoveUnit(g,u) set m2 = Motion.create() set r = Atan2(GetUnitY(u) - y, GetUnitX(u) - x) call PauseUnit(u, true) call m2.AddNewMotion(u, .4, m.incr, m.x, m.y, 0, r, r, 0, mf) call m2.Start() endloop endfunction function Trig_Orb_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local real x = GetLocationX(GetSpellTargetLoc()) local real y = GetLocationY(GetSpellTargetLoc()) local unit dummy local real angle = Atan2(y-GetUnitY(u), x-GetUnitX(u)) local integer I = 0 local Motion m local MotionFunction mf = Really local MotionFunction mz = KillCollision loop set dummy = CreateUnit(GetOwningPlayer(u), 'h000', x, y, 0) call UnitAddAbility(dummy, 'Aloc') set m = Motion.create() call m.AddNewMotion(dummy, 1, dist*update, .1, .1, 0, angle + 1.707*I, angle + 1.707*I, 0, mf) call m.SetOrigin(x, y) call m.SetCollisionEvent(64, mz, false, Condition(function KillExpir)) call m.Start() exitwhen(I == 3) set I = I + 1 endloop endfunction As you can see, alot of things still have to be handled by the user, as destroying passed structs is illogical. I'll probably make it so if the callback is null it'll handle destroying automatically. So, is there anything I can do better/fix/add to in this system? There's also a less dire problem, simply being the Z height settings (UnitFlyHeight) doesn't work at all. I have no idea why? Whenever I code UnitFlyHeight things it always seems to malfunction x-x. Thanks guys! PS: I LOVE FUNCTION POINTERS <3. |
