| 08-29-2008, 07:07 AM | #1 |
ok im gonna be implementing some substantial amount of summon-a-guy-follow-me-do-function spells so i made some general system for controlling them. i need criticism so i can fix this before proceeding to make the spells; i don't want to fix this then put in syntax every instance of this in the spells. JASS:library Summon globals private timer gTIM = CreateTimer() private real gR_DurationTimer = 0.50 /////////////////// private integer gINT_CountSummon = 0 private Summon array gSUMMON endglobals private struct Summon integer intSummonIndex unit uSummon unit uCaster player pOwnerCaster /////////////////// boolean boolFollow boolean boolFormation boolean boolFocusFire boolean boolSharedDeath /////////////////// real rMaxOffsetDistance real rOffsetAngle //set to a negative value to generate random angles when following.// real rOffsetDistance //set to a negative value to generate random distances when following.// real rXHome real rYHome /////////////////// string strOrder boolexpr boolexprFilterTarget method Destroy takes nothing returns nothing set this.uSummon = null set this.uCaster = null set this.pOwnerCaster = null set this.boolExprFilterTarget = null /////////////////// set gSUMMON[gINT_CountSummon].intSummonIndex = this.intSummonIndex set gSUMMON[this.intSummonIndex] = gSUMMON[gINT_CountSummon] set gSUMMON[gINT_CountSummon] = 0 set gINT_CountSummon = gINT_CountSummon - 1 if gINT_CountSummon == 0 then call PauseTimer(gTIM) endif endmethod method Action takes string order, handle target returns nothing if target == null then call IssueImmediateOrder(this.uSummon, order) elseif GetWidgetLife(target) >= 0 or GetWidgetLife(target) <= 0 then call IssueTargetOrder(this.uSummon, order, target) else call IssuePointOrderLoc(this.uSummon, order, target) endif endfunction method Move takes real x, real y, real dist, real angle nothing returns nothing local real R_OffsetAngle local real R_OffsetDistance local location LOC_Target if dist >= 0.00 then set R_OffsetDistance = dist else set R_OffsetDistance = GetRandomReal(0.00, this.rMaxOffsetDistance) endif if angle >= 0 then set R_OffsetAngle = GetUnitFacing(this.uCaster) - 90.00 + angle else set R_OffsetAngle = GetRandomReal(0.00, 360.00) endif set LOC_Target = Location(R_XCaster + R_OffsetDistance * Cos(R_OffsetAngle * bj_DEGTORAD), R_YCaster + R_OffsetDistance * Sin(R_OffsetAngle * bj_DEGTORAD)) call this.Action("move", LOC_Target) call RemoveLocation(LOC_Target) endmethod method Execute takes nothing returns nothing local real R_XCaster = GetUnitX(this.uCaster) local real R_YCaster = GetUnitY(this.uCaster) local real R_OffsetDistance = SquareRoot(Pow(GetUnitY((this.uSummon) - R_XCaster), 2) + Pow((GetUnitX(this.uSummon) - R_YCaster), 2)) local group UG_Target = CreateGroup() local handle HAND_Target if GetUnitState(this.uSummon, UNIT_STATE_LIFE) <= 0 or GetOwningPlayer(this.uSummon) != this.pOwnerCaster then call this.Destroy() elseif GetUnitState(this.uCaster, UNIT_STATE_LIFE) <= 0 if this.boolSharedDeath then call KillUnit(this.uSummon) else call this.Move(this.rXHome, this.rYHome, 0.00, 0.00) endif else if R_OffsetDistance > this.rMaxOffsetDistanceMove then call this.Move(R_XCaster, R_YCaster, this.rOffsetDistance, this.rOffsetAngle) elseif OrderId2String(GetUnitCurrentOrder(this.uSummon)) != this.strOrder then call GroupEnumUnitsInRange(UG_Target, R_XCaster, R_YCaster, this.rMaxDistanceOffset, this.boolexprFilterTarget) set HAND_Target = FirstOfGroup(UG_Target) call this.Action(this.strOrder, HAND_Target) endif endif call DestroyGroup(UG_Target) set HAND_Target = null endmethod endstruct private function Callback1 takes nothing returns nothing local integer INT_CountSummon = 0 loop set INT_CountSummon = INT_CountSummon + 1 call gSUMMON[INT_CountSummon].Execute() exitwhen INT_CountSummon == gINT_CountSummon endloop endfunction private function Trig_OrderParity_Actions takes nothing returns nothing local unit U_Caster = GetTriggerUnit() local integer INT_CountSummon = 0 local string STR_Order = OrderId2String(GetIssuedOrderId()) local widget WID_Target = GetOrderTarget() loop set INT_CountSummon = INT_CountSummon + 1 if gSUMMON[INT_CountSummon].uCaster == U_Caster then if STR_Order == "move" or (STR_Order == "smart" and WID_Target == null) and gSUMMON[INT_CountSummon].boolFormation == TRUE then call gSUMMON[INT_CountSummon].Move(GetOrderPointX(), GetOrderPointY(), gSUMMON[INT_CountSummon].rOffsetDistance, gSUMMON[INT_CountSummon].rOffsetAngle) elseif (STR_Order == "attack" or (STR_Order == "smart" and IsUnitEnemy(WID_Target, gSUMMON[INT_CountSummon].pOwnerCaster))) and gSUMMON[INT_CountSummon].boolFocusFire == TRUE then call gSUMMON[INT_CountSummon].Action("attack", WID_Target) endif endif exitwhen INT_CountSummon == gINT_CountSummon endloop set STR_Order = null set WID_Target = null set U_Caster = null endfunction //==== Init Trigger OrderParity ==== private function InitTrig_OrderParity takes nothing returns nothing local integer INT_CountPlayer = 0 set gg_trg_OrderParity = CreateTrigger() loop call TriggerRegisterPlayerUnitEvent(gg_trg_OrderParity, Player(INT_CountPlayer) EVENT_PLAYER_UNIT_ISSUED_ORDER) exitwhen INT_CountPlayer == 12 set INT_CountPlayer = INT_CountPlayer + 1 endloop call TriggerAddAction(gg_trg_OrderParity, function Trig_OrderParity_Actions) endfunction //-----------------------//FUNCTIONS//-----------------------// function SummonCreate takes unit summon, unit caster, boolean follow, boolean form, boolean ff, boolean sharedDeath, real maxDist, real dist, real angle, real x, real y, string order, boolexpr targetFilter returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) set New.boolFollow = Move set New.boolFormation = form set New.boolFocusFire = ff set New.boolSharedDeath = sharedDeath set New.rMaxOffsetDistance = maxDist set New.rOffsetDistance = dist set New.rOffsetAngle = angle set New.rXHome = x set New.rYHome = y set New.strOrder = order set New.boolexprFilterTarget = targetFilter return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonDestroy takes Summon whichSummon, returns nothing call Summon.Destroy() endfunction function SummonOrder takes Summon whichSummon, string order, handle target returns nothing call whichSummon.Action(order, target) endfunction function SummonChangeOwner takes Summon whichSummon, player newOwner returns nothing set whichSummon.uCaster = newOwner set whichSummon.pOwnerCasterCaster = GetOwningPlayer(newOwner) endfunction function SummonChangeFollow takes Summon whichSummon, boolean newFollow returns nothing set whichSummon.boolFollow = newFollow endfunction function SummonChangeFormation takes Summon whichSummon, boolean newForm returns nothing set whichSummon.boolFormation = newForm endfunction function SummonSharedDeath takes Summon whichSummon, boolean newDeath returns nothing set whichSummon.boolSharedDeath = newDeath endfunction function SummonChangeFocusFire takes Summon whichSummon, boolean newFF returns nothing set whichSummon.boolFocusFire = newFF endfunction function SummonChangeVectors takes Summon whichSummon, real newMaxDist, real newDist, real newAngle, real newHomeX, real newHomeY returns nothing set whichSummon.rMaxOffsetDistance = newMaxDist set whichSummon.rOffsetDistance = newDist set whichSummon.rAngleDistance = newAngle set whichSummon.rXHome = newHomeX set whichSummon.rYHome = newHomeY endfunction function SummonChangeOrder takes Summon whichSummon, string newOrder, boolexpr newFilter returns nothing set whichSummon.strOrder = newOrder set whichSummon.boolexprFilterTarget = newFilter endfunction endlibrary |
| 09-02-2008, 02:11 AM | #2 |
edit: 2nd post is also a bump from 2nd page btw changed it a bit. i still need to know if it's ok. i want to know particularly about this part, w/c is supposed to find a random suitable target loc within the AoE around a certain point: JASS:set R_XQuery = R_XSummon - this.rRangeAoE loop exitwhen R_XQuery > R_XSummon + this.rRangeAoE set R_MaxDistanceOffX = SquareRoot(Pow(this.RangeAoE, 2) - Pow(R_XQuery, 2)) set R_YQuery = R_YSummon - R_MaxDistanceOffX loop exitwhen R_YQuery > RY_Summon + R_MaxDistanceOffX //Evaluate// if this.boolexprFilterOrderTarget(R_XQuery, R_YQuery) then set INT_CountTarget = INT_CountTarget + 1 set R_XTarget[INT_CountTarget] = R_XQuery set R_YTarget[INT_CountTarget] = R_YQuery endif set R_XQuery = R_XQuery + gR_DistanceIncrement endloop set R_XQuery = R_XQuery + gR_DistanceIncrement endloop set INT_Randomizer = GetRandomReal(1, INT_CountTarget) set HAND_Target = Location(R_XTarget[INT_Randomizer], R_YTarget[INT_Randomizer]) JASS:library Summon globals private timer gTIM = CreateTimer() private constant real gR_DurationTimer = 0.50 private constant real gR_DistanceIncrement = 100.00 private integer gINT_CountSummon = 0 private Summon array gSUMMON private constant string gSTR_OrderTargetTypeUnit = "unit" private constant string gSTR_OrderTargetTypeLocation = "location" endglobals private struct Summon integer intSummonIndex unit uSummon unit uCaster player pOwnerCaster boolean boolFollow boolean boolFormationFollow real rDistanceMove real rAngleMove real rMaxDistanceMove boolean boolGoHome real rXHome real rYHome boolean boolFocusAttack string strOrderTargetType string strOrder boolexpr boolexprFilterOrderTarget real rRangeAoE method Destroy takes nothing returns nothing set this.uSummon = null set this.uCaster = null set this.pOwnerCaster = null set this.strOrderTargetType = null set this.strOrder = null set this.boolexprFilterOrderTarget = null set gSUMMON[gINT_CountSummon].intSummonIndex = this.intSummonIndex set gSUMMON[this.intSummonIndex] = gSUMMON[gINT_CountSummon] set gSUMMON[gINT_CountSummon] = 0 set gINT_CountSummon = gINT_CountSummon - 1 if gINT_CountSummon == 0 then call PauseTimer(gTIM) endif endmethod private method CheckNotBusy takes Summon whichSummon returns boolean return OrderId2String(GetUnitCurrentOrder(whichSummon.uSummon)) != whichSummon.strOrder endmethod static method Order takes Summon whichSummon, string order, handle target returns nothing local location LOC_Target if target == null then call IssueImmediateOrder(whichSummon.uSummon, order) elseif GetWidgetLife(target) > 0 then call IssueTargetOrder(whichSummon.uSummon, order, target) else set LOC_Target = target IssuePointOrder(whichSummon.uSummon, order, GetLocationX(LOC_Target), GetLocationY(LOC_Target)) endif call RemoveLocation(LOC_Target) endmethod private method Follow takes nothing returns nothing local real R_Distance local real R_Angle local location LOC_Target if this.rDistanceMove >= 0.00 then set R_Distance = this.rDistanceMove else set R_Distance = GetRandomReal(0.00, this.rMaxDistanceMove) endif if this.rAngle >= 0.00 then set R_Angle = this.rAngleMove else set R_Angle = GetRandomReal(0.00, 360.00) endif set R_Angle = (GetUnitFacing(this.uCaster) - 90.00 + R_Angle) * bj_DEGTORAD set LOC_Target = Location(GetUnitX(this.uCaster) + R_Distance * Cos(R_Angle), GetUnitY(this.uCaster) + R_Distance * Sin(R_Angle)) call Summon.Order(gSUMMON[this.intSummonIndex], "move", LOC_Target) call RemoveLocation(LOC_Target) endmethod private method GoHome takes nothing returns nothing local location LOC_Target = Location(this.rXHome, this.rYHome) call OSummon.rder(gSUMMON[this.intSummonIndex], "move", LOC_Target) call RemoveLocation(LOC_Target) endmethod private method Action takes nothing returns nothing local group UG_Target local handle HAND_Target local real R_XSummon = GetUnitX(U_Summon) local real R_YSummon = GetUnitY(U_Summon) local real array R_XTarget local real array R_YTarget local real R_XQuery local real R_YQuery local real R_MaxDistanceOffX local integer INT_CountTarget local integer INT_Randomizer if this.strOrderTargetType == gSTR_OrderTargetTypeUnit then call GroupEnumUnitsInRange(UG_Target, R_XSummon), R_YSummon, this.rRangeAoE, Filter(function this.boolexprFilterOrderTarget)) set HAND_Target = FirstOfGroup(UG_Target) elseif this.strOrderTargetType == gSTR_OrderTargetTypeLocation then set R_XQuery = R_XSummon - this.rRangeAoE loop exitwhen R_XQuery > R_XSummon + this.rRangeAoE set R_MaxDistanceOffX = SquareRoot(Pow(this.RangeAoE, 2) - Pow(R_XQuery, 2)) set R_YQuery = R_YSummon - R_MaxDistanceOffX loop exitwhen R_YQuery > RY_Summon + R_MaxDistanceOffX //Evaluate// if this.boolexprFilterOrderTarget(R_XQuery, R_YQuery) then set INT_CountTarget = INT_CountTarget + 1 set R_XTarget[INT_CountTarget] = R_XQuery set R_YTarget[INT_CountTarget] = R_YQuery endif set R_XQuery = R_XQuery + gR_DistanceIncrement endloop set R_XQuery = R_XQuery + gR_DistanceIncrement endloop set INT_Randomizer = GetRandomReal(1, INT_CountTarget) set HAND_Target = Location(R_XTarget[INT_Randomizer], R_YTarget[INT_Randomizer]) else set HAND_Target = null endif call Summon.Order(gSUMMON[this.intSummonIndex], this.strOrder, HAND_Target) set HAND_Target = null call DestroyGroup(UG_Target) endmethod method Execute takes nothing returns nothing if GetUnitState(this.uSummon, UNIT_STATE_LIFE) > 0 and GetOwningPlayer(this.uSummon) == this.pOwnerCaster then if this.Follow and SquareRoot(Pow(GetUnitY(this.uSummon) - GetUnitY(this.uCaster), 2) + Pow(GetUnitX(this.uSummon) - GetUnitX(this.uCaster), 2)) > this.rMaxDistanceMove then if GetUnitState(this.uCaster, UNIT_STATE_LIFE) <= 0 and this.boolGoHome then call this.GoHome() else call this.Follow() endif else //If he's not busy, give him something to do.// if CheckNotBusy(gSUMMON[this.intSummonIndex]) then call this.Action() endif endif else call this.Destroy() endif endmethod endstruct private function Callback1 takes nothing returns nothing local integer INT_CountSummon = 0 loop set INT_CountSummon = INT_CountSummon + 1 call gSUMMON[INT_CountSummon].Execute() exitwhen INT_CountSummon == gINT_CountSummon endloop endfunction ////////////////////////////////////////////////////////////////////// ////////====================CONSOLE====================/////////////// function SummonCreate takes unit summon, unit caster, boolean follow, boolean formationFollow, real distanceFollow, real maxDistanceFollow, real angleFollow, boolean goHome, real xHome, real yHome, boolean focusAttack, string targetType, string order, boolexpr targetFilter, real rangeTarget returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) set New.boolFollow = follow set New.boolFormationFollow = formationFollow set New.rDistanceMove = distanceFollow set New.rAngleMove = angleFollow if (not formationFollow and randomMove) or (formationFollow and randomMove and (distanceFollow < 0.00 or angleFollow < 0.00)) then set New.boolFormationFollow = FALSE if distanceFollow < 0.00 then set New.rDistanceMove = -1.00 endif if angleFollow < 0.00 then set New.rAngleMove = -1.00 endif endif set New.rMaxDistanceMove = maxDistanceFollow set New.boolGoHome = goHome set New.rXHome = xHome set new.rYHome = yHome set New.boolAttack = attack set New.boolFocusAttack = focusAttack if targetType == gSTR_OrderTargetTypeUnit or targetType == gSTR_OrderTargetTypeLocation then set New.strOrderTargetType = targetType else set New.strOrderTargetType = null endif set New.strOrder = order set New.boolexprFilterOrderTarget = targetFilter set New.rRangeAoE = rangeTarget return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonCreateMove takes unit summon, unit caster, boolean formationFollow, boolean randomMove, real distanceFollow, real maxDistanceFollow, real angleFollow returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) set New.boolFollow = TRUE set New.boolFormationFollow = formationFollow set New.rDistanceMove = distanceFollow set New.rAngleMove = angleFollow if (not formationFollow and randomMove) or (formationFollow and randomMove and (distanceFollow < 0.00 or angleFollow < 0.00)) then set New.boolFormationFollow = FALSE if distanceFollow < 0.00 then set New.rDistanceMove = -1.00 endif if angleFollow < 0.00 then set New.rAngleMove = -1.00 endif endif set New.rMaxDistanceMove = maxDistanceFollow set New.boolGoHome = FALSE set New.rXHome = 0.00 set new.rYHome = 0.00 set New.boolFocusAttack = FALSE set New.strOrderTargetType = null set New.strOrder = null set New.boolexprFilterOrderTarget = null set New.rRangeAoE = 0.00 return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonCreateOrder takes unit summon, unit caster, boolean focusAttack, string targetType, string order, boolexpr targetFilter, real rangeTarget returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) set New.boolFollow = FALSE set New.boolFormationFollow = FALSE set New.rDistanceMove = 0.00 set New.rAngleMove = 0.00 set New.rMaxDistanceMove = 0.00 set New.boolFocusAttack = focusAttack if targetType == gSTR_OrderTargetTypeUnit or targetType == gSTR_OrderTargetTypeLocation then set New.strOrderTargetType = targetType else set New.strOrderTargetType = null endif set New.strOrder = order set New.boolexprFilterOrderTarget = targetFilter set New.rRangeAoE = rangeTarget return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonDestroy takes Summon whichSummon, returns nothing call whichSummon.Destroy() endfunction function SummonFind takes unit summonUnit returns Summon local integer INT_CountSummon = 0 loop set INT_CountSummon = INT_CountSummon + 1 if gSUMMON[INT_CountSummon].uSummon == summonUnit then return gSUMMON[INT_CountSummon] endif exitwhen INT_CountSummon == gINT_CountSummon endloop return 0 endfunction function SummonOrder takes Summon whichSummon, string order, handle target returns nothing call Summon.Order(whichSummon, order, target) endfunction function SummonChangeProperty takes Summon whichSummon, unit newSummon, unit newCaster returns nothing set whichSummon.uSummon = newSummon set whichSummon.uCaster = newCaster set whichSummon.pOwnerCaster = GetOwningPlayer(newCaster) endfunction function SummonChangeMove takes Summon whichSummon, boolean randomMove, boolean newFollow, boolean newFormation, real newDistance, real newAngle, real newMaxDistance, boolean newGoHome, real newXHome, real newYHome returns nothing set whichSummon.boolFollow = newFollow set whichSummon.boolFormationFollow = newFormation set whichSummon.rDistanceMove = newDistance set whichSummon.rAngleMove = newAngle if (not newFormation and randomMove) or (newFormationFollow and randomMove and (newDistance < 0.00 or newAngle < 0.00)) then set whichSummon.boolFormationFollow = FALSE if newDistance < 0.00 then set whichSummon.rDistanceMove = -1.00 endif if newAngle < 0.00 then set whichSummon.rAngleMove = -1.00 endif endif set whichSummon.rMaxDistanceMove = newMaxDistance set whichSummon.boolGoHome = newGoHome set whichSummon.rXGoHome = newXHome set whichSummon.rYGoHome = newYHome endfunction function SummonChangeOrder takes Summon whichSummon, string newTargetType, string newOrder, boolexpr newTargetFilter, real newRange, boolean newFocusAttack returns nothing set whichSummon.strOrderTargetType = newTargetType set whichSummon.strOrder = newOrder set whichSummon.boolexprFilterOrderTarget = newTargetFilter set whichSummon.rRangeAoE = newRange set whichSummon.boolFocusAttack = newFocusAttack endfunction endlibrary answers?? |
| 09-03-2008, 01:18 PM | #3 | |
Quote:
|
| 09-04-2008, 07:49 AM | #4 |
specs prescribed in the boolexprFilterOrderTarget member, w/c should evaluate the coords by expressions concerning coords. ex. for an aoe spell, evaluate if there are enemies in range of (x1, y1) boolexprFilterOrderTarget(x1,y1) call groupenumunitsinrange(enum group, x1, y1, range, filter isunitenemy) u = firstofgroup(enumgroup) if u != null then return true else return false endif something like that |
| 09-04-2008, 07:41 PM | #5 |
JASS:... endif set R_XQuery = R_XQuery + gR_DistanceIncrement endloop set R_XQuery = R_XQuery + gR_DistanceIncrement ... Anyway, this grid search seems very unoptimized. You sample the entire area and create a list of acceptable locations and then pick one at random. There are many better ways of doing this. One is to simply pick points at random and use the first one that's acceptable. As long as a large percentage of points are acceptable it is also much faster than what you have now. It is only problematic when you have few or no acceptable locations, in that case using a linear search is better. However, even as far as linear searches go, you could do better. You could simply pick a random point in the grid to start your linear search and then go from there and select the first point that you find that matches the criteria. The only problem here would be that acceptable points that come after a long string of unacceptable ones in the search have a higher probability of being picked, but you can remedy that by using a different search pattern (left to right, right to left, up to down, down to up, diagonally...) every time. |
| 09-05-2008, 12:59 AM | #6 |
i dont like the random search idea coz it doesnt seem reliable. by linear search you mean to sweep-scan like a radar? i can 'rotate' a line around the point, and at each instance of the turn (every x degrees) evaluate each point on the line every delta-distance from the point the line is rotated about? this will yield a suitable point closer to the target more immediately (w/c is probably a good thing). but: therell be overkill checking for points closer to the center and possible omission of points further out of the center, depending on the rOrderAoE ??? edit: JASS:library Summon globals private timer gTIM = CreateTimer() private constant real gR_DurationTimer = 0.50 private constant real gR_AngleIncrement = 36.00 private integer gINT_CountSummon = 0 private Summon array gSUMMON private constant string gSTR_OrderTargetTypeUnit = "unit" private constant string gSTR_OrderTargetTypeLocation = "location" endglobals private struct Summon integer intSummonIndex unit uSummon unit uCaster player pOwnerCaster boolean boolFollow boolean boolFormationFollow real rDistanceMove real rAngleMove real rMaxDistanceMove boolean boolGoHome real rXHome real rYHome boolean boolFocusAttack string strOrderTargetType string strOrder real rOrderAoE boolexpr boolexprFilterOrderTarget real rRangeAoE method Destroy takes nothing returns nothing set this.uSummon = null set this.uCaster = null set this.pOwnerCaster = null set this.strOrderTargetType = null set this.strOrder = null set this.boolexprFilterOrderTarget = null set gSUMMON[gINT_CountSummon].intSummonIndex = this.intSummonIndex set gSUMMON[this.intSummonIndex] = gSUMMON[gINT_CountSummon] set gSUMMON[gINT_CountSummon] = 0 set gINT_CountSummon = gINT_CountSummon - 1 if gINT_CountSummon == 0 then call PauseTimer(gTIM) endif endmethod private method CheckNotBusy takes Summon whichSummon returns boolean return OrderId2String(GetUnitCurrentOrder(whichSummon.uSummon)) != whichSummon.strOrder endmethod static method Order takes Summon whichSummon, string order, handle target returns nothing local location LOC_Target if target == null then call IssueImmediateOrder(whichSummon.uSummon, order) elseif GetWidgetLife(target) > 0 then call IssueTargetOrder(whichSummon.uSummon, order, target) else set LOC_Target = target IssuePointOrder(whichSummon.uSummon, order, GetLocationX(LOC_Target), GetLocationY(LOC_Target)) endif call RemoveLocation(LOC_Target) endmethod private method Follow takes nothing returns nothing local real R_Distance local real R_Angle local location LOC_Target if GetUnitState(this.uCaster, UNIT_STATE_LIFE) <= 0 and this.boolGoHome then set LOC_Target = Location(this.rXHome, this.rYHome) else if this.rDistanceMove >= 0.00 then set R_Distance = this.rDistanceMove else set R_Distance = GetRandomReal(0.00, this.rMaxDistanceMove) endif if this.rAngle >= 0.00 then set R_Angle = this.rAngleMove else set R_Angle = GetRandomReal(0.00, 360.00) endif set R_Angle = (GetUnitFacing(this.uCaster) - 90.00 + R_Angle) * bj_DEGTORAD set LOC_Target = Location(GetUnitX(this.uCaster) + R_Distance * Cos(R_Angle), GetUnitY(this.uCaster) + R_Distance * Sin(R_Angle)) endif call Summon.Order(gSUMMON[this.intSummonIndex], "move", LOC_Target) call RemoveLocation(LOC_Target) endmethod private method Action takes nothing returns nothing local handle HAND_Target local real R_XSummon = GetUnitX(U_Summon) local real R_YSummon = GetUnitY(U_Summon) local boolean BOOL_GotTarget = FALSE local group UG_Target = CreateGroup() local real R_XTarget local real R_YTarget local real R_OffsetAngle = 0.00 local real R_OffsetDistance = 0.00 if this.strOrderTargetType == gSTR_OrderTargetTypeUnit then call GroupEnumUnitsInRange(UG_Target, R_XSummon), R_YSummon, this.rRangeAoE, Filter(function this.boolexprFilterOrderTarget)) set HAND_Target = FirstOfGroup(UG_Target) set BOOL_GotTarget = (HAND_Target != null) elseif this.strOrderTargetType == gSTR_OrderTargetTypeLocation then loop set R_OffsetDistance = R_OffsetDistance + this.rOrderAoE loop set R_OffsetAngle = R_OffsetAngle + gR_AngleIncrement set R_XTarget = R_XSummon + R_OffsetDistance * Cos(R_OffsetAngle * bj_DEGTORAD) set R_YTarget = R_YSummon + R_OffsetDistance * Sin(R_OffsetAngle * bj_DEGTORAD) if this.boolexprFilterOrderTarget(R_XTarget, R_YTarget) then set BOOL_GotTarget = TRUE set HAND_Target = Location(R_XTarget, R_YTarget) endif exitwhen R_OffsetAngle == 360.00 or BOOL_GotTarget endloop exitwhen R_OffsetDistance == this.rRangeAoE or BOOL_GotTarget endloop else call GroupEnumUnitsInRange(UG_Target, R_XSummon), R_YSummon, this.rRangeAoE, Filter(function this.boolexprFilterOrderTarget)) set BOOL_GotTarget = (FirstOfGroup(UG_Target) != null) set HAND_Target = null endif if BOOL_GotTarget then call Summon.Order(gSUMMON[this.intSummonIndex], this.strOrder, HAND_Target) endif set HAND_Target = null call DestroyGroup(UG_Target) endmethod method Execute takes nothing returns nothing if GetUnitState(this.uSummon, UNIT_STATE_LIFE) > 0 and GetOwningPlayer(this.uSummon) == this.pOwnerCaster then if this.Follow and SquareRoot(Pow(GetUnitY(this.uSummon) - GetUnitY(this.uCaster), 2) + Pow(GetUnitX(this.uSummon) - GetUnitX(this.uCaster), 2)) > this.rMaxDistanceMove then call this.Follow() else if CheckNotBusy(gSUMMON[this.intSummonIndex]) then call this.Action() endif endif else call this.Destroy() endif endmethod endstruct private function Callback1 takes nothing returns nothing local integer INT_CountSummon = 0 loop set INT_CountSummon = INT_CountSummon + 1 call gSUMMON[INT_CountSummon].Execute() exitwhen INT_CountSummon == gINT_CountSummon endloop endfunction ////////////////////////////////////////////////////////////////////// ////////====================CONSOLE====================/////////////// function SummonCreate takes unit summon, unit caster, boolean follow, boolean formationFollow, real distanceFollow, real maxDistanceFollow, real angleFollow, boolean goHome, real xHome, real yHome, boolean focusAttack, string targetType, string order, real orderAOE, boolexpr targetFilter, real rangeTarget returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) if randomMove then set New.boolFollow = TRUE set New.boolFormationFollow = FALSE set New.rDistanceMove = -1.00 set New.rAngleMove = -1.00 else set New.boolFollow = follow set New.boolFormationFollow = formationFollow set New.rDistanceMove = distanceFollow set New.rAngleMove = angleFollow endif set New.rMaxDistanceMove = maxDistanceFollow set New.boolGoHome = goHome set New.rXHome = xHome set new.rYHome = yHome set New.boolAttack = attack set New.boolFocusAttack = focusAttack if targetType == gSTR_OrderTargetTypeUnit or targetType == gSTR_OrderTargetTypeLocation then set New.strOrderTargetType = targetType else set New.strOrderTargetType = null endif set New.strOrder = order set New.rOrderAoE = orderAOE set New.boolexprFilterOrderTarget = targetFilter set New.rRangeAoE = rangeTarget return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonCreateMove takes unit summon, unit caster, boolean formationFollow, boolean randomMove, real distanceFollow, real maxDistanceFollow, real angleFollow, boolean goHome, real xHome, real yHome, returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) set New.boolFollow = TRUE if randomMove then set New.boolFormationFollow = FALSE set New.rDistanceMove = -1.00 set New.rAngleMove = -1.00 else set New.boolFormationFollow = formationFollow set New.rDistanceMove = distanceFollow set New.rAngleMove = angleFollow endif set New.rMaxDistanceMove = maxDistanceFollow set New.boolGoHome = goHome set New.rXHome = xHome set new.rYHome = yHome set New.boolFocusAttack = FALSE set New.strOrderTargetType = null set New.strOrder = null set New.rOrderAoE = 0.00 set New.boolexprFilterOrderTarget = null set New.rRangeAoE = 0.00 return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonCreateOrder takes unit summon, unit caster, boolean focusAttack, string targetType, string order, real orderAOE, boolexpr targetFilter, real rangeTarget returns Summon local Summon New = Summon.allocate() set gINT_CountSummon = gINT_CountSummon + 1 set New.intSummonIndex = gINT_CountSummon set New.uSummon = summon set New.uCaster = caster set New.pOwnerCaster = GetOwningPlayer(caster) set New.boolFollow = FALSE set New.boolFormationFollow = FALSE set New.rDistanceMove = 0.00 set New.rAngleMove = 0.00 set New.rMaxDistanceMove = 0.00 set New.boolFocusAttack = focusAttack if targetType == gSTR_OrderTargetTypeUnit or targetType == gSTR_OrderTargetTypeLocation then set New.strOrderTargetType = targetType else set New.strOrderTargetType = null endif set New.strOrder = order set New.rOrderAoE = orderAOE set New.boolexprFilterOrderTarget = targetFilter set New.rRangeAoE = rangeTarget return New if gINT_CountSummon == 1 then call TimerStart(gTIM, gR_DurationTimer, TRUE, function Callback1) endif endfunction function SummonDestroy takes Summon whichSummon, returns nothing call whichSummon.Destroy() endfunction function SummonFind takes unit summonUnit returns Summon local integer INT_CountSummon = 0 loop set INT_CountSummon = INT_CountSummon + 1 if gSUMMON[INT_CountSummon].uSummon == summonUnit then return gSUMMON[INT_CountSummon] endif exitwhen INT_CountSummon == gINT_CountSummon endloop return 0 endfunction function SummonOrder takes Summon whichSummon, string order, handle target returns nothing call Summon.Order(whichSummon, order, target) endfunction function SummonChangeProperty takes Summon whichSummon, unit newSummon, unit newCaster returns nothing set whichSummon.uSummon = newSummon set whichSummon.uCaster = newCaster set whichSummon.pOwnerCaster = GetOwningPlayer(newCaster) endfunction function SummonChangeMove takes Summon whichSummon, boolean randomMove, boolean newFollow, boolean newFormation, real newDistance, real newAngle, real newMaxDistance, boolean newGoHome, real newXHome, real newYHome returns nothing set whichSummon.boolFollow = newFollow set whichSummon.boolFormationFollow = newFormation set whichSummon.rDistanceMove = newDistance set whichSummon.rAngleMove = newAngle if (not newFormation and randomMove) or (newFormationFollow and randomMove and (newDistance < 0.00 or newAngle < 0.00)) then set whichSummon.boolFormationFollow = FALSE if newDistance < 0.00 then set whichSummon.rDistanceMove = -1.00 endif if newAngle < 0.00 then set whichSummon.rAngleMove = -1.00 endif endif set whichSummon.rMaxDistanceMove = newMaxDistance set whichSummon.boolGoHome = newGoHome set whichSummon.rXGoHome = newXHome set whichSummon.rYGoHome = newYHome endfunction function SummonChangeOrder takes Summon whichSummon, string newTargetType, string newOrder, boolexpr newTargetFilter, real newRange, boolean newFocusAttack returns nothing set whichSummon.strOrderTargetType = newTargetType set whichSummon.strOrder = newOrder set whichSummon.boolexprFilterOrderTarget = newTargetFilter set whichSummon.rRangeAoE = newRange set whichSummon.boolFocusAttack = newFocusAttack endfunction endlibrary |
| 09-05-2008, 11:12 AM | #7 | |||
Quote:
Quote:
Quote:
|
