ScriptName DMRowBoatScript
;merged aaGlobalRowBoatScript
;doesn't use Globals: float PlayerX, float PlayerY, float PlayerZ, float PlayerAngle,
;doesn't use Global: short BoatSkiffMove
float aPlayerX
float aPlayerY
float aPlayerZ
float aPlayerAngle
float bPlayerX
float bPlayerY
float bPlayerZ
float bPlayerAngle
float RowBoatX
float RowBoatY
float RowBoatZ
float RowBoatAngle
short RowBoatSpeed
short RowBoatInitialize
short RowBoatTurn
short RowBoatMenu
short RowBoatStartMove
float Diff
float Hemi
float FixAngle
float r
float r2
float d
float d2
float x
float y
ref newRef
short button = -2
ref AntiGravRef2
float TurnRate
short xBoatSkiffDeployed
short xBoatSkiffMove
short PCPosX
short PCPosY
float pos
float ang ;(the measure of the angle, first deg, then radians)
float ang2 ;(ang^2) Just for convenience. Could use ang*ang directly.
float ang4 ;(ang^4) Just for convenience. Could use ang*ang*ang*ang directly.
float sign ;sign correction
float sin ;(sine of the angle)
float cos ;(cosine of the angle)
short Pulling
short curKey
short sneakturn
short BoatIsMoving
short FirstRun
short diffcell
short FirstTime
Begin OnActivate
if player.IsSneaking == 0
if player.getitemcount Oar01 >= 1
if (xBoatSkiffDeployed == 0)
Set xBoatSkiffDeployed to 1
Set xBoatSkiffMove to 99
MessageBox "Es kann losgehen. Drücke deine Laufen-Taste (Standard: SHIFT), um in das Boot-Menü zu gelangen. Drücke deine Schleichen-Taste (Standard: STRG), um das Boot zu lenken. Drücke sie noch einmal, um in den normalen Modus zu wechseln. So kannst du beispielsweise Pfeile oder Zauber benutzen."
else
Set xBoatSkiffMove to 1
MessageBox "Es kann losgehen. Drücke deine Laufen-Taste (Standard: SHIFT), um in das Boot-Menü zu gelangen. Drücke deine Schleichen-Taste (Standard: STRG), um das Boot zu lenken. Drücke sie noch einmal, um in den normalen Modus zu wechseln. So kannst du beispielsweise Pfeile oder Zauber benutzen."
endif
else
MessageBox "Wie wollt Ihr ohne Ruder rudern?"
;do nothing
endif
endif
;the following was made by Fellan (and the CSwiki), allowing the player to pull the boat behind him with an invisible
;rope in case it might run aground. also works with the large ships which might look unrealistic but is
;for practical purposes only! boat is simply being placed behind the player. unfortunately, it doesn't work by now.
if player.IsSneaking == 1
set Pulling to 1
Messagebox "Du ziehst das Boot nun hinter dir her. Drücke die Greifen-Taste, um aufzuhören, das Boot zu ziehen!"
; else
; Set xBoatSkiffDeployed to 0
; Set xBoatSkiffMove to 0
; endif
endif
End
begin GameMode
if ( Pulling == 1 )
set sign to 1
set ang to player.getAngle z
if ang > 270
set ang to ang - 360
elseif ang > 90
set ang to ang - 180
set sign to -1
endif
set ang to 0.017453*ang
set ang2 to ang * ang
set ang4 to ang2 * ang2
set sin to sign*ang*(1 - 0.16605*ang2 + 0.00761*ang4)
set cos to sign*(1 - 0.4967*ang2 + 0.03705*ang4)
;--Move it
moveTo player
set pos to player.getPos x - 200*sin
setPos x pos
set pos to player.getPos y - 200*cos
setPos y pos
;--Set angle of bed relative to PC heading
set ang to player.getAngle z + 90
setAngle x 0
setAngle y 0
setAngle z ang
if ( curKey && isControlPressed curkey ) ; key still being held down
return ; wait until it's released
else
set curkey to 0
endif
if ( isControlPressed 28 )
;disable and re-enable the reference in order to update solids
set Pulling to 0
disable
enable
disable
enable
set curKey to 28
endif
endif
if (xBoatSkiffDeployed == 0)
if (AntiGravRef2 != 0)
AntiGravRef2.disable
Set RowBoatStartMove to 0
endif
Return
endif
; moved below initial xboatskiffdeployed check
if (RowBoatInitialize == 0)
Set RowBoatInitialize to 1
Set RowBoatAngle to GetAngle z
Set RowBoatAngle to RowBoatAngle - 90
if (RowBoatAngle < 0)
Set RowBoatAngle to RowBoatAngle + 360
elseif (RowBoatAngle >= 360)
Set RowBoatAngle to RowBoatAngle - 360
endif
Set RowBoatX to GetPos x
Set RowBoatY to GetPos y
; Set RowBoatZ to GetPos z
; fix the "run aground" problem with boat is activated for the very first time.
Set RowBoatZ to 1
endif
if (xBoatSkiffDeployed == 1)
; Places the boat flat
SetPos z, 1
SetAngle x, 0
SetAngle y, 0
Set xBoatSkiffDeployed to 2
endif
if (xBoatSkiffDeployed == 2)
if (xBoatSkiffMove == 1)
if (RowBoatStartMove == 0)
set AntiGravRef2 to player.PlaceAtMe DMAntiGrav, 1, 0, 0
AntiGravRef2.SetScale 1.0
AntiGravRef2.SetRigidBodyMass 100
Set RowBoatStartMove to 1
endif
if (RowBoatMenu == 1)
set button to getbuttonpressed
if (button == 1)
Set RowBoatSpeed to 0
set BoatIsMoving to 0
Set xBoatSkiffMove to -1
elseif (button == 2)
Set RowBoatSpeed to 0
set BoatIsMoving to 0
elseif (button == 3)
if player.getitemcount Oar01 < 2
message "Mit nur einem Ruder könnt ihr nur langsam rudern..."
Set RowBoatSpeed to 4
set BoatIsMoving to 1
elseif player.getitemcount Oar01 >= 2
Set RowBoatSpeed to 4
set BoatIsMoving to 1
endif
elseif (button == 4)
if player.getitemcount Oar01 < 2
message "Mit nur einem Ruder könnt ihr nur langsam rudern..."
Set RowBoatSpeed to 4
set BoatIsMoving to 1
elseif player.getitemcount Oar01 >= 2
Set RowBoatSpeed to 10
set BoatIsMoving to 1
endif
elseif (button == 5)
if player.getitemcount Oar01 < 2
message "Mit nur einem Ruder könnt ihr nur langsam rudern..."
Set RowBoatSpeed to 4
set BoatIsMoving to 1
elseif player.getitemcount Oar01 >= 2
Set RowBoatSpeed to 18
set BoatIsMoving to 1
endif
elseif (button == 6)
if player.getitemcount Oar01 < 2
message "Mit nur einem Ruder könnt ihr nur langsam rudern..."
Set RowBoatSpeed to -4
set BoatIsMoving to 1
elseif player.getitemcount Oar01 >= 2
Set RowBoatSpeed to -10
set BoatIsMoving to 1
endif
elseif (button == 7)
Set RowBoatTurn to 0
endif
Set button to -2
endif
if (player.IsRunning && RowBoatMenu == 0)
Set RowBoatMenu to 1
messagebox "Befehle?!", "Keine", "Anker werfen", "Stehenbleiben", "Langsam Rudern", "Rudern", "Schnell Rudern", "Rückwärts Rudern", "Kurs beibehalten"
elseif (player.IsRunning != 1)
Set RowBoatMenu to 0
endif
Set RowBoatX to GetPos x
Set RowBoatY to GetPos y
Set RowBoatZ to GetPos z
;Determine which way to rotate and adjust angle
Set aPlayerAngle to player.GetAngle z
if (aPlayerAngle < 0)
Set aPlayerAngle to aPlayerAngle + 360
elseif (aPlayerAngle >= 360)
Set aPlayerAngle to aPlayerAngle - 360
endif
endif
endif
if BoatIsMoving == 1
if ( sneakturn == 0 )
if ( player.IsSneaking == 1 )
set RowBoatTurn to 1
set sneakturn to 1
endif
endif
endif
if BoatIsMoving == 1
if ( sneakturn == 1 )
if ( player.isSneaking == 0 )
set RowBoatTurn to 0
set sneakturn to 0
endif
endif
endif
If (RowBoatTurn == 1)
Set Diff to aPlayerAngle - RowBoatAngle
if (Diff > 1 || Diff < -1)
if (aPlayerAngle > 180)
Set Hemi to aPlayerAngle - 180
else
Set Hemi to aPlayerAngle + 180
endif
if (Hemi < 0)
Set Hemi to Hemi + 360
elseif (Hemi >= 360)
Set Hemi to Hemi - 360
endif
Set TurnRate to 2.0
if (aPlayerAngle > Hemi)
if (RowBoatAngle > Hemi && RowBoatAngle < aPlayerAngle)
Set RowBoatAngle to RowBoatAngle + TurnRate
else
Set RowBoatAngle to RowBoatAngle - TurnRate
endif
else
if (RowBoatAngle < Hemi && RowBoatAngle > aPlayerAngle)
Set RowBoatAngle to RowBoatAngle - TurnRate
else
Set RowBoatAngle to RowBoatAngle + TurnRate
endif
endif
endif
if (RowBoatAngle < 0)
Set RowBoatAngle to RowBoatAngle + 360
elseif (RowBoatAngle >= 360)
Set RowBoatAngle to RowBoatAngle - 360
endif
endif
;Adjust for model alignment
Set FixAngle to RowBoatAngle + 90
if (FixAngle < 0)
Set FixAngle to FixAngle + 360
elseif (FixAngle >= 360)
Set FixAngle to FixAngle - 360
endif
;Get degrees by quadrant
if (FixAngle < 90)
Set d to FixAngle
elseif (FixAngle < 180)
Set d to FixAngle - 90
elseif (FixAngle < 270)
Set d to FixAngle - 180
else
Set d to FixAngle - 270
endif
;Get reverse in order to use sine for both offsets, improving accuracy
Set d2 to 90 - d
;Calculate radians
Set r to (d * 3.14159265) / 180
Set r2 to (d2 * 3.14159265) / 180
;Calculate offsets with Taylor series expansion of sine
Set x to r - ((r * r * r) / 6) + ((r * r * r * r * r) / 120) - ((r * r * r * r * r * r * r) / 5040)
Set y to r2 - ((r2 * r2 * r2) / 6) + ((r2 * r2 * r2 * r2 * r2) / 120) - ((r2 * r2 * r2 * r2 * r2 * r2 * r2) / 5040)
;Multiply offsets to get new position
if (FixAngle < 90)
Set RowBoatX to RowBoatX - (y * RowBoatSpeed)
Set RowBoatY to RowBoatY + (x * RowBoatSpeed)
elseif (FixAngle < 180)
Set RowBoatX to RowBoatX + (x * RowBoatSpeed)
Set RowBoatY to RowBoatY + (y * RowBoatSpeed)
elseif (FixAngle < 270)
Set RowBoatX to RowBoatX + (y * RowBoatSpeed)
Set RowBoatY to RowBoatY - (x * RowBoatSpeed)
else
Set RowBoatX to RowBoatX - (x * RowBoatSpeed)
Set RowBoatY to RowBoatY - (y * RowBoatSpeed)
endif
;Move to offsets
PositionWorld RowBoatX, RowBoatY, RowBoatZ, FixAngle, Tamriel
SetPos x, RowBoatX
SetPos y, RowBoatY
SetPos z, 1
SetAngle z, FixAngle
if (xBoatSkiffMove == 1)
if (player.GetPos z > 35)
Message "Das Boot ist auf Grund gelaufen."
Set RowBoatTurn to 0
; PlaySound3D TRPMineExplode
Set RowBoatSpeed to 0
else
Set aPlayerX to RowBoatX
Set aPlayerY to RowBoatY
player.SetPos x, aPlayerX
player.SetPos y, aPlayerY
Set aPlayerZ to 2
player.SetPos z, aPlayerZ
player.ResetFallDamageTimer
if (AntiGravRef2 != 0)
AntiGravRef2.SetPos x, aPlayerX
AntiGravRef2.SetPos y, aPlayerY
AntiGravRef2.SetPos z, aPlayerZ
endif
if (RowBoatSpeed != 0)
; PlaySound3D FootSoundWater
PlaySound3D FSTWaterSwim
endif
endif
endif
if (xBoatSkiffMove == -1 || xBoatSkiffMove == 99)
if (xBoatSkiffMove == -1)
Set xBoatSkiffMove to -2
else
Set xBoatSkiffMove to 98
Set aPlayerX to player.GetPos x
Set aPlayerY to player.GetPos y
Set aPlayerZ to player.GetPos z
; To fix the "boat has run aground" bug on first run
if (FirstTime == 0)
Set FirstTime to 1
Set aPlayerZ to 1
endif
Set aPlayerAngle to player.GetAngle z
endif
DisablePlayerControls
;Move player temporarily to empty cell in order to force recalculation of solids
player.PositionCell 0, 0, 0, 0, DMPlayerShipTemp
endif
if (xBoatSkiffMove == -2 || xBoatSkiffMove == 98)
EnablePlayerControls
player.SetAngle z, aPlayerAngle
if (xBoatSkiffMove == -2)
Set xBoatSkiffMove to 0
Set RowBoatTurn to 0
; Resets the boat deployment after the anchor is dropped to reduce script slowdown
Set xBoatSkiffDeployed to 0
player.PositionWorld aPlayerX, aPlayerY, aPlayerZ, aPlayerAngle, Tamriel
if (AntiGravRef2 != 0)
AntiGravRef2.disable
Set RowBoatStartMove to 0
endif
else
; Set xBoatSkiffMove to 0
; Automatically readies the boat to row after activating it
Set xBoatSkiffMove to 1
player.PositionWorld aPlayerX, aPlayerY, aPlayerZ, aPlayerAngle, Tamriel
endif
player.SetAngle z, aPlayerAngle
endif
end