System UserData

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
This system is mostly a wrapper for the native Player, while maybe you don't think its a big deal, this system will completely change the way you program in vJass in scopes or other systems.
When your code is optimized, you will take full advantage of this system.

What this system does:
  • It is a wrapper for most common player related natives.
  • Player Color Id and Slot Id compatible.
  • Access to player related data like a colored player name ( and a lot more ) in a flash.
  • Easy access to the person who's hosting the game.
  • RGB integers compatible, with either Player Color Id or Slot Id.

I've tested around with the FindHost method, and it seems to work perfectly in mid game. Its automatically updated so you don't have to worry about it.
I'd suggest taking a look at the example script before looking at the system.
It may profide you with some information on howto use this it, but what is shown there is just a small portion of what this system can do!

Goto www.clanbom.com for future updates/plugins for this system.

The System
JASS:
library UserData
    scope ReadMe
        //**************************
        //* UserData
        //* ¯¯¯¯¯¯¯¯
        //* Author  : Themis@Azeroth, StealthOfKing@Azeroth.
        //* URL     : <a href="http://www.clanbom.com" target="_blank" class="link link--external" rel="nofollow ugc noopener">www.clanbom.com</a>
        //* Credits : Required.
        //* Date    : Thursday, 8 January, 2009
        //* 
        //* The struct UserData holds values of players that can be used globaly in any map.
        //* Instead of calling the good old natives like &quot;Player&quot; always return the same value.
        //* If you look at the system you will see a lot of globals and methods, these are all
        //*  inlined in your code if you&#039;re using vexorians optimizer so the speed of this script
        //*  will increase, while your way of programming is changed completely.
        //* No more messing with indexes of player values, most values you need are in global 
        //*  variables so no more inefficient scripts!
        //* 
        //* This system is designed to keep track of the players original color.
        //* For example, if I&#039;m first in the game lobby my Player() index would be 0 (red).
        //* However if I can choose my player color ( for example orange ) my index would still
        //*  be 0 but my username in color should change from red to orange.
        //* This system is desinged to fix that issue for you, so even with my index as 0 my
        //*  color would be orange, not only for the hex string but for the rgb color aswell.
        //* RGB can be used for unit vertex color, minimap ping colors, lightning colors, with
        //*  this system keeping track of the player data, making scripts was never so easy!
        //*                                                ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
        //****************************************************************************************************************
    endscope
    
    scope Configuration
        globals
            constant integer USERDATA_HOST_DEFAULT_ID      = 0
            constant boolean USERDATA_HOST_USE_FINDHOST    = true
            constant string  USERDATA_HEX_STRING           = &quot;FF02020041FF1BE6D8530080FFFC00FE890D1FBF00E55AAF9495967DBEF10F61454D2903272727272727272727272727&quot;
            constant string  USERDATA_RGB_R_STRING         = &quot;255000027083255254031229148125015077039039039039&quot;
            constant string  USERDATA_RGB_G_STRING         = &quot;002065230000252137191090149190097041039039039039&quot;
            constant string  USERDATA_RGB_B_STRING         = &quot;002255184128000013000175150241069003039039039039&quot;
            constant string  USERDATA_NAMES_STRING         = &quot;redbluetealpurpleyelloworangegreenpinkgraylight bluedark greenbrown&quot;
            constant string  USERDATA_NAMES_FILTER         = &quot;030711172329343842526267&quot;
        endglobals
    endscope
    
    struct user extends array
        
        static trigger         eventUpdate   = CreateTrigger()
        static gamecache       findHostCache = null
        
        static player          localPlayer
        static user            localUser
        public boolean         isLocal
        static user            host
        
        public player          p
        public integer         cid
        public string          name
        public race            specie
        public playercolor     color
        public string          colorName
        public string          hex
        public string          hexName
        public string          hexColorName
        public integer         rgbRed
        public integer         rgbGreen
        public integer         rgbBlue
        
        public mapcontrol      controller
        public playerslotstate slotState
        

     /////////////////////////////
     // Private Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods are used within the system and do not concern you.
     // Don&#039;t though them unless you know what you&#039;re doing.
      //
        private static method h2i takes handle h returns integer
            return h
            return 0
        endmethod
        private method getHex takes nothing returns string
            return &quot;|cff&quot; + SubString( USERDATA_HEX_STRING, this * 6, ( this * 6 ) + 6 )
        endmethod
        private method getColorRgb takes string s returns integer
            return S2I( SubString( s, this * 3, ( this * 3 ) + 3 ) )
        endmethod
        private method getColorName takes nothing returns string
            return SubString( USERDATA_NAMES_STRING, S2I( SubString( USERDATA_NAMES_FILTER, (this * 2) - 2, (this * 2) ) ), S2I( SubString( USERDATA_NAMES_FILTER, (this * 2), (this * 2) + 2 ) ) )
        endmethod
        private static method findHost takes nothing returns user
            local integer array count
            local user          syncedPlayer = 0
            local user          tempPlayer   = 0
            
            if not USERDATA_HOST_USE_FINDHOST then
                return USERDATA_HOST_DEFAULT_ID
            endif
            loop
               exitwhen tempPlayer &gt;= 12
               set tempPlayer:count = 0
               set tempPlayer = tempPlayer + 1
            endloop
            loop
               exitwhen tempPlayer &lt;= 0
               call StoreInteger( .findHostCache, &quot;find&quot;, &quot;host&quot;, .localUser + 1 ) 
               call TriggerSyncStart()
               call SyncStoredInteger( .findHostCache, &quot;find&quot;, &quot;host&quot; )
               call TriggerSyncReady()
               set syncedPlayer = GetStoredInteger( .findHostCache, &quot;find&quot;, &quot;host&quot; ) - 1
               set syncedPlayer:count = syncedPlayer:count + 1
               set tempPlayer = tempPlayer - 1
            endloop
            set syncedPlayer = 0
            loop
               exitwhen tempPlayer &gt;= 12
               if syncedPlayer:count &lt; tempPlayer:count then
                  set syncedPlayer = tempPlayer
               endif
               set tempPlayer = tempPlayer + 1
            endloop
            return syncedPlayer
        endmethod

        
     /////////////////////////////
     // Fetching The User Type
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // A more simplified way to retrieve the user data of a player.
      //
        static method getTriggerUser takes nothing returns user
            return GetPlayerId( GetTriggerPlayer() )
        endmethod
        static method getFilterUser takes nothing returns user
            return GetPlayerId( GetFilterPlayer() )
        endmethod
        static method getItemUser takes item i returns user
            return GetPlayerId( GetItemPlayer( i ) )
        endmethod
        static method getOwningUser takes unit u returns user
            return GetPlayerId( GetOwningPlayer( u ) )
        endmethod
        static method getEventDetectingUser takes nothing returns user
            return GetPlayerId( GetEventDetectingPlayer() )
        endmethod

        
     /////////////////////////////
     // Display Game Messages
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Display text to a player, or display them to all using the local player 
     //  variable inside this library.
      //
        method displayText takes string s returns nothing
            call DisplayTextToPlayer( .p, 0, 0, s )
        endmethod
        method displayTextEx takes real x, real y, string s returns nothing
            call DisplayTextToPlayer( .p, x, y, s ) 
        endmethod
        method displayTimedText takes string s, real duration returns nothing
            call DisplayTimedTextToPlayer( .p, 0, 0, duration, s )
        endmethod
        method displayTimedTextEx takes real x, real y, string s, real duration returns nothing
            call DisplayTimedTextToPlayer( .p, x, y, duration, s )
        endmethod


     /////////////////////////////
     // Set Player Values
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Methods that set player values to their new value.
     // Don&#039;t forget to use the user[0].update() method if you change values that
     //  that are stored in the variables.
     // This is updated on certain events only, but if you set a new player 
     //  name update it manually.
      //
        method setAlliance takes user u, alliancetype setting, boolean value returns nothing
            call SetPlayerAlliance( .p, u.p, setting, value )
        endmethod
        method setColor takes playercolor c returns nothing
            call SetPlayerColor( .p, c )
        endmethod
        method setController takes mapcontrol controller returns nothing
            call SetPlayerController( .p, controller )
        endmethod
        method setHandicap takes real value returns nothing
            call SetPlayerHandicap( .p, value )
        endmethod
        method setHandicapXP takes real value returns nothing
            call SetPlayerHandicapXP( .p, value )
        endmethod
        method setName takes string name returns nothing
            call SetPlayerName( .p, name )
        endmethod
        method setRacePreference takes racepreference preference returns nothing
            call SetPlayerRacePreference( .p, preference )
        endmethod
        method setState takes playerstate state, integer value returns nothing
            call SetPlayerState( .p, state, value )
        endmethod
        method setTaxRate takes user u, playerstate state, integer rate returns nothing
            call SetPlayerTaxRate( .p, u.p, state, rate )
        endmethod
        
        
     /////////////////////////////
     // Get Player Values
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Some methods like getting the players name are not in this list.
     // Use the variable for that, its more efficient.
      //
        method getAlliance takes user u, alliancetype setting returns boolean
            return GetPlayerAlliance( .p, u.p, setting )
        endmethod
        method getColor takes nothing returns playercolor
            return GetPlayerColor( .p )
        endmethod
        method getController takes nothing returns mapcontrol
            return GetPlayerController( .p )
        endmethod
        method getHandicap takes nothing returns real
            return GetPlayerHandicap( .p )
        endmethod        
        method getHandicapXP takes nothing returns real
            return GetPlayerHandicapXP( .p )
        endmethod 
        method getName takes nothing returns string
            return GetPlayerName( .p )
        endmethod
        method getRace takes nothing returns race
            return GetPlayerRace( .p )
        endmethod
        method getScore takes playerscore score returns integer
            return GetPlayerScore( .p, score )
        endmethod
        method getSlotState takes nothing returns playerslotstate
            return GetPlayerSlotState( .p )
        endmethod
        method getState takes playerstate state returns integer
            return GetPlayerState( .p, state )
        endmethod
        method getStructureCount takes boolean includeIncomplete returns integer
            return GetPlayerStructureCount( .p, includeIncomplete )
        endmethod
        method getTaxRate takes user u, playerstate state returns integer
            return GetPlayerTaxRate( .p, u.p, state )
        endmethod
        method getTypedUnitCount takes string unitName, boolean includeIncomplete, boolean includeUpgrades returns integer
            return GetPlayerTypedUnitCount( .p, unitName, includeIncomplete, includeUpgrades )
        endmethod
        method getUnitCount takes boolean includeIncomplete returns integer
            return GetPlayerUnitCount( .p, includeIncomplete )
        endmethod

        
     /////////////////////////////
     // Player ID values
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Need player values by their true slot ID, use these methods.
     // UserData profides you only with variable indexes that match the player
     //  color, so using these methods allow you access their default values.
     // Still, they are depriciated and you shouldn&#039;t use them.
      //
        method getIdHex takes nothing returns string
            return .getHex()
        endmethod
        method getIdHexName takes nothing returns string
            return .getHex() + .getName() + &quot;|r&quot;
        endmethod
        method getIdColorName takes nothing returns string
            return .getColorName()
        endmethod
        method getIdHexColorName takes nothing returns string
            return .getHex() + .getColorName() + &quot;|r&quot;
        endmethod
        method getIdRgbRed takes nothing returns integer
            return .getColorRgb( USERDATA_RGB_R_STRING )
        endmethod
        method getIdRgbGreen takes nothing returns integer
            return .getColorRgb( USERDATA_RGB_G_STRING )
        endmethod
        method getIdRgbBlue takes nothing returns integer
            return .getColorRgb( USERDATA_RGB_B_STRING )
        endmethod
        
        
     /////////////////////////////
     // Is Checks
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods profide an easy boolean check for players.
     // From slotstates to controller to race checks, and other
     //  stuff all made easy.
      //
        method isHost takes nothing returns boolean
            return this == user.host
        endmethod
        method isUser takes nothing returns boolean
            return .controller == MAP_CONTROL_USER
        endmethod
        method isComputer takes nothing returns boolean
            return .controller == MAP_CONTROL_COMPUTER
        endmethod
        method isCreep takes nothing returns boolean
            return .controller == MAP_CONTROL_CREEP
        endmethod
        method isNeutral takes nothing returns boolean
            return .controller == MAP_CONTROL_NEUTRAL
        endmethod
        method isNone takes nothing returns boolean
            return .controller == MAP_CONTROL_NONE
        endmethod
        method isRescuable takes nothing returns boolean
            return .controller == MAP_CONTROL_RESCUABLE
        endmethod
        method isPlaying takes nothing returns boolean
            return .slotState == PLAYER_SLOT_STATE_PLAYING
        endmethod
        method isLeaver takes nothing returns boolean
            return .slotState == PLAYER_SLOT_STATE_LEFT
        endmethod
        method isEmpty takes nothing returns boolean
            return .slotState == PLAYER_SLOT_STATE_EMPTY
        endmethod
        method isPlayingUser takes nothing returns boolean
            return .isUser() and .isPlaying()
        endmethod
        method isUserAlly takes user u returns boolean
            return IsPlayerAlly( .p, u.p )
        endmethod
        method isUserEnemy takes user u returns boolean
            return IsPlayerEnemy( .p, u.p )
        endmethod
        method isInForce takes force whichForce returns boolean
            return IsPlayerInForce( .p, whichForce )
        endmethod
        method isObserver takes nothing returns boolean
            return IsPlayerObserver( .p )
        endmethod
        method isRace takes race whichRace returns boolean
            return .specie == whichRace
        endmethod
        method isRacePrefSet takes racepreference pref returns boolean
            return IsPlayerRacePrefSet( .p, pref )
        endmethod
        method isUnitOwner takes unit whichUnit returns boolean
            return IsUnitOwnedByPlayer( whichUnit, .p )
        endmethod
        method isUnitAlly takes unit whichUnit returns boolean
            return IsUnitAlly( whichUnit, .p )
        endmethod
        method isUnitEnemy takes unit whichUnit returns boolean
            return IsUnitEnemy( whichUnit, .p )
        endmethod    
        method isUnitVisible takes unit whichUnit returns boolean
            return IsUnitVisible( whichUnit, .p )
        endmethod  
        method isUnitDetected takes unit whichUnit returns boolean
            return IsUnitDetected( whichUnit, .p )
        endmethod   
        method isUnitInvisible takes unit whichUnit returns boolean
            return IsUnitInvisible( whichUnit, .p )
        endmethod  
        method isUnitFogged takes unit whichUnit returns boolean
            return IsUnitFogged( whichUnit, .p )
        endmethod       
        method isUnitMasked takes unit whichUnit returns boolean
            return IsUnitMasked( whichUnit, .p )
        endmethod     
        method isUnitSelected takes unit whichUnit returns boolean
            return IsUnitSelected( whichUnit, .p )
        endmethod   
        method isVisible takes real x, real y returns boolean
            return IsVisibleToPlayer( x, y, .p )
        endmethod
        method isFogged takes real x, real y returns boolean
            return IsFoggedToPlayer( x, y, .p )
        endmethod
        method isMasked takes real x, real y returns boolean
            return IsMaskedToPlayer( x, y, .p )
        endmethod


     /////////////////////////////
     // Force Related Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods profide an easy call to a force related native.
     // You are not forced to use them, but just like the event registering
     //  it can make it easier to do things.
      //
        method forceAdd takes force whichForce returns nothing
            call ForceAddPlayer( whichForce, .p )
        endmethod
        method forceRemove takes force whichForce returns nothing
            call ForceRemovePlayer( whichForce, .p )
        endmethod
        method forceEnumAllies takes force whichForce, boolexpr filter returns nothing
            call ForceEnumAllies( whichForce, .p, filter )
        endmethod
        method forceEnumEnemies takes force whichForce, boolexpr filter returns nothing
            call ForceEnumEnemies( whichForce, .p, filter )
        endmethod
        
     /////////////////////////////
     // Unit Related Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods profide an easy call to a unit related native.
     // You are not forced to use them, but just like the event registering
     //  it can make it easier to do things.
      //
        method createUnit takes integer id, real x, real y, real face returns unit
            return CreateUnit( .p, id, x, y, face )
        endmethod
        method createCorpse takes integer id, real x, real y, real face returns unit
            return CreateCorpse( .p, id, x, y, face )
        endmethod
        method groupEnumUnits takes group whichGroup, boolexpr filter returns nothing
            call GroupEnumUnitsOfPlayer( whichGroup, .p, filter )
        endmethod

        
     /////////////////////////////
     // Other Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods are uncatagorized, just look at the method
     //  name and see what it does.
      //
        method addState takes playerstate state, integer value returns nothing
            call SetPlayerState( .p, state, GetPlayerState( .p, state ) + value )
        endmethod
        method dialogDisplay takes dialog whichDialog, boolean flag returns nothing
            call DialogDisplay( .p, whichDialog, flag )
        endmethod
    
        
     /////////////////////////////
     // Registering Player Events
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Registering player events made easy.
      //
        method registerEvent takes trigger t, playerevent e returns event
            return TriggerRegisterPlayerEvent( t, .p, e )
        endmethod
        method registerChatEvent takes trigger t, string message, boolean exactMatch returns event
            return TriggerRegisterPlayerChatEvent( t, .p, message, exactMatch )
        endmethod
        method registerAllianceChange takes trigger t, alliancetype a returns event
            return TriggerRegisterPlayerAllianceChange( t, .p, a )
        endmethod
        method registerStateEvent takes trigger t, playerstate state, limitop opcode, real limitval returns event
            return TriggerRegisterPlayerStateEvent( t, .p, state, opcode, limitval )
        endmethod
        method registerUnitEvent takes trigger t, playerunitevent e, boolexpr filter returns event
            return TriggerRegisterPlayerUnitEvent( t, .p, e, filter )
        endmethod
        
        
     /////////////////////////////
     // Update Player Data
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Important if you use some set methods, otherwise obeselete.
      //
        method update takes nothing returns nothing
            set .controller     = .getController()
            set .slotState      = .getSlotState()
            
            if .color != .getColor() or .name != .getName() then
                set .name           = .getName()
                set .color          = .getColor()
                set .cid             = user.h2i( .color )
                
                set .colorName      = user[.cid].getColorName()
                set .hex            = user[.cid].getHex()
                set .hexName        =           .hex + .name + &quot;|r&quot;
                set .hexColorName   =           .hex + .colorName + &quot;|r&quot;
                set .rgbRed         = user[.cid].getColorRgb( USERDATA_RGB_R_STRING )
                set .rgbGreen       = user[.cid].getColorRgb( USERDATA_RGB_G_STRING )
                set .rgbBlue        = user[.cid].getColorRgb( USERDATA_RGB_B_STRING )
            endif
            
            if .isHost() then
                set .host = .findHost()
            endif
        endmethod
        private static method onEventUpdate takes nothing returns nothing
            call .getTriggerUser().update()
        endmethod

        
     /////////////////////////////
     // UserData Plugin System
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // The UserData library supports plugins that could extend the use of it.
     // Instead of making a wide complicated system and give support for
     //  everything, people have the option to use a plugin or not.
     // Run the plugin textmacro for the UserData library here.
      //
        
        
     /////////////////////////////
     // The onInit method
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // This is were the magic happens.
      //        
        private static method onInit takes nothing returns nothing
            local user    u = 0

            set .findHostCache     = InitGameCache( &quot;findHost.w3v&quot; )     
            set .localPlayer       = GetLocalPlayer()
            set .localUser         = GetPlayerId( .localPlayer )
            set .localUser.isLocal = true
            set .host              = .findHost()
            
            loop
                exitwhen integer( u ) &gt; 15
                
                set u.p      = Player( u )
                set u.specie = GetPlayerRace( u.p )
                
                call u.update()
                
                if u.isPlayingUser() then
                    call u.registerEvent( .eventUpdate, EVENT_PLAYER_LEAVE )
                endif
                
                set u = u + 1
            endloop

            call TriggerAddAction( .eventUpdate, function user.onEventUpdate )
        endmethod

    endstruct

endlibrary


Example Code
JASS:
scope UserDataExample initializer init
    
    function actions takes nothing returns nothing
        local user dying   = user.getOwningUser( GetDyingUnit() )
        local user killer  = user.getOwningUser( GetKillingUnit() )
        
        // What if the player is killing his own units...
        if dying == killer then
            return
        endif
        
        // Display Messages to the triggering players.
        call dying.displayText( &quot;Your unit was kiled by one of &quot; + killer.hexName + &quot;&#039;s units.&quot; )
        call killer.displayText( &quot;You killed &quot; + dying.hexName + &quot;&#039;s unit for an aditional 10 gold bonus!&quot; )
        call killer.addState( PLAYER_STATE_RESOURCE_GOLD, 10 )
        
        if dying.isLocal or killer.isLocal then
            // Exit the code for the people who were battling against each other..
            return
        endif
        
        // Ping the minimap in the colors of the triggering players..
        call PingMinimapEx( GetUnitX( GetDyingUnit() ), GetUnitY( GetDyingUnit() ), 10, dying.rgbRed, dying.rgbGreen, dying.rgbBlue, false ) 
        call PingMinimapEx( GetUnitX( GetKillingUnit() ), GetUnitY( GetKillingUnit() ), 10, killer.rgbRed, killer.rgbGreen, killer.rgbBlue, true ) 
        
        // Display messages to the players that must know their was an epic battle..
        // Since the triggering users already exited the function, this doesn&#039;t count for them.
        call user.localUser.displayText( killer.hexName + &quot; has killed &quot; + dying.hexName + &quot;&#039;s unit!&quot; )
    endfunction
    
    function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local user    u = 0
        
        loop
            exitwhen integer( u ) &gt; 11
            
            call u.registerUnitEvent( t, EVENT_PLAYER_UNIT_DEATH, null )
            set u = u + 1
        endloop
        
        call TriggerAddAction( t, function actions )
        
        set t = null
    endfunction

endscope
 

UndeadDragon

Super Moderator
Reaction score
447
It sounds/looks really useful. I haven't had time to look through the system code yet, but I like the looks of it.
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
It does not just extend player function, it replaces most of them with very efficient coding.
With this, you don't have to worry about the player ID, or Player Color ID.
Since this struct extends an array, you have the option of using arrays but it build so you don't have to use them.

JASS:
    local user u = 6

    call user[4].displayText( &quot;Send a message to Player(4) almost like the the old fashion way&quot; )
    call u.displayText( &quot;Display a message to Player(6) the newer way&quot; )
    call user.host.displayText( &quot;Display a message to the host the newer way&quot; )
    call user.localUser.displayText( &quot;Display a message to all players with their own colored &quot; + user.localUser.hexName )
    call user.localUser.displayText( I2S( user.localUser ) + &quot; is the player ID of the local user&quot; ) // Meaning message displays their player ID to every player
    call u.displayText( &quot;According to the slot ID, I should appear colored in&quot; u.getIdHex() + &quot;this|r color&quot; )
    call u.displayText( &quot;But according to my player color ID, I should appear in &quot; + u.hex + &quot;this|r color!&quot; )

    if u.isLocal then
        call PanCameraTo( 30, 30, 0 ) // Pan a camera for Player( 6 ) to coordianates
    endif


Most static values are replaced with variables, meaning faster execution.
Its a wrapper for the Player Functions yes, but its a lot more then that.
 

Flare

Stops copies me!
Reaction score
662
Some of it looks pretty useful, but...
It's quite long, so I best spoiler it
JASS:
        static method getTriggerUser takes nothing returns user
            return GetPlayerId( GetTriggerPlayer() )
        endmethod
        static method getFilterUser takes nothing returns user
            return GetPlayerId( GetFilterPlayer() )
        endmethod
        static method getItemUser takes item i returns user
            return GetPlayerId( GetItemPlayer( i ) )
        endmethod
        static method getOwningUser takes unit u returns user
            return GetPlayerId( GetOwningPlayer( u ) )
        endmethod
        static method getEventDetectingUser takes nothing returns user
            return GetPlayerId( GetEventDetectingPlayer() )
        endmethod

        
     /////////////////////////////
     // Display Game Messages
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Display text to a player, or display them to all using the local player 
     //  variable inside this library.
      //
        method displayText takes string s returns nothing
            call DisplayTextToPlayer( .p, 0, 0, s )
        endmethod
        method displayTextEx takes real x, real y, string s returns nothing
            call DisplayTextToPlayer( .p, x, y, s ) 
        endmethod
        method displayTimedText takes string s, real duration returns nothing
            call DisplayTimedTextToPlayer( .p, 0, 0, duration, s )
        endmethod
        method displayTimedTextEx takes real x, real y, string s, real duration returns nothing
            call DisplayTimedTextToPlayer( .p, x, y, duration, s )
        endmethod


     /////////////////////////////
     // Set Player Values
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Methods that set player values to their new value.
     // Don&#039;t forget to use the user[0].update() method if you change values that
     //  that are stored in the variables.
     // This is updated on certain events only, but if you set a new player 
     //  name update it manually.
      //
        method setAlliance takes user u, alliancetype setting, boolean value returns nothing
            call SetPlayerAlliance( .p, u.p, setting, value )
        endmethod
        method setColor takes playercolor c returns nothing
            call SetPlayerColor( .p, c )
        endmethod
        method setController takes mapcontrol controller returns nothing
            call SetPlayerController( .p, controller )
        endmethod
        method setHandicap takes real value returns nothing
            call SetPlayerHandicap( .p, value )
        endmethod
        method setHandicapXP takes real value returns nothing
            call SetPlayerHandicapXP( .p, value )
        endmethod
        method setName takes string name returns nothing
            call SetPlayerName( .p, name )
        endmethod
        method setRacePreference takes racepreference preference returns nothing
            call SetPlayerRacePreference( .p, preference )
        endmethod
        method setState takes playerstate state, integer value returns nothing
            call SetPlayerState( .p, state, value )
        endmethod
        method setTaxRate takes user u, playerstate state, integer rate returns nothing
            call SetPlayerTaxRate( .p, u.p, state, rate )
        endmethod
        
        
     /////////////////////////////
     // Get Player Values
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Some methods like getting the players name are not in this list.
     // Use the variable for that, its more efficient.
      //
        method getAlliance takes user u, alliancetype setting returns boolean
            return GetPlayerAlliance( .p, u.p, setting )
        endmethod
        method getColor takes nothing returns playercolor
            return GetPlayerColor( .p )
        endmethod
        method getController takes nothing returns mapcontrol
            return GetPlayerController( .p )
        endmethod
        method getHandicap takes nothing returns real
            return GetPlayerHandicap( .p )
        endmethod        
        method getHandicapXP takes nothing returns real
            return GetPlayerHandicapXP( .p )
        endmethod 
        method getName takes nothing returns string
            return GetPlayerName( .p )
        endmethod
        method getRace takes nothing returns race
            return GetPlayerRace( .p )
        endmethod
        method getScore takes playerscore score returns integer
            return GetPlayerScore( .p, score )
        endmethod
        method getSlotState takes nothing returns playerslotstate
            return GetPlayerSlotState( .p )
        endmethod
        method getState takes playerstate state returns integer
            return GetPlayerState( .p, state )
        endmethod
        method getStructureCount takes boolean includeIncomplete returns integer
            return GetPlayerStructureCount( .p, includeIncomplete )
        endmethod
        method getTaxRate takes user u, playerstate state returns integer
            return GetPlayerTaxRate( .p, u.p, state )
        endmethod
        method getTypedUnitCount takes string unitName, boolean includeIncomplete, boolean includeUpgrades returns integer
            return GetPlayerTypedUnitCount( .p, unitName, includeIncomplete, includeUpgrades )
        endmethod
        method getUnitCount takes boolean includeIncomplete returns integer
            return GetPlayerUnitCount( .p, includeIncomplete )
        endmethod

     /////////////////////////////
     // Player ID values
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Need player values by their true slot ID, use these methods.
     // UserData profides you only with variable indexes that match the player
     //  color, so using these methods allow you access their default values.
     // Still, they are depriciated and you shouldn&#039;t use them.
      //
        method getIdHex takes nothing returns string
            return .getHex()
        endmethod
        method getIdHexName takes nothing returns string
            return .getHex() + .getName() + &quot;|r&quot;
        endmethod
        method getIdColorName takes nothing returns string
            return .getColorName()
        endmethod
        method getIdHexColorName takes nothing returns string
            return .getHex() + .getColorName() + &quot;|r&quot;
        endmethod
        method getIdRgbRed takes nothing returns integer
            return .getColorRgb( USERDATA_RGB_R_STRING )
        endmethod
        method getIdRgbGreen takes nothing returns integer
            return .getColorRgb( USERDATA_RGB_G_STRING )
        endmethod
        method getIdRgbBlue takes nothing returns integer
            return .getColorRgb( USERDATA_RGB_B_STRING )
        endmethod
        

     /////////////////////////////
     // Is Checks
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods profide an easy boolean check for players.
     // From slotstates to controller to race checks, and other
     //  stuff all made easy.
      //
        method isHost takes nothing returns boolean
            return this == user.host
        endmethod
        method isUser takes nothing returns boolean
            return .controller == MAP_CONTROL_USER
        endmethod
        method isComputer takes nothing returns boolean
            return .controller == MAP_CONTROL_COMPUTER
        endmethod
        method isCreep takes nothing returns boolean
            return .controller == MAP_CONTROL_CREEP
        endmethod
        method isNeutral takes nothing returns boolean
            return .controller == MAP_CONTROL_NEUTRAL
        endmethod
        method isNone takes nothing returns boolean
            return .controller == MAP_CONTROL_NONE
        endmethod
        method isRescuable takes nothing returns boolean
            return .controller == MAP_CONTROL_RESCUABLE
        endmethod
        method isPlaying takes nothing returns boolean
            return .slotState == PLAYER_SLOT_STATE_PLAYING
        endmethod
        method isLeaver takes nothing returns boolean
            return .slotState == PLAYER_SLOT_STATE_LEFT
        endmethod
        method isEmpty takes nothing returns boolean
            return .slotState == PLAYER_SLOT_STATE_EMPTY
        endmethod
        method isPlayingUser takes nothing returns boolean
            return .isUser() and .isPlaying()
        endmethod
        method isUserAlly takes user u returns boolean
            return IsPlayerAlly( .p, u.p )
        endmethod
        method isUserEnemy takes user u returns boolean
            return IsPlayerEnemy( .p, u.p )
        endmethod
        method isInForce takes force whichForce returns boolean
            return IsPlayerInForce( .p, whichForce )
        endmethod
        method isObserver takes nothing returns boolean
            return IsPlayerObserver( .p )
        endmethod
        method isRace takes race whichRace returns boolean
            return .specie == whichRace
        endmethod
        method isRacePrefSet takes racepreference pref returns boolean
            return IsPlayerRacePrefSet( .p, pref )
        endmethod
        method isUnitOwner takes unit whichUnit returns boolean
            return IsUnitOwnedByPlayer( whichUnit, .p )
        endmethod
        method isUnitAlly takes unit whichUnit returns boolean
            return IsUnitAlly( whichUnit, .p )
        endmethod
        method isUnitEnemy takes unit whichUnit returns boolean
            return IsUnitEnemy( whichUnit, .p )
        endmethod    
        method isUnitVisible takes unit whichUnit returns boolean
            return IsUnitVisible( whichUnit, .p )
        endmethod  
        method isUnitDetected takes unit whichUnit returns boolean
            return IsUnitDetected( whichUnit, .p )
        endmethod   
        method isUnitInvisible takes unit whichUnit returns boolean
            return IsUnitInvisible( whichUnit, .p )
        endmethod  
        method isUnitFogged takes unit whichUnit returns boolean
            return IsUnitFogged( whichUnit, .p )
        endmethod       
        method isUnitMasked takes unit whichUnit returns boolean
            return IsUnitMasked( whichUnit, .p )
        endmethod     
        method isUnitSelected takes unit whichUnit returns boolean
            return IsUnitSelected( whichUnit, .p )
        endmethod   
        method isVisible takes real x, real y returns boolean
            return IsVisibleToPlayer( x, y, .p )
        endmethod
        method isFogged takes real x, real y returns boolean
            return IsFoggedToPlayer( x, y, .p )
        endmethod
        method isMasked takes real x, real y returns boolean
            return IsMaskedToPlayer( x, y, .p )
        endmethod


     /////////////////////////////
     // Force Related Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods profide an easy call to a force related native.
     // You are not forced to use them, but just like the event registering
     //  it can make it easier to do things.
      //
        method forceAdd takes force whichForce returns nothing
            call ForceAddPlayer( whichForce, .p )
        endmethod
        method forceRemove takes force whichForce returns nothing
            call ForceRemovePlayer( whichForce, .p )
        endmethod
        method forceEnumAllies takes force whichForce, boolexpr filter returns nothing
            call ForceEnumAllies( whichForce, .p, filter )
        endmethod
        method forceEnumEnemies takes force whichForce, boolexpr filter returns nothing
            call ForceEnumEnemies( whichForce, .p, filter )
        endmethod
        
     /////////////////////////////
     // Unit Related Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods profide an easy call to a unit related native.
     // You are not forced to use them, but just like the event registering
     //  it can make it easier to do things.
      //
        method createUnit takes integer id, real x, real y, real face returns unit
            return CreateUnit( .p, id, x, y, face )
        endmethod
        method createCorpse takes integer id, real x, real y, real face returns unit
            return CreateCorpse( .p, id, x, y, face )
        endmethod
        method groupEnumUnits takes group whichGroup, boolexpr filter returns nothing
            call GroupEnumUnitsOfPlayer( whichGroup, .p, filter )
        endmethod

        
     /////////////////////////////
     // Other Methods
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // These methods are uncatagorized, just look at the method
     //  name and see what it does.
      //
        method addState takes playerstate state, integer value returns nothing
            call SetPlayerState( .p, state, GetPlayerState( .p, state ) + value )
        endmethod
        method dialogDisplay takes dialog whichDialog, boolean flag returns nothing
            call DialogDisplay( .p, whichDialog, flag )
        endmethod
    
        
     /////////////////////////////
     // Registering Player Events
     //¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
     // Registering player events made easy.
      //
        method registerEvent takes trigger t, playerevent e returns event
            return TriggerRegisterPlayerEvent( t, .p, e )
        endmethod
        method registerChatEvent takes trigger t, string message, boolean exactMatch returns event
            return TriggerRegisterPlayerChatEvent( t, .p, message, exactMatch )
        endmethod
        method registerAllianceChange takes trigger t, alliancetype a returns event
            return TriggerRegisterPlayerAllianceChange( t, .p, a )
        endmethod
        method registerStateEvent takes trigger t, playerstate state, limitop opcode, real limitval returns event
            return TriggerRegisterPlayerStateEvent( t, .p, state, opcode, limitval )
        endmethod
        method registerUnitEvent takes trigger t, playerunitevent e, boolexpr filter returns event
            return TriggerRegisterPlayerUnitEvent( t, .p, e, filter )
        endmethod
helps to achieve
When your code is optimized, you will take full advantage of this system.

To me, that looks like a long list of lame-ass BJ functions. If/when our code is fully optimized, and consequently takes full advantage of this system, it's just nullifying that optimization since we have to do an extra function call for just about everything. I don't particularly see why the native Player functions need a struct wrapper, other than for the sake of mixing it up a little bit, so would you like to give me an explanation?

As for the Player ID values functions (well, the first 3 or 4 at least), why not just let the end-user call .getHex directly, or do the concatenation themselves?

it replaces most of them with very efficient coding.
Considering half your code is just methods calling/returning a single native, do explain yourself on this one :) At least the natives have AutoComplete compatibility
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
You do not --have-- to use those method, its there if you prefer a cleaner code.
Those methods are meant for in-lining, so that you can refer to a player related native without having to put in the player value.
This causes your script to shrink in sizes and it looks a -lot- more cleaner.

JASS:
if u.isPlayingUser() then

But I see you like the old fashion way, right?


Be my guest, I don't mind. Since you were so generous of including every in lining method in there without taking a good look on what they are doing.
Not all of them are just wrappers, some are there for simplicity and some really shorten your code down.

>> As for the Player ID values functions (well, the first 3 or 4 at least), why not just let the end-user call .getHex directly, or do the concatenation themselves?

Player ID's should be depreciated with this system, but its there for compatibility. Thats why their not in variables because it would cash in some useless amount of memory.
All values necessary are there with the Player Color ID fix, easy to grab.

And if you were talking about the "getPlayerId" functions, and do a concatenation themselves provokes complexity and execution time for what you call the end-user.

>> Considering half your code is just methods calling/returning a single native, do explain yourself on this one At least the natives have AutoComplete compatibility

Its an option. I disabled my auto completion because A. I don't need it. B. Sometimes it can be pretty annoying.
Secondly I'd prefer...
JASS:
   call u.registerUnitEvent( trig, EVENT, filter )
   call TriggerRegisterPlayerUnitEvent( trigger, Player( 0 ), event, filter )
   call user[1].displayText( &quot;Message&quot; )
   call DisplayTextToPlayer( Player( 1 ), 0, 0, &quot;Message&quot; )

the system methods, over natives at ANY given time.

You can use these methods, or not.
Optimized is a must, so either they are removed because they aren't used or they are removed because they are in lined or you removed them yourself.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
If/when our code is fully optimized, and consequently takes full advantage of this system, it's just nullifying that optimization since we have to do an extra function call for just about everything.

The optimization is all done through the code in-lining, so the extra function calls are nullified.

I think the idea behind this was not so much as to use the BJ-methods as it was to automatically pre-set some variables and keep them updated, so that you don't have to create them every time you need them, such as the user.isLocal boolean or the user.hexName string.

Who knows, some people might prefer coding with structs. The syntax is certainly a bit nicer for some things.

Personally, I think although many people won't find much use out of it, a few people will. If anything, it's an experiment that some people might learn something from, or even build off the ideas with a few of their own.
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
>> To me, that looks like a long list of lame-ass BJ functions.
>> The optimization is all done through the code in-lining, so the extra function calls are nullified.]

I just noticed this, when I read the comments through again.
At first I did not fully understand what he meant but now I do.

I guess you don't know what "optimizing" does to a map, as Darthfett said that those what you call 'bj methods', are inlined.
This means that functions that has just 1 line of code ( which over 95% of this system has ) is inlined into the the code where the function call occurs with of course the fixed arguments.

Example:
JASS:
function meh takes nothing returns nothing
	local user u = 3
	
	if u.isPlayingUser() then
		call u.registerUnitEvent( t, EVENT_PLAYER_UNIT_DEATH, null )
	endif
	
	call TriggerAddAction( t, function main ) // I love crashing a map.
endfunction

// Becomes this when it is inlined.

function meh takes nothing returns nothing
	local user u = 3
	
	if struct_user_controller<u> == MAP_CONTROL_USER and struct_user_slotState<u> == PLAYER_SLOT_STATE_PLAYING then
		call TriggerRegisterPlayerUnitEvent( t, struct_user_p<u>, EVENT_PLAYER_UNIT_DEATH, null )
	endif
	
	call TriggerAddAction( t, function main ) // I love crashing a map.
endfunction
</u></u></u>


Its like you never called the method, because it does not exists at all anymore after inlining.
Infact, when the map is optimized, even some of the methods inside the system are inlined.
So using these methods will not slow your script down, it just allows you to reach the same thing by doing less.

Who knows, some people might prefer coding with structs. The syntax is certainly a bit nicer for some things.

Personally, I think although many people won't find much use out of it, a few people will. If anything, it's an experiment that some people might learn something from, or even build off the ideas with a few of their own.

I certainly like this syntax much better, fetching player related data is certainly a lot easier.
And I think you're right about your second statement, but I'm gonna twist it a bit.
Some people may not find much use of it, because they don't understand the system, take Flare for example.
Here he go's ranting my code because he doesn't understand it at all.
So not knowing what this system exactly does, he made up his mind already thinking this is useless.
 

Flare

Stops copies me!
Reaction score
662
Hmm, forgot about inlining :eek:

Fair enough on that point, but considering you are giving people a whole bunch of methods that are unfamiliar (since a number of them don't have a similar name to the native) - they may shorten the code, but to be honest, you end up wasting any time you saved by going back because you forgot the name of the method, and you had to search for it... either way, there's a inconvienience

it looks a -lot- more cleaner.
Well, that's opinion - personally, I don't really like the appearance of struct syntax, so for me, natives would be much cleaner

But I see you like the old fashion way, right?
Well...
Not everyone spaces things out in brackets like you have done there (well, I don't anyway :p). Anyway, if/when people get bored of that, they can always make their own function if needs be?

I can't really see why the player type should need a wrapper - the native functions may have a longer name, but someone you don't want to type code, should they really be using JASS?
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Sorry if it seems a bit like I'm reviving a dead thread, but it's relevant. :p

I noticed a possible problem with the way the system is set up.

I was thinking of a making a system set up similar to this (for my own purposes), in which you simply used a Player's Id for the struct itself. However, when I was thinking about it, I realized a potential problem. Invalid/null structs return "0", the same as Player 1, Red.

JASS:
static method getOwningUser takes unit u returns user
    return GetPlayerId( GetOwningPlayer( u ) )
endmethod


If I were to give this function a null unit, it would return that the user Player 1 (Red) owned the unit, even though the unit does not exist. Instead, it should return an invalid struct. This means that your system cannot be used for null comparison.

Making the system based off the player Id, but adding one/reducing one to get the actual player Id (Similar to what the GUI uses GetPlayerConvertedId for) could fix it, but that seems like it's losing the original point of the system.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top