- Joined
- Nov 7, 2014
- Messages
- 571
Blackboard - a simple way of using multiboards
Simple example:
BBDebugMsg:
Note that you can only use Blackboard after the "loading screen ends"
(
because multiboards created during map initialization time don't work correctly.
This means that the following won't work:
JASS:
library Blackboard requires PlayerArray
//! novjass
Blackboard - a simple way of using multiboards
General notes:
This library comes with extarnal commands that change a few values of the
Game Interface that make multiboards look good/black. The original idea comes
from user Toadcop at www.wc3c.net, I have simply translated it into vJass and
Grimoire commands which make importing a bit easier.
Blackboard uses multiboards with 1 column (thus every multiboard item has the same with as the multiboard itself),
it does not use icons (MultiboardSetItemIcon(...)),
it does not use value colors (MultiboardSetItemValueColor(...), one can print a string with a color code of course)
and it does not require manual multiboard item retrieval (MultiboardGetItem(...) or mb[<row>][<column>]),
that happens implicitly / transparently from the user while using the print and println methods.
Credits:
Toadcop - BX-TRS II: http://www.wc3c.net/showthread.php?t=91163
Requirements:
PlayerArray - http://www.hiveworkshop.com/threads/players.276065/
API:
//
// Getting/Retrieving a player specific Blackboard:
//
local Blackboard bb = Blackboard(0) // Player Red's blackboard
local Blackboard bb2 = Blackboard(PlayingPlayers[1]) // first playing player's blackboard (usually Player Red)
//
// Printing
//
// Prints the string s to the current line without going to the next, i.e print buffers the text.
// One can access that buffer with: bb.buf and concatenate directly to it if they want to
// avoid the extra function call.
//
method print takes string s returns nothing
// Prints the string s and the previously buffered text to the current line and goes to the next, also
// clears the buffer.
// In debug mode if the number of printed lines exceeds the constant MAX_LINES an error is displayed.
//
method println takes string s returns nothing
//
// Showing/Hiding
//
// NOTE: this method must be called first after all the print/println calls
// It takes the width for the Blackboard to have.
// There are predefined widths that can be used:
//
// static constant real MAX_WIDTH = 0.780
// static constant real HALF_WIDTH = 0.385
// static constant real GOLD_ICON_START_WIDTH = 0.325
// static constant real TRSII_WIDTH = 0.315
//
method flush takes real width returns thistype
// Sets the title of the Blackboard
//
method title takes string s returns thistype
// Shows the Blackboard to the player that was specified when it was retrieved.
//
method show takes nothing returns thistype
// Shows the Blackboard to the players inside the PlayerArray pa.
//
method show_to takes PlayerArray pa returns thistype
// Shows the Blackboard to all players.
//
method show_all takes nothing returns thistype
// Hides the Blackboard from the player that was specified when it was retrieved.
//
method hide takes nothing returns thistype
// Hides the Blackboard from the players inside the PlayerArray pa.
//
method hide_from takes PlayerArray pa returns thistype
// Hides the Blackboard from all players.
//
method hide_all takes nothing returns thistype
//! endnovjass
// Allow the external commands to be executed by saving the map. After that remove the '!',
// close the map and reopen it again.
// The external commands change some Game Interface values so that the multiboards look good/black =).
//
// import "blackboard/external-commands.j"
struct Blackboard extends array
// the number of rows the multiboard native type can display seems to be 39;
// you can set this value to something smaller if you know you are never going to
// write more than that many lines (each line uses 1 row), doing so would save some RAM
//
static constant integer MAX_LINES = 39
// some predefined widths that can be used with the flush method, e.g:
// call bb.flush(bb.HALF_WIDTH).show()
//
static constant real MAX_WIDTH = 0.780
static constant real HALF_WIDTH = 0.385
static constant real GOLD_ICON_START_WIDTH = 0.325
static constant real TRSII_WIDTH = 0.315
private static multiboard array mbs
private static string array lns
readonly integer p
readonly integer ln_count
string buf
private multiboard selected_mb
// the players for which we create multiboards
private static method multiboard_players takes nothing returns PlayerArray
local PlayerArray result = PlayerArray.create()
local integer i
if PlayingPlayers != 0 then
set i = 1
loop
exitwhen i > PlayingPlayers.count
call result.add(PlayingPlayers[i])
set i = i + 1
endloop
endif
// if Observers != 0 then
// set i = 1
// loop
// exitwhen i > Observers.count
// call result.add(Observers[i])
// set i = i + 1
// endloop
// endif
// whenever we want to show a Blackboard to all players (show_all) we use the
// local Blackboard bb = Blackboard(15)
call result.add(15)
return result
endmethod
// multiboards cannot be created correctly during map init time
//
private static method lazy_init takes nothing returns nothing
local Blackboard b
local multiboard mb
local integer p
local integer rows_count
local integer i
local PlayerArray pa
set pa = multiboard_players()
set i = 1
loop
exitwhen i > pa.count
set p = pa[i]
set b = Blackboard(p)
set b.p = p
// set b.ln_count = 0
set b.buf = ""
set rows_count = 1
loop
exitwhen rows_count > MAX_LINES
set mb = CreateMultiboard()
call MultiboardMinimize(mb, false)
call MultiboardSetRowCount(mb, rows_count)
call MultiboardSetColumnCount(mb, 1)
call MultiboardSetItemsStyle(mb, /*show-values:*/ true, /*show-icons:*/ false)
set mbs[p * MAX_LINES + rows_count - 1] = mb
set rows_count = rows_count + 1
endloop
set i = i + 1
endloop
call pa.destroy()
call DestroyTimer(GetExpiredTimer())
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.0, false, function thistype.lazy_init)
endmethod
static if DEBUG_MODE then
private static method panic takes string msg returns nothing
call BJDebugMsg("|cffFF0000[thistype] error: " + msg + "|r")
if 1 / 0 == 0 then
endif
endmethod
endif
// NOTE: this method does not inline
// one can concatenate directly to the this.buf field if they want to avoid
// the extra function call
//
method print takes string s returns nothing
set this.buf = this.buf + s
endmethod
method println takes string s returns nothing
static if DEBUG_MODE then
if this.ln_count >= MAX_LINES then
call panic("attempt to println " + I2S(this.ln_count + 1) + " lines but MAX_LINES is " + I2S(MAX_LINES))
endif
endif
set lns[this.p * MAX_LINES + this.ln_count] = this.buf + s
set this.ln_count = this.ln_count + 1
set this.buf = ""
endmethod
method flush takes real width returns thistype
local multiboard mb
local multiboarditem mbi
local integer line_index
local integer p = this.p
local integer ln_count = this.ln_count
if ln_count == 0 then
static if DEBUG_MODE then
call panic("nothing to flush for Blackboard(" + I2S(this) + ")")
endif
endif
set mb = mbs[p * MAX_LINES + ln_count - 1]
set this.selected_mb = mb
set line_index = 0
loop
exitwhen line_index >= ln_count
set mbi = MultiboardGetItem(mb, line_index, 0)
call MultiboardSetItemValue(mbi, lns[p * MAX_LINES + line_index])
call MultiboardSetItemWidth(mbi, width)
call MultiboardReleaseItem(mbi)
set line_index = line_index + 1
endloop
set this.ln_count = 0
set mbi = null
return this
endmethod
// these methods must be called after the flush method because
// before that we don't know which multiboard would be selected,
// i.e there could be println(...) calls after title(...)
//
method title takes string s returns thistype
call MultiboardSetTitleText(this.selected_mb, s)
return this
endmethod
method show takes nothing returns thistype
if LOCAL_PLAYER[this.p] then
call MultiboardDisplay(this.selected_mb, true)
endif
return this
endmethod
method show_to takes PlayerArray pa returns thistype
local integer i = 1
loop
exitwhen i > pa.count
if LOCAL_PLAYER[pa[i]] then
call MultiboardDisplay(this.selected_mb, true)
endif
set i = i + 1
endloop
return this
endmethod
method show_all takes nothing returns thistype
call MultiboardDisplay(this.selected_mb, true)
return this
endmethod
method hide takes nothing returns thistype
if LOCAL_PLAYER[this.p] then
call MultiboardDisplay(this.selected_mb, false)
endif
return this
endmethod
method hide_from takes PlayerArray pa returns thistype
local integer i = 1
loop
exitwhen i > pa.count
if LOCAL_PLAYER[pa[i]] then
call MultiboardDisplay(this.selected_mb, false)
endif
set i = i + 1
endloop
return this
endmethod
method hide_all takes nothing returns thistype
call MultiboardDisplay(this.selected_mb, false)
return this
endmethod
endstruct
endlibrary
Simple example:
JASS:
local Blackboard bb = Blackboard(0)
// local Blackboard bb = Blackboard(PlayingPlayers[1])
call bb.println("A")
call bb.print("B")
call bb.print("C")
call bb.print("D")
call bb.println("")
call bb.println("E")
call bb.print("F")
call bb.print("G")
call bb.print("H")
call bb.println("I")
call bb.println("THEND")
call bb.flush(bb.TRSII_WIDTH).title("|cffFFFFFFBlackboard|r").show()
BBDebugMsg:
JASS:
library BBDebugMsg initializer init requires Blackboard
globals
private constant integer MAX_LINES = 16 // must be <= Blackboard.MAX_LINES
private string array lines
private integer line_p = 1
endglobals
private function init takes nothing returns nothing
local integer i = 1
loop
exitwhen i > MAX_LINES
set lines[i] = ""
set i = i + 1
endloop
endfunction
function BBDebugMsg takes string s returns nothing
local Blackboard bb = Blackboard(PlayingPlayers[1])
local integer i
local integer n
set lines[line_p] = s
set line_p = line_p + 1
if line_p > MAX_LINES then
set line_p = 1
endif
set n = 1
set i = line_p
loop
exitwhen n > MAX_LINES
call bb.println(lines[i])
set i = i + 1
if i > MAX_LINES then
set i = 1
endif
set n = n + 1
endloop
call bb.flush(bb.GOLD_ICON_START_WIDTH).show()
endfunction
endlibrary
Note that you can only use Blackboard after the "loading screen ends"
(
TimerStart(CreateTimer(), 0.0, false, function init)
)because multiboards created during map initialization time don't work correctly.
This means that the following won't work:
JASS:
private static method onInit takes nothing returns nothing
local Blackboard bb = Blackboard(0)
call bb.println(...)
call bb.flush(bb.HALF_WIDTH).show()
endmethod
Attachments
Last edited: