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

[JASS] First JASS system attempt, please critique

Status
Not open for further replies.
Level 25
Joined
Jul 10, 2006
Messages
3,315
I was requested to make a JASS version of my http://www.hiveworkshop.com/forums/spells-569/gui-camera-shake-system-1-03-a-227421/

I didn't really have the patience for the unnecessarily long JASS tutorials, so I mainly reverse engineered this from triggers and various JASS systems.

Also please point out anything that should be replaced with more efficient code. It is, after all, a GUI system.

-- UPDATED --
- It is now a library
- Removed locations, using sqrt and coords for distance

-- UPDATED 2 --
- Removed BJs

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
//------------------------------------------

Thanks!
 
Last edited:
Arrays should have max indexes.
Player current shakes in the GetLocalPlayer if block should be inside a function.
So that you are just cacheing.

Ex.
Ill try fixing your dist thingy
[jass=]
private function Distance takes real x , real y returns real
return SquareRoot(Pow((x-EventX), 2) + Pow((y-EventY), 2)
endfunction
[/code]

That's how we use it in vJASS and JASS

Indention is a bit messy,should be 4 spaces in every block like:

library MYLIB
1234globals
12341234private constant real REAL
1234endglobals
endlibrary

That's how to indent

For the Init,you can put it inside a module.Modules are way faster in initialization.
like:
Module Init
implement Init
endmodule

Anyways,good job :D
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
Arrays should have max indexes.

How do I set this?

Player current shakes in the GetLocalPlayer if block should be inside a function.
So that you are just cacheing.

Will do.

Ill try fixing your dist thingy

Isn't it better to use less function calls? It is only used once, after all. From my understanding, functions are there to reduce redundant code, which this isn't.

Indention is a bit messy,should be 4 spaces in every block like:

Go count them, the indentation is perfect ;p

For the Init,you can put it inside a module.Modules are way faster in initialization.
like:
Module Init
implement Init
endmodule

I don't really understand exactly what the syntax for this should be, could you please provide a reference or a longer example?

Anyways,good job :D

Thanks. Not bad for learning vJASS overnight, hey? :p
 
How do I set arrays?
[jass=]
private integer Max Array = 10
private integer array Ex[Max Array][/code]
I don't really understand exactly what the syntax for this should be, could you please provide a reference or a longer example?
[jass=]
library Ex
module Init
implement AnInitializerFunction
endmodule
endlibrary
[/code]
Go count them, the indentation is perfect ;p
[jass=]
library MissIndention
private function Loop takes nothing returns nothing
call ForForce(ShakingPlayers, function LoopPerPlayer)
endfunction
endlibrary[/code]
Really??
Isn't it better to use less function calls? It is only used once, after all. From my understanding, functions are there to reduce redundant code, which this isn't.
View some vJASS spells in Hive.
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
[jass=]
library MissIndention
private function Loop takes nothing returns nothing
call ForForce(ShakingPlayers, function LoopPerPlayer)
endfunction
endlibrary[/code]
Really??

Missed that one, thanks. Observant as always :)

[EDIT: Strange, in the map the indentation is fine. I knew it was right... it must have somehow messed up when I put it in the post]

View some vJASS spells in Hive.

The point remains, the only advantage of that function in this case is that it improves readability.

It is used only once, so all that really changes is that this:
Code:
//get coords
dist = sqrt(stuff)
//use dist
becomes this:
Code:
//get coords
dist = call function
  return sqrt(stuff)
//use dist

So just an additional function call.
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
JASS:
library Ex
    module Init
        implement AnInitializerFunction
    endmodule
endlibrary

I can't get this to work.

Where should it go in the library? Is there any additional code needed?

I renamed my Init function to InitFunc and my module is:
JASS:
module Init
    implement InitFunc
endmodule
I've tried placing it first in library, then below globals, then just init func, then at the very end.

It doesn't do anything.
 
Level 37
Joined
Mar 6, 2006
Messages
9,243
According to Mag96, GetLocalPlayer causes Desyncs.

Only if you manipulate things that affect all players in the block basically. Don't go killing a unit in GetLocalPlayer block, but you can move camera there for example.

Some people say that Pow is a slow function, x*x is better than Pow(x,2). Also, instead of
JASS:
x = 3
if x > SquareRoot(y)
you can do
JASS:
x = 9
if x > y

This can save some processing power but I doubt it is anything meaningful in this script.
 
Status
Not open for further replies.
Top