library AdvBoard/*
*********************************************************************************************************************
*
* *****************************************************************************************************************
*
* */ uses /*
* */ ARGB /* wc3c.net/showthread.php?t=101858
* */ IconLibrary /* hiveworkshop.com/forums/submissions-414/snipet-iconlibrary-264329/
* */ MultiboardTools /* hiveworkshop.com/forums/submissions-414/snipet-multiboardtools-263709/#post2664244
* */ OrderEvent /* hiveworkshop.com/forums/jass-resources-412/snippet-order-event-190871/
* */ TeamIndex /* hiveworkshop.com/forums/submissions-414/snippet-teamreforce-257915/
* */ TimerUtils /* hiveworkshop.com/forums/graveyard-418/system-timerutilsex-204500/
* */ ReviveEvent /* hiveworkshop.com/forums/submissions-414/snippet-reviveevent-263628/
* */ RegisterPlayerUnitEvent /* hiveworkshop.com/forums/showthread.php?t=203338
*
* *****************************************************************************************************************
*
* AdvBoard
* ________
* v2.0.0.0
* by Thelordmarshall
*
*
* AdvBoard (AdvanceMultiboard) is designed to work in any map, inspired from dota
* multiboard; you can see all the basic information in it: player name, unit icon,
* levels, cooldown, kill, deaths, gold, etc....
*
* One could say that the system is still in beta phase, in previous versions
* I found a lots of bugs that i fixed with success. Maybe this version contains
* some bugs.
*
* IMPORTANT:
* __________
*
* - In order that it work correctly go to: Scenario/Player Properties/Forces
* and select the box "Allied" of each force of your map.
*
* Pros:
* _____
*
* - Designed for ANY map.
* - The multiboard is refreshed in separated methods, this prevent the short
* period of lag caused for update ALL multiboard data at the same time.
* - The teams can see your private DATA.
* - No EMPTY slots.
*
* API:
* ____
*
* struct AdvBoard:
* - static method operator title= takes string s returns nothing
* - change multiboard title.
* - static method operator title takes nothing returns string
* - get current title.
* - method operator teamTitle= takes string name returns nothing
* - change any team name: set AdvBoard[teamIndex].teamTitle=teamTitle
* - method operator teamTitle takes nothing returns string
* - current team title: AdvBoard[teamIndex].teamTitle
* - static method operator unit= takes unit u returns nothing
* - synchronize unit to multiboard.
* - method operator cooldown= takes integer c returns nothing
* - start cooldown for player: set AdvBoard[playerId].cooldown=20.
* - static method show takes boolean show returns nothing
* - show/hide multiboard.
*
* Credits:
* ________
*
* - Bribe: OrderEvent.
* - Vexorian: ARGB, TimerUtils.
* - Magtheridon96: RegisterPlayerUnitEvent.
*********************************************************************************************************************/
//CONFIGURATION
//============================================================================
globals
//Names
private constant string DEFAULT_BOARD_TITLE = "AdvBoard v2.0"
private constant string DEFAULT_TEAM_NAME = "Team"
private constant string COOLDOWN_NAME = "CD"
private constant string LEVEL_NAME = "lvl"
private constant string KILL_NAME = "K"
private constant string DEATH_NAME = "D"
//Icons
private constant string GOLD_ICON = "UI\\Feedback\\Resources\\ResourceGold.blp"
private constant string LUMBER_ICON = "UI\\Feedback\\Resources\\ResourceLumber.blp"
private constant string FOOD_ICON = "UI\\Feedback\\Resources\\ResourceSupply.blp"
//ARGB Colors
private ARGB DEFAULT_COLOR = 0x22222222
private ARGB KILL_DEATH_COLOR = 0xffaaaaaa
private ARGB CD_COLOR = 0x00C1C1C1
private ARGB LVL_COLOR = 0x00797979
private ARGB KILL_COLOR = 0x008000FF
private ARGB DEATH_COLOR = 0x00F43535
private ARGB GOLD_COLOR = 0xffffcc00
private ARGB LUMBER_COLOR = 0x00006C00
private ARGB FOOD_COLOR = 0x00CA6500
private ARGB ITEM_COLOR = 0x008080C0
endglobals
//============================================================================
//ENDCONFIGURATION
globals
private Multiboard mb=0
private string mbTitle=""
private constant integer COLUMN_COUNT=14
private integer array level
private integer array kills
private integer array deaths
private integer array teamKills
private integer array teamDeaths
private integer array teamIndex
private unit array boardUnit
private string array teamName
private real array cd
private trigger array t
endglobals
//! textmacro ADV_MULTIBOARD_STATE takes FUNC,STATE,RETURN
private function $FUNC$ takes player p returns $RETURN$
return $STATE$
endfunction
//! endtextmacro
//! runtextmacro ADV_MULTIBOARD_STATE("IsPlaying","GetPlayerSlotState(p)==PLAYER_SLOT_STATE_PLAYING","boolean")
//! runtextmacro ADV_MULTIBOARD_STATE("IsLeft","GetPlayerSlotState(p)==PLAYER_SLOT_STATE_LEFT","boolean")
//! runtextmacro ADV_MULTIBOARD_STATE("GetGold","GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)","integer")
//! runtextmacro ADV_MULTIBOARD_STATE("GetLumber","GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)","integer")
//! runtextmacro ADV_MULTIBOARD_STATE("GetPlayerFoodUsed","GetPlayerState(p,PLAYER_STATE_RESOURCE_FOOD_USED)","integer")
//! runtextmacro ADV_MULTIBOARD_STATE("GetFoodCap","GetPlayerState(p,PLAYER_STATE_RESOURCE_FOOD_CAP)","integer")
private function UpdateResource takes player p, integer c, string r returns nothing
if(IsPlaying(p) and IsPlayerAlly(p,GetLocalPlayer()))then
set mb[2+GetPlayerForceId(p)+GetPlayerIdInForce(p)][c].text=r
endif
endfunction
private function UpdateGold takes nothing returns nothing
local player p=GetTriggerPlayer()
call UpdateResource(p,5,GOLD_COLOR.str(I2S(GetGold(p))))
endfunction
private function UpdateLumber takes nothing returns nothing
local player p=GetTriggerPlayer()
call UpdateResource(p,6,LUMBER_COLOR.str(I2S(GetLumber(p))))
endfunction
private function UpdateFood takes nothing returns nothing
local player p=GetTriggerPlayer()
call UpdateResource(p,7,FOOD_COLOR.str(I2S(GetPlayerFoodUsed(p))+"/"+I2S(GetFoodCap(p))))
endfunction
private function FoodOnRevive takes nothing returns nothing
local unit u=GetLastRevivedUnit()
local player p=GetOwningPlayer(u)
if(GetUnitFoodUsed(u)>0 or GetUnitFoodMade(u)>0)then
call UpdateResource(p,7,FOOD_COLOR.str(I2S(GetPlayerFoodUsed(p))+"/"+I2S(GetFoodCap(p))))
endif
set u=null
endfunction
private function UpdateKillsDeaths takes nothing returns nothing
local unit d=GetDyingUnit()
local unit k=GetKillingUnit()
local player l=GetLocalPlayer()
local player p1=GetOwningPlayer(d)
local player p2=GetOwningPlayer(k)
local integer id1=GetPlayerId(p1)
local integer id2=GetPlayerId(p2)
local integer t1=GetPlayerForceId(p1)
local integer t2=GetPlayerForceId(p2)
local integer row1=2+GetPlayerForceId(p1)+GetPlayerIdInForce(p1)
local integer row2=2+GetPlayerForceId(p2)+GetPlayerIdInForce(p2)
local boolean b=IsPlayerEnemy(p1,p2)
if(p1==GetOwningPlayer(boardUnit[id1]) and b)then
set deaths[id1]=deaths[id1]+1
set teamDeaths[t1]=teamDeaths[t1]+1
set mb[row1][4].text=DEATH_COLOR.str(I2S(deaths[id1]))
set mb[teamIndex[t1]][4].text=DEATH_COLOR.str(I2S(teamDeaths[t1]))
if(l==p1)then
set mb.title=KILL_DEATH_COLOR.str(I2S(kills[id1])+"/"+I2S(deaths[id1]))+" - "+mbTitle
endif
endif
if(p2==GetOwningPlayer(boardUnit[id2]) and b)then
set kills[id2]=kills[id2]+1
set teamKills[t2]=teamKills[t2]+1
set mb[row2][3].text=KILL_COLOR.str(I2S(kills[id2]))
set mb[teamIndex[t2]][3].text=KILL_COLOR.str(I2S(teamKills[t2]))
if(l==p2)then
set mb.title=KILL_DEATH_COLOR.str(I2S(kills[id2])+"/"+I2S(deaths[id2]))+" - "+mbTitle
endif
endif
set d=null
set k=null
endfunction
private function UpdateLevel takes nothing returns nothing
local unit u=GetTriggerUnit()
local player p=GetTriggerPlayer()
local integer id=GetPlayerId(p)
local integer row=2+GetPlayerForceId(p)+GetPlayerIdInForce(p)
if(u==boardUnit[id] and IsUnitType(u,UNIT_TYPE_HERO))then
set level[id]=GetUnitLevel(u)
set mb[row][2].text=LVL_COLOR.str(I2S(level[id]))
endif
set u=null
endfunction
private function UpdateAllSlotsIcons takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetTimerData(t)
local player p=Player(id)
local integer row=2+GetPlayerForceId(p)+GetPlayerIdInForce(p)
local integer i=0
loop
exitwhen(i==bj_MAX_INVENTORY)
set mb[row][8+i].icon=GetItemIcon(UnitItemInSlot(boardUnit[id],i))
set i=i+1
endloop
call ReleaseTimer(t)
endfunction
private function UpdateSlots takes nothing returns nothing
local unit u=GetTriggerUnit()
local integer id=GetPlayerId(GetOwningPlayer(u))
if(u==boardUnit[id])then
call TimerStart(NewTimerEx(id),0,false,function UpdateAllSlotsIcons)
endif
set u=null
endfunction
struct AdvBoard extends array
static method operator [] takes integer this returns thistype
return this
endmethod
static method operator show= takes boolean show returns nothing
set mb.show=show
endmethod
static method operator title takes nothing returns string
return mbTitle
endmethod
static method operator title= takes string s returns nothing
local player l=GetLocalPlayer()
local integer i=0
set mbTitle=s
loop
exitwhen(i==bj_MAX_PLAYERS)
if(l==Player(i))then
set mb.title=KILL_DEATH_COLOR.str(I2S(kills[i])+"/"+I2S(deaths[i]))+" - "+mbTitle
endif
set i=i+1
endloop
endmethod
method operator teamTitle= takes string name returns nothing
if(this>=0 and this<=CountMapTeams()-1)then
set teamName[this]=name
set mb[teamIndex[this]][0].text=teamName[this]
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0.,0.,60.,"[AdaptiveMultiboard] Error: unable to change name to nonexistent teamId ["+I2S(this)+"]")
endif
endmethod
method operator teamTitle takes nothing returns string
return teamName[this]
endmethod
static method operator unit= takes unit u returns nothing
local player p=GetOwningPlayer(u)
local integer id=GetPlayerId(p)
local integer row=2+GetPlayerForceId(p)+GetPlayerIdInForce(p)
if(IsPlaying(p))then
set boardUnit[id]=u
set mb[row][0].icon=GetUnitIcon(u)
set mb[row][2].text=LVL_COLOR.str(I2S(GetUnitLevel(u)))
call TimerStart(NewTimerEx(id),0,false,function UpdateAllSlotsIcons)
endif
endmethod
method operator cooldown= takes integer c returns nothing
local player p=Player(this)
if(IsPlaying(p) and cd[this]<=1.)then
set cd[this]=I2R(c)+1.
call TimerStart(NewTimerEx(this),.03125,true,function thistype.onCooldown)
debug elseif(cd[this]>1.)then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0.,0.,60.,"[AdaptiveMultiboard] Error: "+ARGB.fromPlayer(p).str(GetPlayerName(p))+" cooldown is allready started.")
endif
endmethod
private static method onCooldown takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetTimerData(t)
local player p=Player(id)
local integer row=2+GetPlayerForceId(p)+GetPlayerIdInForce(p)
set cd[id]=cd[id]-.03125
set mb[row][1].text=CD_COLOR.str(I2S(R2I(cd[id])))
if(cd[id]<=1.)then
set mb[row][1].text=DEFAULT_COLOR.str(I2S(R2I(cd[id])))
call ReleaseTimer(t)
endif
endmethod
endstruct
private function ClearMultiboard takes nothing returns nothing
local integer l=1+CountMapTeams()+GetStartPlayers()
local integer i=1
local integer h=1
loop
exitwhen(i==l)
loop
exitwhen(h==8)
set mb[i][h].text=""
set h=h+1
endloop
set h=1
set i=i+1
endloop
call mb[0][0].setStyle(true,false)
set mb[0][5].icon=GOLD_ICON
set mb[0][6].icon=LUMBER_ICON
set mb[0][7].icon=FOOD_ICON
endfunction
private function InitTeams takes nothing returns nothing
local integer c=CountMapTeams()
local integer n=0
local integer i=0
local integer row=1
loop
exitwhen(i==c)
if(i>0)then
set n=n+CountPlayersInForce(i-1)
set row=1+n+i
endif
set teamIndex[i]=row
if(teamName[i]==null)then
set teamName[i]=DEFAULT_TEAM_NAME+" "+I2S(i+1)
endif
set mb[row][0].text=ARGB(0xffffcc00).str(teamName[i])
set mb[row][3].text=KILL_COLOR.str(I2S(teamKills[i]))
set mb[row][4].text=DEATH_COLOR.str(I2S(teamDeaths[i]))
set i=i+1
endloop
endfunction
private function InitPlayers takes nothing returns nothing
local player l=GetLocalPlayer()
local integer i=0
local integer row
local player p
local string s
loop
exitwhen(i==bj_MAX_PLAYERS)
set p=Player(i)
set row=2+GetPlayerForceId(p)+GetPlayerIdInForce(p)
if(IsLeft(p))then
set s=DEFAULT_COLOR.str(GetPlayerName(p))
else
set s=ARGB.fromPlayer(p).str(GetPlayerName(p))
endif
if(IsPlaying(p) or IsLeft(p))then
set mb[row][0].icon=GetUnitIcon(boardUnit[i])
call mb[row][0].setStyle(true,true)
set mb[row][0].text=s
set mb[row][1].text=DEFAULT_COLOR.str(I2S(R2I(cd[i])))
set mb[row][2].text=DEFAULT_COLOR.str(I2S(level[i]))
set mb[row][3].text=KILL_COLOR.str(I2S(kills[i]))
set mb[row][4].text=DEATH_COLOR.str(I2S(deaths[i]))
if(IsPlayerAlly(p,l))then
set mb[row][5].text=GOLD_COLOR.str(I2S(GetGold(p)))
set mb[row][6].text=LUMBER_COLOR.str(I2S(GetLumber(p)))
set mb[row][7].text=FOOD_COLOR.str(I2S(GetPlayerFoodUsed(p))+"/"+I2S(GetFoodCap(p)))
endif
endif
set i=i+1
endloop
endfunction
private function InitItemsIcons takes nothing returns nothing
local integer h=0
local integer n=8
local integer s=0
local integer row
local player p
loop
exitwhen(h==bj_MAX_PLAYERS)
set p=Player(h)
set row=2+GetPlayerForceId(p)+GetPlayerIdInForce(p)
loop
exitwhen(n==14)
set mb[row][n].icon=GetItemIcon(UnitItemInSlot(boardUnit[h],s))
call mb[row][n].setStyle(true,true)
set s=s+1
set n=n+1
endloop
set s=0
set n=8
set h=h+1
endloop
call ReleaseTimer(GetExpiredTimer())
endfunction
private function InitMultiboard takes nothing returns nothing
set mbTitle=DEFAULT_BOARD_TITLE
set mb=Multiboard.create(KILL_DEATH_COLOR.str("0"+"/"+"0"+"|r - ")+mbTitle,1+CountMapTeams()+GetCountPlayers(),COLUMN_COUNT)
call mb[0][0].setStyle(true,false)
set mb[0][0].width=10.20//player name
set mb[0][1].width=1.80 //cooldown
set mb[0][2].width=1.80 //levels
set mb[0][3].width=1.30 //kills
set mb[0][4].width=1.30 //deaths
set mb[0][5].width=3.00 //gold
set mb[0][6].width=3.00 //lumber
set mb[0][7].width=3.00 //food
set mb[0][8].width=1.10 //items slots
set mb[0][9].width=1.10
set mb[0][10].width=1.10
set mb[0][11].width=1.10
set mb[0][12].width=1.10
set mb[0][13].width=1.10//items slots end
set mb[0][1].text=CD_COLOR.str(COOLDOWN_NAME)
set mb[0][2].text=LVL_COLOR.str(LEVEL_NAME)
set mb[0][3].text=KILL_COLOR.str(KILL_NAME)
set mb[0][4].text=DEATH_COLOR.str(DEATH_NAME)
set mb[0][5].icon=GOLD_ICON
set mb[0][6].icon=LUMBER_ICON
set mb[0][7].icon=FOOD_ICON
set mb[0][9].text=ITEM_COLOR.str("ite")
set mb[0][10].text=ITEM_COLOR.str("ms")
set mb.show=false
endfunction
private function RenderBoard takes nothing returns nothing
if(mb==0)then
call InitMultiboard()
else
call ClearMultiboard()
endif
call InitTeams()
call InitPlayers()
call TimerStart(NewTimer(),0,false,function InitItemsIcons)
endfunction
private function RegisterStateEvent takes playerstate s, code c returns nothing
local integer h=GetHandleId(s)
local integer i=15
local integer r
local player p
set t[h]=CreateTrigger()
loop
set p=Player(i)
set r=GetPlayerState(p,s)
call TriggerRegisterPlayerStateEvent(t[h],p,s,GREATER_THAN,r)
call TriggerRegisterPlayerStateEvent(t[h],p,s,LESS_THAN,r)
exitwhen(0==i)
set i=i-1
endloop
call TriggerAddCondition(t[h],Filter(c))
endfunction
private module Init
private static method onInit takes nothing returns nothing
local integer i=0
loop
exitwhen(i==bj_MAX_INVENTORY)
call RegisterOrderEvent(852002+i,function UpdateSlots)
set i=i+1
endloop
call RegisterReviveEvent(function FoodOnRevive)
call RegisterEventAllianceChange(function RenderBoard)
call RegisterStateEvent(PLAYER_STATE_RESOURCE_GOLD,function UpdateGold)
call RegisterStateEvent(PLAYER_STATE_RESOURCE_LUMBER,function UpdateLumber)
call RegisterStateEvent(PLAYER_STATE_RESOURCE_FOOD_CAP,function UpdateFood)
call RegisterStateEvent(PLAYER_STATE_RESOURCE_FOOD_USED,function UpdateFood)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function UpdateKillsDeaths)
call RegisterPlayerUnitEvent(EVENT_PLAYER_HERO_LEVEL,function UpdateLevel)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM,function UpdateSlots)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DROP_ITEM,function UpdateKillsDeaths)
endmethod
endmodule
private struct i extends array
implement Init
endstruct
endlibrary