Untitled
unknown
python
3 months ago
16 kB
4
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