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:
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
Example Code
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 "Player" 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'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'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 = "FF02020041FF1BE6D8530080FFFC00FE890D1FBF00E55AAF9495967DBEF10F61454D2903272727272727272727272727"
constant string USERDATA_RGB_R_STRING = "255000027083255254031229148125015077039039039039"
constant string USERDATA_RGB_G_STRING = "002065230000252137191090149190097041039039039039"
constant string USERDATA_RGB_B_STRING = "002255184128000013000175150241069003039039039039"
constant string USERDATA_NAMES_STRING = "redbluetealpurpleyelloworangegreenpinkgraylight bluedark greenbrown"
constant string USERDATA_NAMES_FILTER = "030711172329343842526267"
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't though them unless you know what you're doing.
//
private static method h2i takes handle h returns integer
return h
return 0
endmethod
private method getHex takes nothing returns string
return "|cff" + 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 >= 12
set tempPlayer:count = 0
set tempPlayer = tempPlayer + 1
endloop
loop
exitwhen tempPlayer <= 0
call StoreInteger( .findHostCache, "find", "host", .localUser + 1 )
call TriggerSyncStart()
call SyncStoredInteger( .findHostCache, "find", "host" )
call TriggerSyncReady()
set syncedPlayer = GetStoredInteger( .findHostCache, "find", "host" ) - 1
set syncedPlayer:count = syncedPlayer:count + 1
set tempPlayer = tempPlayer - 1
endloop
set syncedPlayer = 0
loop
exitwhen tempPlayer >= 12
if syncedPlayer:count < 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'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't use them.
//
method getIdHex takes nothing returns string
return .getHex()
endmethod
method getIdHexName takes nothing returns string
return .getHex() + .getName() + "|r"
endmethod
method getIdColorName takes nothing returns string
return .getColorName()
endmethod
method getIdHexColorName takes nothing returns string
return .getHex() + .getColorName() + "|r"
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 + "|r"
set .hexColorName = .hex + .colorName + "|r"
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( "findHost.w3v" )
set .localPlayer = GetLocalPlayer()
set .localUser = GetPlayerId( .localPlayer )
set .localUser.isLocal = true
set .host = .findHost()
loop
exitwhen integer( u ) > 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( "Your unit was kiled by one of " + killer.hexName + "039;s units." )
call killer.displayText( "You killed " + dying.hexName + "039;s unit for an aditional 10 gold bonus!" )
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't count for them.
call user.localUser.displayText( killer.hexName + " has killed " + dying.hexName + "039;s unit!" )
endfunction
function init takes nothing returns nothing
local trigger t = CreateTrigger()
local user u = 0
loop
exitwhen integer( u ) > 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