extends Spatial onready var exhaust_node = $Exhaust; const ACCEL = 0.1; #24.5; # Unit: m/s^2 const MAX_DV = 0.2;#3300.0; # Delta V in m/s const MAX_TURN_RATE = 1.0; # Universal turn rate in °/s^2 var MISSILE_ID = "UNKNOWN"; var is_operational: bool = true; # if the missile is operational var has_fuel: bool = true; var turn_instruction: Vector3 = Vector3(0, 0, 0); # vector of (X, Y, Z) possible rotational thrust to apply (0.0 to 1.0 for full turn) var thrust_instruction: float = 0.5; # throttle between 0.0 and 1.0 of available thrust to apply var curr_rotation_vel: Vector3 = Vector3(); var curr_thrust: float = 0.0; var curr_velocity: Vector3 = Vector3(); var curr_DV: float = MAX_DV; var __curr_shader_param_cache = {}; func _set_thruster_thrust(node: MeshInstance, power): #print("Node: ", node.name) var MAX_POWER = 10; if node.name in __curr_shader_param_cache: if __curr_shader_param_cache[node.name] == power: #print("Skipped shader edit"); pass;#return; ### DEBUG CODE #if node.name in __curr_shader_param_cache: #print("Editing "+node.name+" because "+str(__curr_shader_param_cache[node.name])+" != "+str(power)+" (old vs new)"); ### __curr_shader_param_cache[node.name] = power; node.get_surface_material(0).set_shader_param("power", clamp(power, .0, MAX_POWER)); var particle_node: Particles = node.get_node("./Particles"); if power < 2.0: if power == 0.0: node.set_visible(false); particle_node.set_emitting(false); else: node.set_visible(true); particle_node.set_emitting(true); # Set the visual main engine flare from 0.0 to 10.0 # 0.0 turns off all engine effects func set_main_engine_thrust(power: float): var exhausts = exhaust_node.get_node("Main").get_children(); #print("Changing main exhaust to: ", power); for node in exhausts: self._set_thruster_thrust(node, power); # Set the visual rotational engine flare from -10.0 to 10.0 # Negative power visualizes downwards, Positive upwards and 0.0 turns all X thrusters off func set_X_rotational_thrust(power: float): var up_rotation_thrusters = [exhaust_node.get_node("FrontThrusters/ThrusterBottom"), exhaust_node.get_node("RearThrusters/ThrusterTop")]; var down_rotation_thrusters = [exhaust_node.get_node("FrontThrusters/ThrusterTop"), exhaust_node.get_node("RearThrusters/ThrusterBottom")]; if power > 0.0: #print("Changing rotation thrust upwards to: ", power); for node in up_rotation_thrusters: self._set_thruster_thrust(node, power); for node in down_rotation_thrusters: self._set_thruster_thrust(node, 0.0); elif power < 0.0: #print("Changing rotation thrust downwards to: ", power); for node in down_rotation_thrusters: self._set_thruster_thrust(node, -1 * power); for node in up_rotation_thrusters: self._set_thruster_thrust(node, 0.0); else: #print("Turning X rotation thrusters off"); for node in up_rotation_thrusters+down_rotation_thrusters: self._set_thruster_thrust(node, 0.0); # Set the visual rotational engine flare from -10.0 to 10.0 # Negative power visualizes left, Positive right and 0.0 turns all Y thrusters off func set_Y_rotational_thrust(power: float): var MAX_POWER = 10; var left_rotation_thrusters = [exhaust_node.get_node("FrontThrusters/ThrusterLeft"), exhaust_node.get_node("RearThrusters/ThrusterRight")]; var right_rotation_thrusters = [exhaust_node.get_node("FrontThrusters/ThrusterRight"), exhaust_node.get_node("RearThrusters/ThrusterLeft")]; if power > 0.0: #print("Changing rotation thrust right to: ", power); for node in right_rotation_thrusters: self._set_thruster_thrust(node, power); for node in left_rotation_thrusters: self._set_thruster_thrust(node, 0.0); elif power < 0.0: #print("Changing rotation thrust left to: ", power); for node in left_rotation_thrusters: self._set_thruster_thrust(node, -1 * power); for node in right_rotation_thrusters: self._set_thruster_thrust(node, 0.0); else: #print("Turning Y rotation thrusters off"); for node in right_rotation_thrusters+left_rotation_thrusters: self._set_thruster_thrust(node, 0.0); func _ready(): set_main_engine_thrust(0.0); set_X_rotational_thrust(0.0); set_Y_rotational_thrust(0.0); var timer = 0.0; func _physics_process(delta): timer -= delta; if not self.has_fuel or not self.is_operational: if timer <= 0.0: set_main_engine_thrust(0.0); set_X_rotational_thrust(0.0); set_Y_rotational_thrust(0.0); timer = 1.0 else: if timer <= 0.0: set_X_rotational_thrust(lerp(0.0, 10.0, turn_instruction.x)); set_Y_rotational_thrust(lerp(0.0, 10.0, turn_instruction.y)); set_main_engine_thrust(lerp(0.0, 10.0, thrust_instruction)); self.transform = self.transform.orthonormalized(); ### DEBUG CODE #print("Rotation: "+str(self.curr_rotation_vel)+", Velocity: "+str(self.curr_velocity)+" Remeining dV: "+str(self.curr_DV)); ### timer = 1.0; self.curr_rotation_vel += turn_instruction * Vector3(MAX_TURN_RATE, MAX_TURN_RATE, MAX_TURN_RATE) * delta; self.curr_thrust = thrust_instruction * ACCEL * delta; self.curr_velocity += self.global_transform.basis.z * self.curr_thrust * -1; self.curr_DV -= curr_thrust; if curr_DV <= 0.0: print("Missile "+MISSILE_ID+" has run out of fuel!"); self.has_fuel = false; if self.curr_rotation_vel.length() > 0.0: self.rotate_x(deg2rad(self.curr_rotation_vel.x)); self.rotate_y(deg2rad(self.curr_rotation_vel.y)); self.rotate_z(deg2rad(self.curr_rotation_vel.z)); if self.curr_velocity.length() > 0.0: #self.translate(self.curr_velocity); self.global_translate(self.curr_velocity);