/// <summary> /// glorious people's democratic proletariat AI of the space invaders' revolution? /// pilots badly but bravely for motherland and mothership /// </summary> /// <param name="gameTime"></param> public override void UpdateActions(GameTime gameTime) { ++update_ticks; if (update_ticks % 30 == 0) { jitter = (float)Game1.main_instance.dispatcher.rand.NextDouble() * nav_AI_period; } bool alternate_propulsion = jitter < (nav_AI_period / 2.0f); if (last_nav_AI == 0) { // first update, just set up our jittery execution last_fire_AI = gameTime.TotalGameTime.TotalMilliseconds + jitter; last_nav_AI = last_fire_AI; } if (gameTime.TotalGameTime.TotalMilliseconds > last_fire_AI + fire_AI_period) { last_fire_AI = gameTime.TotalGameTime.TotalMilliseconds; // try shooting! fire(gameTime); } if (gameTime.TotalGameTime.TotalMilliseconds > last_nav_AI + nav_AI_period) { last_nav_AI = gameTime.TotalGameTime.TotalMilliseconds; if (sec_fraction < 0.4F && (velocity.LengthSquared() > 388 * 388) && ((velocity + acceleration).LengthSquared() < velocity.LengthSquared())) { velocity *= (1.0F - 0.83f * sec_fraction); // put the space-brakes on :P } float separation = (Game1.main_instance.protagonist.world.Translation - world.Translation).LengthSquared() / this.velocity.LengthSquared(); // approximate time to close with target, still grows in inaccuracy at higher speeds separation = (float)Math.Sqrt(separation); //float separation = 1.0f; Vector3 prediction = Game1.main_instance.protagonist.world.Translation + Game1.main_instance.protagonist.velocity * (separation * jitter / nav_AI_period) * skillz; Vector3 wtf = prediction - world.Translation; wtf.Normalize(); // direction toward our hated enemy, in world terms... // now, compare our own direction vectors to that vector to see what do Vector3 what_do = Vector3.Up; AI_turning = new Vector3(1, 0, 0); float dist = Vector3.DistanceSquared(wtf, world.Up); what_do *= 1.33F; // they go a little faster when moving forward? *shrug* float d2 = Vector3.DistanceSquared(wtf, world.Down); if (d2 < dist) { dist = d2; what_do = Vector3.Down; AI_turning = new Vector3(-1, 0, 0); } d2 = Vector3.DistanceSquared(wtf, world.Left); if (cautious) { d2 /= 2; // overvalue strafing left and right when cautious } if (d2 < dist) { dist = d2; what_do = Vector3.Left; AI_turning = new Vector3(0, 1, 0); } d2 = Vector3.DistanceSquared(wtf, world.Right); if (cautious) { d2 /= 2; } if (d2 < dist) { dist = d2; what_do = Vector3.Right; AI_turning = new Vector3(0, -1, 0); } d2 = Vector3.DistanceSquared(wtf, world.Backward); if (d2 < dist) { dist = d2; what_do = Vector3.Backward; AI_turning = new Vector3(0, -1, 0); } d2 = Vector3.DistanceSquared(wtf, world.Forward); if (d2 < dist) { dist = d2; what_do = Vector3.Forward; /* this means nothing to our stupid turning strategy */ } AI_thrust = what_do; // // I know that was like the dumbest thing ever but I'm really tired, OK? // // Also, it doesn't even work right... we can cheat harder, though if (alternate_propulsion) { AI_thrust = wtf; } AI_turning /= 3.0F; // they turn slow... because they're so bad at aiming ._. } if (alternate_propulsion) { acceleration = AI_thrust; } else { Thrust(AI_thrust); } if (!Game1.TestLineSphereIntersection(world.Translation, world.Translation + world.Forward * 3000, Game1.main_instance.protagonist.world.Translation, 30f - 29.5f * skillz)) { angular_thrust = AI_turning; } else { angular_thrust = Vector3.Zero; } // if we're cheating hard, don't call the base method, as it overwrites acceleration if (!alternate_propulsion) { base.UpdateActions(gameTime); } // copying the rotation stuff from base, though else { rotate(angular_thrust.Y * max_angular_acceleration, angular_thrust.X * max_angular_acceleration, angular_thrust.Z * max_angular_acceleration); } }
/// <summary> /// glorious people's democratic proletariat AI of the space invaders' revolution? /// pilots badly but bravely for motherland and mothership /// </summary> /// <param name="gameTime"></param> public override void UpdateActions(GameTime gameTime) { Vector3 prediction; ++update_ticks; // if (update_ticks % 30 == 0) jitter = (float)Game1.main_instance.dispatcher.rand.NextDouble() * nav_AI_period; // bool alternate_propulsion = jitter < (nav_AI_period / 2.0f); if (last_nav_AI == 0) { // first update, just set up our jittery execution last_fire_AI = gameTime.TotalGameTime.TotalMilliseconds + jitter; last_nav_AI = last_fire_AI; } if (gameTime.TotalGameTime.TotalMilliseconds > last_fire_AI + fire_AI_period) { last_fire_AI = gameTime.TotalGameTime.TotalMilliseconds; // try shooting! fire(gameTime); } if (gameTime.TotalGameTime.TotalMilliseconds > last_nav_AI + nav_AI_period) { last_nav_AI = gameTime.TotalGameTime.TotalMilliseconds; separation = (Game1.main_instance.protagonist.world.Translation - world.Translation).Length() / Bullet.default_velocity; // approximate time for bullet to intercept target, still grows in inaccuracy at higher speeds maybe Vector3 wtf = Game1.main_instance.protagonist.world.Translation - world.Translation; if (sec_fraction < 0.4F && velocity.LengthSquared() > 330 * 330 && (velocity + wtf).LengthSquared() > wtf.LengthSquared()) // headed the wrong way, are we? :( { velocity *= (1.0F - 0.850f * sec_fraction); // put the space-brakes on :P } // the NPC ships are completely hopeless at maneuvering without this cheat wtf.Normalize(); // direction toward our hated enemy, in world terms... // now, compare our own direction vectors to that vector to see what do Vector3 what_do = Vector3.Up; AI_turning = new Vector3(1, 0, 0); float dist = Vector3.DistanceSquared(wtf, world.Up); what_do *= 1.33F; // they go a little faster when moving forward? *shrug* float d2 = Vector3.DistanceSquared(wtf, world.Down); if (d2 < dist) { dist = d2; what_do = Vector3.Down; AI_turning = new Vector3(-1, 0, 0); } d2 = Vector3.DistanceSquared(wtf, world.Left); if (d2 < dist) { dist = d2; what_do = Vector3.Left; AI_turning = new Vector3(0, 1, 0); } d2 = Vector3.DistanceSquared(wtf, world.Right); if (d2 < dist) { dist = d2; what_do = Vector3.Right; AI_turning = new Vector3(0, -1, 0); } d2 = Vector3.DistanceSquared(wtf, world.Backward); if (d2 < dist) { dist = d2; what_do = Vector3.Backward; AI_turning = new Vector3(0, -1, 0); } d2 = Vector3.DistanceSquared(wtf, world.Forward); if (d2 < dist) { dist = d2; what_do = Vector3.Forward; /* this means nothing to our stupid turning strategy */ } AI_thrust = what_do; // // I know that was like the dumbest thing ever but I'm really tired, OK? // // Also, it doesn't even work right... we can cheat harder, though //if (alternate_propulsion) AI_thrust = wtf; if (cautious) { wtf *= 1.5f; // light a fire under them, eh? } AI_thrust = wtf; AI_turning /= 3.0F; // they turn slow... because they're so bad at aiming ._. } //if (alternate_propulsion) acceleration = AI_thrust; //else Thrust(AI_thrust); acceleration = AI_thrust; prediction = Game1.main_instance.protagonist.world.Translation + Game1.main_instance.protagonist.velocity * separation * skillz; // without skillz being in here, the AI's aim is actually uncanny and superhuman if (!Game1.TestLineSphereIntersection(world.Translation, world.Translation + world.Forward * 6000, prediction, 30f - 27f * skillz)) { angular_thrust = AI_turning; } else { angular_thrust = Vector3.Zero; } // if we're cheating hard, don't call the base method, as it overwrites acceleration //if (!alternate_propulsion) base.UpdateActions(gameTime); // copying the rotation stuff from base, though /*else*/ rotate(angular_thrust.Y * max_angular_acceleration, angular_thrust.X * max_angular_acceleration, angular_thrust.Z * max_angular_acceleration); }
public override void UpdateActions(GameTime gameTime) { float secFraction = gameTime.ElapsedGameTime.Milliseconds / (float)1000.0; Game1 game = Game1.main_instance; // these are not smart bullets... they just go straight. :3 // check whether we've left the player's local area entirely if (Vector3.DistanceSquared(world.Translation, game.protagonist.world.Translation) > 3000.0F * 3000.0F) { active = false; return; } // let's do collision detection against ships here, though // that way there should be no confusion about whether bullets move or do this check first... Vector3 future = world.Translation + (velocity * secFraction); bool removebullet = false; // is the player hit? if (from != game.protagonist && Game1.TestLineSphereIntersection(world.Translation, future, game.protagonist.world.Translation, game.spaceship.Meshes[0].BoundingSphere.Radius)) { IOConsole.instance.WriteLine("player is hit."); game.protagonist.TakeHit(world.Translation, 0); removebullet = true; } // check all the other ships, if any >_< // foreach (ActorModel who in modelManager.models) // same problem as above with foreach() if (!removebullet) { for (int j = 0; j < game.modelManager.models.Count;) { BasicSpaceshipActor who = game.modelManager.models[j] as BasicSpaceshipActor; if (from != who && Game1.TestLineSphereIntersection(world.Translation, future, who.world.Translation, who.model.Meshes[0].BoundingSphere.Radius * 1.1f)) // XXX are we supposed to add BoundingSphere.Center to the translation as an offset? let's assume not. { who.TakeHit(world.Translation, 0); if (!who.active) { game.modelManager.models.RemoveAt(j); // I guess they asploded? } removebullet = true; } ++j; } } // this is getting twisted now :( if (removebullet) { this.active = false; } }