Procrastination Incarnate
Development Director
Join Date: Feb 2004
Posts: 8,190
|
Cinema Workshop

Requirements:
ARGB
Table
LinkedList
TimerUtils
UnitAppearanceTracker
DisplayCenteredText | CINEMA WORKSHOP
This is a compilation of vJass libraries intended to replace the old Cinematic System, which is over five years old already. This compilation itself has been in the making for two years now and represents a major leap forward in terms of speed, functionality and user-friendliness.
Like its predecessor, Cinema Workshop consists of three main components:
- Transition - A library that facilitates gradual changes of various properties such as unit position.
Additional modules:
|
| - UnitColorTransition
- UnitScaleTransition
- UnitFacingTransition
- UnitPositionTransition
|
|
- CineCam - A library that takes command of the game camera and gives the user more control over it.
- CineScript - The core of the system, a powerful library for composing and playing sequences of events.
Additional modules:
| - UnitAnimationCineScript
- UnitTransitionCineScript
- EnvironmentCineScript
| - UtilityCineScript
- EffectCineScript
- SoundCineScript
| - CameraCineScript
- SubtitleCineScript
|
The new design is completely modular, each component can be used independently from the other two. Transition and CineScript each come with a collection of extensions that can be included in your map as needed. When used for their primary purpose of making cinematics, the three otherwise independent components achieve a strong synergy. The demo map includes both a sample cinematic that uses the entire CinemaWorkshop as well as a sample code for a triggered spell that only uses CineScript.
|
 Transition library: library Transition requires optional CineCam
globals
constant real TRANSITION_UPDATE_PERIOD=0.02
constant integer TRANSITION_TYPE_LINEAR=0
constant integer TRANSITION_TYPE_SQUARE1=-1
constant integer TRANSITION_TYPE_SQUARE2=-2
constant integer TRANSITION_TYPE_SINE=-3
endglobals
function interface TransitionType takes real linearFactor returns real
module Transition
private real time
private real duration
private integer transtype
private boolean autodestroy
private boolean running
private boolean active
private static thistype array V
private static integer N = 0
private static timer T
private static method main takes nothing returns nothing
local thistype this
local integer i=0
local integer j=0
local real f
loop
exitwhen i>=thistype.N
set this=thistype.V[i]
if .running then
static if LIBRARY_CineCam then
set .time=.time+CINECAM_UPDATE_PERIOD
else
set .time=.time+TRANSITION_UPDATE_PERIOD
endif
if .time>=.duration then
set .time=.duration
set .running=false
endif
set f=.time/.duration
if .transtype==TRANSITION_TYPE_LINEAR then
elseif .transtype==TRANSITION_TYPE_SINE then
set f = (1.0 - Cos(f*bj_PI)) / 2
elseif .transtype==TRANSITION_TYPE_SQUARE1 then
set f = f*f
elseif .transtype==TRANSITION_TYPE_SQUARE2 then
set f = 1.0 - f
set f = 1.0 - f*f
else
set f = TransitionType(.transtype).evaluate(f)
endif
call .onTransition(f)
set thistype.V[j]=this
set j=j+1
else
set .active=false
if .autodestroy then
call .destroy()
endif
endif
set i=i+1
endloop
set thistype.N=j
static if not(LIBRARY_CineCam) then
if thistype.N==0 then
call PauseTimer(thistype.T)
endif
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_CineCam then
call OnCineCamUpdate(thistype.main)
else
set thistype.T=CreateTimer()
endif
endmethod
public method startTransition takes real duration, integer transitiontype, boolean autodestroy returns nothing
static if LIBRARY_CineCam then
if duration<CINECAM_UPDATE_PERIOD then
set duration=CINECAM_UPDATE_PERIOD
endif
else
if duration<TRANSITION_UPDATE_PERIOD then
set duration=TRANSITION_UPDATE_PERIOD
endif
endif
set .autodestroy=autodestroy
set .transtype=transitiontype
set .duration=duration
set .time=0.0
if not .active then
static if not(LIBRARY_CineCam) then
if thistype.N==0 then
call TimerStart(thistype.T, TRANSITION_UPDATE_PERIOD, true, function thistype.main)
endif
endif
set thistype.V[thistype.N]=this
set thistype.N=thistype.N+1
set .active=true
endif
set .running=true
endmethod
public method stopTransition takes nothing returns nothing
set .running=false
endmethod
endmodule
struct Transition
stub method onTransition takes real factor returns nothing
endmethod
implement Transition
endstruct
endlibrary
 CineCam library: library CineCam initializer Init requires optional xebasic
globals
constant real CINECAM_UPDATE_PERIOD = 0.02
private constant boolean CINECAM_CONTINUE_MOVE = true
private constant integer CINECAM_FADE_FILTER_UNIT_TYPE = 'e000'
unit CINECAM_FADE_FILTER_UNIT
private constant integer HEIGHT_ENABLER = 'Amrf'
endglobals
globals
constant integer CINECAM_MOVE_INSTANT = 0
constant integer CINECAM_MOVE_LINEAR = 1
constant integer CINECAM_MOVE_SQUARE = 2
constant integer CINECAM_MOVE_CUBIC = 3
constant integer CINECAM_FIELD_TARGET_X = 1
constant integer CINECAM_FIELD_TARGET_Y = 2
constant integer CINECAM_FIELD_ZOFFSET = 3
constant integer CINECAM_FIELD_ROTATION = 4
constant integer CINECAM_FIELD_ANGLE_OF_ATTACK = 5
constant integer CINECAM_FIELD_ROLL = 6
constant integer CINECAM_FIELD_FIELD_OF_VIEW = 7
constant integer CINECAM_FIELD_FARZ = 8
constant integer CINECAM_FIELD_TARGET_DISTANCE = 9
private location stupid = Location(0.0,0.0)
private timer t
private real array time
private real array startval
private real array startvel
private real array accprim
private real array accsec
private real array endtime
private unit OvRxyzUnitPrim = null
private unit OvRxyzUnitSec = null
private real OvRxyzTime = 0.0
private real OvRxyzEndtime = 0.0
private boolean OvRxyzSmooth = false
private unit OvRangUnitPrim = null
private unit OvRangUnitSec = null
private real OvRangTime = 0.0
private real OvRangEndtime = 0.0
private boolean OvRangSmooth = false
private real array OvRoffset
private unit fadeUnit = null
private boolean ignoreTerrain = false
private real speed = 1.0
endglobals
private function CurrentValue takes integer field returns real
return startval[field] + ( startvel[field] * time[field] ) + ( accprim[field] * Pow(time[field], 2.0) / 2.0 )+ ( accsec[field] * Pow(time[field], 3.0) / 3.0 )
endfunction
private function CurrentVelocity takes integer field returns real
return startvel[field] + ( accprim[field] * time[field] )+ ( accsec[field] * time[field] *time[field] )
endfunction
function SetCameraZ takes real z returns nothing
set z = GetCameraField(CAMERA_FIELD_ZOFFSET)+z-GetCameraTargetPositionZ()
call SetCameraField(CAMERA_FIELD_ZOFFSET,z,- 0.01)
call SetCameraField(CAMERA_FIELD_ZOFFSET,z,0.01)
endfunction
public function interface Callback takes nothing returns nothing
globals
private Callback array C
private integer N=0
endglobals
function OnCineCamUpdate takes Callback c returns nothing
set C[N]=c
set N=N+1
endfunction
private function MainLoop takes nothing returns nothing
local real array s
local real ovrFactor
local integer i = 0
loop
exitwhen i==N
call C[i].execute()
set i=i+1
endloop
set i=0
loop
exitwhen i == 9
set i = i + 1
set time[i] = time[i] + CINECAM_UPDATE_PERIOD*speed
static if not( CINECAM_CONTINUE_MOVE ) then
if time[i] > endtime[i] then
set time[i] = endtime[i]
endif
endif
set s[i] = CurrentValue(i)
if i==CINECAM_FIELD_ROTATION or i==CINECAM_FIELD_ANGLE_OF_ATTACK or i==CINECAM_FIELD_ROLL then
loop
exitwhen s[i] < 360.0
set s[i] = s[i] - 360.0
endloop
loop
exitwhen s[i] > 0
set s[i] = s[i] + 360.0
endloop
endif
endloop
if OvRxyzUnitPrim!=null or OvRxyzUnitSec!=null then
set OvRxyzTime = OvRxyzTime + CINECAM_UPDATE_PERIOD*speed
if OvRxyzTime > OvRxyzEndtime then
set OvRxyzTime = OvRxyzEndtime
endif
if OvRxyzEndtime>0.0 then
set ovrFactor = OvRxyzTime/OvRxyzEndtime
else
set ovrFactor = 1.0
endif
if OvRxyzSmooth then
set ovrFactor = (1.0 - Cos(ovrFactor*bj_PI)) / 2
endif
call MoveLocation(stupid, GetUnitX(OvRxyzUnitPrim),GetUnitY(OvRxyzUnitPrim))
set s[19] = GetLocationZ(stupid)
call MoveLocation(stupid, GetUnitX(OvRxyzUnitSec),GetUnitY(OvRxyzUnitSec))
set s[20] = GetLocationZ(stupid)
if OvRxyzUnitSec==null then
set s[1] = s[1]*(1-ovrFactor) + (GetUnitX(OvRxyzUnitPrim)+OvRoffset[1])*ovrFactor
set s[2] = s[2]*(1-ovrFactor) + (GetUnitY(OvRxyzUnitPrim)+OvRoffset[2])*ovrFactor
set s[3] = s[3]*(1-ovrFactor) + (s[19]+GetUnitFlyHeight(OvRxyzUnitPrim)+OvRoffset[3])*ovrFactor
elseif OvRxyzUnitPrim==null then
set s[1] = s[1]*ovrFactor + (GetUnitX(OvRxyzUnitSec)+OvRoffset[7])*(1.0-ovrFactor)
set s[2] = s[2]*ovrFactor + (GetUnitY(OvRxyzUnitSec)+OvRoffset[8])*(1.0-ovrFactor)
set s[3] = s[3]*ovrFactor + (s[20]+GetUnitFlyHeight(OvRxyzUnitSec)+OvRoffset[9])*(1.0-ovrFactor)
else
set s[1] = (GetUnitX(OvRxyzUnitSec)+OvRoffset[7])*(1-ovrFactor) + (GetUnitX(OvRxyzUnitPrim)+OvRoffset[1])*ovrFactor
set s[2] = (GetUnitY(OvRxyzUnitSec)+OvRoffset[8])*(1-ovrFactor) + (GetUnitY(OvRxyzUnitPrim)+OvRoffset[2])*ovrFactor
set s[3] = (s[20]+GetUnitFlyHeight(OvRxyzUnitSec)+OvRoffset[9])*(1-ovrFactor) + (s[19]+GetUnitFlyHeight(OvRxyzUnitPrim)+OvRoffset[3])*ovrFactor
endif
if OvRxyzTime == OvRxyzEndtime then
if OvRxyzUnitPrim==null then
set OvRxyzUnitSec = null
endif
endif
endif
if OvRangUnitPrim!=null or OvRangUnitSec!=null then
set OvRangTime = OvRangTime + CINECAM_UPDATE_PERIOD*speed
if OvRangTime > OvRangEndtime then
set OvRangTime = OvRangEndtime
endif
if OvRangEndtime>0.0 then
set ovrFactor = OvRangTime/OvRangEndtime
else
set ovrFactor = 1.0
endif
if OvRangSmooth then
set ovrFactor = (1.0 - Cos(ovrFactor*bj_PI)) / 2
endif
call MoveLocation(stupid, GetUnitX(OvRangUnitPrim),GetUnitY(OvRangUnitPrim))
set s[19] = GetLocationZ(stupid)
call MoveLocation(stupid, GetUnitX(OvRangUnitSec),GetUnitY(OvRangUnitSec))
set s[20] = GetLocationZ(stupid)
if OvRangUnitPrim!=null then
set s[21]=(GetUnitX(OvRangUnitPrim)+OvRoffset[4])-s[1]
set s[22]=(GetUnitY(OvRangUnitPrim)+OvRoffset[5])-s[2]
set s[23]=(s[19]+GetUnitFlyHeight(OvRangUnitPrim)+OvRoffset[6])-s[3]
set s[24]=Atan2(s[22], s[21]) * bj_RADTODEG
set s[25]=Atan2(s[23], SquareRoot(s[21]*s[21]+s[22]*s[22])) * bj_RADTODEG
else
set s[24]=s[4]
set s[25]=s[5]
endif
if OvRangUnitSec!=null then
set s[21]=(GetUnitX(OvRangUnitSec)+OvRoffset[10])-s[1]
set s[22]=(GetUnitY(OvRangUnitSec)+OvRoffset[11])-s[2]
set s[23]=(s[20]+GetUnitFlyHeight(OvRangUnitSec)+OvRoffset[12])-s[3]
set s[26]=Atan2(s[22], s[21]) * bj_RADTODEG
set s[27]=Atan2(s[23], SquareRoot(s[21]*s[21]+s[22]*s[22])) * bj_RADTODEG
else
set s[26]=s[4]
set s[27]=s[5]
endif
if (s[26] - s[24]) > 180 then
set s[24] = s[24] + 360
elseif (s[26] - s[24]) < -180 then
set s[24] = s[24] - 360
endif
set s[4] = ovrFactor * s[24] + (1-ovrFactor) * s[26]
if (s[27] - s[25]) > 180 then
set s[25] = s[25] + 360
elseif (s[27] - s[25]) < -180 then
set s[25] = s[25] - 360
endif
set s[5] = ovrFactor * s[25] + (1-ovrFactor) * s[27]
if OvRangTime == OvRangEndtime then
if OvRangUnitPrim==null then
set OvRangUnitSec = null
endif
endif
endif
if s[9]<100.0 then
set s[9]=100.0
endif
if fadeUnit!=null then
set s[23]=Sin(s[5]*bj_DEGTORAD)
set s[20]=Cos(s[5]*bj_DEGTORAD)
set s[21]=Cos(s[4]*bj_DEGTORAD)*s[20]
set s[22]=Sin(s[4]*bj_DEGTORAD)*s[20]
set s[19]=(s[9]-128.0)
set s[20]=Tan(s[7]*bj_DEGTORAD/2) *40
set s[21]=s[1]-s[19]*s[21]
set s[22]=s[2]-s[19]*s[22]
set s[23]=s[3]-s[19]*s[23]
call MoveLocation(stupid, s[21], s[22])
set s[23]=s[23]-GetLocationZ(stupid)
call SetUnitX(fadeUnit, s[21])
call SetUnitY(fadeUnit, s[22])
call SetUnitFlyHeight(fadeUnit, s[23], 0.0)
call SetUnitScale(fadeUnit, s[20],s[20],s[20])
endif
call PanCameraToTimed( s[1], s[2], 0.0 )
if ignoreTerrain then
call SetCameraZ(s[3])
else
call MoveLocation(stupid, s[1], s[2])
call SetCameraField( CAMERA_FIELD_ZOFFSET, s[3]-GetLocationZ(stupid), 0.00 )
endif
call SetCameraField( CAMERA_FIELD_ROTATION, s[4], 0.00 )
call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, s[5], 0.00 )
call SetCameraField( CAMERA_FIELD_ROLL, s[6], 0.00 )
call SetCameraField( CAMERA_FIELD_FIELD_OF_VIEW, s[7], 0.00 )
call SetCameraField( CAMERA_FIELD_FARZ, s[8], 0.00 )
call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, s[9], 0.00 )
endfunction
function CineCamFieldMove takes integer field, real endvalue, real endvelocity, real duration, integer movetype returns nothing
local real startvalue=CurrentValue(field)
local real startvelocity=CurrentVelocity(field)
local boolean radial=(field==CINECAM_FIELD_ROTATION or field==CINECAM_FIELD_ANGLE_OF_ATTACK or field==CINECAM_FIELD_ROLL)
local real distance=endvalue-startvalue
if duration < CINECAM_UPDATE_PERIOD then
set duration = CINECAM_UPDATE_PERIOD
endif
if radial then
loop
exitwhen distance>0.0
set startvalue=startvalue-360.0
set distance=distance+360.0
endloop
loop
exitwhen distance<360.0
set startvalue=startvalue+360.0
set distance=distance-360.0
endloop
endif
if movetype==CINECAM_MOVE_INSTANT then
set startval[field]= endvalue
set startvel[field] = 0.0
set accprim[field] = 0.0
set accsec[field] = 0.0
elseif movetype==CINECAM_MOVE_LINEAR then
set startval[field]= startvalue
if not radial or distance<(360.0-distance) then
set startvel[field] = distance/duration
else
set startvel[field] = (distance-360.0)/duration
endif
set accprim[field] = 0.0
set accsec[field] = 0.0
elseif movetype==CINECAM_MOVE_SQUARE then
set startval[field]= startvalue
set startvel[field] = startvelocity
if not radial or RAbsBJ(distance - startvelocity * duration)<RAbsBJ((distance-360.0) - startvelocity * duration) then
set accprim[field] = 2 * ( distance - startvelocity * duration ) / ( duration * duration )
else
set accprim[field] = 2 * ( (distance-360.0) - startvelocity * duration ) / ( duration * duration )
endif
set accsec[field] = 0.0
elseif movetype==CINECAM_MOVE_CUBIC then
set startval[field]= startvalue
set startvel[field] = startvelocity
if not radial or RAbsBJ(3 * ( startvelocity + endvelocity ) / ( duration * duration ) - 6 * distance / Pow( duration, 3.0 ))<RAbsBJ(3 * ( startvelocity + endvelocity ) / ( duration * duration ) - 6 * (distance-360.0) / Pow( duration, 3.0 )) then
set accprim[field] = 6 * distance / ( duration * duration ) - ( 2 * endvelocity + 4 * startvelocity ) / duration
set accsec[field] = 3 * ( startvelocity + endvelocity ) / ( duration * duration ) - 6 * distance / Pow( duration, 3.0 )
else
set accprim[field] = 6 * (distance-360.0) / ( duration * duration ) - ( 2 * endvelocity + 4 * startvelocity ) / duration
set accsec[field] = 3 * ( startvelocity + endvelocity ) / ( duration * duration ) - 6 * (distance-360.0) / Pow( duration, 3.0 )
endif
endif
set time[field] = 0.0
set endtime[field] = duration
endfunction
function CineCamMove takes camerasetup whichSetup, real duration, integer movetype returns nothing
call MoveLocation(stupid, CameraSetupGetDestPositionX( whichSetup ), CameraSetupGetDestPositionY( whichSetup ))
call CineCamFieldMove(1, CameraSetupGetDestPositionX( whichSetup ), 0.0, duration, movetype)
call CineCamFieldMove(2, CameraSetupGetDestPositionY( whichSetup ), 0.0, duration, movetype)
call CineCamFieldMove(3, CameraSetupGetField( whichSetup, CAMERA_FIELD_ZOFFSET ) + GetLocationZ(stupid), 0.0, duration, movetype)
call CineCamFieldMove(4, CameraSetupGetField( whichSetup, CAMERA_FIELD_ROTATION ), 0.0, duration, movetype)
call CineCamFieldMove(5, CameraSetupGetField( whichSetup, CAMERA_FIELD_ANGLE_OF_ATTACK ), 0.0, duration, movetype)
call CineCamFieldMove(6, CameraSetupGetField( whichSetup, CAMERA_FIELD_ROLL ), 0.0, duration, movetype)
call CineCamFieldMove(7, CameraSetupGetField( whichSetup, CAMERA_FIELD_FIELD_OF_VIEW ), 0.0, duration, movetype)
call CineCamFieldMove(8, CameraSetupGetField( whichSetup, CAMERA_FIELD_FARZ ), 0.0, duration, movetype)
call CineCamFieldMove(9, CameraSetupGetField( whichSetup, CAMERA_FIELD_TARGET_DISTANCE ), 0.0, duration, movetype)
endfunction
function CineCamTargetLock takes unit u, real xoff, real yoff, real zoff, real duration, boolean smooth returns nothing
set OvRxyzUnitSec = OvRxyzUnitPrim
set OvRxyzUnitPrim = u
set OvRxyzSmooth = smooth
set OvRoffset[7]=OvRoffset[1]
set OvRoffset[8]=OvRoffset[2]
set OvRoffset[9]=OvRoffset[3]
set OvRoffset[1]=xoff
set OvRoffset[2]=yoff
set OvRoffset[3]=zoff
set OvRxyzTime = 0.0
set OvRxyzEndtime = duration
endfunction
function CineCamTargetUnlock takes real duration, boolean smooth returns nothing
call CineCamTargetLock(null, 0.0,0.0,0.0, duration, smooth)
endfunction
function CineCamFacingLock takes unit u, real xoff, real yoff, real zoff, real duration, boolean smooth returns nothing
set OvRangUnitSec = OvRangUnitPrim
set OvRangUnitPrim = u
set OvRangSmooth = smooth
set OvRoffset[10]=OvRoffset[4]
set OvRoffset[11]=OvRoffset[5]
set OvRoffset[12]=OvRoffset[6]
set OvRoffset[4]=xoff
set OvRoffset[5]=yoff
set OvRoffset[6]=zoff
set OvRangTime = 0.0
set OvRangEndtime = duration
endfunction
function CineCamFacingUnlock takes boolean smooth, real duration returns nothing
call CineCamFacingLock(null, 0.0,0.0,0.0, duration, smooth)
endfunction
function CineCamEnable takes boolean b returns nothing
if b then
call CineCamMove( GetCurrentCameraSetup(), 0.0, CINECAM_MOVE_INSTANT )
call TimerStart(t, CINECAM_UPDATE_PERIOD, true, function MainLoop )
call ShowUnit(fadeUnit, true)
else
call ShowUnit(fadeUnit, false)
call PauseTimer(t)
endif
endfunction
function CineCamSmooth takes boolean b returns nothing
set ignoreTerrain = not b
endfunction
function CineCamSetSpeed takes real r returns nothing
set speed = r
endfunction
function CineCamGetSpeed takes nothing returns real
return speed
endfunction
private function Init takes nothing returns nothing
set t = CreateTimer()
if CINECAM_FADE_FILTER_UNIT_TYPE==0 then
set fadeUnit = null
else
set fadeUnit = CreateUnit(Player(12), CINECAM_FADE_FILTER_UNIT_TYPE, 0,0,0)
call SetUnitVertexColor(fadeUnit, 255,255,255,0)
static if LIBRARY_xebasic then
call UnitAddAbility(fadeUnit, XE_HEIGHT_ENABLER)
call UnitRemoveAbility(fadeUnit, XE_HEIGHT_ENABLER)
else
call UnitAddAbility(fadeUnit, HEIGHT_ENABLER)
call UnitRemoveAbility(fadeUnit, HEIGHT_ENABLER)
endif
endif
set CINECAM_FADE_FILTER_UNIT = fadeUnit
endfunction
endlibrary
 CineScript library: library CineScript requires LinkedList, TimerUtils
private interface Action
method run takes nothing returns nothing defaults nothing
method update takes real timeElapsed returns nothing defaults nothing
method stop takes nothing returns nothing defaults nothing
endinterface
private keyword addAction
struct CineScript
real x=0.0
real y=0.0
private real a=0.0
private real s=1.0
readonly real duration=0.0
private timer t
private boolean new=true
private boolean running=false
private boolean processing=false
private real timestamp
private real timeskip=0.0
private List list
private Link pending
method addAction takes ScriptAction a, real timestamp, real duration returns Link
local Link l=.list.last
if .duration < timestamp+duration then
set .duration = timestamp+duration
endif
if l==0 or ScriptAction(l.data).timestamp<=timestamp then
return Link.createLast(.list, integer(a))
endif
loop
exitwhen l.prev==0 or ScriptAction(l.prev.data).timestamp<=timestamp
set l=l.prev
endloop
return l.insertBefore(integer(a))
endmethod
private static method timerEndCallback takes nothing returns nothing
call CineScript(GetTimerData(GetExpiredTimer())).stop()
endmethod
private static method timerCallback takes nothing returns nothing
local CineScript this=CineScript(GetTimerData(GetExpiredTimer()))
local ScriptAction a=ScriptAction(.pending.data)
set .new=false
set .processing=true
set .timestamp=a.timestamp
loop
exitwhen not (.s>0.0)
call a.run()
exitwhen not(.running) or .new
set .pending=.pending.next
exitwhen .pending==0
set a=ScriptAction(.pending.data)
exitwhen a.timestamp>.timestamp
endloop
set .processing=false
if .new or not (.s>0.0) or not .running then
elseif .pending!=0 then
call TimerStart(.t, (a.timestamp-.timestamp)/.s, false, function CineScript.timerCallback)
else
call TimerStart(.t, (.duration-.timestamp)/.s, false, function CineScript.timerEndCallback)
endif
endmethod
method stop takes nothing returns nothing
local ScriptAction a
local Link l
if .running then
call ReleaseTimer(.t)
set .running=false
set l=.list.first
loop
exitwhen l==.pending
set a=ScriptAction(l.data)
if a.timestamp>=.timeskip and a.timestamp+a.duration>.timestamp and a.stop.exists then
call a.stop()
endif
set l=l.next
endloop
set .timeskip=0.0
endif
endmethod
method run takes nothing returns nothing
call .stop()
set .timestamp=.timeskip
set .pending=.list.first
loop
if .pending==0 then
return
endif
exitwhen ScriptAction(.pending.data).timestamp>=.timestamp
set .pending=.pending.next
endloop
set .t=NewTimer()
call SetTimerData(.t, this)
if .s!=0.0 then
call TimerStart(.t, (ScriptAction(.pending.data).timestamp-.timestamp)/.s, false, function CineScript.timerCallback)
endif
set .running=true
set .new=true
endmethod
method globalX takes real x, real y returns real
return .x + Cos(.a)*x - Sin(.a)*y
endmethod
method globalY takes real x, real y returns real
return .y + Sin(.a)*x + Cos(.a)*y
endmethod
method globalAngle takes real angle returns real
return .a*bj_RADTODEG + angle
endmethod
method operator time takes nothing returns real
if .running then
if .s==0.0 then
return .timestamp
elseif .processing then
return ScriptAction(.pending.data).timestamp
elseif .pending!=0 then
return ScriptAction(.pending.data).timestamp - TimerGetRemaining(.t)*.s
else
return .duration - TimerGetRemaining(.t)*.s
endif
endif
return .timeskip
endmethod
method operator time= takes real newTime returns nothing
if .running then
call .stop()
set .timeskip=newTime
call .run()
else
set .timeskip=newTime
endif
endmethod
method operator speed takes nothing returns real
return .s
endmethod
method operator speed= takes real newSpeed returns nothing
local ScriptAction a
local Link l
if newSpeed<0.0 then
set newSpeed=0.0
endif
set .timestamp=.time
set .s=newSpeed
if .running then
call PauseTimer(.t)
if not(.processing) and .s>0.0 then
if .pending!=0 then
call TimerStart(.t, (ScriptAction(.pending.data).timestamp - .timestamp)/.s, false, function CineScript.timerCallback)
else
call TimerStart(.t, (.duration - .timestamp)/.s, false, function CineScript.timerEndCallback)
endif
endif
set l=.list.first
loop
exitwhen l==.pending
set a=ScriptAction(l.data)
if a.timestamp>=.timeskip and a.timestamp+a.duration>.timestamp and a.update.exists then
call a.update(.timestamp-a.timestamp)
endif
set l=l.next
endloop
endif
endmethod
method operator angle takes nothing returns real
return .a*bj_RADTODEG
endmethod
method operator angle= takes real newAngle returns nothing
set .a = newAngle*bj_DEGTORAD
endmethod
static method create takes nothing returns CineScript
local CineScript this=CineScript.allocate()
set .list=List.create()
return this
endmethod
method onDestroy takes nothing returns nothing
call .stop()
loop
exitwhen .list.first==0
call ScriptAction(.list.first.data).destroy()
endloop
call .list.destroy()
endmethod
endstruct
struct ScriptAction extends Action
private Link l
readonly CineScript parent
readonly real timestamp
readonly real duration
static method create takes CineScript s, real timestamp, real duration returns ScriptAction
local ScriptAction this=ScriptAction.allocate()
if duration<0.0 then
set duration=0.0
endif
set .timestamp=timestamp
set .duration=duration
set .parent=s
set .l=s.addAction(this, timestamp, duration)
return this
endmethod
method onDestroy takes nothing returns nothing
call .l.destroy()
endmethod
endstruct
endlibrary
__________________
Last edited by Anitarf : 01-29-2014 at 05:06 PM.
|