Untitled
unknown
python
10 months ago
16 kB
7
Indexable
#
# TODO: A mission to fly to the nearby launchpad for refuel.
#
# This mission shall teach how to orient the vehicle using the heading
# indicator, and how to use the RCS thrusters to translate the spacecraft
# horizontally. During this mission, by taking off and landing on the nearby
# launchpad, the player shall learn the basics of horizontal flight, useful
# during landing from orbital or suborbital flights.
#
# The final objective of the mission shall be landing on the other launchpad.
# Once the landing happens, the spacecraft shall be automatically fully
# refueled.
#
# Objectives:
# - teach about heading (cardinal directions, compass, etc?)
# - let take off and hover above the ground
# - let rotate vertically using roll controls (Q/E) towards the other
# launchpad, orienting roughly towards N
# - let fly towards the other launchpad using RCS thrusters for translation
# (I/K and J/L)
# - once above the other launchpad, let land on it
# - congratulate the player and refuel the spaceship
#
# Tips:
# - Use the Gui.hint() for showing a hint to the player for some 3D object in
# the cockpit, in a form of a colored arrow. There are some utility "anchor"
# 3D nodes, meant to be used highlighting the related controls. Most
# instruments on the dashboard have anchors, open the
# spacecraft/dumpster/interior.tscn scene and search for "anchor".
#
# - Use the Gui.prompt() for prompting messages and optionally, waiting for
# confirmation. It supports the `await` keyword and allows for sequential
# asynchronous programming of tutorial-like steps.
#
extends Mission
const Camera = preload("res://camera.gd")
const _CURENT_LAUNCHPAD_SPAWN_POINT = "/root/Main/World/Asteroid/JunoBase/Launchpad/SpawnPoint"
const _OTHER_LAUNCHPAD_SPAWN_POINT = "/root/Main/World/Asteroid/JunoBase/Launchpad2/SpawnPoint"
const _DUMPSTER_CAMERA = "/root/Main/World/Dumpster/Assembly/Camera"
const _DUMPSTER = "/root/Main/World/Dumpster"
const _LAUNCHPAD_SCENE = "res://buildings/launchpad/launchpad.tscn"
const ANIMATION_LENGTH = 2.0
# Objective 0 - Reaction Control System
func _objective_0_rsc(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
await Gui.prompt("To complete serious missions we need much more fuel.")
# Show the Fuel Indicator
_hint('Fuel')
if not await Gui.prompt("As you can see, this fuel won’t get us far — no epic space adventures on an empty tank!"):
return
_hint('')
var messages = [
"We will refuel at the other launchpad — it’s hiding in plain sight next to that giant tower!",
"We need the main engine to hover and RCS thrusters to maneuver.",
"The Reaction Control System (RCS) is a set of thrusters placed around your ship to help you maneuver.",
"‘Reaction’ — fire thrusters on one side, move the other. Newton’s third law, you know.",
]
while !obj.canceled and messages:
if not await Gui.prompt(messages.pop_front()):
return
await Gui.prompt("Enough theory - let's lift off and try it!")
obj.completed = true
# Objective 1 - Take off and hover above the ground
func _objective_1_take_over(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
Gui.prompt("Lift off and hover at 20m. Shall be easy for you!", false)
while !obj.canceled:
await Game.tick
if Game.get_local_vehicle().get_assembly().is_engine_enabled(0) and Game.get_local_vehicle().get_vectors().surface_position.length() > .5:
break
var hover_start_time: int = 0
var desired_height: int = 20
while not obj.canceled:
await Game.tick
var vehicle = Game.get_local_vehicle()
var altitude = vehicle.get_vectors().surface_position.length()
var diff = absf(altitude - desired_height)
# If within +- 1m -> sub-mission compledted
if diff < 1:
var elapsed: float = (Time.get_ticks_msec() - hover_start_time) / 1000.0
# When 1 second passed, complete the mission
if elapsed > 1.0:
#print('final vehicle translation vector = ', vehicle.translation)
print('surface_position = ', vehicle.get_vectors().surface_position)
break
else:
Gui.prompt("Yoohoo! Reach an altitude of 20m.", false, true, _NO_ANIM)
if obj.canceled:
return
obj.completed = true
# Objective 2 - Push forward/backward using the RCS thrusters
func _objective_2_rcs_forward_and_backward(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
if not await Gui.prompt("Time to fire up those thrusters!"):
return
# Enter the external view mode
Gui.prompt("Press [color=$H]TAB[/color] to switch to external view.", false)
while !obj.canceled:
await Game.tick
if Game.get_view_mode() == Game.ViewMode.EXTERNAL:
break
var rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_forward_pressed = false
# RSC throttle forward
Gui.prompt("Press [color=$H]I[/color] shortly to give a push [color=$H]forward[/color] by activating the [color=$H]rear[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press I character to move forward
is_forward_pressed = is_forward_pressed or Input.is_key_pressed(KEY_I)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_forward_pressed:
break
rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_backward_pressed = false
# RSC throttle backward
Gui.prompt("Press [color=$H]K[/color] shortly to give a push [color=$H]backward[/color] by activating the [color=$H]front[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press K characters to move backward
is_backward_pressed = is_backward_pressed or Input.is_key_pressed(KEY_K)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_backward_pressed:
break
if obj.canceled:
return
obj.completed = true
# Objective 3 - Push right/left using the RCS thrusters
func _objective_3_rcs_push_left(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
if not await Gui.prompt("Left and right thrusters are next!"):
return
var rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_left_pressed = false
# RSC throttle left
Gui.prompt("Press [color=$H]J[/color] shortly to give a push [color=$H]left[/color] by activating the [color=$H]right[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press J character to move left
is_left_pressed = is_left_pressed or Input.is_key_pressed(KEY_J)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_left_pressed:
break
rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_right_pressed = false
# RSC throttle right
Gui.prompt("Press [color=$H]L[/color] shortly to give a push [color=$H]right[/color] by activating the [color=$H]left[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press L character to move right
is_right_pressed = is_right_pressed or Input.is_key_pressed(KEY_L)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_right_pressed:
break
if obj.canceled:
return
obj.completed = true
# Objective 5 - Push right using the RCS thrusters
func _objective_5_rcs_push_right(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
var rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_right_pressed = false
# RSC throttle right
Gui.prompt("Press [color=$H]L[/color] shortly to give a push [color=$H]right[/color] by activating the [color=$H]left[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press L character to move right
is_right_pressed = is_right_pressed or Input.is_key_pressed(KEY_L)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_right_pressed:
break
# Enter the internal view mode
Gui.prompt("Press [color=$H]TAB[/color] to switch back to interior view.", false)
while !obj.canceled:
await Game.tick
if Game.get_view_mode() == Game.ViewMode.INTERNAL:
break
# Make sure a player is controlling the speed and position in the air
Gui.prompt("Still at 20m? Double-check!", false)
var hover_start_time: int = 0
var desired_altitude: int = 20
while not obj.canceled:
await Game.tick
var vehicle = Game.get_local_vehicle()
var altitude = vehicle.get_vectors().surface_position.length()
var diff = altitude - desired_altitude
# If within +- 1m -> sub-mission compledted
if diff < 1 and diff > 0:
var elapsed: float = (Time.get_ticks_msec() - hover_start_time) / 1000.0
# When 1 second passed, complete the mission
if elapsed > 1.0:
break
else:
Gui.prompt("Get back to an altitude of 20m.", false, true, _NO_ANIM)
if obj.canceled:
return
obj.completed = true
# Objective 6 - Push up using the RCS thrusters
func _objective_6_rcs_push_up(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
if not await Gui.prompt("Let’s figure out how to fire the top and bottom RCS thrusters!"):
return
# Enter the external view mode
Gui.prompt("Press [color=$H]TAB[/color] to switch to external view.", false)
while !obj.canceled:
await Game.tick
if Game.get_view_mode() == Game.ViewMode.EXTERNAL:
break
var rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_up_pressed = false
# RSC throttle up
Gui.prompt("Press [color=$H]O[/color] shortly to give a push [color=$H]up[/color] by activating the [color=$H]bottom[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press O character to move up
is_up_pressed = is_up_pressed or Input.is_key_pressed(KEY_O)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_up_pressed:
break
if obj.canceled:
return
obj.completed = true
# Objective 7 - Push down using the RCS thrusters
func _objective_7_rcs_push_down(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
var rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_down_pressed = false
# RSC throttle down
Gui.prompt("Press [color=$H]U[/color] shortly to give a push [color=$H]down[/color] by activating the [color=$H]top[/color] thrusters.", false)
while !obj.canceled:
await Game.tick
var rcs_prop_consumed_after = Game.get_local_vehicle().rcs_propellant_consumed
# Check if a player tried to press U character to move down
is_down_pressed = is_down_pressed or Input.is_key_pressed(KEY_U)
if rcs_prop_consumed_after - rcs_prop_consumed_before > .05 and is_down_pressed:
break
# Enter the internal view mode
Gui.prompt("Press [color=$H]TAB[/color] to switch back to interior view.", false)
while !obj.canceled:
await Game.tick
if Game.get_view_mode() == Game.ViewMode.INTERNAL:
break
# Make sure a player is controlling the speed and position in the air
Gui.prompt("Still at 20m? Stay there!", false)
var hover_start_time: int = 0
var desired_altitude: int = 20
while not obj.canceled:
await Game.tick
var vehicle = Game.get_local_vehicle()
var altitude = vehicle.get_vectors().surface_position.length()
var diff = altitude - desired_altitude
# If within +- 1m -> sub-mission compledted
if diff < 1 and diff > 0:
var elapsed: float = (Time.get_ticks_msec() - hover_start_time) / 1000.0
# When 1 second passed, complete the mission
if elapsed > 1.0:
break
else:
Gui.prompt("Get back to an altitude of 20m.", false, true, _NO_ANIM)
if obj.canceled:
return
obj.completed = true
# Objective 8 - Fly towards the other launchpad using RCS thrusters for tranlation
func _objective_8_fly_with_rcs(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
var rcs_prop_consumed_before = Game.get_local_vehicle().rcs_propellant_consumed
var is_backward_pressed = false
var is_forward_pressed = false
Gui.prompt("Now fly to the other launchpad using the RCS.", false)
while !obj.canceled:
await Game.tick
if Input.is_key_pressed(KEY_I):
break
_hint('OrbitalSpeed')
Gui.prompt("Try to keep your speed around 3m/s!", false, true, _NO_ANIM)
await _pause(5)
_hint('')
var maximum_threshold = 30.0
var desired_threshold = 7.0
var measurement_gap = 10.0
var first_launchpad = Game.get_node(_CURENT_LAUNCHPAD_SPAWN_POINT) as Marker3D
var second_launchpad = Game.get_node(_OTHER_LAUNCHPAD_SPAWN_POINT) as Marker3D
var pos_first = first_launchpad.global_position
var pos_second = second_launchpad.global_position
var half_way_position = absf(pos_second.y - pos_first.y) / 2
while not obj.canceled:
await Game.tick
var vehicle = Game.get_local_vehicle()
var vehicle_position = vehicle.get_absolute_position()
var diff_y = vehicle_position.y - second_launchpad.global_position.y
if diff_y < half_way_position + measurement_gap and diff_y > maximum_threshold:
Gui.prompt("You're already halfway there!", false, true, _NO_ANIM)
if diff_y < maximum_threshold and diff_y > desired_threshold:
Gui.prompt("Approaching our refuel spot! Control your speed and direction.", false, true, _NO_ANIM)
if diff_y < desired_threshold and diff_y > 0:
Gui.prompt("You are above the launchpad! Press [color=$H]K[/color] to hover above it. ", false, true, _NO_ANIM)
var altitude = vehicle.get_vectors().surface_position.length_squared()
var speed = vehicle.get_relative_velocity().length_squared()
var landed = altitude < 1 and speed < 0.01
if landed:
# Cast a ray from the vehicle towards the center of the body
var from = vehicle.to_global(Vector3.UP)
var to = vehicle.get_orbited_body().get_absolute_position()
var query = PhysicsRayQueryParameters3D.create(from, to)
query.exclude = [vehicle.get_rid()]
var result = vehicle.get_world_3d().direct_space_state.intersect_ray(query)
# If the ray picked the launchpad, then we landed straight on top of
# it; complete the objective
if result and result.collider.scene_file_path == _LAUNCHPAD_SCENE:
vehicle.propellant_consumed = 0
vehicle.rcs_propellant_consumed = 0
obj.completed = true
# Otherwise we landed somewhere else; fail the objective
else:
await Gui.prompt("Well... at least you tried! But uh, any ideas on how we’re refueling now?")
await Gui.prompt("[color=red]Try again![/color]")
obj.failed = true
break
if diff_y + measurement_gap < 0:
Gui.prompt("Oops... it looks like you overshot the launchpad.", false, true, _NO_ANIM)
if obj.canceled:
return
obj.completed = true
# Objective 9 - Let land on it
func _objective_9_refuel(obj: Objective):
Gui.prompt_canceled.connect(func (): obj.canceled = true, CONNECT_ONE_SHOT)
_hint('Switch')
Gui.prompt("Don't forget to turn off the engines! Remember, safety - first!", false)
while !obj.canceled:
await Game.tick
if not Game.get_local_vehicle().get_assembly().is_engine_enabled(0):
break
_hint('')
_hint('Fuel')
await Gui.prompt("Congratulations, pilot! Your fuel tanks are now fuller than a black hole’s appetite!")
_hint('')
obj.completed = true
Editor is loading...
Leave a Comment