private void Collision_BeanTerrain(object sender, MaterialCollisionArgs e) { try { // Find the affected bean Body beanBody = e.GetBody(_material_Bean); Bean bean = _beans.Where(o => o.PhysicsBody.Equals(beanBody)).FirstOrDefault(); // Inform it if (bean != null) { bean.CollidedGround(); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Collision_BotFood(object sender, MaterialCollisionArgs e) { try { Body shipBody = e.GetBody(_material_Bot); Body mineralBody = e.GetBody(_material_Food); Swimbot bot = _bots.Where(o => o.PhysicsBody.Equals(shipBody)).FirstOrDefault(); if (bot == null) { return; } Mineral mineral = _map.GetItem<Mineral>(mineralBody); if (mineral == null) { return; } bot.CollidedMineral(mineral); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Collision_AsteroidProjectile(object sender, MaterialCollisionArgs e) { try { Body asteroidBody = e.GetBody(_material_Asteroid); Body projectileBody = e.GetBody(_material_Projectile); if (asteroidBody == null || projectileBody == null) { return; } //NOTE: this.Map_ItemRemoved will dispose the projectile once the map removes it, so get these stats now double projectileMass = projectileBody.Mass; Point3D projectilePos = projectileBody.Position; Vector3D projectileVelocity = projectileBody.Velocity; // Find and remove the projectile Projectile projectile = _map.RemoveItem<Projectile>(projectileBody); if (projectile == null) { // Already gone return; } // Damage the asteroid Asteroid asteroid = _map.GetItem<Asteroid>(asteroidBody); if (asteroid != null) { asteroid.TakeDamage_Projectile(projectileMass, projectilePos, projectileVelocity); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Collision_AsteroidSwarmBot(object sender, MaterialCollisionArgs e) { try { Body asteroidBody = e.GetBody(_material_Asteroid); Body botBody = e.GetBody(_material_SwarmBot); if (asteroidBody == null || botBody == null) { return; } //NOTE: this.Map_ItemRemoved will dispose the swarmbot once the map removes it, so get these stats now double botMass = botBody.Mass; Point3D botPos = botBody.Position; Vector3D botVelocity = botBody.Velocity; // Damage the bot SwarmBot1b bot = _map.GetItem<SwarmBot1b>(botBody); if (bot != null) { bot.TakeDamage(asteroidBody.Velocity); } else { // Already gone return; } // Damage the asteroid Asteroid asteroid = _map.GetItem<Asteroid>(asteroidBody); if (asteroid != null) { //TODO: When swarmbots can grow and specialize, remove this mass/vel boost asteroid.TakeDamage_Projectile(botMass * 5, botPos, botVelocity * 3); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Collision_ShipAsteroid(object sender, MaterialCollisionArgs e) { try { Body asteroidBody = e.GetBody(_material_Asteroid); Body shipBody = e.GetBody(_material_Ship); if (asteroidBody == null || shipBody == null) { return; } Asteroid asteroid = _map.GetItem<Asteroid>(asteroidBody); Bot ship = _map.GetItem<Bot>(shipBody); if (asteroid == null || ship == null) { return; } // Cache some props double asteroidMass = asteroidBody.Mass; //Point3D asteroidPos = asteroidBody.Position; //Vector3D asteroidVelocity = asteroidBody.Velocity; double shipMass = shipBody.Mass; //Point3D shipPos = shipBody.Position; //Vector3D shipVelocity = shipBody.Velocity; var collisions = e.Collisions. Select(o => { Point3D pos; Vector3D norm; double speed; o.GetContactPositionAndNormalWorld(out pos, out norm, out speed, asteroidBody); return new { Position = pos, Normal = norm, Speed = speed }; }). ToArray(); Point3D collisionPos = Math3D.GetCenter(collisions.Select(o => o.Position)); Vector3D collisionVelocity = Math3D.GetAverage(collisions.Select(o => o.Normal)).ToUnit() * collisions.Average(o => o.Speed); // this is relative to the ship. It will need to be reversed for the asteroid if (collisionVelocity.IsNearZero()) { return; } //var test1 = ship.PositionWorld; //var test2 = ship.Radius; //var test3 = asteroid.PositionWorld; //var test4 = asteroid.Radius; //var test5 = Math3D.GetAABB(collisions.Select(o => o.Position)); //var test6 = (test5.Item2 - test5.Item1).Length; // Damage the asteroid // The asteroid has a hit counter, and breaks up after a few hits. That would need to be removed for this type of hit //TODO: The asteroid should only take damage if the impact exceeds a threshold //asteroid.TakeDamage_Other(shipMass, collisionPos, -collisionVelocity); // negative velocity, because the collision velocity is in reference to the ship // Damage the ship Point3D posModel = ship.PhysicsBody.PositionFromWorld(collisionPos); Vector3D velModel = ship.PhysicsBody.DirectionFromWorld(collisionVelocity); ship.TakeDamage_Collision(asteroid, posModel, velModel, asteroidMass, shipMass); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Collision_ShipMineral(object sender, MaterialCollisionArgs e) { try { Body botBody = e.GetBody(_material_Ship); Body mineralBody = e.GetBody(_material_Mineral); Bot bot = _map.GetItem<Bot>(botBody); if (bot == null) { return; } // For now, only the player ship can take minerals if (!(bot is ShipPlayer)) { return; } Mineral mineral = _map.GetItem<Mineral>(mineralBody); if (mineral == null) { return; } ((ShipPlayer)bot).CollidedMineral(mineral, _world, _material_Mineral, _sharedVisuals); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Collision_SpaceStation(object sender, MaterialCollisionArgs e) { SpaceStation station = _map.GetItem<SpaceStation>(e.GetBody(_material_SpaceStation)); if (station != null) { station.Collided(e); } }
private void Collision_Sand(object sender, MaterialCollisionArgs e) { // When the sand hits the ship, it is staying alive too long and messing up other sand Body body = e.GetBody(_material_Sand); TempBody tempBody = _tempBodies.FirstOrDefault(o => o.PhysicsBody.Equals(body)); if (tempBody != null) { _tempBodies.Remove(tempBody); _tempBodies.Add(new TempBody(tempBody.PhysicsBody, TimeSpan.FromSeconds(1))); } }
private void Collision_ProjectileBrick(object sender, MaterialCollisionArgs e) { const double MAXIMPULSE = 150; Body body0 = e.Body0; Body body1 = e.Body1; if (body0 == null || body1 == null || body0.MaterialGroupID == _material_ExplodingProjectile || body1.MaterialGroupID == _material_ExplodingProjectile) { // Since I'm changing the material to an explosion, this event still gets called several times in a single frame, but the body has changed // material type and GetBody throws an exception return; } Body projectile = e.GetBody(_material_Projectile); if (projectile == null) { return; } #region Light Fuse if (radProjectilesExplode.IsChecked.Value && !_projectilesLitFuse.ContainsKey(projectile)) { _projectilesLitFuse.Add(projectile, .01); // seconds } else if (radProjectilesImplode.IsChecked.Value && !_projectilesLitFuse.ContainsKey(projectile)) { _projectilesLitFuse.Add(projectile, .01); // seconds } #endregion #region Paint Red if (chkColoredImpacts.IsChecked.Value) { Body brickBody = e.GetBody(_material_Brick); if (brickBody != null) { BodyMaterial material = _bodyMaterials[brickBody]; foreach (MaterialCollision collision in e.Collisions) { if (collision.ContactNormalSpeed > material.MaxImpulse) { // This is the biggest force this brick has felt, paint it a shade of red material.MaxImpulse = collision.ContactNormalSpeed; byte red = Convert.ToByte(UtilityCore.GetScaledValue_Capped(material.OrigColor.R, 255, 0, MAXIMPULSE, material.MaxImpulse)); // increase red byte green = Convert.ToByte(UtilityCore.GetScaledValue_Capped(0, material.OrigColor.G, MAXIMPULSE, 0, material.MaxImpulse)); // decrease green and blue byte blue = Convert.ToByte(UtilityCore.GetScaledValue_Capped(0, material.OrigColor.B, MAXIMPULSE, 0, material.MaxImpulse)); material.Material.Brush = new SolidColorBrush(Color.FromArgb(255, red, green, blue)); } } } } #endregion }