diff --git a/auto_dogfight.py b/auto_dogfight.py index 5181af5..40dd739 100644 --- a/auto_dogfight.py +++ b/auto_dogfight.py @@ -77,8 +77,8 @@ def window_resize(window, width, height): # READ INDUSTRY DATA airframes, engines = read_industry() - player_airframe = airframes["LM Bombcat"] - player_engine = engines["APS 7K"] + player_airframe = airframes["OSB Serce"] + player_engine = engines["SE 7000"] # INIT VESSELS print("Initializing vessels...") @@ -361,6 +361,7 @@ def rotate_cam(rotation): altitude_conversion_factor = 3.28084 # feet # AUTOPILOT + ctrl_state = [0,0,0] # pull up! AP.engine.throttle = 1 @@ -371,11 +372,14 @@ def rotate_cam(rotation): if np.dot(AP.orient[1], np.array([0, 1, 0])) < max_orient * 0.8: if np.dot(AP.orient[0], np.array([0, 1, 0])) < 0: AP.aileron(-0.8) + ctrl_state[0] = -0.8 else: AP.aileron(0.8) + ctrl_state[0] = 0.8 if np.dot(AP.orient[1], np.array([0, 1, 0])) > 0: AP.elevator(0.8) + ctrl_state[1] = 0.8 # dogfight elif current_encounter: @@ -385,21 +389,23 @@ def rotate_cam(rotation): enemy_actual_rel_pos = (enemy.pos - player.pos) enemy_actual_dist = np.linalg.norm(enemy_actual_rel_pos) - enemy_rel_pos = (enemy.pos - player.pos) + enemy.vel * enemy_actual_dist / 500 + enemy_rel_pos = (enemy.pos - player.pos) + enemy.vel * enemy_actual_dist / 600 enemy_dist = np.linalg.norm(enemy_rel_pos) enemy_dir = enemy_rel_pos / enemy_dist max_orient_1 = np.linalg.norm( enemy_dir - np.dot(player.orient[2], enemy_dir) * player.orient[2] ) # lift vector not aligned with player? - if np.dot(player.orient[1], enemy_dir) < max_orient_1 * 0.8: + if np.dot(player.orient[1], enemy_dir) < max_orient_1 * 0.94: # should I roll clockwise? if np.dot(player.orient[0], enemy_dir) > 0: aileron_amount = np.dot(player.orient[0], enemy_dir) player.aileron(0.8 * aileron_amount) + ctrl_state[0] = 0.8 * aileron_amount else: aileron_amount = -np.dot(player.orient[0], enemy_dir) player.aileron(-0.8 * aileron_amount) + ctrl_state[0] = -0.8 * aileron_amount # should I pitch? if np.linalg.norm(player.vel) < 100: @@ -412,15 +418,18 @@ def rotate_cam(rotation): if np.dot(player.orient[1], enemy_dir) > 0: if np.dot(player.orient[2], enemy_dir) < 0.98: player.elevator(0.8) + ctrl_state[1] = 0.8 else: - player.elevator(0.3) + player.elevator(0.3 * (np.dot(player.orient[2], enemy_dir) - 0.98) / 0.02 + 0.5) + ctrl_state[1] = 0.3 * (np.dot(player.orient[2], enemy_dir) - 0.98) / 0.02 + 0.5 player.weapons[0].shoot(bodies) # PHYSICS for b in bodies: if isinstance(b, Rocket): + b.guidance(dt) b.apply_accel(gravity) b.apply_drag() b.apply_aero_torque() @@ -480,16 +489,17 @@ def rotate_cam(rotation): bodies.remove(current_encounter.enemy) current_encounter = None - if AP_city == None: - play_bgm("pluvious") - else: - play_bgm(AP_city.bgm) +## if AP_city == None: +## play_bgm("pluvious") +## else: +## play_bgm(AP_city.bgm) - if rwr_snd and not get_channel_busy(6): - if not (rwr_snd == "rwr_new" or rwr_snd == "rwr_lost"): - play_sfx(rwr_snd, -1, 6) - else: - play_sfx(rwr_snd, 0, 6) + if rwr_snd and (not (rwr_snd == "rwr_new" or rwr_snd == "rwr_lost")) and not get_channel_busy(6): + play_sfx(rwr_snd, -1, 6) + + if rwr_snd and (rwr_snd == "rwr_new" or rwr_snd == "rwr_lost"): + play_sfx(rwr_snd, 0, 8) + elif not rwr_snd or rwr_snd == "rwr_new" or rwr_snd == "rwr_lost": stop_channel(6) diff --git a/auto_dogfight_external.py b/auto_dogfight_external.py index bbb95e4..9f9f264 100644 --- a/auto_dogfight_external.py +++ b/auto_dogfight_external.py @@ -363,7 +363,8 @@ def rotate_cam(rotation): velocity_conversion_factor = 1.943844 # knots altitude_conversion_factor = 3.28084 # feet - # AUTOPILOT + # AUTOPILOT + ctrl_state = [0,0,0] # pull up! AP.engine.throttle = 1 @@ -374,11 +375,14 @@ def rotate_cam(rotation): if np.dot(AP.orient[1], np.array([0, 1, 0])) < max_orient * 0.8: if np.dot(AP.orient[0], np.array([0, 1, 0])) < 0: AP.aileron(-0.8) + ctrl_state[0] = -0.8 else: AP.aileron(0.8) + ctrl_state[0] = 0.8 if np.dot(AP.orient[1], np.array([0, 1, 0])) > 0: AP.elevator(0.8) + ctrl_state[1] = 0.8 # dogfight elif current_encounter: @@ -388,21 +392,23 @@ def rotate_cam(rotation): enemy_actual_rel_pos = (enemy.pos - player.pos) enemy_actual_dist = np.linalg.norm(enemy_actual_rel_pos) - enemy_rel_pos = (enemy.pos - player.pos) + enemy.vel * enemy_actual_dist / 500 + enemy_rel_pos = (enemy.pos - player.pos) + enemy.vel * enemy_actual_dist / 600 enemy_dist = np.linalg.norm(enemy_rel_pos) enemy_dir = enemy_rel_pos / enemy_dist max_orient_1 = np.linalg.norm( enemy_dir - np.dot(player.orient[2], enemy_dir) * player.orient[2] ) # lift vector not aligned with player? - if np.dot(player.orient[1], enemy_dir) < max_orient_1 * 0.8: + if np.dot(player.orient[1], enemy_dir) < max_orient_1 * 0.94: # should I roll clockwise? if np.dot(player.orient[0], enemy_dir) > 0: aileron_amount = np.dot(player.orient[0], enemy_dir) player.aileron(0.8 * aileron_amount) + ctrl_state[0] = 0.8 * aileron_amount else: aileron_amount = -np.dot(player.orient[0], enemy_dir) player.aileron(-0.8 * aileron_amount) + ctrl_state[0] = -0.8 * aileron_amount # should I pitch? if np.linalg.norm(player.vel) < 100: @@ -415,15 +421,20 @@ def rotate_cam(rotation): if np.dot(player.orient[1], enemy_dir) > 0: if np.dot(player.orient[2], enemy_dir) < 0.98: player.elevator(0.8) + ctrl_state[1] = 0.8 else: - player.elevator(0.3) - player.weapons[0].shoot(bodies) + player.elevator(0.3 * (np.dot(player.orient[2], enemy_dir) - 0.98) / 0.02 + 0.5) + ctrl_state[1] = 0.3 * (np.dot(player.orient[2], enemy_dir) - 0.98) / 0.02 + 0.5 + + if np.dot(player.orient[2], enemy_dir) > 0.92: + player.weapons[0].shoot(bodies) # PHYSICS for b in bodies: if isinstance(b, Rocket): + b.guidance(dt) b.apply_accel(gravity) b.apply_drag() b.apply_aero_torque() @@ -483,16 +494,17 @@ def rotate_cam(rotation): bodies.remove(current_encounter.enemy) current_encounter = None - if AP_city == None: - play_bgm("pluvious") - else: - play_bgm(AP_city.bgm) +## if AP_city == None: +## play_bgm("pluvious") +## else: +## play_bgm(AP_city.bgm) - if rwr_snd and not get_channel_busy(6): - if not (rwr_snd == "rwr_new" or rwr_snd == "rwr_lost"): - play_sfx(rwr_snd, -1, 6) - else: - play_sfx(rwr_snd, 0, 6) + if rwr_snd and (not (rwr_snd == "rwr_new" or rwr_snd == "rwr_lost")) and not get_channel_busy(6): + play_sfx(rwr_snd, -1, 6) + + if rwr_snd and (rwr_snd == "rwr_new" or rwr_snd == "rwr_lost"): + play_sfx(rwr_snd, 0, 8) + elif not rwr_snd or rwr_snd == "rwr_new" or rwr_snd == "rwr_lost": stop_channel(6) diff --git a/data/models/rocket.mdl b/data/models/rocket.mdl index 2893e01..9e9d393 100644 --- a/data/models/rocket.mdl +++ b/data/models/rocket.mdl @@ -1,15 +1,19 @@ -V|0, 0, 1 -V|0, 0, 0 -V|0.5, 0, 0 -V|-0.5, 0, 0 -V|0, 0.5, 0 -V|0, -0.5, 0 -L|1, 2 -L|2, 3 -L|2, 4 -L|2, 5 -L|2, 6 -L|3, 5 -L|5, 4 -L|4, 6 -L|6, 3 +V|0,0,-0.10 +V|0,0,0.10 +V|0.2,0,0.7 +V|-0.2,0,0.7 +V|0,0.2,0.7 +V|0,-0.2,0.7 +V|0.4,0,-1.0 +V|-0.4,0,-1.0 +V|0,0.4,-1.0 +V|0,-0.4,-1.0 +L|1,2 +L|2,3 +L|2,4 +L|2,5 +L|2,6 +L|1,7 +L|1,8 +L|1,9 +L|1,10 diff --git a/encounter.py b/encounter.py index b56136b..5e05141 100644 --- a/encounter.py +++ b/encounter.py @@ -98,7 +98,7 @@ def update(self, gravity, bodies, dt): player_actual_dist = np.linalg.norm(player.pos - self.enemy.pos) # aimpoint position - player_rel_pos = (player.pos - self.enemy.pos) + player.vel * player_actual_dist / 1000 + player_rel_pos = (player.pos - self.enemy.pos) + player.vel * player_actual_dist / 600 player_dist = np.linalg.norm(player_rel_pos) player_dir = player_rel_pos / player_dist @@ -120,7 +120,7 @@ def update(self, gravity, bodies, dt): else: max_orient_1 = np.linalg.norm( player_dir - np.dot(self.enemy.orient[2], player_dir) * self.enemy.orient[2] ) # lift vector not aligned with player? - if np.dot(self.enemy.orient[1], player_dir) < max_orient_1 * 0.8: + if np.dot(self.enemy.orient[1], player_dir) < max_orient_1 * 0.94: # should I roll clockwise? if np.dot(self.enemy.orient[0], player_dir) > 0: @@ -139,11 +139,11 @@ def update(self, gravity, bodies, dt): self.enemy.elevator(elevator_amount) if np.dot(self.enemy.orient[1], player_dir) > 0: - if np.dot(self.enemy.orient[2], player_dir) < 0.94: + if np.dot(self.enemy.orient[2], player_dir) < 0.98: self.enemy.elevator(0.8) else: - self.enemy.elevator(0.3) + self.enemy.elevator(0.3 * (np.dot(self.enemy.orient[2], player_dir) - 0.98) / 0.02 + 0.5) self.enemy.weapons[0].shoot(bodies, self.player) self.enemy.engine.intake.air_intake_vector = -self.enemy.orient[2] diff --git a/main.py b/main.py index f5f0ce7..cbcbdef 100644 --- a/main.py +++ b/main.py @@ -420,6 +420,7 @@ def rotate_cam(rotation): for b in bodies: if isinstance(b, Rocket): + b.guidance(dt) b.apply_accel(gravity) b.apply_drag() b.apply_aero_torque() diff --git a/quick_dogfight.py b/quick_dogfight.py index 3542f5f..4ef23ef 100644 --- a/quick_dogfight.py +++ b/quick_dogfight.py @@ -77,13 +77,13 @@ def window_resize(window, width, height): # READ INDUSTRY DATA airframes, engines = read_industry() - player_airframe = airframes["LM Bombcat"] - player_engine = engines["SE 7000"] + player_airframe = airframes["OSB Kirlangic"] + player_engine = engines["APS 7K"] # INIT VESSELS print("Initializing vessels...") init_pos = np.array([0.0, 1000, 0.0]) # m - init_vel = np.array([0.0, 0.0, 100.0]) # m s-1 + init_vel = np.array([0.0, 0.0, 150.0]) # m s-1 init_accel = np.array([0.0, 0.0, 0.0]) # m s-2 init_orient = np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], @@ -426,6 +426,7 @@ def rotate_cam(rotation): for b in bodies: if isinstance(b, Rocket): + b.guidance(dt) b.apply_accel(gravity) b.apply_drag() b.apply_aero_torque() diff --git a/rigidbody.py b/rigidbody.py index 282c1fb..ab80476 100644 --- a/rigidbody.py +++ b/rigidbody.py @@ -1,3 +1,4 @@ +import math import numpy as np from scipy.spatial.transform import Rotation @@ -96,6 +97,24 @@ def check_target(self, bodies): play_sfx("explosion", channel=6) del self + def guidance(self, dt): + if (not self.target) or np.linalg.norm(self.vel) == 0: + return + + t = self.target + m = self + + if np.dot(t.pos - m.pos, self.orient[2]) < 0.1: + return + + K_p = 0.001 + + aimpoint = t.pos + t.vel * K_p * np.linalg.norm(t.pos - m.pos) + aimpoint_dir = aimpoint - m.pos + aimpoint_dir /= np.linalg.norm(aimpoint_dir) + + m.vel = m.vel * (1 - dt * 2) + (aimpoint_dir * np.linalg.norm(m.vel)) * dt * 2 + def drain_fuel(self, dt): self.update_mass(-self.mass_flow * self.throttle / 100, dt)