System Player Tracking and Host Tracking Add-On

Nestharus

o-o
Reaction score
84
I fixed this up to all the specifications a long time ago..

When do you plan on ungraveyarding this??

Found one error- TriggerRegisterEvent on a trigger that doesn't exist o-o, which has been fixed. Also updated it to use the below. Build 5.2

While writing my JASS guide, I found this to be an interesting way to check to see if a player is in the game or not-
[ljass]if GetPlayerTeam(player) != -1 {}[/ljass]

It proved to be faster than the normal slot check method =). Once a player is verified with this method, the player owner will be checked and it'll be categorized into the utility =).

Benchmark Code
JASS:
include "cj_types.j"
include "cj_typesEx.j"
include "cj_print.j"
include "cj_types_priv.j"  
include "cj_typesEx_priv.j"
include "cj_order.j"  
include "cj_antibj_base.j"

scope Demo initializer Initialization {
    trigger t = CreateTrigger()
    event e = TriggerRegisterTimerEvent(t, 0, false)
    int sw, i = 5000; float mark
    
    bool Test() {
        sw = StopWatchCreate()
        do {
            if GetPlayerTeam(Player(0)) != -1 {} //.007
            //if GetPlayerSlotState(Player(0)) == PLAYER_SLOT_STATE_PLAYING {} //.011
        } whilenot --i == 0
        mark = StopWatchMark(sw)
        StopWatchDestroy(sw)
        printf(R2S(mark))
        return false
    }
    
    void Initialization() {
        TriggerAddCondition(t, Condition(function Test))
    }
}



Build 5.3 will be a cJASS implementation which will feature:
less of a code impact on the compiled map script


As for optimization, I will always continue to try and make this better. I am really unsure what else I can do though o-o.
 

Nestharus

o-o
Reaction score
84
Ok, after some twiddling, i've decided to do a cJASS version of this with added features-

JASS:
ploop(type, active, var) //type is computer, player, all
endploop


And it'd be used something like this-
JASS:
ploop(player, true, int p)
    CreateUnit(GetIndexedPlayer(p)), 'hpea', x, y, 270)
endploop


Also, I'm obviously adding tracking for inactive players (inactive doesn't matter on type ><).


After player tracking, I'll probably do team tracking.

Team tracking will make this stuff easy-
Easy management of all currently playing players (let's say you have people who are playing and people who are watching)

Easy management of players in a given match or w/e (let's say you have 2 people in each given match, 5 different types of matches, and 2 people in lobby or something)


Furthermore, it'll also include a tloop ^_^

JASS:
tloop(team, int p)
    GetPlayer(p) //spiffy
endtloop
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
[DEL]probably because its in cJASS?[/DEL]

EDIT: why don't we have strikethrough tags

EDIT2: Oh we do, ty azlier
 

Nestharus

o-o
Reaction score
84
Human: Human player
Computer: Computer player
Active Player: A player that is in the game, whether computer or human
Inactive Player: A player that isn't in the game, whether computer or human

I thought it was pretty straight forward ; ).

Oh yea, players can be made inactive without removing them from the game by using the inactive function or w/e ;p. Inactive players are permanently inactive, so only set if the game is 100% over for them = p.



I can be more clear if you like :)

Finally, hidden returns a player that isn't 0-11, an extra player ; ). It's actually Player 14.


On a side note, some of the internal updates-
Cleaner code
Faster Indexing
New features (obviously ;p)


Any other questions? : D
 

Jesus4Lyf

Good Idea™
Reaction score
397
>I can be more clear if you like
Yeah, that'd be great, it doesn't make sense...
I thought "active players" meant players who aren't AFK, and this Player Tracking meant tracking player's actions.

It was the logical conclusion from your documentation, which you still haven't updated.
JASS:

library PlayerTracker initializer Initialization
/*Utility Information
===================================================================
Name: Player
Version: 6.0
Author: Nestharus

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

Description:
    What it does-
        Tracks human, computer, active, and inactive players through out the game and
        allows you to iterate through them. 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. It also uses techniques that most people don&#039;t know
        about to further increase the speed.
        
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.
    
API
------------------------------------------------------------------
constant function GetHiddenPlayer takes nothing returns player
    Returns a hidden player with all player features working.
    
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 CreateUnit(GetHumanId(x), &#039;hpea&#039;, 0, 0, 270) //human 0 might be player 11
            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 CreateUnit(GetComputerId(x), &#039;hpea&#039;, 0, 0, 270) //computer 8 might be player 7
            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 CreateUnit(GetActivePlayerId(x), &#039;hpea&#039;, 0, 0, 270) //active player 4 might be player 0
            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 CreateUnit(GetInactivePlayerId(x), &#039;hpea&#039;, 0, 0, 270) //inactive player 0 might be player 1
            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 nothing
    Runs code whenever a human is removed or leaves the game.
    
function OnComputerLeave takes boolexpr onLeaveCode returns nothing
    Runs code whenever a computer is removed.
    
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.
===================================================================*/
 

Nestharus

o-o
Reaction score
84
Ok description updated.

I'll fix description on HiddenPlayer to explicitly say that it returns Player 14 when I get the chance : o.


Few things I probably need to fix in the cJASS version as well (just background cosmetics for readability and maintainability: no API changes or actual code changes).

Edit
Hidden player desc updated
 

Nestharus

o-o
Reaction score
84
cJASS version updated to 1.3

-Player(i) override definition fixed to single line method rather than multi line method.
 

Azlier

Old World Ghost
Reaction score
461
JASS:
int x = GetHumanCount()
loop
    set x = x - 1
    DisplayTextToPlayer(GetHuman(x), 0, 0, &quot;Hello there &quot; + GetPlayerName(GetHuman(x)))
    exitwhen x == 0
endloop


I don't think you know how to use vJass anymore.
 

Nestharus

o-o
Reaction score
84
JASS:
int x = GetHumanCount()
loop
    set x = x - 1
    DisplayTextToPlayer(GetHuman(x), 0, 0, &quot;Hello there &quot; + GetPlayerName(GetHuman(x)))
    exitwhen x == 0
endloop


I don't think you know how to use vJass anymore.

woops, thinks for spotting that in example mate ; )

I actually have to code vjass with cjass disabled as I end up doing that so often ><, lol. With cjass enabled, compiler doesn't catch it, but with it disabled I can go through and fix all the syntax ^_^.

I started doing this with arrays now too-
[ljass]int x[][/ljass]

lol
 

Nestharus

o-o
Reaction score
84
Updated to 7.3, 2.2/2.3-
Removed an extra trigger that was useless
Removed an extra useless function
Removed a few extra operations
Fixed a syntax error for vJASS version
Fixed 2 bugs for vJASS version (fixed it in cJASS long ago but forgot about doing it for vJASS).
Fixed a cJASS bug (missing if statement)

Documentation fix on two wrong examples will be done eventually
 

Nestharus

o-o
Reaction score
84
Updated to 2.4 and 7.4

Added 2 functions for removing code events, return triggercondition for adding code for events

Made cjass version auto include necessary files

Changed GetPlayerTeam method of player checking back to GetPlayerSlotState as GetPlayerTeam is very unstable ^_-.

Fixed documentation errors

So when can this get approved? I fixed every complaint every person had ;o...


For messing with groups of players, use Team Manager, which is only in cJASS but is being written for vJASS : ).


Possible update to 8.0/3.0-
Possibly move to a list array. This will allow iteration via .next and .previous. This will also keep players in order. The overhead is slightly bigger, but some people have wanted players to be kept in order ;o.

So in essence-
JASS:

active.next.previous = player.previous
active.previous.next = player.next
inactive.count.next = inactive.count++
inactive.count.previous = inactive.count-1
inactive.count.player = active
active = 0


So same amount of operations on removal of players
1 extra operation on add
faster iteration
maintains order

I think my mind is made up : ).

This will break backwards compatibility, but I'm already renown for that, so might as well keep it up, lol : D

Edit
Ok, starting on some major memory updates : )

edit
... well, static ifs are officially broken for me.. I've been trying to get them to work for hours, but they return things that are totally random..

and now sometimes i can put globals in static ifs and have them work properly, but sometimes I can't -.-... it's totally fritzed..

JASS:

constant boolean MY_BOOL = true
function blelah takes nothing returns nothing
static if MY_BOOL then
DISPLAY THIS ERROR DAMNIT
else
local integer x
endif
endfunction


It writes local integer x instead of DISPLAY THIS ERROR -.-...
 

Nestharus

o-o
Reaction score
84
cJASS Player Manager 3.0 (lib name changed)

includes-
Move from functions to struct arrays
Move from indexed arrays to linked lists

Much more maintainable code for my side ^_^. (-100+ lines of code)
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
this seems rather pointless, honestly lots of the functions provided only benefit seem to be "a slight speed increase"
 

Nestharus

o-o
Reaction score
84
It was primarily made for speed freaks, like me : P.

I got this sort of code all over my map ^^

JASS:

HumanPlayer i = HumanPlayer.first
do {
    //code
    i = i.next
} whilenot i.get == null
 

Nestharus

o-o
Reaction score
84
cJASS version is now at 3.3

There were a few bugs with auto kick on remove and running removal events =P.

All works now =)
 

Nestharus

o-o
Reaction score
84
cJASS now at 3.4 with the latest cJASS release.


I'd also like to take this moment to go over why to use the cJASS version over the vJASS version.

1. The cJASS version works off of linked lists for faster iteration speeds and each id on the list corresponds with the player id for random access

2. The cJASS version has way less global variables with the use of definitions and uses #ifs to remove more, thus increasing the speed of the map.

And that about sums it up ; ).


The last cJASS version just removed some extra code by using the || and && statement added to #ifs for cJASS. I also remember optimizing one specific mode by removing an else statement.

The vJASS version will probably never be updated to follow suit with the cJASS version as static ifs do not control the adding in of global variables. The cJASS version is also superior to the vJASS version.
 
General chit-chat
Help Users

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top