1
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

399 lines
14 KiB

Scriptname CWCatapultScript extends ObjectReference
{Script on the CWCatapult Activator}
;NOTES:
;NORMAL OPERATION:
;To start catapults, 1) Enable() them, THEN 2) call TurnOn() -- THE ORDER IS IMPORTANT... ENABLE() FIRST if you don't then you put it in the mode to always fire as if it were "offscreen" and unloaded
;To stop catapults, 1) call the turnOff() function, then 2) Disable() them -- THE ORDER IS IMPORTANT
;When it's appropriate and you want to start using the CWCatapultStrikeSpawners to pin point where each hit should land, disable() the catapult which will cause it to start using the special effects instead of practical projectiles.
;When the catapult unloads it sets the UseCWCatapultStrikeSpawners bool to true and calls startSpawningCatapultStrikes() which based on the CWBattlePhase will place special fx explosions at linked refs linked with keywords CW1, CW2, CW3, CW4, CW5 based on the phase
;START DISABLED AND FIRE USING SPECIAL EFFECTS ONLY:
;To make a catapult never appear in the world but still fire with the special fx explosions, make sure it starts disabled, and instead of enable() it, just call turnOn() function on it. It assumes if it's disabled and you call turnOn() it should start firing as if it was unloaded
;AIMING THE CATAPULT
;Run the game, and "setpv aim True" on it in the console
;Now when you activate it in the ready position, it will pop up an aim menu
;One of the options is "Log Coordinates" this will print out the x, y, z position and angles to a text file so you can then enter those in the editor
;One special option is the "Face Target" button. By default this is the player, so you can run to where you want it to aim towards and then activate it via console (prid it, then "activate player") and it will face toward you
;you can also set this as a property on the reference if you have another reference you want to aim it at
;DON'T FORGET to push the "Log Coordinates" button on each catapult you aim, or you will have lost your targetting data
Weapon Property WeaponToFire Auto
{BASEOBJECT: Set this to CWCatapultWeapon, this is the weapon that the fire() function is called on.}
Ammo Property AmmoToFire Auto
{BASEOBJECT: Set this to CWCatapultAmmo, this is the ammo parameter that the fire() function is passed.}
GlobalVariable Property CWBattlePhase Auto
{BASEOBJECT: Pointer to CWBattlePhase global}
keyword Property CW1 Auto
{BASEOBJET: pointer to keyword CW1 which defines the CWCatapultStrikerSpawner associated with phase 1 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase}
keyword Property CW2 Auto
{BASEOBJET: pointer to keyword CW2 which defines the CWCatapultStrikerSpawner associated with phase 2 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase}
keyword Property CW3 Auto
{BASEOBJET: pointer to keyword CW3 which defines the CWCatapultStrikerSpawner associated with phase 3 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase}
keyword Property CW4 Auto
{BASEOBJET: pointer to keyword CW4 which defines the CWCatapultStrikerSpawner associated with phase 4 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase}
keyword Property CW5 Auto
{BASEOBJET: pointer to keyword CW5 which defines the CWCatapultStrikerSpawner associated with phase 5 that should place catapult strike effects if this catapult is unloaded and CWBattlePhase is the correct phase}
keyword Property CWAllPhases Auto
{BASEOBJET: pointer to keyword CWAllPhases which defines the CWCatapultStrikerSpawner associated with all phases that should place catapult strike effects if this catapult is unloaded}
Message Property CWCatapultMsgAngle Auto
{BASEOBJECT: pointer to the CWCatapultMsgAngle message}
Message Property CWCatapultMsgPosition Auto
{BASEOBJECT: pointer to the CWCatapultMsgAngle message}
float property MinStrikeSpawnerTime = 5.0 Auto
{Optional REFERENCE: minimum seconds that should pass between each CWCatapultStrike special effect Explosion from this catapult}
float property MaxStrikeSpawnerTime = 10.0 Auto
{Optional REFERENCE: maximum seconds that should pass between each CWCatapultStrike special effect Explosion from this catapult}
Bool Property Aim Auto
{DEBUG: Put the catapult in aiming mode.}
ObjectReference Property FaceTarget auto
{DEBUG: object ref id aim at, set before activating the Aiming mode menu in game}
;Private Properties / Variables
bool property UseCWCatapultStrikeSpawners auto ;when this is true, don't launch normally, but instead call in special effect explosions (this is set to true when the object is unloaded)
{DON'T SET THIS, FOR DEBUGGING AND INTERNAL USE BY SCRIPT ONLY}
;set bu TurnOn() and TurnOff()
bool Property TurnedOn Auto ;*** WHEN WE ARE DONE SETTING UP THIS SHOULD BE OFF BY DEFAILT AND TURNED ON WITH A FUNCTION
{DON'T SET THIS, FOR DEBUGGING AND INTERNAL USE BY SCRIPT ONLY}
;<constants>
;state names - must be the same as the name of the states
string busy = "busy" ;busy animating
string ready = "ready" ;loaded and ready to fire
string fired = "fired" ;fired Projectile
;animation events - for convenience these are declared as string variables
string aeFire = "fire" ;send this event to cause the catapult arm to fly up and launch the payload
string aeLaunch = "launch" ;[OBSOLETE] sent from activator at the moment the payload leaves the arm - this is when the weapon should call fire()
string aeFired = "fired" ;sent from activator when the launch animation is complete and it's safe to allow activate events to load it again
string aeReload = "reload" ;send this event to cause the catapult arm to lower and spawn a new payload
string aeReloaded = "reloaded" ;sent from activator when the reload animation is finished and it's safe to allow activate events to launch it again
string aeStartFired = "startFired" ;send to activator to start a catapult in the fired position. Do not call this any other time than OnLoad or it will look bad.
;</constants>
Event OnLoad()
((self as ObjectReference) as CWCatapultOffscreenFireControlScript).StopOffscreenFiring()
UseCWCatapultStrikeSpawners = False
; CWScript.Log("CWCatapultScript", self + "OnLoad()")
RegisterForAnimationEvent(self, aeFire) ;arm goes up and payload launces
RegisterForAnimationEvent(self, aeLaunch) ;last few frames as the payload launches - should coincide with the fire() function call
RegisterForAnimationEvent(self, aeFired) ;arm is at rest after finished launching
RegisterForAnimationEvent(self, aeReload) ;arm goes down and payload appears in it
RegisterForAnimationEvent(self, aeReloaded) ;arm is down and payload appeared
RegisterForAnimationEvent(self, aeStartFired) ;arm should start up
endEvent
Event OnUnload()
if UseCWCatapultStrikeSpawners == False && TurnedOn == true ;if we aren't already doing this for some reason, go ahead and Start
startSpawningCatapultStrikes()
EndIf
; debug.MessageBox(self + "OnUnload()")
; CWScript.Log("CWCatapultScript", self + "OnUnload()")
UnRegisterForAnimationEvent(self, aeFire)
UnRegisterForAnimationEvent(self, aeLaunch)
UnRegisterForAnimationEvent(self, aeFired)
UnRegisterForAnimationEvent(self, aeReload)
UnRegisterForAnimationEvent(self, aeReloaded)
UnRegisterForAnimationEvent(self, aeStartFired)
endEvent
state busy
Event OnBeginState()
; CWScript.Log("CWCatapultScript", self + "OnBeginState() busy")
EndEvent
;catch activate
Event OnActivate(ObjectReference akActionRef)
; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + "): busy, so doing nothing.")
EndEvent
EndState
auto state ready
Event OnBeginState()
; CWScript.Log("CWCatapultScript", self + "OnBeginState() ready")
EndEvent
;catch activate
Event OnActivate(ObjectReference akActionRef)
if aim == true
showAimingMenu()
Else
if UseCWCatapultStrikeSpawners == False
launch()
; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + ") ready, so called launch().")
Else
; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + ") UseCWCatapultStrikeSpawners == True so I am not launching normally but calling in SFX catapult explosions.")
EndIf
EndIf
EndEvent
EndState
state fired
Event OnBeginState()
; CWScript.Log("CWCatapultScript", self + "OnBeginState() fired")
EndEvent
;catch activate
Event OnActivate(ObjectReference akActionRef)
reload()
; CWScript.Log("CWCatapultScript", self + "OnActivate(" + akActionRef + ") fired, so called reload.")
EndEvent
EndState
Event OnAnimationEvent(ObjectReference akSource, string asEventName)
; CWScript.Log("CWCatapultScript", self + "ProcessAnimationEvent(" + asEventName + ")")
if asEventName == aeReloaded
GoToState(ready)
elseif asEventName == aeFired
GoToState(fired)
endif
EndEvent
function TurnOn()
;allowed to fire
TurnedOn = True
;*** PUT THIS BACK IN WHEN WE HAVE ACTORS LAUNCHING ENABLED CATAPULTS
; if IsDisabled()
startSpawningCatapultStrikes()
; EndIf
EndFunction
function TurnOff(bool AndDisable = True)
;not allowed to fire
TurnedOn = False
if AndDisable == True
disable()
EndIf
((self as ObjectReference) as CWCatapultOffscreenFireControlScript).StopOffscreenFiring()
EndFunction
float function GetTimeToNextLaunch()
float timeToNextLaunch = Utility.RandomFloat(MinStrikeSpawnerTime, MaxStrikeSpawnerTime)
; CWScript.Log("CWCatapultScript", self + "GetTimeToNextLaunch() returning " + timeToNextLaunch)
Return timeToNextLaunch
EndFunction
function startSpawningCatapultStrikes()
if TurnedOn == False
; CWScript.Log("GetTimeToNextLaunch", self + "WARNING: my TurnedOn variable is false, I should NOT be calling startSpawningCatapultStrikes on myself.", 2, 1, 1)
Else
UseCWCatapultStrikeSpawners = True
((self as ObjectReference) as CWCatapultOffscreenFireControlScript).StartOffscreenFiring(GetTimeToNextLaunch())
EndIf
EndFunction
function launch()
GoToState(busy)
; CWScript.Log("CWCatapultScript", self + "launch()")
PlayAnimationAndWait(aeFire, aeLaunch)
WeaponToFire.fire(self, AmmoToFire)
EndFunction
function reload()
GoToState(busy)
; CWScript.Log("CWCatapultScript", self + "reload()")
PlayAnimation(aeReload)
EndFunction
;AIMING MENU STUFF
function showAimingMenu()
float translateSpeed = 100
Message thisMessage = CWCatapultMsgAngle
int button = thisMessage.Show()
int left = 0
int right = 1
int back = 2
int forward = 3
int face = 4
int nextMenu = 5
int log = 6
int done = 7
float offset = 1
if button == left
translateTo(X, Y, Z, GetAngleX(), GetAngleY(), GetAngleZ() - offset, translateSpeed)
elseif button == right
translateTo(X, Y, Z, GetAngleX(), GetAngleY(), GetAngleZ() + offset, translateSpeed)
elseif button == back
translateTo(X, Y, Z, GetAngleX(), GetAngleY() - offset, GetAngleZ(), translateSpeed)
elseif button == forward
translateTo(X, Y, Z, GetAngleX(), GetAngleY() + offset, GetAngleZ(), translateSpeed)
elseif button == face
translateTo(X, Y, Z, GetAngleX(), GetAngleY(), GetFacingToTarget(FaceTarget, True), translateSpeed)
elseif button == nextMenu
showPositioningMenu()
elseif button == log
logPositionAndAngle()
EndIf
if button != done
showAimingMenu()
EndIf
EndFunction
function showPositioningMenu()
float translateSpeed = 100
Message thisMessage = CWCatapultMsgPosition
int button = thisMessage.Show()
int left = 0
int right = 1
int back = 2
int forward = 3
int up = 4
int down = 5
int nextMenu = 6
int log = 7
int done = 8
float offset = 1
float xOffset
float yOffset
;NOTE: the catapult art is setup facing backwards which is why when moving left/back we add the offsets and moving right/forward we subtract the offsets
if button == left
xOffset = offset * math.cos(GetAngleZ())
yOffset = offset * -( math.sin(GetAngleZ()) )
translateTo(X + xOffset, Y + yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed)
elseif button == right
xOffset = offset * math.cos(GetAngleZ())
yOffset = offset * -( math.sin(GetAngleZ()) )
translateTo(X - xOffset, Y - yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed)
elseif button == back
xOffset = offset * math.sin(GetAngleZ())
yOffset = offset * math.cos(GetAngleZ())
translateTo(X + xOffset, Y + yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed)
elseif button == forward
xOffset = offset * math.sin(GetAngleZ())
yOffset = offset * math.cos(GetAngleZ())
translateTo(X - xOffset, Y - yOffset, Z, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed)
elseif button == up
translateTo(X, Y, Z + offset, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed)
elseif button == down
translateTo(X, Y, Z - offset, GetAngleX(), GetAngleY(), GetAngleZ(), translateSpeed)
elseif button == nextMenu
showAimingMenu()
elseif button == log
LogPositionAndAngle()
EndIf
if button != done
showPositioningMenu()
EndIf
EndFunction
function LogPositionAndAngle()
; CWScript.Log("CWCatapultAimingLog", self + "X: " + X + ", Y:" + Y + ", Z:" + Z + ", Angle X:" + GetAngleX() + ", Angle Y:" + GetAngleY() + ", Angle Z:" + GetAngleZ(), 1, 1)
EndFunction
float function GetFacingToTarget(ObjectReference TargetRef, bool invertFacing = False)
float deltaX = TargetRef.X - X
float deltaY = TargetRef.Y - Y
float newAngle = math.atan(deltaX/deltaY)
if TargetRef.Y < Y
newAngle += 180
EndIf
if invertFacing
if newAngle >= 180
newAngle -= 180
Else
newAngle += 180
EndIf
EndIf
return newAngle
EndFunction