• 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.

Canceling of unit transmissions

Status
Not open for further replies.
Level 3
Joined
Jul 11, 2007
Messages
51
Hey,
is there a way to prevent people from canceling the transmissions by hitting esc in a multiplayer map?

Thanks for the help.
 
Level 6
Joined
Sep 13, 2008
Messages
261
I'm not sure but the funniest thing I've seen was on a map. If someone hit escape during the cinematic they got autokicked, but it told them not to hit escape before it started. Then it said something like xxxxx got owned for being stupid when they pressed escape.
 
Level 3
Joined
Jul 11, 2007
Messages
51
Hm, if I get what you mean, that could be exploited pretty easily. Is there no way to deactivate ESC somehow?
 
Level 31
Joined
May 3, 2008
Messages
3,154
I'm not sure but the funniest thing I've seen was on a map. If someone hit escape during the cinematic they got autokicked, but it told them not to hit escape before it started. Then it said something like xxxxx got owned for being stupid when they pressed escape.

  • Melee Initialization
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
      • Player - Player 2 (Blue) skips a cinematic sequence
      • Player - Player 3 (Teal) skips a cinematic sequence
      • Player - Player 4 (Purple) skips a cinematic sequence
      • Player - Player 5 (Yellow) skips a cinematic sequence
    • Conditions
    • Actions
      • Game - Victory (Triggering player) (Skip dialogs, Skip scores)
      • Game - Display to (All players) for 15.00 seconds the text: ((Name of (Triggering player)) + have been a idiot by pressing ESC.)
Simple, eh ?

That is how we set it up if you wish to prevent a user from pressing ESC.
 
Sorry to rez this but there is definitely a way. All it requires is a bit of jass altering.

Ok, so the transmission turns out to be a BJ function, what a surprise! Well, anyway, let's take a look at it:
JASS:
function TransmissionFromUnitTypeWithNameBJ takes force toForce, player fromPlayer, integer unitId, string unitName, location loc, sound soundHandle, string message, integer timeType, real timeVal, boolean wait returns nothing
    call TryInitCinematicBehaviorBJ()

    // Ensure that the time value is non-negative.
    set timeVal = RMaxBJ(timeVal, 0)

    set bj_lastTransmissionDuration = GetTransmissionDuration(soundHandle, timeType, timeVal)
    set bj_lastPlayedSound = soundHandle

    if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
        // Use only local code (no net traffic) within this block to avoid desyncs.

        call DoTransmissionBasicsXYBJ(unitId, GetPlayerColor(fromPlayer), GetLocationX(loc), GetLocationY(loc), soundHandle, unitName, message, bj_lastTransmissionDuration)
    endif

    if wait and (bj_lastTransmissionDuration > 0) then
        // call TriggerSleepAction(bj_lastTransmissionDuration)
        call WaitTransmissionDuration(soundHandle, timeType, timeVal)
    endif

endfunction

Alright, seems simple eh? (well, it is if you know JASS pretty much)

Ok, so lucky for you I've studied these problems. Anything you notice that might in someway be related to the ESCing? Well, look at the first function.
JASS:
    call TryInitCinematicBehaviorBJ()

Hm... This might be it! Notice it has a BJ at the end so it is likely it is a potential candidate. Or at least it makes you know that you will be able to probably alter some part of it... =P

Ok, so let's look at THAT function:
JASS:
function TryInitCinematicBehaviorBJ takes nothing returns nothing
    local integer index

    if (bj_cineSceneBeingSkipped == null) then
        set bj_cineSceneBeingSkipped = CreateTrigger()
        set index = 0
        loop
            call TriggerRegisterPlayerEvent(bj_cineSceneBeingSkipped, Player(index), EVENT_PLAYER_END_CINEMATIC)
            set index = index + 1
            exitwhen index == bj_MAX_PLAYERS
        endloop
        call TriggerAddAction(bj_cineSceneBeingSkipped, function CancelCineSceneBJ)
    endif
endfunction

Hm.. Now what did it do? Basically, this is registering the cinematic ESC event, and the actions function is "function CancelCineSceneBJ". Let's look at that bj. (Don't jump to conclusions, you most likely can NOT do that with most jass functions.)

JASS:
function CancelCineSceneBJ takes nothing returns nothing
    call StopSoundBJ(bj_cineSceneLastSound, true)
    call EndCinematicScene()
endfunction

Basically, this stops the sound. The sound value you enter in GUI is stored in a variable called "bj_cineSceneLastSound" which is used globally to refer to the last cineSceneLastSound. Just so you know, they overwrite its data so you can't refer to older sounds you played with this unless it is part of the last transmission you did. Even if you input no sound, it runs a "no sound" sound that lasts 5 seconds. The transmission depends the sound duration, but you can alter it with the "add" or "subtract" or "set to" arguments in GUI.

Ok, now back on track. The next function is "EndCinematicScene()". Does that look like a native? It has no BJ at the end, and it is actually in fact a native. But BJs don't always have the BJ at the end. Sometimes they don't have the BJ suffix and it becomes confusing. Basically, BJs are functions that are made using natives, that are contained within the "blizzard.j" file.

So basically, EndCinematicScene() does not wait for the sound to end, it just ends the cinematic transmission.

Ok, with this knowledge we can construct a new cinematic function useable that WON'T let the transmission be skipped by pressing ESC.

Basically, just remove the "TryInitCinematicBehaviorBJ".
JASS:
function TransmissionFromUnitTypeWithNameEx takes force toForce, player fromPlayer, integer unitId, string unitName, location loc, sound soundHandle, string message, integer timeType, real timeVal, boolean wait returns nothing
    // Ensure that the time value is non-negative.
    set timeVal = RMaxBJ(timeVal, 0)

    set bj_lastTransmissionDuration = GetTransmissionDuration(soundHandle, timeType, timeVal)
    set bj_lastPlayedSound = soundHandle

    if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
        // Use only local code (no net traffic) within this block to avoid desyncs.

        call DoTransmissionBasicsXYBJ(unitId, GetPlayerColor(fromPlayer), GetLocationX(loc), GetLocationY(loc), soundHandle, unitName, message, bj_lastTransmissionDuration)
    endif

    if wait and (bj_lastTransmissionDuration > 0) then
        // call TriggerSleepAction(bj_lastTransmissionDuration)
        call WaitTransmissionDuration(soundHandle, timeType, timeVal)
    endif
endfunction

Now you would use it. Basically just like you would in GUI.

Just create a new trigger, create the transmission, then add whatever is in the parentheses to the parentheses of this:
JASS:
    Custom Script: call TransmissionFromUnitTypeWithNameEx( ...Insert parameters here... )

Then you have it ready to go!

It may seem complex, but it is either this or you will have to bear having people skin the function.

(If you find anything wrong with this function, code-wise, please tell me)

Cheers! :thumbs_up:
 
Status
Not open for further replies.
Top