1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. The Results have come out of the old ARENA oven. Check out who won the 30th Texturing Contest!
    Dismiss Notice
  4. Hey guys, we've posted the Results for the 30th Modeling Contest. Check them out!
    Dismiss Notice
  5. The 15th Mini-Mapping Contest came to an end. The Secrets of Warcraft 3 are soon to be revealed! Come and vote in the public poll for your favorite maps.
    Dismiss Notice
  6. The 12th incarnation of the Music Contest is LIVE! The theme is Synthwave. Knight Rider needs a song to listen to on his journey. You should definitely have some fun with this theme!
    Dismiss Notice
  7. Join other hivers in a friendly concept-art contest. The contestants have to create a genie coming out of its container. We wish you the best of luck!
    Dismiss Notice
  8. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[GUI-Friendly] Capture Point System 1.4

Submitted by Tasyen
This bundle is marked as approved. It works and satisfies the submission rules.

  • Capture Point allows a Mapper to make any Unit they want to be Capturable by standing next to it long enough.

    Features


    • Register/Unregister any Unit you want in real time.
    • Change Ownership of Capture Points as soon Influence is maxed.
    • Supports any kind of Teaming.
    • Choose CaptureStyle/Influence/Range for each Capture Point specific.
    • Units can have different Influence-Power; default Hero 2, non-Hero 1, summoned 0.
    • A Progressbar as indicator.
    • Supports moving Capture Points.
    • Taken Capture Points have to be Neutralised before they can be captured again.
    • Throws Events, if influence rises/drops over % values.
    • Throws an Event as soon an Unit starts/stops influencing an Capture Point.

    1. Check Preferences "Copy unknown Variables"
    2. Copy the Empty function of "Cards Specific" Code into the target map, if yours has none ( Only default World Editor has some problems with jass calls if there is none)
    3. Copy "WithinRange"-Folder
    4. Copy "CapturePoint"-Folder - Below the "WithinRange"-Folder
    5. Copy the Bar Model.
      • Import it into your Map.
      • Inside "CapturePoint Init" choose the bar as model, if it is not.

  • Capture Style Defines how and under which situations Influence is generated.
    Code (vJASS):

    //=========================================================================================================
    //Capture Style:
    //=========================================================================================================
    //           0 = +1 Influence, if only Allies are inside the CaptureZone. -1 If only Foes.
    //           1 = Like 0; but Lose Influence, if no Ally is inside.
    //           2 = +1 Influence if more allies; -1 if more foes
    //           3 = Like 2; but Lose Influence, if no Ally is inside.
    //           4 = Influence gain/loss is done by difference of Foes and allies
    //           5 = Like 4; but Lose Influence, if no Ally is inside.

    // to define new Styles Checkout "function CaptureGetInfluenceChange" and inser them.
     


  • Definitions allows you to change some Values: They are the first real functions inside the CapturePoint-Trigger
    Code (vJASS):

    //=============================================================================
    //=========================================================================================================
    //Definitions:
    //=========================================================================================================
    //who is on default excluded from influenceing Capture Points.
    //   function CapturePointDefaultFiler takes nothing returns boolean
    //       default Structures, Neutral Passive Units, Capture Points and Aloc Units

    //   function CaptureInflunece takes unit u returns integer
    //       Definies how much a unit does Influence CapturePoints
    //           Default: Hero 2, Non-Hero 1, summoned 0.

    //   constant function CaptureTimerInterval takes nothing returns real
    //       Defines Bar/Influence Update Interval

    //   constant function CaptureBarUnitType takes nothing returns integer
    //       The ObjectId of the used GenericBar Unit, Make sure it is correct.

    //   constant function CaptureUsePercentEvents takes nothing returns boolean
    //       Enables % Influence Events

    //   constant function CapturePercentEventBase takes nothing returns integer
    //       On which x * base % a Event is Thrown

    //   constant function CapturePointDefaultStyle takes nothing returns integer
    //   constant function CapturePointDefaultInfluence takes nothing returns integer
    //   constant function CapturePointDefaultRange takes nothing returns real
    //       These 3 are used in RegisterCapturePointSimple

    //   constant function CaptureBarOffsetX takes nothing returns real
    //       Default XOffset used by not Specific CapturePoints

    //   constant function CaptureBarOffsetY takes nothing returns real
    //       Default YOffset used by not Specific CapturePoints

    //   constant function CaptureBarOffsetZ takes nothing returns real
    //       Default Flying Height of all Bars + Flying height of attached Unit
    //       used by not Specific CapturePoints
     


    They look like this one
    Code (vJASS):

    constant function CaptureUsePercentEvents takes nothing returns boolean
       return true
    endfunction
     


  • You can catch any Capturing by using this method
    • Demo ControlPoint Converted
      • Events
        • Unit - A unit Changes owner
      • Conditions
        • ((Triggering unit) is in CapturePoints) Equal to True
      • Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Owner of (Triggering unit)) Equal to Neutral Passive
          • Then - Actions
            • Game - Display to (All players) for 6.00 seconds the text: Neutralisiert
          • Else - Actions
            • Game - Display to (All players) for 6.00 seconds the text: (farbcode[(Player number of (Triggering player))] + ((Name of (Triggering player)) + (|r has captured: + (Name of (Triggering unit)))))



    After beeing Captured this specific demolisher does not change ownership anymore.
    • Demo Demolisher one time controll
      • Events
        • Unit - Demolisher 0006 <gen> Changes owner
      • Conditions
        • (Owner of (Triggering unit)) Not equal to Neutral Passive
      • Actions
        • Set CapturePoint_Register_Unit = (Triggering unit)
        • Trigger - Run CapturePoint_DeRegister (ignoring conditions)


  • Capture Point Event allows you catch the moment an Unit starts/stopps influencening an Capture Point or if an % of the needed influence is reached.
    Code (vJASS):

    //=========================================================================================================
    //CapturePointEvent
    //=========================================================================================================
    // With CapturePointEvent you can catch some nice Situations.
    //
    //        CatpurePointEvent = 1      udg_CapturePointEventMovedUnit Starts Influenceing udg_CapturePointEventUnit
    //        CapturePointEvent = -1   udg_CapturePointEventMovedUnit stopps Influenceing udg_CapturePointEventUnit

    //        InfluencePercent Steps: udg_CapturePointEventPlayer = leadingPlayer, on a negative capturePointEvent its equal to owner.

    //        CapturePointEvent = 25  udg_CapturePointEventPlayer reached 25% Influence on udg_CapturePointEventUnit
    //        CapturePointEvent = 50  udg_CapturePointEventPlayer reached 50% Influence on udg_CapturePointEventUnit
    //        CapturePointEvent = 75  udg_CapturePointEventPlayer reached 75% Influence on udg_CapturePointEventUnit
    //        CapturePointEvent = -75 controlled CapturePoint udg_CapturePointEventUnit was reduced below 75%
    //        CapturePointEvent = -50 controlled CapturePoint udg_CapturePointEventUnit was reduced below 50%
    //        CapturePointEvent = -25 controlled CapturePoint udg_CapturePointEventUnit was reduced below 25%

    // You can modify the Percent Events in the approaching Definition

    //   constant function CapturePercentEventBase takes nothing returns integer
     

    This Trigger prints out any Percentlimit reached.
    • Demo Send Warning Controll
      • Events
        • Game - CapturePointEvent becomes greater Equal 5.00
        • Game - CapturePointEvent becomes smaller Equal -5.00
      • Conditions
      • Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • CapturePointEvent smaller as 0.00
          • Then - Actions
            • Game - Display to (All players) for 5.00 seconds the text: ((farbcode[(Player number of CapturePointEventPlayer)] + ((Name of CapturePointEventPlayer) + |r's Influence on )) + ((Name of CapturePointEventUnit) + ( went below: + ((String((Abs(CapturePointEvent)))) + %))))
          • Else - Actions
            • Game - Display to (All players) for 5.00 seconds the text: ((farbcode[(Player number of CapturePointEventPlayer)] + ((Name of CapturePointEventPlayer) + |r's Influence on )) + ((Name of CapturePointEventUnit) + ( went above: + ((String((Abs(CapturePointEvent)))) + %))))


  • The Demo Map contains an easy to use example of CapturePoints.

    Register to be capturable:


    • Demo ControlPoint init
      • Events
        • Time - Elapsed game time is 0.00 seconds
      • Conditions
      • Actions
        • Custom script: set bj_wantDestroyGroup=true
        • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • Or - Any (Conditions) are true
                  • Conditions
                    • (Unit-type of (Picked unit)) Equal to Demolisher
                    • ((Picked unit) is A structure) Equal to True
              • Then - Actions
                • -------- default Turn Intervall is 1/2 second. 16 => 8 seconds to capture --------
                • Set CapturePoint_Register_Influ = 16
                • Set CapturePoint_Register_Range = (200.00 + (Collision Size of (Picked unit)))
                • Set CapturePoint_Register_Unit = (Picked unit)
                • Set CapturePoint_Register_Style = 2
                • Trigger - Run CapturePoint_Register (ignoring conditions)
              • Else - Actions



  • The functions you call from outside.
    Code (vJASS):

    //=========================================================================================================
    //API:
    //=========================================================================================================

    //  function RegisterCapturePointSpecific takes unit u, real range, integer influence, integer style, real x, real y, real z, real scale returns boolean
    //       Makes an Unit Captureable and generateds an CaptureBar over it.

    //    function RegisterCapturePoint takes unit u, real range, integer influence, integer style returns boolean
    //       Makes an Unit Captureable and generateds an CaptureBar over it.
    //       Simple Ones use default X/Y/Z offset and the unit scale from Object Editor

    //   function RegisterCapturePointSimple takes unit u returns boolean
    //       Wrapper for RegisterCapturePoint by using the Default Values in Definitions
    //       Except for the unit.

    //   function DeRegisterCapturePoint takes unit u, boolean DeregisterUnitWithin returns boolean
    //       Makes an Captureable Unit uncaptureable again.
    //       If true the unit will be kicked out of UnitWithin too.

    //   function CapturePointStopTimer takes nothing returns nothing
    //       Stops the Influence Timer and the Grafic Update Timer of CapturePoint

    //   function CapturePointStartTimer takes nothing returns nothing
    //       Starts the timers of this System.
    //       Is done if you call this System the first time.

    //   udg_CatpurePointEvent = 1 | -1

    //API UnitWithinRange
    //   function RegisterUnitWithinRange takes unit u, real range, boolean cleanOnKilled returns boolean
    //       Start the detection for this Unit with this range
    //       can not register twice the same range onto 1 unit.

    //   function DeRegisterUnitWithinRange takes unit u, real range returns boolean
    //       Destroys the range detection with this specific Range and Unit.

    //   function DeRegisterUnitWithinRangeUnit takes unit u returns boolean
    //       Destroys all Triggers used by the unit from UnitWithinRange.
     

  • Code (vJASS):

    //CapturePoint System 1.4
    //   By Tasyen

    //Allows to Make any Unit, you Register, captureable by staying near to it.
    //This System has to be called before it starts working, is done in "CapturePoint Init" on default.
    //Uses the UnitWithinRangeEvent

    //=========================================================================================================
    //Capture Style:
    //=========================================================================================================
    //       0 = +1 Influence, if only Allies are inside the CaptureZone. -1 If only Foes.
    //       1 = Like 0; but Lose Influence, if no Ally is inside.
    //       2 = +1 Influence if more allies; -1 if more foes
    //       3 = Like 2; but Lose Influence, if no Ally is inside.
    //       4 = Influence gain/loss is done by difference of Foes and allies
    //       5 = Like 4; but Lose Influence, if no Ally is inside.

    // to define new Styles Checkout "function CaptureGetInfluenceChange" and inser them

    //=========================================================================================================
    //CapturePointEvent
    //=========================================================================================================
    // With CapturePointEvent you can catch some nice Situations.
    //
    //        CatpurePointEvent = 1      udg_CapturePointEventMovedUnit Starts Influenceing udg_CapturePointEventUnit
    //        CapturePointEvent = -1   udg_CapturePointEventMovedUnit stopps Influenceing udg_CapturePointEventUnit
       
    //        InfluencePercent Steps: udg_CapturePointEventPlayer = leadingPlayer, on a negative capturePointEvent its equal to owner.

    //        CapturePointEvent = 25  udg_CapturePointEventPlayer reached 25% Influence on udg_CapturePointEventUnit
    //        CapturePointEvent = 50  udg_CapturePointEventPlayer reached 50% Influence on udg_CapturePointEventUnit
    //        CapturePointEvent = 75  udg_CapturePointEventPlayer reached 75% Influence on udg_CapturePointEventUnit
    //        CapturePointEvent = -75 controlled CapturePoint udg_CapturePointEventUnit was reduced below 75%
    //        CapturePointEvent = -50 controlled CapturePoint udg_CapturePointEventUnit was reduced below 50%
    //        CapturePointEvent = -25 controlled CapturePoint udg_CapturePointEventUnit was reduced below 25%

    // You can modify the Percent Events in the approaching Definition

    //=========================================================================================================
    //Definitions:
    //=========================================================================================================
    //   function CapturePointDefaultFiler takes nothing returns boolean
    //       Defines who is excluded from influencing capture points.
    //           Default: Structures, Neutral Passive Units, Capture Points and Aloc Units are exclude from using capturing.

    //   function Captureinfluence takes unit u returns integer
    //       Definies how much a unit does Influence CapturePoints
    //           Default: Hero 2, Non-Hero 1, summoned 0.

    //   constant function CaptureTimerInterval takes nothing returns real
    //       Defines Bar/Influence Update Interval

    //   constant function CaptureBarUnitType takes nothing returns integer
    //       The ObjectId of the used GenericBar Unit, Make sure it is correct.

    //   constant function CaptureUsePercentEvents takes nothing returns boolean
    //       Enables % Influence Events

    //   constant function CapturePercentEventBase takes nothing returns integer
    //       On which x * base % a Event is Thrown

    //   constant function CapturePointDefaultStyle takes nothing returns integer
    //   constant function CapturePointDefaultInfluence takes nothing returns integer
    //   constant function CapturePointDefaultRange takes nothing returns real
    //       used in RegisterCapturePointSimple

    //   constant function CaptureBarDefaultX_Offset takes nothing returns real
    //   constant function CaptureBarDefaultY_Offset takes nothing returns real
    //   constant function CaptureBarDefaultZ_Offset takes nothing returns real
    //       used by RegisterCapturePointSimple & RegisterCapturePoint

    //=========================================================================================================
    //API:
    //=========================================================================================================

    //   function RegisterCapturePointSpecific takes unit u, real range, integer influence, integer style, real x, real y, real z, real scale returns boolean
    //       Makes an Unit Captureable and generateds an CaptureBar over it.

    //    function RegisterCapturePoint takes unit u, real range, integer influence, integer style returns boolean
    //       Makes an Unit Captureable and generateds an CaptureBar over it.
    //       Simple Ones use default X/Y/Z offset and the unit scale from Object Editor

    //   function RegisterCapturePointSimple takes unit u returns boolean
    //       Wrapper for RegisterCapturePoint by using the Default Values in Definitions
    //       Except for the unit.

    //   function DeRegisterCapturePoint takes unit u, boolean DeregisterUnitWithin returns boolean
    //       Makes an Captureable Unit uncaptureable again.
    //       If true the unit will be kicked out of UnitWithin too.

    //   function CapturePointStopTimer takes nothing returns nothing
    //       Stops the Influence Timer and the Grafic Update Timer of CapturePoint

    //   function CapturePointStartTimer takes nothing returns nothing
    //       Starts the timers of this System.
    //       Is done if you call this System the first time.

    //   udg_CatpurePointEvent = 1 | -1

    //=========================================================================================================
    //       Definitions:
    //=========================================================================================================

    //Define how much influnce Influnce Generated by unit u
    //If you don't want such a behaviour simply remove anything except the last "return 1"
    function Captureinfluence takes unit u returns integer
       if IsUnitType(u, UNIT_TYPE_HERO) then
           return 2
       else
           if IsUnitType(u, UNIT_TYPE_SUMMONED) then
               return 0
           else
               return 1  
           endif
       endif
       return 1  
    endfunction

    //Structures, Neutral Passive Units, Capture Points and Aloc Units are exclude from using capturing.
    function CapturePointDefaultFiler takes nothing returns boolean
       local unit u = GetTriggerUnit()
       local boolean b = not IsUnitType(u, UNIT_TYPE_STRUCTURE) and GetOwningPlayer(u) != Player(PLAYER_NEUTRAL_PASSIVE) and not IsUnitInGroup(u, udg_CapturePoints) and GetUnitAbilityLevel(u,'Aloc') == 0
       set u = null
       return b
    endfunction

    constant function CaptureUsePercentEvents takes nothing returns boolean
       return true
    endfunction
    //If Influence Rises/Falls over a negative/positive x time of this value a Event with this Value is thrown
    //Default 25/50/75 %;
    //0% Event is hardcoded excluded.
    // Anything below 5 is not Recommented.
    // Insering 0 or 1 will break the system.
    constant function CapturePercentEventBase takes nothing returns integer
       return 25
    endfunction

    //Is used in RegisterCapturePointSimple
    constant function CapturePointDefaultStyle takes nothing returns integer
       return 0
    endfunction
    constant function CapturePointDefaultRange takes nothing returns real
       return 200.0
    endfunction
    constant function CapturePointDefaultInfluence takes nothing returns integer
       return 30
    endfunction

    //Is used in RegisterCapturePointSimple & RegisterCapturePoint
    constant function CaptureBarDefaultX_Offset takes nothing returns real
       return 0.0
    endfunction
    constant function CaptureBarDefaultY_Offset takes nothing returns real
       return 50.0
    endfunction
    constant function CaptureBarDefaultZ_Offset takes nothing returns real
       return 300.0
    endfunction
    constant function CaptureBarDefaultScale takes nothing returns real
       return 3.0
    endfunction

    //How long is one Interval of Capture, The time to capture a CapturePoint is CaptureTimerInterval*Influence (*2, if Controled by foe)
    //Capture Points first have to be neutralised
    constant function CaptureTimerInterval takes nothing returns real
       return 0.5
    endfunction  


    //=========================================================================================================
    //Hashtable Indexes:
    //=========================================================================================================
    //Handle
    function CapturePointHashIndex_Group takes nothing returns integer
       return 0
    endfunction
    function CapturePointHashIndex_LeadingPlayer takes nothing returns integer
       return 1
    endfunction
    function CapturePointHashIndex_Bar takes nothing returns integer
       return 2
    endfunction
    //Real
    function CapturePointHashIndex_Range takes nothing returns integer
       return 0
    endfunction
    function CapturePointHashIndex_XOffset takes nothing returns integer
       return 1
    endfunction
    function CapturePointHashIndex_YOffset takes nothing returns integer
       return 2
    endfunction
    function CapturePointHashIndex_ZOffset takes nothing returns integer
       return 3
    endfunction
    //Int
    function CapturePointHashIndex_Influence takes nothing returns integer
       return 0
    endfunction
    function CapturePointHashIndex_InfluenceNeed takes nothing returns integer
       return 1
    endfunction
    function CapturePointHashIndex_Style takes nothing returns integer
       return 2
    endfunction
    //Boolean
    function CapturePointHashIndex_UseOffset takes nothing returns integer
       return 0
    endfunction
    //======================================================================================================
    //System Code Start
    //======================================================================================================

    function CapturePointCreateBar takes unit u, real x, real y, real z, real scale returns nothing
       local integer cpId = GetHandleId(u)
       local player owner = GetOwningPlayer(u)
       local effect bar = AddSpecialEffect(udg_CapturePointBarType, GetUnitX(u)+x, GetUnitY(u)+y)
       call BlzSetSpecialEffectTimeScale(bar, 0)   //Disalbe AutoAnimation
       call BlzSetSpecialEffectTime(bar, 0)
       call BlzSetSpecialEffectScale(bar, scale)
       call BlzSetSpecialEffectHeight(bar, GetUnitFlyHeight(u) + z)
       call SaveEffectHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Bar(), bar)
       
       if x !=  CaptureBarDefaultX_Offset() or y != CaptureBarDefaultY_Offset() or z != CaptureBarDefaultZ_Offset() then
           call SaveBoolean(udg_CapturePointHash,cpId,CapturePointHashIndex_UseOffset(),true)
           call SaveReal(udg_CapturePointHash,cpId,CapturePointHashIndex_XOffset(),x)
           call SaveReal(udg_CapturePointHash,cpId,CapturePointHashIndex_YOffset(),y)
           call SaveReal(udg_CapturePointHash,cpId,CapturePointHashIndex_ZOffset(),z)
       endif  
       if owner != Player(PLAYER_NEUTRAL_PASSIVE) then
           call BlzSetSpecialEffectTime(bar, 1)
           call BlzSetSpecialEffectColorByPlayer(bar, owner)
       endif
       set bar = null
       set owner = null
    endfunction

    function CapturePointSetupData takes unit u, real range, integer influence, integer style returns boolean
       local integer cpId = GetHandleId(u)
       local player owner = GetOwningPlayer(u)
       if IsUnitInGroup( u, udg_CapturePoints) then
           return false
       endif
       call RegisterUnitWithinRangeSuper(u, range, true, udg_CapturePointDefaultFilter, gg_trg_CapturePoint, 0, false)
       call GroupAddUnit(udg_CapturePoints, u)
       call SaveGroupHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Group(), CreateGroup() )
       call SavePlayerHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_LeadingPlayer(),owner)
       call SaveReal(udg_CapturePointHash,cpId,CapturePointHashIndex_Range(),range)
       call SaveInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_InfluenceNeed(),influence)
       //Start with Max Influence, if Controled already
       if owner != Player(PLAYER_NEUTRAL_PASSIVE) then
           call SaveInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_Influence(),influence)
       endif
       call SaveInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_Style(),style)
       
       set owner = null
       return true
    endfunction

    //Inser a Unit as Captureable Capture Unit, Range is the distance from which the unit can be captured,
    //Influence * CaptureTimerInterval() time in seconds, style defines under which situation influences changes
    //Uses more arguments to define x/y/z/facing indiviudal
    function RegisterCapturePointSpecific takes unit u, real range, integer influence, integer style, real x, real y, real z, real scale returns boolean
       if CapturePointSetupData(u, range, influence, style) then
           call CapturePointCreateBar(u, x, y, z, scale)
           return true
       else
           return false
       endif  
    endfunction


    function RegisterCapturePoint takes unit u, real range, integer influence, integer style returns boolean
       if CapturePointSetupData(u, range, influence, style) then
           call CapturePointCreateBar(u, CaptureBarDefaultX_Offset(), CaptureBarDefaultY_Offset(), CaptureBarDefaultZ_Offset(), CaptureBarDefaultScale())
           return true
       else
           return false
       endif
    endfunction

    function RegisterCapturePointSimple takes unit u returns boolean
       return RegisterCapturePoint( u, CapturePointDefaultRange(), CapturePointDefaultInfluence(), CapturePointDefaultStyle())
    endfunction

    //Makes a Capture Point uncapturable, second argument asks if it should be removed from the "Unit within"-System too.
    //Removes the Bar Unit from the game.
    function DeRegisterCapturePoint takes unit u, boolean DeregisterUnitWithin returns boolean
       local integer cpId = GetHandleId(u)
       if DeregisterUnitWithin then
           call DeRegisterUnitWithinRangeUnit(u)
       endif
       call GroupRemoveUnit(udg_CapturePoints, u)
       call DestroyGroup(LoadGroupHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Group()) )
       call BlzSetSpecialEffectTimeScale(LoadEffectHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Bar()), 10)
       call DestroyEffect(LoadEffectHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Bar()))
       call FlushChildHashtable(udg_CapturePointHash, cpId)  
       return true
    endfunction

    //This catches the WithingRangeEvent = -1
    // aka Removed/Killed/Replaced
    //We do not clean in WithinRange cause it does it onitself if this event is thrown.
    function CapturePointAutoClean takes nothing returns nothing
       call DeRegisterCapturePoint (udg_WithinRangeUnit,false)
    endfunction

    //Is Called with the Custom-Event UnitWithin = 1.
    function CapturePointEnter takes nothing returns nothing
       local integer cpId = GetHandleId(udg_WithinRangeUnit)
       local player owner = GetOwningPlayer(udg_WithinRangeEnteringUnit)
       local group g = LoadGroupHandle( udg_CapturePointHash,cpId,CapturePointHashIndex_Group())
       if IsUnitInGroup(udg_WithinRangeEnteringUnit, g) then
           set owner = null
           set g = null
           return   //Do not allow twice
       endif  
       call GroupAddUnit(g ,udg_WithinRangeEnteringUnit)
       
       //Become the Leading Player if current Leadingplayer is Neutral_Passive.
       if LoadPlayerHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_LeadingPlayer()) == Player(PLAYER_NEUTRAL_PASSIVE) then
           call SavePlayerHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_LeadingPlayer(),owner)
           call BlzSetSpecialEffectColorByPlayer(LoadEffectHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Bar()), owner)
       endif
       //Event Entered
       set udg_CapturePointEventMovedUnit = udg_WithinRangeEnteringUnit
       set udg_CapturePointEventUnit = udg_WithinRangeUnit
       set udg_CapturePointEvent = 1
       set udg_CapturePointEvent = 0
       set owner = null
       set g = null
    endfunction

    //Will Return influenceChange the result will be in Bounds of 0 to Max depending on Style regarding foes/allies.
    function CaptureGetInfluenceChange takes integer influence, integer influenceMax, integer allies, integer foes, integer style returns integer
       if style == 0 then
           if allies != 0 and foes == 0 then   //Only Allies?
               if influence == influenceMax then   //Exceed Limit?
                   return 0   //It execeeds.
               else
                   return 1
               endif  
           endif
           if allies == 0 and foes != 0 then   //Only Foes?
               if influence == 0 then   //Exceed Limit?
                   return 0   //It execeeds.
               else
                   return -1
               endif
           endif  
       endif
       if style == 1 then
           if allies != 0 and foes == 0 then   //Only Allies?
               if influence == influenceMax then
                   return 0
               else
                   return 1
               endif  
           else
               if allies == 0 then   //No allies?
                   if influence == 0 then
                       return 0
                   else
                       return -1
                   endif
               else
                   return 0   //There are Allies and Foes, do nothing!
               endif
           endif
       endif
       if style == 2 then
           if allies > foes then   //More Allies?
               if influence == influenceMax then
                   return 0
               else
                   return 1
               endif
           endif
           if  allies < foes then   //Less Allies?
               if influence == 0 then
                   return 0
               else
                   return -1
               endif
           endif
       endif
       if style == 3 then
           if allies > foes then
               if influence == influenceMax then
                   return 0
               else
                   return 1
               endif
           endif
           if  allies < foes or allies == 0 then   //Less Allies or none Ally?
               if influence == 0 then
                   return 0
               else
                   return -1
               endif
           endif
       endif
       if style == 4 then
           if influence + (allies - foes) < influenceMax then   //New Influence below Upper Limit?
               if influence + (allies - foes) > 0 then       //New Influence above lower Limit?
                   return (allies - foes)
               else
                   return   -influence   //Below Lower Limit Reduce by current Influence, to 0 it!
               endif  
           else
               return influenceMax - influence   //Above Upper Limit Return Missing to Upper Limit!
           endif
       endif
       if style == 5 then
           if allies == 0 and foes == 0 then //No Influncing Unit -> Lose 1 Influence?
               if influence == 0 then
                   return 0
               else
                   return -1
               endif
           else //Style 4
               if influence + (allies - foes) < influenceMax then  
                   if influence + (allies - foes) > 0 then
                       return (allies - foes)
                   else
                       return   -influence
                   endif      
               else
                   return influenceMax - influence
               endif
           endif  
       endif  
       return 0
    endfunction

    //Checks all x times of CapturePercentEventBase() and throws the first found Event.
    //Throws negative Events if Influence fall and a positive if Influence Rises.
    // udg_CapturePointEventUnit CapturePoint;
    // udg_CapturePointEventPlayer = leadingPlayer  -> Rising = the one will get the Point; falling the one who is losing this Point
    function CapturePointThrowEvent takes integer oldPercent, integer newPercent, unit cp, player p returns boolean
       local integer oldStep = oldPercent / CapturePercentEventBase()
       local integer newStep = newPercent / CapturePercentEventBase()
       if oldStep != newStep then   //Step changed?
           set udg_CapturePointEventUnit = cp
           set udg_CapturePointEventPlayer = p
           if oldStep < newStep then   //Rise?
               set udg_CapturePointEvent = newStep * CapturePercentEventBase()
           else   //Fallen below newstep + 1 (old => 8 new = 6 you enter 60% realm -> lose the 70% Influence)
               set udg_CapturePointEvent = -(newStep+1) * CapturePercentEventBase()
           endif
           set udg_CapturePointEvent = 0
           return true
       endif
       return false
    endfunction

    //Group Enumeration for all CapturePoints, Changes Influence, Ownership and Bar Color.
    function CapturePointsLoop takes nothing returns nothing
       local unit cp = GetEnumUnit()
       local unit u
       local real oldPercent
       local real newPercent
       local integer cpId = GetHandleId(cp)
       local player leadingPlayer = LoadPlayerHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_LeadingPlayer())
       local group influencingUnits = LoadGroupHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Group())
       local integer index = 0
       local integer allies = 0
       local integer foes = 0
       local real range = LoadReal(udg_CapturePointHash,cpId,CapturePointHashIndex_Range())
       local integer influence = LoadInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_Influence())
       local integer influenceMax = LoadInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_InfluenceNeed())
       local integer array playerInfluence
       local integer playerId
       local integer playerIdMax = bj_MAX_PLAYER_SLOTS
       local integer influenceGain
       local integer style = LoadInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_Style())
       local effect bar = LoadEffectHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Bar())
       local integer influencePower
       set playerInfluence[playerIdMax] = -1
       //call GroupClear(udg_CapturePoint_TempGroup)
       loop
           set u = FirstOfGroup(influencingUnits)
           exitwhen u == null
           call GroupRemoveUnit(influencingUnits, u)
           
           //Is Unit still Influencing?
           if not IsUnitType(u, UNIT_TYPE_DEAD) and IsUnitInRange (u, cp, range) and GetUnitTypeId(u)!=0 then
               call GroupAddUnit(udg_CapturePoint_TempGroup, u)
               if not (IsUnitPaused(u)) and not (IsUnitHidden(u)) then   //can it influence now?
                   //Save Influence of this Player
                   set playerId = GetPlayerId( GetOwningPlayer (u))
                   set influencePower = Captureinfluence(u)
                   set playerInfluence[playerId] = playerInfluence[playerId] + influencePower
                   if playerInfluence[playerId] > playerInfluence[playerIdMax] then
                       set playerIdMax = playerId
                   endif  
                   //Count allies/Foes.
                   if IsUnitAlly (u, leadingPlayer) then
                       set allies = allies + influencePower
                   else
                       set foes = foes + influencePower
                   endif  
               endif
           else
               //This unit is no Influencer for this point anymore.
               //Event Unit stops Influenceing
               set udg_CapturePointEventUnit = cp
               set udg_CapturePointEventMovedUnit = u
               set udg_CapturePointEvent = -1
               set udg_CapturePointEvent = 0
           endif
       endloop
       //Refill
       loop
           set u = FirstOfGroup(udg_CapturePoint_TempGroup)
           exitwhen u == null
           call GroupRemoveUnit(udg_CapturePoint_TempGroup, u)
           call GroupAddUnit(influencingUnits,u)
       endloop  
       
       set influenceGain = CaptureGetInfluenceChange(influence,influenceMax, allies, foes, style)
       //Is there InfluenceGain?
       if influenceGain != 0  then
           set oldPercent = I2R(influence) / influenceMax
           set influence = influence + influenceGain      
           call SaveInteger(udg_CapturePointHash,cpId,CapturePointHashIndex_Influence(),influence)
           set newPercent = I2R(influence) / influenceMax
           call BlzSetSpecialEffectTime(bar, newPercent)
           //Call Influence %-Event?
           if CaptureUsePercentEvents() then
               call CapturePointThrowEvent(R2I(oldPercent*100),R2I(newPercent*100),cp,leadingPlayer)
           endif  
       endif
       if influenceGain != 0 or not IsUnitOwnedByPlayer (cp, leadingPlayer) then  
           //Neutralise the Point?
           if influence == 0 then
               //ControlLose with units?
               if FirstOfGroup(influencingUnits) != null then
                   set leadingPlayer = Player(playerIdMax)
                   call BlzSetSpecialEffectColorByPlayer(bar, leadingPlayer)
               else
                   set leadingPlayer = Player(PLAYER_NEUTRAL_PASSIVE)
                   call BlzSetSpecialEffectColorByPlayer(bar, leadingPlayer)
               endif
               call SetUnitOwner (cp, Player(PLAYER_NEUTRAL_PASSIVE), true)  
               call SavePlayerHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_LeadingPlayer(),leadingPlayer)
               call BlzSetSpecialEffectTime(bar, 0)
           else
               //Leading Player captures it?
               if influence == influenceMax and not IsUnitOwnedByPlayer (cp, leadingPlayer) then
                   call SetUnitOwner (cp, leadingPlayer, true)
               endif
               call BlzSetSpecialEffectColorByPlayer(bar, leadingPlayer)
           endif
       endif  
       //Clear Unit stack
       set leadingPlayer = null
       set cp = null
       set bar = null
       set influencingUnits = null
    endfunction

    //Group Enumeration for all CapturePoints repos Bars
    function CapturePointsReposBar takes nothing returns nothing
       local unit cp = GetEnumUnit()
       local integer cpId = GetHandleId(cp)
       local effect bar =LoadEffectHandle(udg_CapturePointHash,cpId,CapturePointHashIndex_Bar())
       //use Speciifc Offset?
       if LoadBoolean(udg_CapturePointHash,cpId,CapturePointHashIndex_UseOffset()) then
           call BlzSetSpecialEffectPosition(bar, GetUnitX(cp) + LoadReal(udg_CapturePointHash,cpId,CapturePointHashIndex_XOffset()), GetUnitY(cp) + LoadReal(udg_CapturePointHash,cpId,CapturePointHashIndex_YOffset()), GetUnitFlyHeight(cp) + LoadReal(udg_CapturePointHash,cpId,CapturePointHashIndex_ZOffset()) )
       else
           //Used Default
           call BlzSetSpecialEffectPosition(bar, GetUnitX(cp) + CaptureBarDefaultX_Offset(), GetUnitY(cp) + CaptureBarDefaultY_Offset(), GetUnitFlyHeight(cp) + CaptureBarDefaultZ_Offset() )
       endif
       set cp = null
       set bar = null
    endfunction

    function CaptureTimerReposBar takes nothing returns nothing
       call ForGroup (udg_CapturePoints, function CapturePointsReposBar)
    endfunction

    function CaptureTimerInfluence takes nothing returns nothing
        call ForGroup (udg_CapturePoints, function CapturePointsLoop)
    endfunction

    function CapturePointStartTimer takes nothing returns nothing
       call TimerStart(udg_CapturePointTimer[0], CaptureTimerInterval(), true, function CaptureTimerInfluence)
       call TimerStart(udg_CapturePointTimer[1], 1.0/32.0, true, function CaptureTimerReposBar)
    endfunction

    function CapturePointStopTimer takes nothing returns nothing
       call PauseTimer(udg_CapturePointTimer[0])
       call PauseTimer(udg_CapturePointTimer[1])
    endfunction

    //Is Executed if you run CapturePoint the first time.
    //Start Catching Events thrown by UnitWithinRange
    //Start timer[0][1]
    function CaptureInit takes nothing returns nothing
       //Auto deregister on death/Killed/Removed
       set udg_CapturePointDefaultFilter = Condition( function CapturePointDefaultFiler)
       set udg_CapturePointAutoDeregister = CreateTrigger()
       call TriggerRegisterVariableEvent( udg_CapturePointAutoDeregister, "udg_WithinRangeEvent", EQUAL, -1 )
       call TriggerAddAction(udg_CapturePointAutoDeregister,function CapturePointAutoClean)
       //enable Capturing
       call TriggerClearActions(gg_trg_CapturePoint)
       call TriggerRegisterVariableEvent( gg_trg_CapturePoint, "udg_WithinRangeEvent", EQUAL, 1 )
       call TriggerAddAction(gg_trg_CapturePoint,function CapturePointEnter)
       call CapturePointStartTimer()
       
       set udg_CapturePointHash = InitHashtable()
       
       set udg_CapturePoint_Register_Range = CapturePointDefaultRange()
       set udg_CapturePoint_Register_Influ = CapturePointDefaultInfluence()
       set udg_CapturePoint_Register_Style = CapturePointDefaultStyle()
    endfunction

    function CaptureRegisterGUI takes nothing returns nothing
       if udg_CapturePoint_Register_Range <= 0 then
           set udg_CapturePoint_Register_Range = CapturePointDefaultRange()
       endif
       call RegisterCapturePoint(udg_CapturePoint_Register_Unit, udg_CapturePoint_Register_Range, udg_CapturePoint_Register_Influ, udg_CapturePoint_Register_Style)
       set udg_CapturePoint_Register_Range = CapturePointDefaultRange()
       set udg_CapturePoint_Register_Influ = CapturePointDefaultInfluence()
       set udg_CapturePoint_Register_Style = CapturePointDefaultStyle()
    endfunction
    function CaptureDeRegisterGUI takes nothing returns nothing
       call DeRegisterCapturePoint(udg_CapturePoint_Register_Unit, true)
    endfunction

    //===========================================================================
    function InitTrig_CapturePoint takes nothing returns nothing
       set gg_trg_CapturePoint = CreateTrigger()
       call TriggerAddAction(gg_trg_CapturePoint, function CaptureInit)
       set udg_CapturePoint_DeRegister = CreateTrigger()
       set udg_CapturePoint_Register = CreateTrigger()
       call TriggerAddAction(udg_CapturePoint_DeRegister, function CaptureDeRegisterGUI)
       call TriggerAddAction(udg_CapturePoint_Register, function CaptureRegisterGUI)
    endfunction


     

  • V1.4)
    uses now SpecialEffects instead of Units to display the Bar.
    CPT V1.3 bugs with Warcraft 1.29 (one can select the bar units which is quite ugly).​
    uses now UnitWithin 1.5
    Less Magic Numbers
    Does not throw UnitWithin events anymore.
    Uses now Groups instead of emulating them.
    The GUI Registering will now ReLoad itself with Default values after each execution.​
    V1.3)
    uses now UnitWithin 1.4
    the bar unit Type is now defined inside "CapturePoint Init" with a variable.
    the default filter is now a variable of boolexpr used by CapturePoint.
    Included the GUI Triggers into the main Code.​
    V1.2d)
    Autocleans CapturePoints on death/Removed/Replaced, this can be disabled by disabling trigger udg_CapturePointAutoDeregister after starting the system.
    Insert some missing variables into the autogeneration block.​
    V1.2c)
    Changed function CapturePointThrowEvent
    code is now smaller/intuitiver
    throws the highest/lowest(except 0) event, if jumping multiple % limits at once.​
    fixed a bug in the demo Influence Event trigger.
    Changed repos intervale from 0.03 -> 1.0/32.0​
    V1.2b)
    There was a bug with Capture-Style 4/5.
    The demo Capture Points are included again.
    Sets Bar's XYZ/offset at Capture Point generation.
    Insert an disabled PauseTimer[1], aka Reposing Timer, inside the init.​
    V1.2a) CapturePointEvent Units are now called capturePointEventUnit and CapturePointEventMovedUnit
    V1.2) Owned Capture Points starting with a filled bar
    Renamed all RegisterUnitWithinRange Variables
    Added the new Feature CapturePointEvent:
    renamed the current Register Functions
    RegisterCapturePointSimple -> RegisterCapturePoint
    RegisterCapturePoint -> RegisterCapturePointSpecific
    Added a new one which takes only 1 argument
    RegisterCapturePointSimple takes unit u
    V1.1b) Removed a Leak in UnitWithinRange.
    V1.1a) - Fixed an Error with V1.1 and made it better.
    Version 1.1)
    Speededup The Refilling of Lost Influencer by using kind of Dynamic indexing, but will not maintain the Entering-Order anymore.​

Credits

Andrewgosu
Dr Super Good
JesusHipster
rulerofiron99
LSI.Foley


Keywords: Control Point, King of hills, Hold Ground, Influence, Take Over
Previews
Contents

CapturePoint System 1.4 (Map)

Reviews
Dr Super Good
Useful, feature filled, well documented and reasonably well written. Approved... There seems to be a lot of use of magic number constants which might effect maintainability. Additionally there is some hard coded inflexible logic which might effect...
  1. UmbraUnda

    UmbraUnda

    Joined:
    Mar 31, 2016
    Messages:
    605
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Nice, very useful. Works well for many instances. 5/5
     
  2. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,113
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Such a "WithinRange" submission is useful as standalone. And I would feel better, too, if it's looked at/judged seperatly, if it's used by this system.
     
  3. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,191
    Resources:
    16
    Tools:
    2
    Maps:
    2
    Spells:
    7
    Tutorials:
    4
    JASS:
    1
    Resources:
    16
    Good, WithinRange will be uploaded as standalone.
     
  4. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,379
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Useful, feature filled, well documented and reasonably well written. Approved...

    There seems to be a lot of use of magic number constants which might effect maintainability. Additionally there is some hard coded inflexible logic which might effect usability for some people.
     
  5. Hazop

    Hazop

    Joined:
    Jul 2, 2015
    Messages:
    738
    Resources:
    2
    Maps:
    2
    Resources:
    2
    What you mean by "Correct the Raw-Code inside the "ControlPoint"-Trigger"
     
  6. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,191
    Resources:
    16
    Tools:
    2
    Maps:
    2
    Spells:
    7
    Tutorials:
    4
    JASS:
    1
    Resources:
    16
    Object Editor gives each existing object (UnitType, itemType, ability...) a 4 sign number. When copying the Bar Unit into a map this number is not taken over, World Editor calculates a new one, which in almost any case differs from the one which is expected inside the jass code.

    Inside object Editor you can show raw codes of objects under the menu "view".

    then the name will be displayed in this style:

    'A000:Absk' (berserk2)
    unique id : orginal: (name)
    The first 4 signs are important.
    'A000' <- representing the wanted object​

    Inside the Jass Code you have to change the return value of the function "CaptureBarUnitType", seen below.
    Code (vJASS):

    //=========================================================================================================
    //       Definitions:
    //=========================================================================================================
    //Id of The Generic Bar Unit in Object Editor
    constant function CaptureBarUnitType takes nothing returns integer
       return 'h000'  <---- this value have to be the same as the number the bar unit inside your map got.
    endfunction
     
     
    Last edited: Feb 1, 2018
  7. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,191
    Resources:
    16
    Tools:
    2
    Maps:
    2
    Spells:
    7
    Tutorials:
    4
    JASS:
    1
    Resources:
    16
    Updated to V1.3.