wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Resources > Code Resources > Scripts
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 02-17-2013, 10:38 PM   #1
Deaod
User
 
Join Date: Jan 2007
Posts: 538

Submissions (12)

Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)

Send a message via ICQ to Deaod Send a message via MSN to Deaod
Default ScrollingText

A library for scrolling text upwards.

Uses vJass.

Changelog:

04/01/2013 - Version 2.3.0
- removed overhead associated with displaying ScrollingText instances
- added a way to stop displaying a ScrollingText instance immediately.
- added a way to retrieve the currently displaying ScrollingText instance

12/27/2012 - Version 2.2.1
- optimizations (building the text to display only when needed)
- refactoring for better readability

12/27/2012 - Version 2.2.0
- removed tokenization and method addEx
- renamed struct from ScrollText to ScrollingText to match the library name
- removed counting calls to DisplayTimedTextToPlayer (debug-only before)
- added comments to the main logic

08/12/2012 - Version 2.1.0
- now automatically delays destroying until after finishing displaying the text

08/12/2012 - Version 2.0.0
- major refactoring for code cleanliness, descriptive names, better interface
- fixed the major caveat of lag after too many calls to DisplayTimedTextToPlayer by reducing calls to that function by a factor of at best 15

03/26/2009 - Version 1.0.0
- initial release



Collapse JASS:
// *************************************************************
// *             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
Attached Files
File Type: w3x ScrollingText_2.3.0.w3x (17.6 KB, 6 views)
__________________

Last edited by Deaod : 04-01-2013 at 04:02 PM. Reason: Updated to 2.3.0
Deaod is online now   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 02-19-2013, 01:45 PM   #2
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,083

Submissions (19)

Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

Hmm, not sure why you need support for multiple simultaneously running scrolling texts since only one can be on the screen at once anyway.
__________________
Anitarf is online now   Reply With Quote
Old 02-19-2013, 05:44 PM   #3
Deaod
User
 
Join Date: Jan 2007
Posts: 538

Submissions (12)

Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)

Send a message via ICQ to Deaod Send a message via MSN to Deaod
Default

Because you might want to display different scrolling texts to different players. Also because you might have different texts you want to scroll, so you set them up when the maps loaded and later display them as you wish.
__________________
Deaod is online now   Reply With Quote
Old 02-19-2013, 07:50 PM   #4
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,083

Submissions (19)

Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

That's not what I was talking about, though. What I meant was that the callback method does not need to have a loop.
__________________
Anitarf is online now   Reply With Quote
Old 03-30-2013, 05:02 PM   #5
Deaod
User
 
Join Date: Jan 2007
Posts: 538

Submissions (12)

Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)

Send a message via ICQ to Deaod Send a message via MSN to Deaod
Default

How about this then?

Collapse JASS:
// *************************************************************
// *             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
// *
// *************************************************************
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 thistype array structs
        private static integer structsCount = 0
        private static timer structsTimer = 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
                set structsCount = structsCount - 1
                set structs[index] = structs[structsCount]
                if structsCount == 0 then
                    call PauseTimer(structsTimer)
                endif
                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)
            
            set structs[structsCount] = this
            if structsCount == 0 then
                call TimerStart(structsTimer, TICK, true, function thistype.callback)
            endif
            set structsCount = structsCount + 1
        endmethod
        
        method destroy takes nothing returns nothing
            if running != 0 then
                set destroyWhenDone = true
                return
            endif
            call deallocate()
        endmethod
    endstruct
    
endlibrary
__________________
Deaod is online now   Reply With Quote
Old 03-31-2013, 10:23 PM   #6
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,083

Submissions (19)

Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

Yeah, something like that. With this setup, you no longer need the structs array and structsCount integer, as you only need to keep track of the single instance stored in the running static member.

It seems more intuitive that if the display method is called when a different instance is already running, the new instance replaces it, rather than the call doing nothing. With the current code I don't actually see a way to stop a running scrolling text, even the destroy method will only destroy it when it finishes, which is a problem if for example a user wants to make a scrolling text a part of a skippable cinematic.
__________________

Last edited by Anitarf : 03-31-2013 at 10:27 PM.
Anitarf is online now   Reply With Quote
Old 04-01-2013, 04:02 PM   #7
Deaod
User
 
Join Date: Jan 2007
Posts: 538

Submissions (12)

Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)Deaod is a jewel in the rough (182)

Send a message via ICQ to Deaod Send a message via MSN to Deaod
Default

Version 2.3.0
__________________
Deaod is online now   Reply With Quote
Old 04-01-2013, 04:14 PM   #8
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,083

Submissions (19)

Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)Anitarf has a brilliant future (883)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

Approved.
__________________
Anitarf is online now   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 05:51 PM.


Donate

Affiliates
The Hubb http://bylur.com - Warcraft, StarCraft, Diablo and DotA Blog & Forums The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2013, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services