System Player Tracking and Host Tracking Add-On

Nestharus

o-o
Reaction score
84
Player Tracking

Host Tracking

cJASS overhaul done!

Read API to see all of the improved features and the move from indexed arrays to dequeues.

ploop was also removed.

cJASS
JASS:
include "cj_types.j" 

library PlayerManager initializer Ini {
/*===================================================================
Name: C Player Manager
Version: 3.4
Author: Nestharus

Settings:
*///===================================================================                   
    //remove all units owned by players not in map at ini
    define REMOVE_UNITS_ON_INI_FOR_INACTIVE = false
    
    //remove all units owned by player when that player leaves, done after event fire
    define REMOVE_UNITS_ON_LEAVE = false
    
    define TRACK_HUMAN = true
    define TRACK_COMPUTER = false
    define TRACK_ACTIVE = false
    define TRACK_INACTIVE = false
    
    define KICK_PLAYER_ON_REMOVE = true
    
    //fire events when a human leaves/removed
    define HUMAN_OUT_EVENT = true
    
    //fire events when a computer is removed
    define COMPUTER_OUT_EVENT = false
    
    //for use with GetHiddenPlayer
    //player 14 is suggested as it has bounty etc enabled
    define private HIDDEN_PLAYER_ID = 14
/*//===================================================================
    Player Manager keeps track of players in linked lists for easier traversal, faster loops, and less operations.
    It has 5 collections of players-
        HumanPlayer
            Has all active human players in the game in order
            
        ComputerPlayer
            Has all active computer players in the game in order
            
        ActivePlayer
            Has all active players in the game in order
            
        InactivePlayer
            Has all inactive players in the game in order
            
        Players
            Has all players in the game in order
            
    All collections are kept updated through out the game except for Players as it will always contain
    all players 0-15 within the game. All collections always maintain initial order.
    
    Example- 1, 3, 5, and 8 are active human players
            5 leaves
            1, 3, 8 would now be in human players in that order

    InactivePlayers are stored in the order of leaving players, so it's possible to see who
    left first and who left last.
    
    All functions and collections relating to specific features are only in the code if specified in settings.
    For this reason, all setting definitions that relates to code that might be removed are not private.
    To keep code from breaking and keep code efficient, use #if with the settings.
    
API-
    Structs:
        HumanPlayer, ComputerPlayer, ActivePlayer, InactivePlayer
        
            Propertiers:
                thistype first
                    First player (id)
                thistype last
                    Last player (id)
                thistype next
                    Next player (id)
                thistype previous
                    Previous player (id)
                player get
                    Get player (id). If get is null, player is not in the collection. This can happen
                    with id 0 a lot.
                static int count
                    Gets the total player count
                    
            Methods:
                HumanPlayer and ComputerPlayer only-
                
                void remove()
                    Removes player from the game
                    
                static triggercondition addOnOut(boolexpr c)
                    Adds boolexpr to player out trigger and returns the triggercondition
                
                static void removeOnOut(triggercondition c)
                    Removes triggercondition from player out trigger
                
        Players
            player get
                Gets the player handle
            bool active
                Is player active?
            static player lastRemoved
                Stores last removed player for event response
            static int lastRemovedId
                Stores the id of last removed player for event response
            static player getLocal
                GetLocalPlayer() but faster
            static player hidden
                HIDDEN_PLAYER_ID
===================================================================*/
    private player localPlayer
    private bool isPlayerActive[]
    private player lastRemovedPlayer = null
    private int lastRemovedPlayerId = 0
    private player players[]
    
    private trigger humanLeaves;
    
    define private REMOVE_PLAYER(PLAYER_TYPE, PLAYER_OUT_EVENT) = {
        public void remove() {
            #if KICK_PLAYER_ON_REMOVE
                RemovePlayer(.get, PLAYER_GAME_RESULT_DEFEAT)
                if (localPlayer == .get) {
                    EndGame(false)
                }
            #endif
            
            REMOVE_PLAYER(PLAYER_TYPE, .get, PLAYER_OUT_EVENT)
        }
    }

    define private PLAYER_STRUCT(PLAYER_TYPE) = {
        private struct P_##PLAYER_TYPE extends array {
            public static thistype first = 0
            public static thistype last = 0
            public static int count = 0
        
            public player get;
            public thistype next;
            public thistype previous;
        }//end struct P_##PLAYER_TYPE
    
        struct PLAYER_TYPE extends array {
            public player operator get() {
                return P_##PLAYER_TYPE[this].get;
            }//end operator getPlayer
            
            public static thistype operator first() {
                return P_##PLAYER_TYPE[this].first;
            }//end static operator first
            
            public static thistype operator last() {
                return P_##PLAYER_TYPE[this].last;
            }//end static operator last
            
            public static int operator count() {
                return P_##PLAYER_TYPE[this].count;
            }//end static operator count
            
            public thistype operator next() {
                return P_##PLAYER_TYPE[this].next;
            }//end operator next
            
            public thistype operator previous() {
                return P_##PLAYER_TYPE[this].previous;
            }//end operator previous
            
            #if PLAYER_TYPE == HumanPlayer
                REMOVE_PLAYER(PLAYER_TYPE, HUMAN_OUT_EVENT)
                
                #if HUMAN_OUT_EVENT
                    public static trigger out = CreateTrigger();
                    
                    public static triggercondition addOnOut(boolexpr c) {return TriggerAddCondition(out, c);}
                    public static void removeOnOut(triggercondition c) {TriggerRemoveCondition(out, c);}
                #endif
            #endif
            
            #if PLAYER_TYPE == ComputerPlayer
                REMOVE_PLAYER(PLAYER_TYPE, COMPUTER_OUT_EVENT)
                
                #if COMPUTER_OUT_EVENT
                    public static trigger out = CreateTrigger();
                    
                    public static triggercondition addOnOut(boolexpr c) {return TriggerAddCondition(out, c);}
                    public static void removeOnOut(triggercondition c) {TriggerRemoveCondition(out, c);}
                #endif
            #endif
        }//end struct Players
    }//end define PLAYER_STRUCT
    
    #if TRACK_HUMAN
        PLAYER_STRUCT(HumanPlayer);
    #endif
    
    #if TRACK_COMPUTER
        PLAYER_STRUCT(ComputerPlayer);
    #endif
    
    #if TRACK_ACTIVE
        PLAYER_STRUCT(ActivePlayer);
    #endif
    
    #if TRACK_INACTIVE
        PLAYER_STRUCT(InactivePlayer);
    #endif

    struct Players extends array {
        public player operator get() {
            return players[this]
        }//end player operator get()
        
        public bool operator active() {
            return isPlayerActive[this]
        }//end bool operator active
        
        public static player operator lastRemoved() {
            return lastRemovedPlayer
        }//end player operator lastRemoved
        
        public static int operator lastRemovedId() {
            return lastRemovedPlayerId
        }//end player operator lastRemovedId
        
        public static player operator getLocal() {
            return localPlayer
        }//end player operator local
        
        public static player operator hidden() {
            return players[HIDDEN_PLAYER_ID];
        }//end player operator hidden
    }//end struct Players
    
    #if REMOVE_UNITS_ON_INI_FOR_INACTIVE || REMOVE_UNITS_ON_LEAVE
        private group removeUnitGroup = CreateGroup();
        private boolexpr removeUnits
    #endif
    
    define private REMOVE_FROM_PLAYER_STRUCT(PLAYER_TYPE, WHICH_PLAYER_ID) = {
        //decrease count
            P_##PLAYER_TYPE.count--
            
            //remove from PLAYER_TYPE struct
            if (WHICH_PLAYER_ID == P_##PLAYER_TYPE.last) {
                P_##PLAYER_TYPE.last = P_##PLAYER_TYPE[WHICH_PLAYER_ID].previous
            }//end if
            if (WHICH_PLAYER_ID == P_##PLAYER_TYPE.first) {
                P_##PLAYER_TYPE.first = P_##PLAYER_TYPE[WHICH_PLAYER_ID].next
            }//end elseif
            
            P_##PLAYER_TYPE[WHICH_PLAYER_ID].next.previous = P_##PLAYER_TYPE[WHICH_PLAYER_ID].previous
            P_##PLAYER_TYPE[WHICH_PLAYER_ID].previous.next = P_##PLAYER_TYPE[WHICH_PLAYER_ID].next
            
            //set to null
            P_##PLAYER_TYPE[WHICH_PLAYER_ID].get = null
    }//end define REMOVE_FROM_PLAYER_STRUCT(PLAYER_TYPE, WHICH_PLAYER)
    
    define private ADD_TO_PLAYER_STRUCT(PLAYER_TYPE, WHICH_PLAYER_ID) = {
        //increase count
            P_##PLAYER_TYPE.count++
            
            //add to PLAYER_TYPE struct
            P_##PLAYER_TYPE.last.next = WHICH_PLAYER_ID
            P_##PLAYER_TYPE[WHICH_PLAYER_ID].previous = P_##PLAYER_TYPE.last
            P_##PLAYER_TYPE.last = WHICH_PLAYER_ID
            P_##PLAYER_TYPE.last.next = bj_MAX_PLAYER_SLOTS
            
            if (P_##PLAYER_TYPE.first.get == null) {//if empty
                P_##PLAYER_TYPE.first = WHICH_PLAYER_ID
                P_##PLAYER_TYPE.first.previous = bj_MAX_PLAYER_SLOTS
            }//if
            
            //set the get
            P_##PLAYER_TYPE[WHICH_PLAYER_ID].get = players[WHICH_PLAYER_ID]
    }//end define ADD_TO_PLAYER_STRUCT
    
    define private REMOVE_PLAYER(PLAYER_TYPE, WHICH_PLAYER, TRIGGER_CHECK) = {
        //update event variables
        lastRemovedPlayer = WHICH_PLAYER
        lastRemovedPlayerId = GetPlayerId(lastRemovedPlayer)
        
        if (isPlayerActive[lastRemovedPlayerId]) {//if the player is active
            //remove player from specific player struct
            #if PLAYER_TYPE == HumanPlayer //human
                #if TRACK_HUMAN
                    REMOVE_FROM_PLAYER_STRUCT(PLAYER_TYPE, lastRemovedPlayerId)
                #endif
            #else //computer
                #if TRACK_COMPUTER
                    REMOVE_FROM_PLAYER_STRUCT(PLAYER_TYPE, lastRemovedPlayerId)
                #endif
            #endif
            
            //remove from actives
            #if TRACK_ACTIVE
                REMOVE_FROM_PLAYER_STRUCT(ActivePlayer, lastRemovedPlayerId)
            #endif
            
            //add to inactives
            #if TRACK_INACTIVE
                ADD_TO_PLAYER_STRUCT(InactivePlayer, lastRemovedPlayerId)
            #endif
            
            //set active to false
            isPlayerActive[lastRemovedPlayerId] = false
            
            //fire trigger
            #if TRIGGER_CHECK
                TriggerEvaluate(PLAYER_TYPE.out)
            #endif
            
            //remove units on leave
            #if REMOVE_UNITS_ON_LEAVE
                GroupEnumUnitsOfPlayer(removeUnitGroup, lastRemovedPlayer, removeUnits)
            #endif
        }//end if
    }//end define REMOVE_PLAYER
    
    private void Ini() {
        int i = 0
        
        humanLeaves = CreateTrigger()
        
        //do ini if either REMOVE_UNITS
        #if REMOVE_UNITS_ON_INI_FOR_INACTIVE || REMOVE_UNITS_ON_LEAVE
            removeUnits = Condition(lambda bool() {
                RemoveUnit(GetFilterUnit())
                return false
            })
        #endif

        //ini 0 through bj_MAX_PLAYERS - 1
        do {
            players<i> = Player(i)
            
            if (GetPlayerSlotState(players<i>) == PLAYER_SLOT_STATE_PLAYING) then
                #if TRACK_ACTIVE
                    ADD_TO_PLAYER_STRUCT(ActivePlayer, i)
                #endif
                
                if (GetPlayerController(players<i>) == MAP_CONTROL_USER) then
                    #if TRACK_HUMAN
                        ADD_TO_PLAYER_STRUCT(HumanPlayer, i)
                        
                        if (HumanPlayer.count &gt; 1) {
                            TriggerRegisterPlayerEvent(humanLeaves, players<i>, EVENT_PLAYER_LEAVE)
                        }//end if
                    #endif
                    
                    #if TRACK_COMPUTER
                        else
                            ADD_TO_PLAYER_STRUCT(ComputerPlayer, i)
                    #endif
                endif
                
                isPlayerActive<i> = true
                
                #if REMOVE_UNITS_ON_INI_FOR_INACTIVE || TRACK_INACTIVE
                    else
                        #if REMOVE_UNITS_ON_INI_FOR_INACTIVE
                            GroupEnumUnitsOfPlayer(removeUnitGroup, players<i>, removeUnits)
                        #endif
                        
                        #if TRACK_INACTIVE
                            ADD_TO_PLAYER_STRUCT(InactivePlayer, i)
                        #endif
                #endif
            endif
        } whilenot ++i == bj_MAX_PLAYERS
        
        //ini bj_MAX_PLAYERS through bj_MAX_PLAYER_SLOTS-1
        do {
            players<i> = Player(i)
        } whilenot ++i == bj_MAX_PLAYER_SLOTS
        
        #if TRACK_HUMAN
            if (HumanPlayer.count &gt; 1) {
                TriggerRegisterPlayerEvent(humanLeaves, HumanPlayer.first.get, EVENT_PLAYER_LEAVE)
                TriggerAddCondition(humanLeaves, Condition(lambda bool() {
                    REMOVE_PLAYER(HumanPlayer, GetTriggerPlayer(), HUMAN_OUT_EVENT)
                    return false
                }))
            }//end if
            else {
                DestroyTrigger(humanLeaves)
                humanLeaves = null
            }//else
        #endif
        localPlayer = GetLocalPlayer()
    }//end function Ini()
}
</i></i></i></i></i></i></i>


vJASS
JASS:
library PlayerTracker initializer Initialization
/*V Player Tracker
Version: 7.4
Author: Nestharus
CTRL+F =================================================================== to jump category

Settings:
*///===================================================================
globals
    private constant boolean REMOVE_UNITS = false
    private constant boolean REMOVE_UNITS_LEAVE = false
    private constant boolean INACTIVE_PLAYER = false
    private constant boolean ON_HUMAN_LEAVE = true
    private constant boolean ON_COMPUTER_LEAVE = true
endglobals/*//

Description
===================================================================
    Tracks human, computer, active, and inactive players through out the game and
    allows you to iterate through them.

    Human players are people playing the map
    Computer players are computers in the map
    Active Players are all players 0-11 that are in the map
    Inactive Players are all players 0-11 that aren&#039;t in the map

    Leaving players are moved from active to inactive etc and all the collections of players
    are kept updated through the game.

    For example, if you want to run AI for all computer players, you can cycle through them without having to
    filter out human players. It does the indexing, cycling, and set up as fast
    and efficiently as possible.

Requirements: NA

Installation: NA

Variable Settings
===================================================================
-REMOVE_UNITS
    refers to whether or not units should be removed if a player is in the map.

-REMOVE_UNITS_LEAVE
    refers to whether or not units should be removed if a player leaves the game
    or is removed from the game by force.

-INACTIVE_PLAYER
    refers to whether or not inactive players should be tracked.

-ON_HUMAN_LEAVE
    will run a trigger whenever a human leaves or is removed
    Allows use of OnPlayerLeave function

-ON_COMPUTER_LEAVE
    will run a trigger whenever a computer leaves or is removed
    Allows use of OnComputerLeave function

API
===================================================================
constant function GetHiddenPlayer takes nothing returns player
    Returns player 14, which has all features (bounty etc) working. Useful for temporary
    player operations where a dummy player is needed.

constant function GetHumanCount takes nothing returns integer
    Returns a count of all humans. This will not return the index
    for the last human player, but rather the index+1

    example-
        local integer i = GetHumanCount()-1

constant function GetComputerCount takes nothing returns integer
    Returns a count of all computers. This will not return the index
    for the last computer player, but rather the index+1

    example-
        local integer i = GetComputerCount()-1

constant function GetActivePlayerCount takes nothing returns integer
    Returns a count of all active players. This will not return the index
    for the last active player, but rather the index+1

    example-
        local integer i = GetActivePlayerCount()-1

constant function GetInactivePlayerCount takes nothing returns integer
    Returns a count of all inactive players. This will not return the index
    for the last inactive player, but rather the index+1

    example-
        local integer i = GetInactivePlayerCount()-1

function GetPlayer takes integer i returns player
    Returns a player given an id. Exactly like the Player() native, but
    slightly faster.

    example-
        local player p = GetPlayer(0)

function GetHuman takes integer i returns player
    Returns a human player given an indexed id. The indexed ids
    do not refer to the player ids and the order is not maintained.
    This is used for iteration.

    example-
        local integer x = GetHumanCount()
        loop
            set x = x -1
            call CreateUnit(GetHuman(x), &#039;hpea&#039;, 0, 0, 270) //human 0 might be player 11
            exitwhen x == 0
        endloop
        
function GetComputer takes integer i returns player
    Returns a computer player given an indexed id. The indexed ids
    do not refer to the player ids and the order is not maintained.
    This is used for iteration.

    example-
        local integer x = GetComputerCount()
        loop
            set x = x -1
            call CreateUnit(GetComputer(x), &#039;hpea&#039;, 0, 0, 270) //computer 0 might be player 3
            exitwhen x == 0
        endloop

function GetActivePlayer takes integer i returns player
    Returns an active player player given an indexed id. The indexed ids
    do not refer to the player ids and the order is not maintained.
    This is used for iteration.

    example-
        local integer x = GetActivePlayerCount()
        loop
            set x = x -1
            call CreateUnit(GetActivePlayer(x), &#039;hpea&#039;, 0, 0, 270) //active player 0 might be player 6
            exitwhen x == 0
        endloop

function GetInactivePlayer takes integer i returns player
    Returns an inactive player given an indexed id. The indexed ids
    do not refer to the player ids and the order is not maintained.
    This is used for iteration.

    example-
        local integer x = GetInactivePlayerCount()
        loop
            set x = x -1
            call CreateUnit(GetInactivePlayer(x), &#039;hpea&#039;, 0, 0, 270) //inactive player 0 might be player 4
            exitwhen x == 0
        endloop

function GetHumanId takes integer i returns integer
    Returns a player id given an indexed human id. The indexed ids do
    not refer to the player ids and order is not maintainted.
    This is used for iteration

    example-
        local integer x = GetHumanCount()
        loop
            set x = x -1
            call DisplayTextToPlayer(GetLocalHuman(), 0, 0, I2S(GetHumanId(x)))
            exitwhen x == 0
        endloop

function GetComputerId takes integer i returns integer
    Returns a player id given an indexed computer id. The indexed ids do
    not refer to the player ids and order is not maintainted.
    This is used for iteration

    example-
        local integer x = GetComputerCount()
        loop
            set x = x -1
            call DisplayTextToPlayer(GetLocalHuman(), 0, 0, I2S(GetComputerId(x)))
            exitwhen x == 0
        endloop

function GetActivePlayerId takes integer i returns integer
    Returns a player id given an indexed active player id. The indexed ids do
    not refer to the player ids and order is not maintainted.
    This is used for iteration

    example-
        local integer x = GetActivePlayerCount()
        loop
            set x = x -1
            call DisplayTextToPlayer(GetLocalHuman(), 0, 0, I2S(GetActivePlayerId(x)))
            exitwhen x == 0
        endloop

function GetInactivePlayerId takes integer i returns integer
    Returns a player id given an indexed inactive player id. The indexed ids do
    not refer to the player ids and order is not maintainted.
    This is used for iteration

    example-
        local integer x = GetInactivePlayerCount()
        loop
            set x = x -1
            call DisplayTextToPlayer(GetLocalHuman(), 0, 0, I2S(GetInactivePlayerId(x)))
            exitwhen x == 0
        endloop

function IsPlayerActive takes integer i returns boolean
    Checks to see whether or not a player is active given a player id

function IsPlayerInactive takes integer i returns boolean
    Checks to see whether or not a player is inactive given a player id

function OnHumanLeave takes boolexpr onLeaveCode returns triggercondition
    Runs code whenever a human is removed or leaves the game.

function RemoveOnHumanLeave takes triggercondition c returns nothing
    Removes code to be run when a human leaves.

function OnComputerLeave takes boolexpr onLeaveCode returns triggercondition
    Runs code whenever a computer is removed.
    
function RemoveOnComputerLeave takes triggercondition c returns nothing
    Removes code to be run when a computer leaves.

function RemoveHuman takes player playerToRemove returns nothing
    Forcefully deactivates a human player. Will not remove that player from the game.

function RemoveComputer takes player playerToRemove returns nothing
    Forcefully deactivates a computer player. Computer players can&#039;t be removed from the game.

constant function GetRemovedPlayer takes nothing returns player
    Gets the last removed player

constant function GetLocalHuman takes nothing returns player
    Exactly like GetLocalPlayer() but slightly faster.
===================================================================*/
    globals
        private constant integer PLAYER_SLOT_COUNT = 12
        private constant integer SLOT_COUNT = 16
        private constant integer SLOT_START = 0
        private constant integer PLAYER_COUNT = 11
        private constant integer EXT_PLAYER_COUNT = 15
        private constant integer HIDDEN_PLAYER_ID = 14

        private player array human[PLAYER_SLOT_COUNT]
        private integer array humanId[PLAYER_SLOT_COUNT]
        private integer array humanIndex[PLAYER_SLOT_COUNT]
        private integer array humanIndexed[PLAYER_SLOT_COUNT]
        private integer humanCount = SLOT_START

        private player array computer[PLAYER_SLOT_COUNT]
        private integer array computerId[PLAYER_SLOT_COUNT]
        private integer array computerIndex[PLAYER_SLOT_COUNT]
        private integer array computerIndexed[PLAYER_SLOT_COUNT]
        private integer computerCount = SLOT_START

        private player array allPlayers[SLOT_COUNT]
        private integer allPlayersCount = SLOT_START

        private player array activePlayer[PLAYER_SLOT_COUNT]
        private integer array activePlayerId[PLAYER_SLOT_COUNT]
        private integer array activePlayerIndex[PLAYER_SLOT_COUNT]
        private integer array activePlayerIndexed[PLAYER_SLOT_COUNT]
        private integer activePlayerCount = SLOT_START

        private player array inactivePlayer[SLOT_COUNT]
        private integer array inactivePlayerId[SLOT_COUNT]
        private integer inactivePlayerCount = SLOT_START

        private boolean array isInactivePlayer[PLAYER_SLOT_COUNT]

        private player localPlayer

        private trigger humanLeaves = CreateTrigger()

        private trigger onHumanLeave
        private trigger onComputerLeave

        private group removeUnitGroup

        private boolexpr removeUnits

        private integer i

        private player curPlayer
        private integer curPlayerId
    endglobals

    constant function GetRemovedPlayer takes nothing returns player
        return curPlayer
    endfunction

    constant function GetLocalHuman takes nothing returns player
        return localPlayer
    endfunction

    constant function GetHiddenPlayer takes nothing returns player
        return allPlayers[HIDDEN_PLAYER_ID]
    endfunction

    constant function GetHumanCount takes nothing returns integer
        return humanCount
    endfunction

    constant function GetComputerCount takes nothing returns integer
        return computerCount
    endfunction

    constant function GetActivePlayerCount takes nothing returns integer
        return activePlayerCount
    endfunction

    constant function GetInactivePlayerCount takes nothing returns integer
        return inactivePlayerCount
    endfunction

    function GetPlayer takes integer i returns player
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt; EXT_PLAYER_COUNT then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Player ID out of bounds!&quot;)
                return null
            endif
        endif
        return allPlayers<i>
    endfunction

    function GetHuman takes integer i returns player
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= humanCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Human Index Value out of bounds!&quot;)
                return null
            endif
        endif
        return human[humanIndexed<i>]
    endfunction

    function GetComputer takes integer i returns player
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= computerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Computer Index Value out of bounds!&quot;)
                return null
            endif
        endif
        return computer[computerIndexed<i>]
    endfunction

    function GetActivePlayer takes integer i returns player
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= activePlayerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Active Player Index Value out of bounds!&quot;)
                return null
            endif
        endif
        return activePlayer[activePlayerIndexed<i>]
    endfunction

    function GetInactivePlayer takes integer i returns player
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= inactivePlayerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Inactive Player Index Value out of bounds!&quot;)
                return null
            endif
        endif
        return inactivePlayer<i>
    endfunction

    function GetHumanId takes integer i returns integer
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= humanCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Human Index Value out of bounds!&quot;)
                return 0
            endif
        endif
        return humanId[humanIndexed<i>]
    endfunction

    function GetComputerId takes integer i returns integer
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= computerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Computer Index Value out of bounds!&quot;)
                return 0
            endif
        endif
        return computerId[computerIndexed<i>]
    endfunction

    function GetActivePlayerId takes integer i returns integer
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= activePlayerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Active Player Index Value out of bounds!&quot;)
                return 0
            endif
        endif
        return activePlayerId[activePlayerIndexed<i>]
    endfunction

    function GetInactivePlayerId takes integer i returns integer
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt;= inactivePlayerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Inactive Player Index Value out of bounds!&quot;)
                return 0
            endif
        endif
        return inactivePlayerId<i>
    endfunction
    
    function RemoveOnHumanLeave takes triggercondition c returns nothing
        static if ON_HUMAN_LEAVE then
            call TriggerRemoveCondition(onHumanLeave, c)
        endif
    endfunction
    
    function RemoveOnComputerLeave takes triggercondition c returns nothing
        static if ON_COMPUTER_LEAVE then
            call TriggerRemoveCondition(onComputerLeave, c)
        endif
    endfunction

    function OnHumanLeave takes boolexpr onLeaveCode returns triggercondition
        static if ON_HUMAN_LEAVE then
            static if DEBUG_MODE then
                if onLeaveCode == null then
                    call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Invalid On Leave Code!&quot;)
                    return null
                endif
            endif
            return TriggerAddCondition(onHumanLeave, onLeaveCode)
        else
            return null
        endif
    endfunction

    function OnComputerLeave takes boolexpr onLeaveCode returns triggercondition
        static if ON_COMPUTER_LEAVE then
            static if DEBUG_MODE then
                if onLeaveCode == null then
                    call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Invalid On Leave Code!&quot;)
                    return null
                endif
            endif
            return TriggerAddCondition(onComputerLeave, onLeaveCode)
        else
            return null
        endif
    endfunction

    function IsPlayerActive takes integer i returns boolean
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt; EXT_PLAYER_COUNT then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Player Index Value out of bounds!&quot;)
                return false
            endif
        endif
        return not isInactivePlayer<i>
    endfunction

    function IsPlayerInactive takes integer i returns boolean
        static if DEBUG_MODE then
            if i &lt; 0 or i &gt; EXT_PLAYER_COUNT then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;PlayerTracker Error: Player Index Value out of bounds!&quot;)
                return false
            endif
        endif
        return isInactivePlayer<i>
    endfunction

    private function RemoveUnits takes nothing returns boolean
        call RemoveUnit(GetFilterUnit())
        return false
    endfunction

    function RemoveHuman takes player playerToRemove returns nothing
        static if DEBUG_MODE then
            if playerToRemove == null or humanCount == 0 then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;You either have no humans left to remove or you passed in a null player!&quot;)
                return
            endif
        endif
        set curPlayer = playerToRemove
        set curPlayerId = GetPlayerId(curPlayer)
        set humanCount = humanCount - 1
        set activePlayerCount = activePlayerCount - 1
        if humanIndex[curPlayerId] &lt;= humanCount then
            set humanIndexed[humanIndex[curPlayerId]] = humanCount
            set humanIndex[humanId[humanCount]] = humanIndex[curPlayerId]
        endif
        if activePlayerIndex[curPlayerId] &lt;= activePlayerCount then
            set activePlayerIndexed[activePlayerIndex[curPlayerId]] = activePlayerCount
            set activePlayerIndex[activePlayerId[activePlayerCount]] = activePlayerIndex[curPlayerId]
        endif
        set isInactivePlayer[curPlayerId] = true
        static if INACTIVE_PLAYER then
            set inactivePlayer[inactivePlayerCount] = allPlayers<i>
            set inactivePlayerId[inactivePlayerCount] = i
            set inactivePlayerCount = inactivePlayerCount + 1
        endif
        static if ON_HUMAN_LEAVE then
            call TriggerEvaluate(onHumanLeave)
        endif
        static if REMOVE_UNITS_LEAVE then
            call GroupEnumUnitsOfPlayer(removeUnitGroup, curPlayer, removeUnits)
        endif
    endfunction

    function RemoveComputer takes player playerToRemove returns nothing
        static if DEBUG_MODE then
            if playerToRemove == null or computerCount == 0 then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;You either have no computers left to remove or you passed in a null player!&quot;)
                return
            endif
        endif
        set curPlayer = playerToRemove
        set curPlayerId = GetPlayerId(curPlayer)
        set computerCount = computerCount - 1
        set activePlayerCount = activePlayerCount - 1
        if computerIndex[curPlayerId] &lt; computerCount then
            set computerIndexed[computerIndex[curPlayerId]] = computerCount
            set computerIndex[computerId[computerCount]] = computerIndex[curPlayerId]
        endif
        if activePlayerIndex[curPlayerId] &lt;= activePlayerCount then
            set activePlayerIndexed[activePlayerIndex[curPlayerId]] = activePlayerCount
            set activePlayerIndex[activePlayerId[activePlayerCount]] = activePlayerIndex[curPlayerId]
        endif
        set isInactivePlayer[curPlayerId] = true
        static if INACTIVE_PLAYER then
            set inactivePlayer[inactivePlayerCount] = allPlayers<i>
            set inactivePlayerId[inactivePlayerCount] = i
            set inactivePlayerCount = inactivePlayerCount + 1
        endif
        static if ON_COMPUTER_LEAVE then
            call TriggerEvaluate(onComputerLeave)
        endif
        static if REMOVE_UNITS_LEAVE then
            call GroupEnumUnitsOfPlayer(removeUnitGroup, curPlayer, removeUnits)
        endif
    endfunction

    private function HumanLeaves takes nothing returns boolean
        set curPlayer = GetTriggerPlayer()
        set curPlayerId = GetPlayerId(curPlayer)
        if not isInactivePlayer[curPlayerId] then
            set humanCount = humanCount - 1
            set activePlayerCount = activePlayerCount - 1
            if humanIndex[curPlayerId] &lt;= humanCount then
                set humanIndexed[humanIndex[curPlayerId]] = humanCount
                set humanIndex[humanId[humanCount]] = humanIndex[curPlayerId]
            endif
            if activePlayerIndex[curPlayerId] &lt;= activePlayerCount then
                set activePlayerIndexed[activePlayerIndex[curPlayerId]] = activePlayerCount
                set activePlayerIndex[activePlayerId[activePlayerCount]] = activePlayerIndex[curPlayerId]
            endif
            set isInactivePlayer[curPlayerId] = true
            static if INACTIVE_PLAYER then
                set inactivePlayer[inactivePlayerCount] = allPlayers<i>
                set inactivePlayerId[inactivePlayerCount] = i
                set inactivePlayerCount = inactivePlayerCount + 1
            endif
            static if ON_HUMAN_LEAVE then
                call TriggerEvaluate(onHumanLeave)
            endif
            static if REMOVE_UNITS_LEAVE then
                call GroupEnumUnitsOfPlayer(removeUnitGroup, curPlayer, removeUnits)
            endif
        endif
        return false
    endfunction

    private function Initialization takes nothing returns nothing
        static if ON_HUMAN_LEAVE then
            set onHumanLeave = CreateTrigger()
        endif
        static if ON_COMPUTER_LEAVE then
            set onComputerLeave = CreateTrigger()
        endif
        static if REMOVE_UNITS then
            set removeUnitGroup = CreateGroup()
        elseif REMOVE_UNITS_LEAVE then
            set removeUnitGroup = CreateGroup()
        endif
        set i = EXT_PLAYER_COUNT
        static if REMOVE_UNITS then
            set removeUnits = Condition(function RemoveUnits)
        else
            static if REMOVE_UNITS_LEAVE then
                set removeUnits = Condition(function RemoveUnits)
            endif
        endif
        loop
            set allPlayers<i> = Player(i)
            set i = i - 1
            exitwhen i == PLAYER_COUNT
        endloop
        loop
            set allPlayers<i> = Player(i)
            if GetPlayerSlotState(allPlayers<i>) == PLAYER_SLOT_STATE_PLAYING then
                set activePlayerIndex<i> = activePlayerCount
                set activePlayerIndexed[activePlayerCount] = activePlayerCount
                set activePlayer[activePlayerCount] = allPlayers<i>
                set activePlayerId[activePlayerCount] = i
                if GetPlayerController(activePlayer[activePlayerCount]) == MAP_CONTROL_USER then
                    set humanIndex<i> = humanCount
                    set humanIndexed[humanCount] = humanCount
                    set human[humanCount] = activePlayer[activePlayerCount]
                    set humanId[humanCount] = i
                    if humanCount != 0 then
                        call TriggerRegisterPlayerEvent(humanLeaves, human[humanCount], EVENT_PLAYER_LEAVE)
                    endif
                    set humanCount = humanCount + 1
                else
                    set computerIndex<i> = computerCount
                    set computerIndexed[computerCount] = computerCount
                    set computer[computerCount] = activePlayer[activePlayerCount]
                    set computerId[computerCount] = i
                    set computerCount = computerCount + 1
                endif
                set activePlayerCount = activePlayerCount + 1
            else
                set isInactivePlayer<i> = true
                static if REMOVE_UNITS then
                    call GroupEnumUnitsOfPlayer(removeUnitGroup, allPlayers<i>, removeUnits)
                endif
                static if INACTIVE_PLAYER then
                    set inactivePlayer[inactivePlayerCount] = allPlayers<i>
                    set inactivePlayerId[inactivePlayerCount] = i
                    set inactivePlayerCount = inactivePlayerCount + 1
                endif
            endif
            exitwhen i == 0
            set i = i - 1
        endloop
        if humanCount &gt; 1 then
            call TriggerRegisterPlayerEvent(humanLeaves, human[0], EVENT_PLAYER_LEAVE)
            call TriggerAddCondition(humanLeaves, Condition(function HumanLeaves))
        else
            call DestroyTrigger(humanLeaves)
        endif
        set humanLeaves = null
        set localPlayer = GetLocalPlayer()
    endfunction
endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
 

Romek

Super Moderator
Reaction score
963
I've noticed you do this an awful lot in your systems/snippets; You do realise you can declare more than one globals block. There's no need for those fugly textmacros, honestly.

JASS:
.
        call ForGroup(unitGroup, function RemoveUnits)
        call GroupClear(unitGroup)

First of Group loop, no?

> real MFN_PLUGIN_HOST_PL_16_newHostT_521 = -1
I hope you were OK whilst typing that.

Anyway, as the globals are all public, I'd appreciate if you could use some decent naming convention.
Preferably capitalize the first letter of each word, and only use ALL_CAPS for constant variables.
 

Nestharus

o-o
Reaction score
84
Ah, originally the all cap'd variables were constant and uhm, forgot to lowercase them =O.

The text macros are so that they can be contained in the library, I just try to keep it so that people aren't in the library at all ^_^. I know that globals can be declared more than once : ).

real MFN_PLUGIN_HOST_PL_16_newHostT_521 = -1

So it doesn't conflict with anything at all ^_^.
 

Romek

Super Moderator
Reaction score
963
> So it doesn't conflict with anything at all ^_^.
A private variable is the clearer way of achieving the same thing.
 

Nestharus

o-o
Reaction score
84
I have to use it as a string and .name only works on functions : (, so it has to be regular : \.
 

Romek

Super Moderator
Reaction score
963
> I have to use it as a string and .name only works on functions : (, so it has to be regular : \.
...And..?
JASS:
globals
   private constant real SOME_VARIABLE = -1
endglobals

//
local string s = SCOPE_PRIVATE + &quot;SOME_VARIABLE&quot;
 

Jesus4Lyf

Good Idea™
Reaction score
397
I am solidly of the opinion that forces should not exist in any JASS code (until I find an exception).

PlayerTracking is a poorly encapsulated library that consists of blatantly obvious code (but it uses forces to do it for some reason) and Host relies on this poor encapsulation to achieve something that can be natively handled, and otherwise provides functionality which has been commonly done for a long period of time, and once again is also poorly encapsulated.

Graveyarded!
But if you fix up all your encapsulation/interface issues, we can use this perhaps.
 

Nestharus

o-o
Reaction score
84
Updated to 3.0 with a nicer looking API and a little bit more efficient =).

No longer requires BoolExprUtils
 

Azlier

Old World Ghost
Reaction score
461
I would still like to see a struct interface. I actually like those (while lots of people don't).

>Updated to 3.0 with a nicer looking API and a little bit more efficient =).

Gee, I wonder who could've motivated you to do that.
 

Nestharus

o-o
Reaction score
84
All right then...

How is this for a possible update?

This is the best I can do. The variable are put into global blocks to maintain privacy : \. If they went into the structs, they'd have to be public for the entire system to access them ><.
JASS:
library PTN initializer Initialization
/*Utility Information
===================================================================
Name: Player
Version: 3.1
Author: Nestharus

Settings:
*///===================================================================
globals
    private constant boolean REMOVE_UNITS = true
    private constant boolean REMOVE_UNITS_LEAVE = false
endglobals
/*//===================================================================

Description: 
    What it does-
        Tracks player and computer players through out the game
        
    How it does it-
        Stores all player players into a player array, all computer players into
        a computer array, and both of them combined into an all array. It keeps the
        array indexed and updated through out the game by removing leaving/defeated
        players. The final index is used as a total count.

Requirements: NA

Installation: NA

Usage:
------------------------------------------------------------------
-REMOVE_UNITS- refers to whether or not units should be removed 
 if a player is in the map.

-REMOVE_UNITS_LEAVE- refers to whether or not units should be 
 removed if a player leaves.
 
-Players.get(i), Computers.get(i), All.get(i) returns player
    will return a value from the player array, computer array, or all array
    using internal indexes. This is useful for loops.

-Players.count(), Computers.count(), All.count()
    returns a count of how many playing, computer, or all players there are.
    
-Players.onLeave(boolexpr), Computers.onLeave(boolexpr), All.onLeave(boolexpr)
    will add code to the onLeave event. This should be used instead of your own
    triggers unless you only want to register a specific player.
 
 local integer x = Players.count()-1
 loop
    call CreateUnit(Players.get(x), &#039;hpea&#039;, 0, 0, 270)
    set x = x -1
    exitwhen x == 0
 endloop
===================================================================*/
    globals
        private player array players[12]
        private integer array playerID[12]
        private integer playerCount = 0
        
        private boolean array isPlayer

        private player array computers[12]
        private integer array computerID[12]
        private integer computerCount = 0

        private player array all[12]
        private integer array allID[12]
        private integer allCount = 0
        
        private trigger playerLeaves = CreateTrigger()
        private trigger computerLeaves = CreateTrigger()
        private trigger leaves = CreateTrigger()
        
        private boolean playerTrigger = false
        private boolean computerTrigger = false
        
        private group unitGroup = CreateGroup()
        
        private boolexpr removeUnit
    endglobals
    
    struct Players extends array
        public static method get takes integer i returns player
            return players<i>
        endmethod
        
        public static method count takes nothing returns integer
            return playerCount
        endmethod
        
        public static method onLeave takes boolexpr onLeaveCode returns nothing
            call TriggerAddCondition(playerLeaves, onLeaveCode)
            set playerTrigger = true
        endmethod
    endstruct
    
    struct Computers extends array
        public static method get takes integer i returns player
            return computers<i>
        endmethod
        
        public static method count takes nothing returns integer
            return computerCount
        endmethod
        
        public static method onLeave takes boolexpr onLeaveCode returns nothing
            call TriggerAddCondition(computerLeaves, onLeaveCode)
            set computerTrigger = true
        endmethod
    endstruct
    
    struct All extends array
        public static method get takes integer i returns player
            return all<i>
        endmethod
        
        public static method count takes nothing returns integer
            return allCount
        endmethod
        
        public static method onLeave takes boolexpr onLeaveCode returns nothing
            call TriggerAddCondition(leaves, onLeaveCode)
        endmethod
    endstruct

    private function RemoveUnits takes nothing returns boolean
        call RemoveUnit(GetFilterUnit())
        return false
    endfunction
    
    private function ComputerLeave takes nothing returns boolean
        return false
    endfunction
    
    private function Leaves takes nothing returns boolean
        local player p = GetFilterPlayer()
        local integer pID = GetPlayerId(p)
        set allCount = allCount - 1
        if allID[pID] &lt; allCount then
            set all[allID[pID]] = all[allCount]
            set allID[GetPlayerId(all[allCount])] = allID[pID]
        endif
        set allID[pID] = -1
        set all[allCount] = null
        if isPlayer[pID] then
            set playerCount = playerCount - 1
                if playerID[pID] &lt; playerCount then
                set players[playerID[pID]] = players[playerCount]
                set playerID[GetPlayerId(players[playerCount])] = playerID[pID]
            endif
            if playerTrigger then
                call TriggerEvaluate(playerLeaves)
            endif
            set playerID[pID] = -1
            set players[playerCount] = null
        else
            set computerCount = computerCount - 1
                if computerID[pID] &lt; computerCount then
                set computers[computerID[pID]] = computers[computerCount]
                set computerID[GetPlayerId(computers[computerCount])] = computerID[pID]
            endif
            if computerTrigger then
                call TriggerEvaluate(computerLeaves)
            endif
            set computerID[pID] = -1
            set computers[computerCount] = null
        endif
        if REMOVE_UNITS_LEAVE == true then
            call GroupEnumUnitsOfPlayer(unitGroup, p, removeUnit)
        endif
        return false
    endfunction
    
    private function Initialization takes nothing returns nothing
        local integer x = 11
        local player p
        local mapcontrol mapControl
        set removeUnit = Condition(function RemoveUnits)
        loop
            set p = Player(x)
            if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
                set mapControl = GetPlayerController(p)
                if mapControl == MAP_CONTROL_USER then
                    set players[playerCount] = p
                    set playerID[x] = playerCount
                    set playerCount = playerCount + 1
                    set isPlayer[x] = true
                elseif mapControl == MAP_CONTROL_COMPUTER then
                    set computers[computerCount] = p
                    set computerID[x] = computerCount
                    set computerCount = computerCount + 1
                endif
                set all[allCount] = p
                set allID[x] = allCount
                set allCount = allCount + 1
                call TriggerRegisterPlayerEvent(leaves, p, EVENT_PLAYER_LEAVE)
            elseif REMOVE_UNITS == true then
                call GroupEnumUnitsOfPlayer(unitGroup, p, removeUnit)
            endif
            set x = x - 1
            exitwhen x &lt; 0
        endloop
        call TriggerAddCondition(leaves, Condition(function Leaves))
    endfunction
endlibrary
</i></i></i>


Optional Host
JASS:
/*Plugin Information
===================================================================
Name: Host
Version: 3.0
Author: Nestharus

Description:
    What it does-
        Tracks the host through out the game
        
    How it does it-
        Adds a host variable for player tracking and gives a new host event
        for when the host changes. The host is kept updated through out the
        game.

Requirements: Player

Installation: NA

Usage:
------------------------------------------------------------------
-Host.get()
 always refers to the latest host.

-host.triggerRegisterEvent takes trigger t returns integer
    will make the trigger fire whenever the host changes. Does not
    fire upon host initialization. The integer returned is an internal
    trigger event id used to remove the trigger when desired.
 
-Host.triggerRemoveEvent(id)
    will remove the unregister the trigger associated with the id
===================================================================*/

library HTN initializer Initialization requires PTN
    globals
        private player host
        private gamecache getTheHost
        private trigger array hostTrig
        private integer hostTrigIndex = 0
    endglobals
    
    struct Host extends array
        public static method triggerRegisterEvent takes trigger t returns integer
            set hostTrig[hostTrigIndex] = t
            set hostTrigIndex = hostTrigIndex + 1
            return hostTrigIndex-1
        endmethod
        
        public static method triggerRemoveEvent takes integer i returns nothing
            set hostTrigIndex = hostTrigIndex - 1
            set hostTrig<i> = hostTrig[hostTrigIndex]
            set hostTrig[hostTrigIndex] = null
        endmethod
        
        public static method get takes nothing returns player
            return host
        endmethod
    endstruct
    
    private function GetTheHost takes nothing returns player
        call StoreInteger(getTheHost, &quot;missionKey&quot;, &quot;key&quot;, GetPlayerId(GetLocalPlayer()) + 1)
        call TriggerSyncStart()
        call SyncStoredInteger(getTheHost, &quot;missionKey&quot;, &quot;key&quot;)
        call TriggerSyncReady()
        return Player(GetStoredInteger(getTheHost, &quot;missionKey&quot;, &quot;key&quot;) - 1)
    endfunction
    
    private function UpdateHost takes nothing returns boolean
        local integer x = 0
        if GetTriggerPlayer() == host then
            set host = GetTheHost()
            loop
                exitwhen x == hostTrigIndex
                call TriggerExecute(hostTrig[x])
                set x = x + 1
            endloop
        endif
        return false
    endfunction
    
    private function Initialization takes nothing returns nothing
        if Players.count() &gt; 1 then
            call Players.onLeave(Condition(function UpdateHost))
            set getTheHost = InitGameCache(&quot;HOST&quot;)
            set host = GetTheHost()
        endif
    endfunction
endlibrary
</i>
 

Azlier

Old World Ghost
Reaction score
461
Ow. That's not what I meant by struct interface.

Doesn't matter to me, but I like to contain as much stuff as possible into one main struct. The only thing I don't keep in the struct is event responses.
 

Nestharus

o-o
Reaction score
84
No way to put them into 3 main structs ^_^.

I could put them into a struct called Ptn or w/e, but I couldn't do a main Players as that'd be weird =P.

Players.getPlayer
Players.getComputer

yeaa.. =P.
 

Azlier

Old World Ghost
Reaction score
461
I say this is good enough. It has a sane interface, no requirements.

GetPlayer is totally obsolete, if you grab this.
 

Nestharus

o-o
Reaction score
84
Actually, this doesn't use player ids to get players, so something like GetPlayer would not be obsolete as it's purpose is to retrieve players via an array and not thru the Player native. However, I could add that in =).

Also, I saved this and the functions weren't inlining =(. I don't know what's going on /cry.

Although, I'm not sure an array look-up would be faster than the native =), especially considering that many of the constant variables in JASS are slower than the native counterparts-
[ljass]constant alliancetype ALLIANCE_SHARED_SPELLS=ConvertAllianceType(4)[/ljass]

ConvertAllianceType(4) is faster than ALLIANCE_SHARED_SPELLS

so... Player(4) should in technicality be faster than a variable counterpart. Then again, the speed differences were tested on an older patch =).
 

Azlier

Old World Ghost
Reaction score
461
Wait, GetPlayer is working differently here? Oh, it does. Well, I hate that. :p

>ConvertAllianceType(4) is faster than ALLIANCE_SHARED_SPELLS
...How? Who benchmarked that?

ConvertAllianceType actually is native I2H. I would think the constant to be faster.
 

Nestharus

o-o
Reaction score
84
Updated for this-
GetIndexedPlayer() for looping
GetPlayer() to access array

>ConvertAllianceType(4) is faster than ALLIANCE_SHARED_SPELLS
...How? Who benchmarked that?

ConvertAllianceType actually is native I2H. I would think the constant to be faster.

That's exactly what I would think. It was in a guide for optimizing code that I read a long long time ago.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Your host finding method bugs.

Use this instead?

The lowest GetDelay shall be the host. :D

Edit:
It was in a guide for optimizing code that I read a long long time ago.
>ConvertAllianceType(4) is faster than ALLIANCE_SHARED_SPELLS
Benchmark it.
I won't believe the one who said Bit Streams is fast without evidence. ;)

And I sure as hell won't believe some optimisation guide without evidence (since when does that count as an authority?).

And the only thing that classifies as "evidence" is a benchmark result including code for the public to reproduce the test, for that specific native call and var.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top