// *************************************************************
// * Scrolling Text -- Version 2.3.0
// * by Deaod
// *************************************************************
// *
// * CREDITS:
// * - Anitarf (valuable research about in-game messages)
// * - UnMi, overcold_ice (inspiration)
// * - Vexorian (JassHelper)
// * - PitzerMike (JassNewGenPack)
// * - Pipedream (Grimoire)
// * - SFilip (TESH)
// *
// * HOW TO USE:
// * * declare a variable of type ScrollingText
// *
// * * use ScrollingText.create() to create a new instance
// *
// * * add text to display using YourScrollingTextInstance.add(string toAdd)
// * - toAdd is the actual text that should be displayed as credits.
// * - make sure toAdd is not longer than a single line in-game.
// *
// * * to display the ScrollingText, use YourScrollingTextInstance.display(real xOffset, real yOffset, real speed)
// * - xOffset and yOffset move the point where the Credits are being spawned around
// * - speed is the scrolling speed of the credits in lines per second
// *
// * * to stop displaying the ScrollingText, use ScrollingText.stopDisplay()
// * - this will clear the screen of any messages
// *
// * * to get the currently displaying instance, use ScrollingText.getCurrentInstance()
// * - returns the currently displaying instance or 0 if no instance is currently displaying
// *
// *************************************************************
library ScrollingText
globals
private constant real LINE_HEIGHT = 1./15 // 1./15 seems to be the optimal value
private constant integer MAX_DISP_LINES = 15 // 15 is suggested upper limit
private constant integer MAX_LINES_PER_INSTANCE = 1023 //
private constant real TICK = 1./40 // in seconds
endglobals
struct ScrollingText
private real speed
private real scrollDistance
private real xOff
private real yOff
private string linesDisplaying
private string array linesToDisplay[MAX_LINES_PER_INSTANCE]
private integer linesCount = 0
private boolean destroyWhenDone = false
private static integer running = 0
private static timer displayTimer = CreateTimer()
method add takes string toAdd returns nothing
if linesCount >= MAX_LINES_PER_INSTANCE then
debug call BJDebugMsg("ScrollingText.add(): MAX_LINES_PER_INSTANCE exceeded. Discarding following text.")
return
endif
set linesToDisplay[linesCount] = toAdd
if linesToDisplay[linesCount] == "" or linesToDisplay[linesCount] == null then // avoid displaying (null)
set linesToDisplay[linesCount] = " "
endif
set linesCount = linesCount + 1
endmethod
private method regenerateLinesDisplaying takes integer currentLine returns nothing
local integer index
set index = IMinBJ(currentLine, MAX_DISP_LINES) // number of lines to display
// lets gather the last 'index2' lines in 'linesDisplaying'
set linesDisplaying = ""
loop
exitwhen index <= 0
if currentLine - index < linesCount then // do we need to add more lines for padding?
set linesDisplaying = linesDisplaying + linesToDisplay[currentLine - index] // apparently not, so just take whats there.
else
set linesDisplaying = linesDisplaying + " " // we do, so add a single whitespace
endif
if index > 1 then
set linesDisplaying = linesDisplaying + "\n" // add a newline character, unless were at the end
endif
set index = index - 1
endloop
endmethod
private static method callback takes nothing returns nothing
local integer lastLine
local integer currentLine
local thistype this = running
set lastLine = R2I(scrollDistance / LINE_HEIGHT) + 1
set scrollDistance = scrollDistance + speed // scroll further
set currentLine = R2I(scrollDistance / LINE_HEIGHT) + 1 // generate the line were currently on, offset by +1
if lastLine < currentLine then // check whether we need to display a new line
call regenerateLinesDisplaying(currentLine)
endif
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), xOff, yOff + (scrollDistance - R2I(scrollDistance / LINE_HEIGHT) * LINE_HEIGHT), 16*TICK, linesDisplaying)
if currentLine > linesCount + MAX_DISP_LINES then
set running = 0
call PauseTimer(displayTimer)
if destroyWhenDone then
call destroy()
endif
endif
endmethod
method display takes real xOffset, real yOffset, real speed returns nothing
if running != 0 then
debug call BJDebugMsg("ScrollingText.display(): Can not display two instances at the same time.")
return
endif
set this.speed = speed * LINE_HEIGHT * TICK
set scrollDistance = 0
set xOff = xOffset
set yOff = yOffset
set running = this
call regenerateLinesDisplaying(1)
call TimerStart(displayTimer, TICK, true, function thistype.callback)
endmethod
static method stopDisplay takes nothing returns nothing
local thistype this
if running != 0 then
set this = running
call ClearTextMessages()
set running = 0
call PauseTimer(displayTimer)
if destroyWhenDone then
call destroy()
endif
endif
endmethod
static method getDisplayedInstance takes nothing returns thistype
return running
endmethod
method destroy takes nothing returns nothing
if running != 0 then
set destroyWhenDone = true
return
endif
call deallocate()
endmethod
endstruct
endlibrary