• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] CG's Transmission System

Level 14
Joined
Nov 20, 2005
Messages
1,156
Again, taken from Destiny's Wake, my transmission functions. Basically, you can have skippable and unskippable, voiced and not voiced, and stuff like that, with easy to use functions. The basic version requires you to press escape to move along, after you have read the text.

Easiest way to explain is to take a look at the map I used it in: http://www.hiveworkshop.com/resources_new/maps/6283/

If you wanted, you could put in timed versions whereby it was either after a time or after they escape, but personally I don't feel a need for that.

NB: This is single player ONLY. Will (almost) certainly desync on multiplayer.

JASS:
library TransmissionFuncs initializer Init

globals
    private unit bufferUnit
    private string bufferName
    private string bufferMessage = null
    private string bufferSound = null

    private sound currentSound = null
    private string currentSoundString = null

    private boolean EscapeInterrupt = false

    boolean END_AFTER_VOICE = true // this controls whether or not the transmission is auto-skipped after the end of a voiced bit.

    private timer soundTimer
    private string soundTimerString
    
    boolean InCinematic = false
    
    private code interEx
endglobals

// InCinematic should be set properly to avoid problems with the interrupt.
function CinematicModeOn takes nothing returns nothing
    set InCinematic = true
    call CinematicModeBJ(true, bj_FORCE_ALL_PLAYERS)
endfunction

function CinematicModeOff takes nothing returns nothing
    set InCinematic = false
    call CinematicModeBJ(false, bj_FORCE_ALL_PLAYERS)
endfunction

private function Interruption takes nothing returns nothing
    if InCinematic then
        if bufferMessage != null then
            call TimerStart(CreateTimer(), 0.00, false, interEx)
        else
            set EscapeInterrupt = true
        endif
        if currentSound != null and bufferSound != currentSoundString then
            call StopSound(currentSound, true, false)
        endif
    endif
endfunction

private function SetupVoice takes string snd returns nothing
    if currentSound != null then
        call KillSoundWhenDone(currentSound)
    endif
    call Preload(snd)
    set currentSound = CreateSound(snd, false, false, false, 10, 10, "")
    call StartSound(currentSound)
    set currentSoundString = snd
endfunction

private function SoundOver takes nothing returns nothing
    if soundTimer == GetExpiredTimer() and soundTimerString == currentSoundString then
        call Interruption.execute()
    endif
    call DestroyTimer(GetExpiredTimer())
endfunction

function DisplayText takes string data returns nothing
    call DisplayTextToPlayer(GetLocalPlayer(), 0., 0., data)
endfunction

function Transmission takes unit talker, string name, string message returns nothing
    call TransmissionFromUnitWithNameBJ( bj_FORCE_ALL_PLAYERS, talker, name, null, message, bj_TIMETYPE_ADD, 9999., false )
endfunction

function TransmissionSound takes unit talker, string name, string message, string snd returns nothing
    local timer t
    call SetupVoice(snd)
    call TransmissionFromUnitWithNameBJ( bj_FORCE_ALL_PLAYERS, talker, name, null, message, bj_TIMETYPE_ADD, 9999., false )
    if END_AFTER_VOICE then
        set t = CreateTimer()
        set soundTimer = t
        set soundTimerString = snd
        call TimerStart(t, I2R(GetSoundDuration(currentSound)) * 0.003 + 0.25, false, function SoundOver) // Why this is so, I have no idea. It just works.
    endif
endfunction

function TransmissionAndBuffer takes unit talker, string name, string message returns nothing
    call TransmissionFromUnitWithNameBJ( bj_FORCE_ALL_PLAYERS, talker, name, null, message, bj_TIMETYPE_ADD, 9999., false )
    set bufferUnit = talker
    set bufferName = name
    set bufferMessage = message
endfunction

function TransmissionSoundAndBuffer takes unit talker, string name, string message, string snd returns nothing
    call SetupVoice(snd)
    call TransmissionFromUnitWithNameBJ( bj_FORCE_ALL_PLAYERS, talker, name, null, message, bj_TIMETYPE_ADD, 9999., false )
    set bufferUnit = talker
    set bufferName = name
    set bufferMessage = message
    set bufferSound = snd
endfunction

function TransmissionTimed takes unit talker, string name, string message, real time returns nothing
    call TransmissionFromUnitWithNameBJ( bj_FORCE_ALL_PLAYERS, talker, name, null, message, bj_TIMETYPE_ADD, time-5., false )
endfunction

function TransmissionBufferDisplay takes nothing returns nothing
    call TransmissionFromUnitWithNameBJ( bj_FORCE_ALL_PLAYERS, bufferUnit, bufferName, null, bufferMessage, bj_TIMETYPE_ADD, 9999., false )
endfunction

function TransmissionBuffer takes unit talker, string name, string message returns nothing
    set bufferUnit = talker
    set bufferName = name
    set bufferMessage = message
endfunction

function TransmissionSoundBuffer takes unit talker, string name, string message, string snd returns nothing
    set bufferUnit = talker
    set bufferName = name
    set bufferMessage = message
    set bufferSound = snd
endfunction

function TransmissionClearBuffer takes nothing returns nothing
    set bufferUnit = null
    set bufferName = null
    set bufferMessage = null
    set bufferSound = null
endfunction

// This waits for escape, and does nothing else
function WaitEscape takes nothing returns nothing
    set EscapeInterrupt = false
    loop
        exitwhen EscapeInterrupt == true
        call TriggerSleepAction(0.)
    endloop
    set EscapeInterrupt = false
endfunction

// This waits for escape, and then displays the buffer, used to stop someone skipping it.
function WaitBuffer takes nothing returns nothing
    set EscapeInterrupt = false
    loop
        exitwhen EscapeInterrupt == true
        call TriggerSleepAction(0.)
    endloop
    call TransmissionBufferDisplay()
    set EscapeInterrupt = false
endfunction

// This clears the buffer, and then waits for escape. Used at the end of a transmission sequence.
function WaitConclude takes nothing returns nothing
    set EscapeInterrupt = false
    call TransmissionClearBuffer()
    loop
        exitwhen EscapeInterrupt == true
        call TriggerSleepAction(0.)
    endloop
    set EscapeInterrupt = false
endfunction

private function InterruptionEx takes nothing returns nothing
    if bufferSound != null and bufferSound != currentSoundString then
        call TransmissionSound(bufferUnit, bufferName, bufferMessage, bufferSound)
        set bufferSound = null
    else
        call Transmission(bufferUnit, bufferName, bufferMessage)
    endif
    set EscapeInterrupt = true
    call DestroyTimer(GetExpiredTimer())
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( t, GetLocalPlayer() )
    call TriggerAddAction( t, function Interruption )
    set interEx = function InterruptionEx
endfunction

endlibrary

Example usage:

This one is skippable with voice. You do an initial transmission, put the next one in the buffer, and then do WaitBuffer to display the next one when they skip.

JASS:
    call CinematicModeOn()
    call IssueImmediateOrder(udg_PlayerUnit, "holdposition")
    call TransmissionSound(udg_PlayerUnit, udg_PlayerName, "HAI! Take that you fatty!", "Hai!.mp3")
    call TransmissionSoundBuffer(udg_PlayerUnit, udg_PlayerName, "...they'll be after me....", "They'll be after me.mp3")
    call WaitBuffer()
    call TransmissionSoundBuffer(udg_PlayerUnit, udg_PlayerName, "...in force, too...", "In force, too.mp3")
    call WaitBuffer()
    call TransmissionSoundBuffer(udg_PlayerUnit, udg_PlayerName, "Maybe I should go talk to the people in that house over there; find out who's in charge.", "Maybe i should go talk.mp3")
    call WaitBuffer()
    call WaitConclude()
    call CinematicModeOff()

Another example, this time unskippable:

JASS:
    call CinematicModeOn()
    call TransmissionAndBuffer(udg_PlayerUnit, udg_PlayerName, "...new day, new worries.")
    call PolledWait(4.)
    call TransmissionClearBuffer()
    call CinematicModeOff()
 
Last edited:
Level 12
Joined
Aug 20, 2007
Messages
866
Questions

1. Are the texts supposed to have sound to them?
2. When are you going to make the next episode because I enjoyed it.

If it's supposed to have sound, for some reason your RPG does not have the voiced commands :sad:
 
Level 14
Joined
Nov 20, 2005
Messages
1,156
1. Are the texts supposed to have sound to them?
2. When are you going to make the next episode because I enjoyed it.

If it's supposed to have sound, for some reason your RPG does not have the voiced commands :sad:

The current release candidate for the first episode is being voiced. It hasn't been released yet. I can't really guarentee when I'll release the second episode, but don't hold your breath, I have exams coming up.
 
Level 12
Joined
Aug 20, 2007
Messages
866
Dang

Well, good luck on your tests and I hope you can get around to the next episode sooner or later, that was actually a really fun rpg :thumbs_up:
 
Three totally pointless == true and a lot of bad form (split functions which could easily be consolidated) and there's this:

call TriggerRegisterPlayerEventEndCinematic( t, GetLocalPlayer() )

Which will almost certainly desync because the things in the cinematic BJ's would slaughter any possibility of avoiding async. And library initializers are worthless.

And now I see this:

>> NB: This is single player ONLY. Will (almost) certainly desync on multiplayer.

(Because I look at the code long before reading the description)

That's definitely never appropriate for a submission. A resource must always be synchronous for multiplayer.
 
Top