• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[GUI/vJASS] Camera Shake System 1.06

Camera Shake System

Description
A simple system that allows you to create camera shake events at locations, which shake the camera for players that are looking at a nearby position.

  • MPI - Camera shakes individually for each player, and checks camera target (not position of a hero).
  • Shake magnitude is based on the camera's distance from the shake event location, full magnitude at the center and zero at maximum range.
  • Shake magnitude is reduced both by a flat amount and a percentage (both configurable), so the camera stops shaking gradually instead of fully at a set magnitude for a set time.

Installation
GUI (In the downloadable map)
1. Copy the Camera Shake System trigger category into your map, making sure the Automatically Create Unknown Variables is enabled on your editor.
2. Configure in the CSS Config trigger, and check the Readme for how to use the system.

vJASS
1. Copy the code in the jass tags below into your map.

Triggers

  • CSS Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Set how frequently the shake loop will run --------
      • Set CSS_LoopPeriod = 0.10
      • -------- How much shake magnitude is lost each loop --------
      • Set CSS_MagnitudeReduceFlat = 0.50
      • -------- What percentage of shake magnitude is lost every loop --------
      • Set CSS_MagnitudeReducePercent = 0.05
      • -------- How low the shakiness must be to be considered stopped --------
      • Set CSS_StopShakeThreshold = 0.50
      • -------- -------------------------------------------------------------------------------------------- --------
      • Trigger - Add to CSS Loop Shake <gen> the event (Time - Every CSS_LoopPeriod seconds of game time)
  • CSS New Event
    • Events
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Set tempPlayer = (Picked player)
          • Set tempId = (Player number of tempPlayer)
          • -------- Get enum player's camera location --------
          • Custom script: if GetLocalPlayer() == udg_tempPlayer then
          • Set tempX = (Target X of current camera view)
          • Set tempY = (Target Y of current camera view)
          • Custom script: endif
          • Set CSS_PlayerCameraLocation = (Point(tempX, tempY))
          • -------- Check if it is in range of point --------
          • Set tempDistance = (Distance between CSS_EventLocation and CSS_PlayerCameraLocation)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • tempDistance Less than or equal to CSS_EventMaxRange
            • Then - Actions
              • Set CSS_AddedShakiness = (CSS_EventMagnitude x ((CSS_EventMaxRange - tempDistance) / (CSS_EventMaxRange + tempDistance)))
              • Set CSS_PlayerCurrentShake[tempId] = (CSS_PlayerCurrentShake[tempId] + CSS_AddedShakiness)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (tempPlayer is in CSS_ShakingPlayers) Equal to False
                • Then - Actions
                  • Player Group - Add tempPlayer to CSS_ShakingPlayers
                • Else - Actions
            • Else - Actions
          • Custom script: call RemoveLocation(udg_CSS_PlayerCameraLocation)
      • Custom script: call RemoveLocation(udg_CSS_EventLocation)
  • CSS New Player Shake
    • Events
    • Conditions
    • Actions
      • Set CSS_tempId = (Player number of CSS_EventPlayer)
      • Set CSS_PlayerCurrentShake[CSS_tempId] = (CSS_PlayerCurrentShake[CSS_tempId] + CSS_EventMagnitude)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (CSS_EventPlayer is in CSS_ShakingPlayers) Equal to False
        • Then - Actions
          • Player Group - Add CSS_EventPlayer to CSS_ShakingPlayers
        • Else - Actions
  • CSS Loop Shake
    • Events
    • Conditions
    • Actions
      • Player Group - Pick every player in CSS_ShakingPlayers and do (Actions)
        • Loop - Actions
          • Set tempPlayer = (Picked player)
          • Set tempId = (Player number of tempPlayer)
          • Camera - Shake the camera for tempPlayer with magnitude CSS_PlayerCurrentShake[tempId]
          • Set CSS_PlayerCurrentShake[tempId] = (CSS_PlayerCurrentShake[tempId] - (CSS_PlayerCurrentShake[tempId] x CSS_MagnitudeReducePercent))
          • Set CSS_PlayerCurrentShake[tempId] = (CSS_PlayerCurrentShake[tempId] - CSS_MagnitudeReduceFlat)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • CSS_PlayerCurrentShake[tempId] Less than CSS_StopShakeThreshold
            • Then - Actions
              • Camera - Stop swaying/shaking the camera for tempPlayer
              • Player Group - Remove tempPlayer from CSS_ShakingPlayers
            • Else - Actions


  • Set CSS_EventLocation = (Position of (Triggering unit))
  • Set CSS_EventMagnitude = 15.00
  • Set CSS_EventMaxRange = 1000.00
  • Trigger - Run CSS New Event <gen> (ignoring conditions)
JASS
Note: My first attempt at JASS. Be harsh.
JASS:
library RCSS initializer Init
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y           location of origin of shake
//      Magnitude           the magnitude of the camera shake at origin point
//      MaxRange            the maximum range at which players are added
//
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer        the player to be shaken, not stirred
//      Magnitude           the amount of camera shake to be added to the player
//
// Configurables:
//  LOOP_PERIOD             the time between loops - how often the loop will run
//  SHAKE_REDUCE_FLAT       flat shake magnitude lost per loop
//  SHAKE_REDUCE_PERCENT    percent of current shake magnitude lost per loop
//  SHAKE_THRESHOLD         when shakiness goes below the threshold, it stops completely
//  RICHTER_MAX             the maximum magnitude of the shaking
//  RICHTER_MIN             the minimum magnitude of the shaking
//                  Note:   The shake variable still goes above, 
//                          and is then just to determine duration.
//-------------------------------------------------------------------
    globals
        //---- Camera Shake System ----
        //Configurables
        private constant real LOOP_PERIOD = 0.10
        private constant real SHAKE_REDUCE_FLAT = 0.50
        private constant real SHAKE_REDUCE_PERCENT = 0.05
        private constant real SHAKE_THRESHOLD = 0.50
        private constant real RICHTER_MAX = 5.0
        private constant real RICHTER_MIN = 2.0
        //System Variables
        private force shakingPlayers = CreateForce()
        private real array playerCurrentShake
        private real eventShake
        private real eventRange
        private real eventX
        private real eventY
    endglobals
    
    //Loop through players for camera shake
    private function LoopPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real richter = playerCurrentShake[i]
        local real temprichter
        if (richter > RICHTER_MAX) then
            set richter = RICHTER_MAX
        endif
        if (richter < RICHTER_MIN) then
            set richter = RICHTER_MIN
        endif
        if (GetLocalPlayer() == p) then
            set temprichter = playerCurrentShake[i] * Pow(10, richter)
            call CameraSetTargetNoiseEx(playerCurrentShake[i] * 2.0, temprichter, true)
            call CameraSetSourceNoiseEx(playerCurrentShake[i] * 2.0, temprichter, true)
        endif
        set playerCurrentShake[i] = ( playerCurrentShake[i] - ( playerCurrentShake[i] * SHAKE_REDUCE_PERCENT ) )
        set playerCurrentShake[i] = ( playerCurrentShake[i] - SHAKE_REDUCE_FLAT )
        if ( playerCurrentShake[i] < SHAKE_THRESHOLD ) then
            if (GetLocalPlayer() == p) then
                call CameraSetSourceNoise(0, 0)
                call CameraSetTargetNoise(0, 0)
            endif
            call ForceRemovePlayer(shakingPlayers, p)
        endif
        set p = null
    endfunction
    //Loop through players for location event
    private function NewEventLocPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real x
        local real y
        local real dist

        if GetLocalPlayer() == p then // Get enum player's camera location
            set x = GetCameraTargetPositionX()
            set y = GetCameraTargetPositionY()
        endif
        
        set dist = (x - eventX)*(x - eventX) + (y - eventY)*(y - eventY)
        if (dist <= eventRange*eventRange) then // Check if it is in range of point
            set playerCurrentShake[i] = ( playerCurrentShake[i] + ( eventShake * ( ( eventRange - dist ) / ( eventRange + dist ) ) ) ) //add shakiness
            if not (IsPlayerInForce(p, shakingPlayers)) then
                call ForceAddPlayer(shakingPlayers, p) //add player to shaking group
            endif
        endif
        set p = null
    endfunction
    //Register new location shake event
    public function NewEventLoc takes real x, real y, real m, real r returns nothing
        set eventX = x
        set eventY = y
        set eventShake = m
        set eventRange = r
        call ForForce( bj_FORCE_ALL_PLAYERS, function NewEventLocPerPlayer )
    endfunction
    //Register new player shake event
    public function NewEventPlayer takes player p, real m returns nothing
        local integer i = GetPlayerId(p)
        set playerCurrentShake[i] = (playerCurrentShake[i] + m)
        if not (IsPlayerInForce(p, shakingPlayers)) then
            call ForceAddPlayer(shakingPlayers, p)
        endif
    endfunction
    //Main loop for camera shaking
    private function Loop takes nothing returns nothing
        call ForForce(shakingPlayers, function LoopPerPlayer)
    endfunction
    
    private function Init takes nothing returns nothing
        call TimerStart(CreateTimer(), LOOP_PERIOD, true, function Loop)
    endfunction
endlibrary

Changelog
1.05 - 1.06
  • vJASS optimisations.
1.04
  • vJASS version included.
1.03
  • Changed variable name prefix to prevent possible conflict with other systems.
1.02
  • Added function to shake the camera for a specific player (this is useful because the system handles shake reduction and ending)
1.01
  • Cached some function calls. (thanks Radamantus)

Credits
dhguardianes - Advising me on the vJASS code.

Keywords:
camera, camera shake, shake, camera noise, camera rock, shake camera
Contents

Camera Shake System 1.03 (Map)

Reviews
18:12, 7th Jan 2013 Magtheridon96: Approved. vJASS version GUI version

Moderator

M

Moderator

18:12, 7th Jan 2013
Magtheridon96: Approved.

vJASS version
rating_p.gif


GUI version
rating_p.gif
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
@rulerofiron99
you can provide a version vjass ?

My first full attempt into the world of jass. Be harsh.
JASS:
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y - location of origin of shake
//      Magnitude - the magnitude of the camera shake at origin point
//      MaxRange - the maximum range at which players are added
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer - the player to be shaken, not stirred
//      Magnitude - the amount of camera shake to be added to the player
//
//-------------------------------------------------------------------
globals
    //---- Camera Shake System ----
    //Configurables
    real RCSS_LOOP_PERIOD = 0.10               // Set how frequently the shake loop will run
    real RCSS_SHAKE_REDUCE_FLAT = 0.50         // How much shake magnitude is lost each loop
    real RCSS_SHAKE_REDUCE_PERCENT = 0.05      // What percentage of shake magnitude is lost every loop
    real RCSS_SHAKE_THRESHOLD = 0.50           // How low the shakiness must be to be considered stopped
    //System Variables
    trigger RCSS_Setup = null
    force RCSS_ShakingPlayers = CreateForce()
    real array RCSS_PlayerCurrentShake
    real RCSS_EventShake
    real RCSS_EventRange
    location RCSS_EventLoc
    //-----------------------------
endglobals
    
//-------------------------------------
//Loop through players for camera shake
//-------------------------------------
function RCSS_LoopPerPlayer takes nothing returns nothing
    local player pl = GetEnumPlayer()
    local integer id = GetConvertedPlayerId(pl)
    call CameraSetEQNoiseForPlayer( pl, RCSS_PlayerCurrentShake[id] )
    set RCSS_PlayerCurrentShake[id] = ( RCSS_PlayerCurrentShake[id] - ( RCSS_PlayerCurrentShake[id] * RCSS_SHAKE_REDUCE_PERCENT ) )
    set RCSS_PlayerCurrentShake[id] = ( RCSS_PlayerCurrentShake[id] - RCSS_SHAKE_REDUCE_FLAT )
    if ( RCSS_PlayerCurrentShake[id] < RCSS_SHAKE_THRESHOLD ) then
        call CameraClearNoiseForPlayer( pl )
        call ForceRemovePlayerSimple(pl, RCSS_ShakingPlayers )
    endif
endfunction
//---------------------------------------
//Loop through players for location event
//---------------------------------------
function RCSS_NewEventPerPlayer takes nothing returns nothing
    local location ploc
    local player pl = GetEnumPlayer()
    local integer id = GetConvertedPlayerId(pl)
    local real x
    local real y
    local real dist
    local real add

    // Get enum player's camera location
    if GetLocalPlayer() == pl then
        set x = GetCameraTargetPositionX()
        set y = GetCameraTargetPositionY()
    endif
    set ploc = Location(x, y)
    // Check if it is in range of point
    set dist = DistanceBetweenPoints(RCSS_EventLoc, ploc)
    if ( dist <= RCSS_EventRange ) then
        set add = ( RCSS_EventShake * ( ( RCSS_EventRange - dist ) / ( RCSS_EventRange + dist ) ) )
        set RCSS_PlayerCurrentShake[id] = ( RCSS_PlayerCurrentShake[id] + add )
        if ( IsPlayerInForce(pl, RCSS_ShakingPlayers) == false ) then
            call ForceAddPlayer( RCSS_ShakingPlayers, pl )
        endif
    endif
    call RemoveLocation(ploc)
endfunction
//----------------------------------
//Register new location shake event
//----------------------------------
function RCSS_NewEventLoc takes real locx, real locy, real mg, real mr returns nothing
    set RCSS_EventLoc = Location(locx, locy)
    set RCSS_EventShake = mg
    set RCSS_EventRange = mr
    call ForForce( GetPlayersAll(), function RCSS_NewEventPerPlayer )
    call RemoveLocation(RCSS_EventLoc)
endfunction
//------------------------------
//Register new player shake event
//------------------------------
function RCSS_NewEventPlayer takes player pl, real mg returns nothing
    local integer id = GetConvertedPlayerId(pl)
    set RCSS_PlayerCurrentShake[id] = ( RCSS_PlayerCurrentShake[id] + mg )
    if ( IsPlayerInForce(pl, RCSS_ShakingPlayers) == false ) then
        call ForceAddPlayer( RCSS_ShakingPlayers, pl )
    endif
endfunction
//----------------------------
//Main loop for camera shaking
//----------------------------
function RCSS_Loop takes nothing returns nothing
        call ForForce( RCSS_ShakingPlayers, function RCSS_LoopPerPlayer )
endfunction
//--------------------
//Intialize the system
//--------------------
function InitTrig_RCSS_Setup takes nothing returns nothing
    set RCSS_Setup = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( RCSS_Setup, RCSS_LOOP_PERIOD )
    call TriggerAddAction( RCSS_Setup, function RCSS_Loop )
endfunction
//------------------------------------------
//End of camera shake system
//------------------------------------------

To get it to work, I had to
  • InitCamSystem
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: call InitTrig_RCSS_Setup()
I can't for the life of my figure out how to have the system initialize itself, or is that the point? Or would users typically be editing the main function?

When I'm ready to wrestle with jass again I'll make one using a scope/library.
 
If you're using globals.. You must Include Library.

Distance should beset dist = SquareRoot
JASS:
    trigger RCSS_Setup = null
    force RCSS_ShakingPlayers = CreateForce()
    real array RCSS_PlayerCurrentShake
    real RCSS_EventShake
    real RCSS_EventRange
    location RCSS_EventLoc
JASS:
    private trigger RCSS_Setup = null
    private force RCSS_ShakingPlayers = CreateForce()
    private real array RCSS_PlayerCurrentShake
    private real RCSS_EventShake
    private real RCSS_EventRange
    private location RCSS_EventLoc
If you want it in vJASS
Add APIs to make it more beautiful
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
Changes made:
- Now a library + initializer
- Things made private
- Removed locations, now only uses coords

JASS:
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y           location of origin of shake
//      Magnitude           the magnitude of the camera shake at origin point
//      MaxRange            the maximum range at which players are added
//
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer        the player to be shaken, not stirred
//      Magnitude           the amount of camera shake to be added to the player
//
// Configurables:
//  LOOP_PERIOD             the time between loops - how often the loop will run
//  SHAKE_REDUCE_FLAT       flat shake magnitude lost per loop
//  SHAKE_REDUCE_PERCENT    percent of current shake magnitude lost per loop
//  SHAKE_THRESHOLD         when shakiness goes below the threshold, it stops completely
//-------------------------------------------------------------------

library CameraShakeSystem initializer Init

    globals
        //---- Camera Shake System ----
        //Configurables
        private constant real LOOP_PERIOD = 0.10
        private constant real SHAKE_REDUCE_FLAT = 0.50
        private constant real SHAKE_REDUCE_PERCENT = 0.05
        private constant real SHAKE_THRESHOLD = 0.50
        //System Variables
        private trigger Setup = null
        private force ShakingPlayers = CreateForce()
        private real array PlayerCurrentShake
        private real EventShake
        private real EventRange
        private real EventX
        private real EventY
        
        //-----------------------------
    endglobals
    
    //-------------------------------------
    //Loop through players for camera shake
    //-------------------------------------
    private function LoopPerPlayer takes nothing returns nothing
        local player pl = GetEnumPlayer()
        local integer id = GetConvertedPlayerId(pl)
        call CameraSetEQNoiseForPlayer( pl, PlayerCurrentShake[id] )
        set PlayerCurrentShake[id] = ( PlayerCurrentShake[id] - ( PlayerCurrentShake[id] * SHAKE_REDUCE_PERCENT ) )
        set PlayerCurrentShake[id] = ( PlayerCurrentShake[id] - SHAKE_REDUCE_FLAT )
        if ( PlayerCurrentShake[id] < SHAKE_THRESHOLD ) then
            call CameraClearNoiseForPlayer( pl )
            call ForceRemovePlayerSimple(pl, ShakingPlayers )
        endif
    endfunction
    //---------------------------------------
    //Loop through players for location event
    //---------------------------------------
    private function NewEventLocPerPlayer takes nothing returns nothing
        local player pl = GetEnumPlayer()
        local integer id = GetConvertedPlayerId(pl)
        local real x
        local real y
        local real dist
        local real add

        if GetLocalPlayer() == pl then // Get enum player's camera location
            set x = GetCameraTargetPositionX()
            set y = GetCameraTargetPositionY()
        endif
        
        set dist = SquareRoot(Pow((x-EventX), 2) + Pow((y-EventY), 2) )
        if ( dist <= EventRange ) then // Check if it is in range of point
            set add = ( EventShake * ( ( EventRange - dist ) / ( EventRange + dist ) ) )
            set PlayerCurrentShake[id] = ( PlayerCurrentShake[id] + add ) //add shakiness
            if ( IsPlayerInForce(pl, ShakingPlayers) == false ) then
                call ForceAddPlayer( ShakingPlayers, pl ) //add player to shaking group
            endif
        endif
    endfunction
    //----------------------------------
    //Register new location shake event
    //----------------------------------
    function RCSS_NewEventLoc takes real locx, real locy, real mg, real mr returns nothing
        set EventX = locx
        set EventY = locy
        set EventShake = mg
        set EventRange = mr
        call ForForce( GetPlayersAll(), function NewEventLocPerPlayer )
    endfunction
    //-------------------------------
    //Register new player shake event
    //-------------------------------
    function RCSS_NewEventPlayer takes player pl, real mg returns nothing
        local integer id = GetConvertedPlayerId(pl)
        set PlayerCurrentShake[id] = ( PlayerCurrentShake[id] + mg )
        if ( IsPlayerInForce(pl, ShakingPlayers) == false ) then
            call ForceAddPlayer( ShakingPlayers, pl )
        endif
    endfunction
    //----------------------------
    //Main loop for camera shaking
    //----------------------------
    private function Loop takes nothing returns nothing
            call ForForce( ShakingPlayers, function LoopPerPlayer )
    endfunction
    //--------------------
    //Intialize the system
    //--------------------
    private function Init takes nothing returns nothing
        set Setup = CreateTrigger(  )
        call TriggerRegisterTimerEventPeriodic( Setup, LOOP_PERIOD )
        call TriggerAddAction( Setup, function Loop )
    endfunction
endlibrary
//------------------------------------------
//End of camera shake system
//------------------------------------------

If you want it in vJASS
Add APIs to make it more beautiful

What is an API?
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
Here we go!

JASS:
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y           location of origin of shake
//      Magnitude           the magnitude of the camera shake at origin point
//      MaxRange            the maximum range at which players are added
//
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer        the player to be shaken, not stirred
//      Magnitude           the amount of camera shake to be added to the player
//
// Configurables:
//  LOOP_PERIOD             the time between loops - how often the loop will run
//  SHAKE_REDUCE_FLAT       flat shake magnitude lost per loop
//  SHAKE_REDUCE_PERCENT    percent of current shake magnitude lost per loop
//  SHAKE_THRESHOLD         when shakiness goes below the threshold, it stops completely
//  RICHTER_MAX             the maximum magnitude of the shaking
//  RICHTER_MIN             the minimum magnitude of the shaking
//                  Note:   The shake variable still goes above, 
//                          and is then just to determine duration.
//-------------------------------------------------------------------

library CameraShakeSystem initializer Init

    globals
        //---- Camera Shake System ----
        //Configurables
        private constant real LOOP_PERIOD = 0.10
        private constant real SHAKE_REDUCE_FLAT = 0.50
        private constant real SHAKE_REDUCE_PERCENT = 0.05
        private constant real SHAKE_THRESHOLD = 0.50
        private constant real RICHTER_MAX = 5.0
        private constant real RICHTER_MIN = 2.0
        //System Variables
        private trigger Setup = null
        private force ShakingPlayers = CreateForce()
        private real array PlayerCurrentShake
        private real EventShake
        private real EventRange
        private real EventX
        private real EventY
        
        //-----------------------------
    endglobals
    
    //-------------------------------------
    //Loop through players for camera shake
    //-------------------------------------
    private function LoopPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real richter = PlayerCurrentShake[i]
        if (richter > RICHTER_MAX) then
            set richter = RICHTER_MAX
        endif
        if (richter < RICHTER_MIN) then
            set richter = RICHTER_MIN
        endif
        if (GetLocalPlayer() == p) then
            call CameraSetTargetNoiseEx(PlayerCurrentShake[i]*2.0, PlayerCurrentShake[i]*Pow(10,richter),true)
            call CameraSetSourceNoiseEx(PlayerCurrentShake[i]*2.0, PlayerCurrentShake[i]*Pow(10,richter),true)
        endif
        set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] - ( PlayerCurrentShake[i] * SHAKE_REDUCE_PERCENT ) )
        set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] - SHAKE_REDUCE_FLAT )
        if ( PlayerCurrentShake[i] < SHAKE_THRESHOLD ) then
            if (GetLocalPlayer() == p) then
                call CameraSetSourceNoise(0, 0)
                call CameraSetTargetNoise(0, 0)
            endif
            call ForceRemovePlayer(ShakingPlayers, p)
        endif
    endfunction
    //---------------------------------------
    //Loop through players for location event
    //---------------------------------------
    private function NewEventLocPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real x
        local real y
        local real dist
        local real add

        if GetLocalPlayer() == p then // Get enum player's camera location
            set x = GetCameraTargetPositionX()
            set y = GetCameraTargetPositionY()
        endif
        
        set dist = SquareRoot(Pow((x-EventX), 2) + Pow((y-EventY), 2) )
        if ( dist <= EventRange ) then // Check if it is in range of point
            set add = ( EventShake * ( ( EventRange - dist ) / ( EventRange + dist ) ) )
            set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] + add ) //add shakiness
            if ( IsPlayerInForce(p, ShakingPlayers) == false ) then
                call ForceAddPlayer(ShakingPlayers, p) //add player to shaking group
            endif
        endif
    endfunction
    //----------------------------------
    //Register new location shake event
    //----------------------------------
    function RCSS_NewEventLoc takes real x, real y, real m, real r returns nothing
        set EventX = x
        set EventY = y
        set EventShake = m
        set EventRange = r
        call ForForce( bj_FORCE_ALL_PLAYERS, function NewEventLocPerPlayer )
    endfunction
    //-------------------------------
    //Register new player shake event
    //-------------------------------
    function RCSS_NewEventPlayer takes player p, real m returns nothing
        local integer i = GetPlayerId(p)
        set PlayerCurrentShake[i] = (PlayerCurrentShake[i] + m)
        if (IsPlayerInForce(p, ShakingPlayers) == false) then
            call ForceAddPlayer(ShakingPlayers, p)
        endif
    endfunction
    //----------------------------
    //Main loop for camera shaking
    //----------------------------
    private function Loop takes nothing returns nothing
            call ForForce(ShakingPlayers, function LoopPerPlayer)
    endfunction
    //--------------------
    //Intialize the system
    //--------------------
    private function Init takes nothing returns nothing
        set Setup = CreateTrigger(  )
        call TriggerRegisterTimerEvent( Setup, LOOP_PERIOD, true )
        call TriggerAddAction( Setup, function Loop )
    endfunction
endlibrary
//------------------------------------------
//End of camera shake system
//------------------------------------------

It's actually quite nice that JNGP highlights these things in red.
 
@rulerofiron99:

like better
JASS:
library RCSS initializer Init
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y           location of origin of shake
//      Magnitude           the magnitude of the camera shake at origin point
//      MaxRange            the maximum range at which players are added
//
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer        the player to be shaken, not stirred
//      Magnitude           the amount of camera shake to be added to the player
//
// Configurables:
//  LOOP_PERIOD             the time between loops - how often the loop will run
//  SHAKE_REDUCE_FLAT       flat shake magnitude lost per loop
//  SHAKE_REDUCE_PERCENT    percent of current shake magnitude lost per loop
//  SHAKE_THRESHOLD         when shakiness goes below the threshold, it stops completely
//  RICHTER_MAX             the maximum magnitude of the shaking
//  RICHTER_MIN             the minimum magnitude of the shaking
//                  Note:   The shake variable still goes above, 
//                          and is then just to determine duration.
//-------------------------------------------------------------------
    globals
        //---- Camera Shake System ----
        //Configurables
        private constant real LOOP_PERIOD = 0.10
        private constant real SHAKE_REDUCE_FLAT = 0.50
        private constant real SHAKE_REDUCE_PERCENT = 0.05
        private constant real SHAKE_THRESHOLD = 0.50
        private constant real RICHTER_MAX = 5.0
        private constant real RICHTER_MIN = 2.0
        //System Variables
        private force ShakingPlayers = CreateForce()
        private real array PlayerCurrentShake
        private real EventShake
        private real EventRange
        private real EventX
        private real EventY
    endglobals
    
    //Loop through players for camera shake
    private function LoopPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real richter = PlayerCurrentShake[i]
        if (richter > RICHTER_MAX) then
            set richter = RICHTER_MAX
        endif
        if (richter < RICHTER_MIN) then
            set richter = RICHTER_MIN
        endif
        if (GetLocalPlayer() == p) then
            call CameraSetTargetNoiseEx(PlayerCurrentShake[i] * 2.0, PlayerCurrentShake[i] * Pow(10, richter), true)
            call CameraSetSourceNoiseEx(PlayerCurrentShake[i] * 2.0, PlayerCurrentShake[i] * Pow(10, richter), true)
        endif
        set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] - ( PlayerCurrentShake[i] * SHAKE_REDUCE_PERCENT ) )
        set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] - SHAKE_REDUCE_FLAT )
        if ( PlayerCurrentShake[i] < SHAKE_THRESHOLD ) then
            if (GetLocalPlayer() == p) then
                call CameraSetSourceNoise(0, 0)
                call CameraSetTargetNoise(0, 0)
            endif
            call ForceRemovePlayer(ShakingPlayers, p)
        endif
    endfunction
    //Loop through players for location event
    private function NewEventLocPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real x
        local real y
        local real dist
        local real add

        if GetLocalPlayer() == p then // Get enum player's camera location
            set x = GetCameraTargetPositionX()
            set y = GetCameraTargetPositionY()
        endif
        
        set dist = SquareRoot(Pow((x - EventX), 2) + Pow((y - EventY), 2) )
        if ( dist <= EventRange ) then // Check if it is in range of point
            set add = ( EventShake * ( ( EventRange - dist ) / ( EventRange + dist ) ) )
            set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] + add ) //add shakiness
            if ( IsPlayerInForce(p, ShakingPlayers) == false ) then
                call ForceAddPlayer(ShakingPlayers, p) //add player to shaking group
            endif
        endif
    endfunction
    //Register new location shake event
    public function NewEventLoc takes real x, real y, real m, real r returns nothing
        set EventX = x
        set EventY = y
        set EventShake = m
        set EventRange = r
        call ForForce( bj_FORCE_ALL_PLAYERS, function NewEventLocPerPlayer )
    endfunction
    //Register new player shake event
    public function NewEventPlayer takes player p, real m returns nothing
        local integer i = GetPlayerId(p)
        set PlayerCurrentShake[i] = (PlayerCurrentShake[i] + m)
        if (IsPlayerInForce(p, ShakingPlayers) == false) then
            call ForceAddPlayer(ShakingPlayers, p)
        endif
    endfunction
    //Main loop for camera shaking
    private function Loop takes nothing returns nothing
        call ForForce(ShakingPlayers, function LoopPerPlayer)
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterTimerEvent(t, LOOP_PERIOD, true )
        call TriggerAddAction(t, function Loop )
    endfunction
endlibrary
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
@rulerofiron99:

like better
JASS:
library RCSS initializer Init
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y           location of origin of shake
//      Magnitude           the magnitude of the camera shake at origin point
//      MaxRange            the maximum range at which players are added
//
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer        the player to be shaken, not stirred
//      Magnitude           the amount of camera shake to be added to the player
//
// Configurables:
//  LOOP_PERIOD             the time between loops - how often the loop will run
//  SHAKE_REDUCE_FLAT       flat shake magnitude lost per loop
//  SHAKE_REDUCE_PERCENT    percent of current shake magnitude lost per loop
//  SHAKE_THRESHOLD         when shakiness goes below the threshold, it stops completely
//  RICHTER_MAX             the maximum magnitude of the shaking
//  RICHTER_MIN             the minimum magnitude of the shaking
//                  Note:   The shake variable still goes above, 
//                          and is then just to determine duration.
//-------------------------------------------------------------------
    globals
        //---- Camera Shake System ----
        //Configurables
        private constant real LOOP_PERIOD = 0.10
        private constant real SHAKE_REDUCE_FLAT = 0.50
        private constant real SHAKE_REDUCE_PERCENT = 0.05
        private constant real SHAKE_THRESHOLD = 0.50
        private constant real RICHTER_MAX = 5.0
        private constant real RICHTER_MIN = 2.0
        //System Variables
        private force ShakingPlayers = CreateForce()
        private real array PlayerCurrentShake
        private real EventShake
        private real EventRange
        private real EventX
        private real EventY
    endglobals
    
    //Loop through players for camera shake
    private function LoopPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real richter = PlayerCurrentShake[i]
        if (richter > RICHTER_MAX) then
            set richter = RICHTER_MAX
        endif
        if (richter < RICHTER_MIN) then
            set richter = RICHTER_MIN
        endif
        if (GetLocalPlayer() == p) then
            call CameraSetTargetNoiseEx(PlayerCurrentShake[i] * 2.0, PlayerCurrentShake[i] * Pow(10, richter), true)
            call CameraSetSourceNoiseEx(PlayerCurrentShake[i] * 2.0, PlayerCurrentShake[i] * Pow(10, richter), true)
        endif
        set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] - ( PlayerCurrentShake[i] * SHAKE_REDUCE_PERCENT ) )
        set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] - SHAKE_REDUCE_FLAT )
        if ( PlayerCurrentShake[i] < SHAKE_THRESHOLD ) then
            if (GetLocalPlayer() == p) then
                call CameraSetSourceNoise(0, 0)
                call CameraSetTargetNoise(0, 0)
            endif
            call ForceRemovePlayer(ShakingPlayers, p)
        endif
    endfunction
    //Loop through players for location event
    private function NewEventLocPerPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real x
        local real y
        local real dist
        local real add

        if GetLocalPlayer() == p then // Get enum player's camera location
            set x = GetCameraTargetPositionX()
            set y = GetCameraTargetPositionY()
        endif
        
        set dist = SquareRoot(Pow((x - EventX), 2) + Pow((y - EventY), 2) )
        if ( dist <= EventRange ) then // Check if it is in range of point
            set add = ( EventShake * ( ( EventRange - dist ) / ( EventRange + dist ) ) )
            set PlayerCurrentShake[i] = ( PlayerCurrentShake[i] + add ) //add shakiness
            if ( IsPlayerInForce(p, ShakingPlayers) == false ) then
                call ForceAddPlayer(ShakingPlayers, p) //add player to shaking group
            endif
        endif
    endfunction
    //Register new location shake event
    public function NewEventLoc takes real x, real y, real m, real r returns nothing
        set EventX = x
        set EventY = y
        set EventShake = m
        set EventRange = r
        call ForForce( bj_FORCE_ALL_PLAYERS, function NewEventLocPerPlayer )
    endfunction
    //Register new player shake event
    public function NewEventPlayer takes player p, real m returns nothing
        local integer i = GetPlayerId(p)
        set PlayerCurrentShake[i] = (PlayerCurrentShake[i] + m)
        if (IsPlayerInForce(p, ShakingPlayers) == false) then
            call ForceAddPlayer(ShakingPlayers, p)
        endif
    endfunction
    //Main loop for camera shaking
    private function Loop takes nothing returns nothing
        call ForForce(ShakingPlayers, function LoopPerPlayer)
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterTimerEvent(t, LOOP_PERIOD, true )
        call TriggerAddAction(t, function Loop )
    endfunction
endlibrary

That does look better.

Let me know if I missed anything:
  • Library name shortened and moved to top (why should it be at the top?)
  • Comment linebreaks removed (makes sense)
  • Trigger changed to a local variable
 
That does look better.

Let me know if I missed anything:
  • Library name shortened and moved to top (why should it be at the top?)
  • Comment linebreaks removed (makes sense)
  • Trigger changed to a local variable

1,func me have changed is public function NewEventPlayer when call func! typing <LibraryName>_NewEventPlayer Ex: RCSS_NewEventPlayer
if you have any questions about! please visit this page
http://www.wc3c.net/vexorian/jasshelpermanual.html#pub

2, because this is not GUI,I think no need linebreaks
3, because it is very popular with vjass
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
1,func me have changed is public function NewEventPlayer when call func! typing <LibraryName>_NewEventPlayer Ex: RCSS_NewEventPlayer
if you have any questions about! please visit this page
http://www.wc3c.net/vexorian/jasshelpermanual.html#pub

2, because this is not GUI,I think no need linebreaks
3, because it is very popular with vjass

Interesting! I did not know about this feature of libraries.

Thanks for your assistance.
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
vJass looks nice :)

One small thing:

JASS:
if not (IsPlayerInForce(p, shakingPlayers)) then
    call ForceAddPlayer(shakingPlayers, p) //add player to shaking group
endif

->

call ForceAddPlayer(shakingPlayers, p) // add player to shaking group

(Force is a set, not an array-like)
 

Attachments

  • force_add_player_twice_test.w3m
    15.7 KB · Views: 47
Level 20
Joined
Aug 13, 2013
Messages
1,696
In case someone will use the vJASS version of this resource; (If there is)

This should be even set to awaiting update. There's a critical miscalculation made on
JASS:
set dist = (x - eventX)*(x - eventX) + (y - eventY)*(y - eventY) // should be squareroot in this case >.<
set playerCurrentShake[i] = ( playerCurrentShake[i] + ( eventShake * ( ( eventRange - dist ) / ( eventRange + dist ) ) ) )
which make the system don't work in the first place.

At least, GUI works fine.
 
Level 23
Joined
Jan 1, 2011
Messages
1,504
Here is a cleaned up version, fully optimized using a local timer. (Which is completely safe and well tested)
JASS:
library RCSS initializer init
//-------------------------------------------------------------------
//---- Camera Shake System ----
//by rulerofiron99
//  updated by maddeem
//
// Functions:
//  RCSS_NewEventLoc takes real TargetX, real TargetY, real Magnitude, real MaxRange
//      TargetX/Y           location of origin of shake
//      Magnitude           the magnitude of the camera shake at origin point
//      MaxRange            the maximum range at which players are added
//
//  RCSS_NewEventPlayer takes player TargetPlayer, real Magnitude
//      TargetPlayer        the player to be shaken, not stirred
//      Magnitude           the amount of camera shake to be added to the player
//
// Configurables:
//  LOOP_PERIOD             the time between loops - how often the loop will run
//  SHAKE_REDUCE_FLAT       flat shake magnitude lost per loop
//  SHAKE_REDUCE_PERCENT    percent of current shake magnitude lost per loop
//  SHAKE_THRESHOLD         when shakiness goes below the threshold, it stops completely
//  RICHTER_MAX             the maximum magnitude of the shaking
//  RICHTER_MIN             the minimum magnitude of the shaking
//                  Note:   The shake variable still goes above, 
//                          and is then just to determine duration.
//-------------------------------------------------------------------
    globals
        //---- Camera Shake System ----
        //Configurables
        private constant real LOOP_PERIOD = 0.10
        private constant real SHAKE_REDUCE_FLAT = 0.50
        private constant real SHAKE_REDUCE_PERCENT = 0.05
        private constant real SHAKE_THRESHOLD = 0.50
        private constant real RICHTER_MAX = 5.0
        private constant real RICHTER_MIN = 2.0
        //System Variables
        private real playerCurrentShake = 0
        private timer time = CreateTimer()
        private boolean isRunning = false
    endglobals
    
    //Loop through players for camera shake
    private function loopT takes nothing returns nothing
        local real richter 
        set playerCurrentShake = playerCurrentShake - playerCurrentShake * SHAKE_REDUCE_PERCENT - SHAKE_REDUCE_FLAT
        if playerCurrentShake < SHAKE_THRESHOLD  then
            call CameraSetSourceNoise(0, 0)
            call CameraSetTargetNoise(0, 0)
            set isRunning = false
            call PauseTimer(time)
        else
            if playerCurrentShake > RICHTER_MAX then
                set richter = playerCurrentShake * Pow(10, RICHTER_MAX)
            elseif playerCurrentShake < RICHTER_MIN then
                set richter = playerCurrentShake * Pow(10, RICHTER_MIN)
            else
                set richter = playerCurrentShake * Pow(10, playerCurrentShake)
            endif
            call CameraSetTargetNoiseEx(playerCurrentShake * 2.0, richter, true)
            call CameraSetSourceNoiseEx(playerCurrentShake * 2.0, richter, true)
        endif
    endfunction

    //Register new location shake event
    public function NewEventLoc takes real x1, real y1, real m, real r returns nothing
        local real x2 = GetCameraTargetPositionX()
        local real y2= GetCameraTargetPositionY()
        local real dx = x2 - x1
        local real dy = y2 - y1
        local real d = SquareRoot(dx*dx + dy*dy)
        if d < r  then // Check if it is in range of point
            set playerCurrentShake = playerCurrentShake +  m *  ( r - d ) / ( r + d )  //add shakiness
            if not isRunning then
                call TimerStart(time,LOOP_PERIOD,true, function loopT)
                set isRunning = true
            endif
        endif
    endfunction
    //Register new player shake event
    public function NewEventPlayer takes player p, real m returns nothing
        if GetLocalPlayer() == p then
            set playerCurrentShake = playerCurrentShake + m
            if not isRunning then
                call TimerStart(time,LOOP_PERIOD,true, function loopT)
                set isRunning = true
            endif
        endif
    endfunction
    
    private function init takes nothing returns nothing
        call TimerStart(time, 0, false, null)
    endfunction
endlibrary
 
Top