public void AutoFire(Entity target) { var viewing = ViewingMatrix; var projection = ProjectionMatrix; var time = GunBulletComponent.ComputeHitTime(this.Owner, target); var p1 = new Vector3(0, 0, time * GunBulletComponent.BulletSpeed) * this.Transform.Matrix; var p2 = target.Get <TransformComponent>().Position + time * target.Get <PhysicsComponent>().Velocity; if ((p2 - p1).SquaredMagnitude < square(Radius)) { this.Fire(); } }
private void Update() { var myself = Owner; var aircraft = Owner.Get <AircraftComponent>(); var ai = Owner.Get <AIComponent>(); if (pressed(KeyCode.LeftShift) || pressed(KeyCode.RightShift)) { if (pressed(KeyCode.Left)) { aircraft.Yaw(-1.0f); } if (pressed(KeyCode.Right)) { aircraft.Yaw(1.0f); } if (pressed(KeyCode.Up)) { aircraft.YawY(1.0f); } if (pressed(KeyCode.Down)) { aircraft.YawY(-1.0f); } } else { if (pressed(KeyCode.Left)) { aircraft.Roll(-1.0f); } if (pressed(KeyCode.Right)) { aircraft.Roll(1.0f); } if (pressed(KeyCode.Up)) { aircraft.Pitch(1.0f); } if (pressed(KeyCode.Down)) { aircraft.Pitch(-1.0f); } } if (pressed(KeyCode.Left) && pressed(KeyCode.Right) && ai.HasTarget()) { aircraft.AutoPilot(GunBulletComponent.ComputeOptimalAimPosition(this.Owner, ai.TargetEntity)); } if (pressed(KeyCode.Z)) { aircraft.DesiredPower = aircraft.DesiredPower + 0.004f; } if (pressed(KeyCode.X)) { aircraft.DesiredPower = aircraft.DesiredPower - 0.004f; } if (nowpressed(KeyCode.C)) { aircraft.Launch(); } if (pressed(KeyCode.V)) { aircraft.Fire(); } if (!pressed(KeyCode.LeftCtrl) && !pressed(KeyCode.RightCtrl)) { if (nowpressed(KeyCode.W)) { ai.ResetTarget(); } if (nowreleased(KeyCode.S)) { if (GazeKeyPressedTime < 1.0f) { ai.ChangeTarget(); } } if (nowreleased(KeyCode.A)) { Entity.Find("ui").Get <UIComponent>().ChangeRadarRange(); } } #if false if (nowreleased(KeyCode.Left)) { released_frame_left = frame; } if (nowpressed(KeyCode.Left) && (frame - released_frame_left < 10)) { aircraft.Roll(-10.0f); aircraft.Pitch(-60.0f); } if (nowreleased(KeyCode.Right)) { released_frame_right = frame; } if (nowpressed(KeyCode.Right) && (frame - released_frame_right < 10)) { aircraft.Roll(10.0f); aircraft.Pitch(-60.0f); } if (nowreleased(KeyCode.Up)) { released_frame_up = frame; } if (nowpressed(KeyCode.Up) && (frame - released_frame_up < 10)) { } #endif if (nowreleased(KeyCode.Down)) { ReleasedFrameDown = frame; } if (nowpressed(KeyCode.Down) && (frame - ReleasedFrameDown < 10)) { aircraft.Avoid(); } if (pressed(KeyCode.S)) { GazeKeyPressedTime += 0.1f; } else { GazeKeyPressedTime = 0; } var camera = Entity.Find("camera").Get <CameraComponent>(); camera.EnableGazing = false; bool angleOffsetChangedX = false, angleOffsetChangedY = false; if (pressed(KeyCode.LeftCtrl) || pressed(KeyCode.RightCtrl)) { if (pressed(KeyCode.A)) { AngleOffsetY = 0.9f * AngleOffsetY + 0.1f * -PI; angleOffsetChangedY = true; } if (pressed(KeyCode.D)) { AngleOffsetY = 0.9f * AngleOffsetY + 0.1f * PI; angleOffsetChangedY = true; } if (pressed(KeyCode.W)) { AngleOffsetX = 0.9f * AngleOffsetX + 0.1f * -PIOver2; angleOffsetChangedX = true; } if (pressed(KeyCode.S)) { AngleOffsetX = 0.9f * AngleOffsetX + 0.1f * PIOver2; angleOffsetChangedX = true; } } else { if (ai.TargetEntity != null) { camera.GazingPoint = ai.TargetEntity.Get <TransformComponent>().Position; camera.EnableGazing = (1.0f < GazeKeyPressedTime); } else { camera.EnableGazing = false; } } if (!angleOffsetChangedX) { AngleOffsetX *= 0.9f; } if (!angleOffsetChangedY) { AngleOffsetY *= 0.9f; } camera.AngleOffset = new Matrix3x3().Identity().RotateY(AngleOffsetY).RotateX(AngleOffsetX); if (!pressed(KeyCode.LeftCtrl) && nowpressed(KeyCode.D)) { HUDView = !HUDView; } aircraft.Visible = true; if (HUDView) { camera.TrackingOffset = 0.9f * camera.TrackingOffset + 0.1f * aircraft.CockpitPos; } else { camera.TrackingOffset = 0.9f * camera.TrackingOffset + 0.1f * new Vector3(0, 4, -18); } { var distance = (camera.TrackingOffset - aircraft.CockpitPos).Magnitude; var alpha = clamp(distance / 15, 0, 1); aircraft.Opacity = 1 - alpha; if (alpha < .99f) { aircraft.Visible = false; } } camera.EnableTracking = true; camera.TrackingPose = this.Transform.Matrix; camera.TrackingLatency = (int)TrackingLatency; }
private void Draw() { var player = Entity.Find("player"); if (player == null) { return; } var transform = player.Get <TransformComponent>(); var physics = player.Get <PhysicsComponent>(); var target = player.Get <AIComponent>().TargetEntity; bool lockonAlert = false; bool missileAlert = false; Entity.ForEach((e) => { var missile = e.Get <MissileComponent>(); if (missile != null && missile.TargetEntity == player && missile.Locking) { if (missile.Launched) { missileAlert = true; } else { lockonAlert = true; } } }); bool playAlertSound = missileAlert || (lockonAlert && (frame % 60) < 30); if (playAlertSound && !AlertSound.Playing) { AlertSound.LoopPlay(); } if (!playAlertSound && AlertSound.Playing) { AlertSound.Stop(); } { Color Red = new Color(0.8f, 0, 0, 0.8f); Color Blue = new Color(0, 0.4f, 0.8f, 0.8f); Color Black = new Color(0, 0, 0, 0.8f); Color Yellow = new Color(0.6f, 0.6f, 0, 0.8f); Color Green = new Color(0, 0.8f, 0, 0.8f); identity(); blend(HalfAddition); color(Green); #region 制限時間 if (true) { pushMatrix(); { translate(-0.75f, 0.75f, 0.0f); pushMatrix(); { scale(0.3f, 0.08f); //rectangle(); } popMatrix(); pushMatrix(); { scale(0.08f); write(128.ToString(), TextAlignment.Center, TextAlignment.Center); } popMatrix(); } popMatrix(); } #endregion #region 速度計と高度計 if (true) { pushMatrix(); { var velocity = ToKmPerHour(physics.Velocity.Magnitude); translate(-0.55f, 0.0f, 0.0f); pushMatrix(); { translate(-0.15f, 0.0f, 0.0f); scale(0.08f); write(floor(velocity).ToString().PadLeft(4), TextAlignment.Center, TextAlignment.Center); } popMatrix(); pushMatrix(); { scale(0.1f, 0.4f); float v = -velocity / 100; draw(SpeedMeterTexture, 1, v, 0, v + 1); } popMatrix(); } popMatrix(); pushMatrix(); { var altitude = transform.Position.Y; translate(0.55f, 0.0f, 0.0f); pushMatrix(); { translate(0.15f, 0.0f, 0.0f); scale(0.08f); write(floor(altitude).ToString().PadLeft(4), TextAlignment.Center, TextAlignment.Center); } popMatrix(); pushMatrix(); { scale(0.1f, 0.4f); float v = -altitude / 100; draw(SpeedMeterTexture, 0, v, 1, v + 1); } popMatrix(); } popMatrix(); } #endregion #region 針路計 if (true) { pushMatrix(); { Vector3 front = transform.Forward; float angle = atan2(front.X, front.Z); float u = angle / PI; translate(0, 0.75f); scale(0.8f, 0.2f); draw(CourseTexture, u - 0.25f, 0.0f, u + 0.25f, 1.0f); } popMatrix(); pushMatrix(); { translate(0, 0.75f); scale(0.05f, 0.05f); translate(0, -1); draw(CoursePointerTexture); } popMatrix(); } #endregion #region ピッチスケール if (true) { pushMatrix(); { Vector3 front = transform.Forward; float pitch = atan2(front.Y, sqrt(front.X * front.X + front.Z * front.Z)); float v = -1.0f / PI * (pitch - PIOver2); Matrix4x3 matrix = transform.Matrix; matrix.Position = Vector3.Zero; matrix.Invert(); Vector3 direction = new Vector3(0, 1, 0) * matrix; float angle = -atan2(direction.X, direction.Y); rotate(angle); scale(0.75f, 0.75f); addressing(Mirror); draw(PitchscaleTexture, 0.0f, v - 0.1f, 2.0f, v + 0.1f); addressing(Wrap); } popMatrix(); } #endregion #region ターゲットディレクション if (target != null) { var transform2 = target.Get <TransformComponent>(); Vector3 relative = transform2.Position - transform.Position; if (relative.Magnitude < SearchOperationRange && Vector3.Angle(relative, transform.Forward) / PIOver2 > 0.2f) { Matrix4x3 matrix = transform.Matrix; matrix.Position = Vector3.Zero; matrix.Invert(); relative = relative * matrix; relative.Z = 0; float theta = atan2(relative.Y, relative.X); float x = 0.5f * cos(theta); float y = 0.5f * sin(theta); pushMatrix(); { translate(x, y); rotate(theta); scale(0.15f, 0.075f); draw(TargetDirectionTexture); } popMatrix(); pushMatrix(); { translate(x * 0.7f, y * 0.7f); scale(0.06f); write(((int)(transform2.Position - transform.Position).Magnitude).ToString(), TextAlignment.Center, TextAlignment.Center); } popMatrix(); } } #endregion #region ミサイルディレクション Entity.ForEach(e => { color(Red); var missile = e.Get <MissileComponent>(); if (missile != null && missile.TargetEntity == player && missile.Locking && missile.Launched) { var transform2 = e.Get <TransformComponent>(); Vector3 relative = transform2.Position - transform.Position; if (relative.Magnitude < SearchOperationRange && Vector3.Angle(relative, transform.Forward) / PIOver2 > 0.2f) { Matrix4x3 matrix = transform.Matrix; matrix.Position = Vector3.Zero; matrix.Invert(); relative = relative * matrix; relative.Z = 0; float theta = atan2(relative.Y, relative.X); float x = 0.5f * cos(theta); float y = 0.5f * sin(theta); pushMatrix(); { translate(x, y); rotate(theta); scale(0.15f, 0.075f); draw(TargetDirectionTexture); } popMatrix(); pushMatrix(); { translate(x * 0.7f, y * 0.7f); scale(0.06f); write(((int)relative.Magnitude).ToString(), TextAlignment.Center, TextAlignment.Center); } popMatrix(); } } }); #endregion #region ターゲットマーカー Entity.ForEach((e) => { if (e.Has <AIComponent>() && e.Get <AircraftComponent>().Armor > 0 && e.Name != "player") { var missile = player.Get <AircraftComponent>().ActiveMissile; { var world = e.Get <TransformComponent>().Matrix; var viewing = Entity.Find("camera").Get <CameraComponent>().ViewingMatrix; var projection = Entity.Find("projector").Get <ProjectorComponent>().ProjectionMatrix; Vector4 v = new Vector4(Vector3.Zero, 1) * world * viewing * projection; if (0 <= v.W && v.W <= SearchOperationRange) { int distance = (int)(transform.Position - e.Get <TransformComponent>().Position).Magnitude; pushMatrix(); { var x = v.X / v.W; var y = v.Y / v.W; translate(x * DisplayAspect, y); scale(0.06f); if (e.Get <AIComponent>().Group == Enemy) { if ((missile != null) && (missile.TargetEntity == e)) { color(missile.Locking ? Red : Green); if (missile.Locking || (frame % 60 < 30)) { draw(TargetTexture); } } else { color(Green); draw(TargetTexture); } } else { color(Blue); draw(TargetTexture); } write(e.Get <AircraftComponent>().Name + "\n" + distance); translate(0, -2); write(e.Get <SquadronComponent>().SquadronName + " " + (e.Get <SquadronComponent>().Number + 1)); } popMatrix(); } } } }); #endregion #region ガンレティクル if (target != null) { var viewing = ViewingMatrix; var projection = ProjectionMatrix; var time = GunBulletComponent.ComputeHitTime(player, target); var p1 = new Vector3(0, 0, time * GunBulletComponent.BulletSpeed) * transform.Matrix; var v1 = new Vector4(p1, 1) * viewing * projection; var p2 = target.Get <TransformComponent>().Position + time * target.Get <PhysicsComponent>().Velocity; var v2 = new Vector4(p2, 1) * viewing * projection; if (0 <= v2.W && v2.W <= 800) { pushMatrix(); { Vector2 u1 = new Vector2(v1.X / v1.W, v1.Y / v1.W); Vector2 u2 = new Vector2(v2.X / v2.W, v2.Y / v2.W); Vector2 u3 = u1 + (u1 - u2); translate(u3.X * DisplayAspect, u3.Y); scale(0.1f); color(((p2 - p1).SquaredMagnitude < square(AircraftComponent.Radius)) ? Red : Green); draw(GunReticleTexture); } popMatrix(); } } #endregion #if false #region デバッグゾーン { var viewing = ViewingMatrix; var projection = ProjectionMatrix; var v2 = new Vector4(PlayerComponent.AimPoint, 1) * viewing * projection; if (0 <= v2.W) { pushMatrix(); { translate(new Vector2(v2.X / v2.W * DisplayAspect, v2.Y / v2.W)); scale(0.1f); color(Red); draw(GunReticleTexture); } popMatrix(); } } #endregion #endif #region シーカー { var missile = player.Get <AircraftComponent>().ActiveMissile; if (missile != null && missile.TargetEntity != null) { var viewing = Entity.Find("camera").Get <CameraComponent>().ViewingMatrix; var projection = Entity.Find("projector").Get <ProjectorComponent>().ProjectionMatrix; if (missile.Locking) { color(Red); var world = missile.TargetEntity.Get <TransformComponent>().Matrix; Vector4 p = new Vector4(Vector3.Zero, 1) * world * viewing * projection; if (0 <= p.W && p.W <= SearchOperationRange) { pushMatrix(); { var x = p.X / p.W; var y = p.Y / p.W; translate(x * DisplayAspect, y); rotate(deg2rad(45.0f)); scale(0.06f / sqrt(2)); draw(TargetTexture); } popMatrix(); } } else if (missile.Seeking) { color(Green); float dist = (missile.TargetEntity.Get <TransformComponent>().Position - transform.Position).Magnitude; var world = missile.SeekerAngle * transform.Matrix; Vector4 p = new Vector4(0, 0, dist, 1) * world * viewing * projection; pushMatrix(); { var x = p.X / p.W; var y = p.Y / p.W; translate(x * DisplayAspect, y); rotate(deg2rad(45.0f)); scale(0.06f / sqrt(2)); draw(TargetTexture); } popMatrix(); } } } #endregion #region レーダー if (true) { color(Green); pushMatrix(); { translate(-1.0f, -0.7f, 0); scale(0.5f, 0.5f); draw(RadarTexture); } popMatrix(); pushMatrix(); { translate(-1.0f, -0.7f, 0); scale(0.5f, 0.5f); translate(0.5f / sqrt(2), -0.5f / sqrt(2), 0); scale(0.1f); write(RadarRange.ToString()); } popMatrix(); Matrix4x3 local = new Matrix4x3().Identity(); { Vector3 direction = transform.Forward; float theta = atan2(direction.X, direction.Z); local.RotateY(theta); local.Position = transform.Position; local.Invert(); } color(Red); Entity.ForEach((e) => { if (e.Has <AIComponent>() && (e.Name != "player")) { color((e.Get <AIComponent>().Group == Friend) ? Blue : Red); if (!((e == target) && (frame % 60 < 30))) { var transform2 = e.Get <TransformComponent>(); Matrix4x3 matrix = transform2.Matrix * local; if (matrix.Position.Magnitude < SearchOperationRange) { Vector3 point = new Vector3(matrix.M41, 0, matrix.M43); point /= max(RadarRange, point.Magnitude); Vector2 point2D; point2D.X = point.X * 0.5f / 2; point2D.Y = point.Z * 0.5f / 2; point2D += new Vector2(-1.0f, -0.7f); float theta = atan2(matrix.M31, matrix.M33); pushMatrix(); { translate(point2D); rotate(-theta); scale(0.07f); draw(AircraftMarkerTexture); } popMatrix(); } } } else if (e.Has <MissileComponent>() && e.Get <MissileComponent>().Launched) { color(Red); var transform2 = e.Get <TransformComponent>(); Matrix4x3 matrix = transform2.Matrix * local; Vector3 point = new Vector3(matrix.M41, 0, matrix.M43); if (point.Magnitude < SearchOperationRange) { point /= max(RadarRange, point.Magnitude); Vector2 point2D; point2D.X = point.X * 0.5f / 2; point2D.Y = point.Z * 0.5f / 2; point2D += new Vector2(-1.0f, -0.7f); pushMatrix(); { translate(point2D); scale(0.05f); draw(MissileMarkerTexture); } popMatrix(); } } }); } #endregion #region リロード { pushMatrix(); translate(-1, -0.2f); scale(0.15f / 4, 0.15f); { var times = player.Get <AircraftComponent>().ReloadTimes; for (int i = 0; i < 8; i++) { var time = times[i]; pushMatrix(); { switch (i) { case 0: translate(-3.5f, -0.75f); break; case 1: translate(3.5f, -0.75f); break; case 2: translate(-2.5f, -0.5f); break; case 3: translate(2.5f, -0.5f); break; case 4: translate(-1.5f, -0.25f); break; case 5: translate(1.5f, -0.25f); break; case 6: translate(-0.5f, 0); break; case 7: translate(0.5f, 0); break; } color(time == 1 ? Green : Red); drawThreshold(ReloadTimeTexture, 0, 1 - time, 1.0f, 1.0f); draw(ReloadTimeFrameTexture); } popMatrix(); } } popMatrix(); } #endregion #region 全体マップ if (true) { pushMatrix(); { translate(1.0f, -0.7f, 0); scale(0.5f, 0.5f); color(Black); rectangle(); } popMatrix(); Entity.ForEach((e) => { if (e.Has <AIComponent>()) { if (!((target == e) && (frame % 60 < 30))) { color((e.Get <AIComponent>().Group == Friend) ? (e.Name == "player") ? Green : Blue : Red); var transform2 = e.Get <TransformComponent>(); Matrix4x3 matrix = transform2.Matrix; Vector3 point = new Vector3(matrix.M41, 0, matrix.M43); point /= Entity.Find("gamespace").Get <GameSpaceComponent>().AreaLength * 0.5f; if (point.Magnitude <= 1.0f) { Vector2 point2D; point2D.X = point.X * 0.5f / 2; point2D.Y = point.Z * 0.5f / 2; point2D += new Vector2(1.0f, -0.7f); float theta = atan2(matrix.M31, matrix.M33); pushMatrix(); { translate(point2D); rotate(-theta); scale(0.05f); draw(AircraftMarkerTexture); } popMatrix(); } } } }); } #endregion #region アラートメッセージ { if (missileAlert) { color(Red); pushMatrix(); { scale(0.07f); write("Missile Alert", TextAlignment.Center, TextAlignment.Center); } popMatrix(); } else if (lockonAlert && playAlertSound) { color(Yellow); pushMatrix(); { scale(0.07f); write("Lockon Caution", TextAlignment.Center, TextAlignment.Center); } popMatrix(); } } #endregion #region 通知 { if (this.NoticeDisplayTime > 0) { blend(Addition); Color c = Green; c.R *= square(this.NoticeDisplayTime); c.G *= square(this.NoticeDisplayTime); c.B *= square(this.NoticeDisplayTime); color(c); pushMatrix(); { scale(0.07f); translate(0, 1); write(this.NoticeMessage, TextAlignment.Center, TextAlignment.Center); } popMatrix(); this.NoticeDisplayTime = clamp(this.NoticeDisplayTime - 0.005f, 0, 1); } } #endregion } }
public void AutoPilot(Entity target) { Vector3 destination = GunBulletComponent.ComputeOptimalAimPosition(this.Owner, target); this.AutoPilot(destination); }
private void Update() { var aircraft = Owner.Get <AircraftComponent>(); if (aircraft.Armor == 0.0f) { return; } var ai = Owner.Get <AIComponent>(); var squadron = Owner.Get <SquadronComponent>(); if (squadron.Number != 0 && squadron.SquadronLeader != null && squadron.SquadronLeader.IsAlive) { ai.SetSameTarget(squadron.SquadronLeader.Get <AIComponent>()); } this.TargetEntity = ai.TargetEntity; //this.UpdateStateMachine(); if (this.TargetEntity == null || !this.TargetEntity.IsAlive) { return; } Vector3 targetPosition = new Vector3(); switch (StateMachine.CurrentState) { case "attack": { targetPosition = this.TargetEntity.Get <TransformComponent>().Position + this.TargetEntity.Get <PhysicsComponent>().Velocity * 180; var distance = (this.Transform.Position - this.TargetEntity.Get <TransformComponent>().Position).Magnitude; targetPosition = GunBulletComponent.ComputeOptimalAimPosition(this.Owner, this.TargetEntity); if (uniform(0, 600) == 0 && aircraft.Locking) { aircraft.Launch(); } if (distance < 800 && Vector3.Angle(this.Transform.Forward, targetPosition - this.Transform.Position) < deg2rad(10)) { aircraft.Fire(); } aircraft.DesiredPower = 1.0f; } break; case "retreat": { if (squadron.Number == 0 || squadron.SquadronLeader == null || !squadron.SquadronLeader.IsAlive) { targetPosition = TargetEntity.Get <TransformComponent>().Position; targetPosition = Transform.Position + (Transform.Position - targetPosition); targetPosition.Y = Transform.Position.Y; } else { targetPosition = squadron.SquadronLeader.Get <TransformComponent>().Position; } aircraft.DesiredPower = 0.8f; } break; case "avoid missile": { if (ThreatMissile != null) { targetPosition = ThreatMissile.Get <TransformComponent>().Position; } aircraft.DesiredPower = 0.8f; } break; case "do nothing": { if (squadron.SquadronLeader != null) { targetPosition = squadron.SquadronLeader.Get <TransformComponent>().Position; } else { targetPosition = Transform.Position + Transform.Forward; targetPosition.Y = Transform.Position.Y; } aircraft.DesiredPower = 0.6f; } break; default: break; } var curvedSurface = (Entity.Find("ground").Get <CollisionComponent>().Object as CurvedSurfaceCollisionObject); float height = curvedSurface.ComputeHeight(Transform.Position); if (height < 500) { float k = height / 500; k = clamp(k, 0, 1); k = 1 - k; var distance = (targetPosition - Transform.Position).Magnitude; targetPosition = (1 - k) * targetPosition + k * (Transform.Position + new Vector3(0, distance, 0)); aircraft.DesiredPower = (1 - k) * aircraft.DesiredPower + k * 0.8f; } Owner.Get <AircraftComponent>().AutoPilot(targetPosition); }