[Log in / Register]
| News | Chat | Pastebin | Donations | Tutorials | Rules | Forums | Starcraft II |
| Maps | Skins | Icons | Models | Spells | Tools | Jass | Packs |
(Keeps Hive Alive)
Go Back   The Hive Workshop > Warcraft III Resources > JASS Functions

JASS Functions Approved JASS functions will be located here.
Remember to submit your own resources to the submission forum.

Reply
 
LinkBack (2) Thread Tools
Old 09-02-2009, 12:15 AM   2 links from elsewhere to this Post. Click to view. #1 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
[System]PT- 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.3
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 local
                GetLocalPlayer() but faster
            static player hidden
                HIDDEN_PLAYER_ID
===================================================================*/
    define private PLAYER_SLOTS = 12;
    define private TOTAL_SLOTS = 16;
    
    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 local() {
            return localPlayer
        }//end player operator local
        
        public static player operator hidden() {
            return players[HIDDEN_PLAYER_ID];
        }//end player operator hidden
    }//end struct Players
    
    define private REMOVE_UNITS = {
        private group removeUnitGroup = CreateGroup();
        private boolexpr removeUnits
    }//end define private REMOVE_UNITS
    
    #if REMOVE_UNITS_ON_INI_FOR_INACTIVE
        REMOVE_UNITS
    #elseif REMOVE_UNITS_ON_LEAVE
        REMOVE_UNITS
    #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 = TOTAL_SLOTS
            
            if (P_##PLAYER_TYPE.first.get == null) {//if empty
                P_##PLAYER_TYPE.first = WHICH_PLAYER_ID
                P_##PLAYER_TYPE.first.previous = TOTAL_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
    
    define REMOVE_UNITS_INI = {
        removeUnits = Condition(lambda bool() {
                RemoveUnit(GetFilterUnit());
                return false;
            });
    }
    
    private void Ini() {
        int i = 0
        
        humanLeaves = CreateTrigger()
        
        //do ini if either REMOVE_UNITS
        #if REMOVE_UNITS_ON_INI_FOR_INACTIVE
            REMOVE_UNITS_INI
        #elseif REMOVE_UNITS_ON_LEAVE
            REMOVE_UNITS_INI
        #endif

        //ini 0 through PLAYER_SLOTS - 1
        do {
            players[i] = Player(i)
            
            if (GetPlayerSlotState(players[i]) == PLAYER_SLOT_STATE_PLAYING) {
                #if TRACK_ACTIVE
                    ADD_TO_PLAYER_STRUCT(ActivePlayer, i)
                #endif
                
                if (GetPlayerController(players[i]) == MAP_CONTROL_USER) {
                    #if TRACK_HUMAN
                        ADD_TO_PLAYER_STRUCT(HumanPlayer, i)
                        
                        if (HumanPlayer.count > 1) {
                            TriggerRegisterPlayerEvent(humanLeaves, players[i], EVENT_PLAYER_LEAVE)
                        }//end if
                    #endif
                }//end if
                else {
                    #if TRACK_COMPUTER
                        ADD_TO_PLAYER_STRUCT(ComputerPlayer, i)
                    #endif
                }//end else
                
                isPlayerActive[i] = true
            }//end if
            else {
                #if REMOVE_UNITS_ON_INI_FOR_INACTIVE
                    GroupEnumUnitsOfPlayer(removeUnitGroup, players[i], removeUnits)
                #endif
                
                #if TRACK_INACTIVE
                    ADD_TO_PLAYER_STRUCT(InactivePlayer, i)
                #endif
            }//end else
        } whilenot ++i == PLAYER_SLOTS
        
        //ini PLAYER_SLOTS through TOTAL_SLOTS-1
        do {
            players[i] = Player(i)
        } whilenot ++i == TOTAL_SLOTS
        
        #if TRACK_HUMAN
            if (HumanPlayer.count > 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()
}

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'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), 'hpea', 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), 'hpea', 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), 'hpea', 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), 'hpea', 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'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 < 0 or i > EXT_PLAYER_COUNT then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "PlayerTracker Error: Player ID out of bounds!")
                return null
            endif
        endif
        return allPlayers[i]
    endfunction

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

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

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

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

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

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

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

    function GetInactivePlayerId takes integer i returns integer
        static if DEBUG_MODE then
            if i < 0 or i >= inactivePlayerCount then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "PlayerTracker Error: Inactive Player Index Value out of bounds!")
                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, "PlayerTracker Error: Invalid On Leave Code!")
                    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, "PlayerTracker Error: Invalid On Leave Code!")
                    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 < 0 or i > EXT_PLAYER_COUNT then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "PlayerTracker Error: Player Index Value out of bounds!")
                return false
            endif
        endif
        return not isInactivePlayer[i]
    endfunction

    function IsPlayerInactive takes integer i returns boolean
        static if DEBUG_MODE then
            if i < 0 or i > EXT_PLAYER_COUNT then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "PlayerTracker Error: Player Index Value out of bounds!")
                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, "You either have no humans left to remove or you passed in a null player!")
                return
            endif
        endif
        set curPlayer = playerToRemove
        set curPlayerId = GetPlayerId(curPlayer)
        set humanCount = humanCount - 1
        set activePlayerCount = activePlayerCount - 1
        if humanIndex[curPlayerId] <= humanCount then
            set humanIndexed[humanIndex[curPlayerId]] = humanCount
            set humanIndex[humanId[humanCount]] = humanIndex[curPlayerId]
        endif
        if activePlayerIndex[curPlayerId] <= 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, "You either have no computers left to remove or you passed in a null player!")
                return
            endif
        endif
        set curPlayer = playerToRemove
        set curPlayerId = GetPlayerId(curPlayer)
        set computerCount = computerCount - 1
        set activePlayerCount = activePlayerCount - 1
        if computerIndex[curPlayerId] < computerCount then
            set computerIndexed[computerIndex[curPlayerId]] = computerCount
            set computerIndex[computerId[computerCount]] = computerIndex[curPlayerId]
        endif
        if activePlayerIndex[curPlayerId] <= 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] <= humanCount then
                set humanIndexed[humanIndex[curPlayerId]] = humanCount
                set humanIndex[humanId[humanCount]] = humanIndex[curPlayerId]
            endif
            if activePlayerIndex[curPlayerId] <= 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 > 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

Last edited by Nestharus; 03-14-2010 at 03:18 AM.
Nestharus is offline   Reply With Quote
Old 09-02-2009, 06:57 AM   #2 (permalink)
Registered User Element of Water
He has beautiful eyes...
 
Element of Water's Avatar
 
Join Date: Aug 2008
Posts: 2,062
Element of Water is just really nice (284)Element of Water is just really nice (284)Element of Water is just really nice (284)Element of Water is just really nice (284)Element of Water is just really nice (284)
You don't need a force containing all the players - it already exists as native.

Any public names should be capitalised - it's convention.

The library names are too short and generic. Change please.

Other than that, it looks OK. A quite simple library, but useful nonetheless.
Element of Water is offline   Reply With Quote
Old 09-02-2009, 02:10 PM   #3 (permalink)
Registered User aznricepuff
OOP freak.
 
Join Date: Feb 2006
Posts: 751
aznricepuff is a jewel in the rough (181)aznricepuff is a jewel in the rough (181)
Former Staff Member: This user used to be on the Hive Workshop staff. 
I agree with EoW on the library names. Other than that I don't see any problems.
aznricepuff is offline   Reply With Quote
Old 09-02-2009, 11:36 PM   #4 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
Sure thing.. I'll add my customary N to the end of the libraries ^_^.
Nestharus is offline   Reply With Quote
Old 09-03-2009, 06:33 AM   #5 (permalink)
Registered User Element of Water
He has beautiful eyes...
 
Element of Water's Avatar
 
Join Date: Aug 2008
Posts: 2,062
Element of Water is just really nice (284)Element of Water is just really nice (284)Element of Water is just really nice (284)Element of Water is just really nice (284)Element of Water is just really nice (284)
Still quite short. What I meant was, call them PlayerTracking and HostTracking.
Element of Water is offline   Reply With Quote
Old 09-03-2009, 01:10 PM   #6 (permalink)
Registered User MapperMalte
MapperMalte
 
MapperMalte's Avatar
 
Join Date: Nov 2007
Posts: 368
MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)
Jass:
private function GetHost takes nothing returns player
    call StoreInteger(getTheHost, "missionKey", "key", GetPlayerId(GetLocalPlayer()) + 1)
    call TriggerSyncStart()
    call SyncStoredInteger(getTheHost, "missionKey", "key")
    call TriggerSyncReady()
    return Player(GetStoredInteger(getTheHost, "missionKey", "key") - 1)
endfunction

This function was stolen!
MapperMalte is offline   Reply With Quote
Old 09-03-2009, 07:19 PM   #7 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
Quote:
Originally Posted by MapperMalte View Post
Jass:
private function GetHost takes nothing returns player
    call StoreInteger(getTheHost, "missionKey", "key", GetPlayerId(GetLocalPlayer()) + 1)
    call TriggerSyncStart()
    call SyncStoredInteger(getTheHost, "missionKey", "key")
    call TriggerSyncReady()
    return Player(GetStoredInteger(getTheHost, "missionKey", "key") - 1)
endfunction

This function was stolen!
I actually wrote that myself mate -.-. Syncing data up between players is pretty common knowledge... someone used this technique to get the delay of players.
Nestharus is offline   Reply With Quote
Old 09-05-2009, 10:15 PM   #8 (permalink)
Registered User Yixx
Mag hier wel Nederlands?
 
Yixx's Avatar
 
Join Date: Oct 2008
Posts: 1,470
Yixx is just really nice (388)Yixx is just really nice (388)Yixx is just really nice (388)Yixx is just really nice (388)
Something that might be handy to add:
the GET_PLAYER, GET_COMPUTER and GET_ALL take the integer you assign to it, right? Make versions of those that take a player or global player Id (meaning the one generated by GetPlayerId()), because i might not have those integers somewhere where i actually do need this function. I know it seems unlikely but it shouldnt be hard and might actually come in hand i think. Or just GetPlayerCustomId or whatever that returns the ID you assigned to it.

for the rest, this seems like a nice system, good job.
__________________
You dont know me, so dont think you know who, what, how and why I am...
Yixx is offline   Reply With Quote
Old 09-05-2009, 10:40 PM   #9 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
Yixx, originally there were things in this for getting a player using an id... but there's already a native for that =).

If you're going to loop, then just use the regular player array. If you want to attach data to a player, use the player's id. When you are looping, do GetPlayerId(PTN_GET_PLAYER(x)) to access you arrays =).
Nestharus is offline   Reply With Quote
Old 09-05-2009, 11:00 PM   #10 (permalink)
Registered User MapperMalte
MapperMalte
 
MapperMalte's Avatar
 
Join Date: Nov 2007
Posts: 368
MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)
I've got a system that does pretty much the same thing, but is able to do more things (I didn't post it in forums, just use it for me and myself):
It is able to return the highest number of all players.
And it is able to return how many players are still playing.

You should add these things.
MapperMalte is offline   Reply With Quote
Old 09-05-2009, 11:33 PM   #11 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
Mine is also able to return how many players are playing and it can even get the highest player in the game (computer, player, or combination)

Quote:
Tracks player and computer players through out the game
The key words are through out, meaning the variables are updated during the game.
Jass:
PTN_GET_PLAYER_COUNT()
will always return the proper total count of all players =).

As for getting the highest player in the game, the player arrays in the background are indexed in the most efficient way meaning that the players get scrambled after one player leaves.

If you can come up with a really good reason, I'll add it in =). It'd only be 2 lines of code for lowest and biggest.
Nestharus is offline   Reply With Quote
Old 09-05-2009, 11:58 PM   #12 (permalink)
Registered User MapperMalte
MapperMalte
 
MapperMalte's Avatar
 
Join Date: Nov 2007
Posts: 368
MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)
Reason? Ok.
I want to do sth. for all players.
Player 4 left.
Player count is 5.
Highest Player number is 6.

So I loop to the highest ID, and it does everything correct.
I loop to the player count and player 6 isn't used.
MapperMalte is offline   Reply With Quote
Old 09-06-2009, 01:50 AM   #13 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
Fixed

loop
exitwhen x == PTN_GET_PLAYER_COUNT()
//do stuff
set x = x + 1
endloop

that should work now after players leave. The indexing was messed up for pointing the ids to the new index slots ^^.

Last edited by Nestharus; 09-06-2009 at 02:20 AM.
Nestharus is offline   Reply With Quote
Old 09-06-2009, 09:24 AM   #14 (permalink)
Registered User MapperMalte
MapperMalte
 
MapperMalte's Avatar
 
Join Date: Nov 2007
Posts: 368
MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)MapperMalte has little to show at this moment (29)
And what if sb wants to split up respoueces to all players and max player ID is 10, but 3 players play, really, you need two vars.
Also your function/variable naming is always horribly none-saying.
Please think clearly before starting to make a system, that really makes it less complicated and maybe it's designed better then.
This Is not bad, but I won't use it, because it's not very complex.
MapperMalte is offline   Reply With Quote
Old 09-06-2009, 07:45 PM   #15 (permalink)
Registered User Nestharus
User
 
Nestharus's Avatar
 
Join Date: Jul 2007
Posts: 427
Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)Nestharus has little to show at this moment (31)
You don't need a max player id... it's all indexed into an array...

PTN_GET_PLAYER(0)
PTN_GET_PLAYER(1)

Those aren't necessarily player 0 and player 1..

If you want to loop thru all players in the map, then just use 0 thru PTN_GET_PLAYER_COUNT()

if you want to get player via id, then use the GetPlayerId() native.

I don't know how you are using it, but GET_PLAYER does not take a player id =), it takes an internal index because it's kept sequential so that it can be used in loops. It's not meant to be used on specific players, it's meant to be used for all players =).

Again, there is absolutely no need for tracking the highest player id, lol...
Nestharus is offline   Reply With Quote
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


LinkBacks (?)
LinkBack to this Thread: http://www.hiveworkshop.com/forums/jass-functions-413/system-pt-player-tracking-142554/
Posted By For Type Date
Offering JASS Support Services This thread Refback 01-26-2010 01:50 AM
[System]Gcsn- Costs and States - Wc3C.net This thread Refback 09-03-2009 12:17 AM

Similar Threads
Thread Thread Starter Forum Replies Last Post
[Unsolved] how do you place a tracking becan qazsw World Editor Help Zone 3 05-04-2009 10:03 PM
Tracking targets with the cannon tower Discipline Modeling & Animation 5 04-07-2009 01:05 PM
[Unsolved] Follow the player spawn system? Bane World Editor Help Zone 5 03-26-2009 03:30 PM
[Trigger] boot player system PrisonLove Triggers & Scripts 10 07-22-2008 09:39 PM
Tracking assists on a hero kill The_Prophet Map Development 5 07-12-2005 06:57 PM

All times are GMT. The time now is 06:19 AM.






Hosting by SliceHost 
Powered by vBulletin®
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.1
Copyright©Ralle