protected override void OnUpdate(SAMTime gameTime, InputState istate) { BulletPosition = ConvertUnits2.ToDisplayUnitsPoint(PhysicsBody.Position); BulletRotation = PhysicsBody.Rotation; for (int i = _ignoredPortals.Count - 1; i >= 0; i--) { if (MonoSAMGame.GameCycleCounter - _ignoredPortals[i].LastCollidedCycle > 16) { _ignoredPortals[i].LastCollidedCycle = CollisionIgnoreObjectDecayCycles; _ignoredPortals.RemoveAt(i); } } if (Lifetime > MAXIMUM_LIFETIME) { VanishOutOfTime(); } if (GDOwner.WrapMode == GameWrapMode.Death && !Manager.BoundingBox.Contains(BulletPosition)) { if (!GDOwner.MapFullBounds.Contains(BulletPosition)) { VanishOutOfBounds(); } } if (GDOwner.WrapMode == GameWrapMode.Donut && !GDOwner.MapFullBounds.Contains(BulletPosition)) { DonutWrap(); } this.GDOwner().LaserNetwork.SemiDirty = true; }
protected override void OnUpdate(SAMTime gameTime, InputState istate) { BulletPosition = ConvertUnits2.ToDisplayUnitsPoint(PhysicsBody.Position); BulletVelocity = ConvertUnits.ToDisplayUnits(PhysicsBody.LinearVelocity); if (Lifetime > MAXIMUM_LIFETIME) { PredictKill(RemoteBulletState.Dying_FadeSlow); } if (GDOwner.WrapMode == GameWrapMode.Donut && !GDOwner.MapFullBounds.Contains(BulletPosition)) { DonutWrap(); } this.GDOwner().LaserNetwork.SemiDirty = true; }
private List <Tuple <List <Vector2>, ICannonBlueprint, float> > FindBulletPaths(LevelBlueprint lvl, World world, int sourceID, FPoint spawnPoint, Vector2 spawnVeloc, List <Vector2> fullpath, float scale, float lifetime) { var none = new List <Tuple <List <Vector2>, ICannonBlueprint, float> >(); // path, cannon, quality fullpath = fullpath.ToList(); object collisionUserObject = null; Contact collisionContact = null; var farseerBullet = BodyFactory.CreateCircle(world, ConvertUnits.ToSimUnits(scale * Bullet.BULLET_DIAMETER / 2), 1, ConvertUnits2.ToSimUnits(spawnPoint), BodyType.Dynamic, null); farseerBullet.LinearVelocity = ConvertUnits.ToSimUnits(spawnVeloc); farseerBullet.CollidesWith = Category.All; farseerBullet.Restitution = 1f; // Bouncability, 1=bounce always elastic farseerBullet.AngularDamping = 1f; // Practically no angular rotation farseerBullet.Friction = 0f; farseerBullet.LinearDamping = 0f; // no slowing down farseerBullet.OnCollision += (fa, fb, cobj) => { collisionUserObject = fb.UserData; collisionContact = cobj; if (fb.UserData is GlassBlockBlueprint) { return(true); } if (fb.UserData is MirrorBlockBlueprint) { return(true); } if (fb.UserData is MirrorCircleBlueprint) { return(true); } if (fb.UserData is MarkerCollisionBorder) { return(true); } return(false); }; farseerBullet.AngularVelocity = 0; fullpath.Add(spawnPoint.ToVec2D()); for (;;) { collisionUserObject = null; foreach (var bh in lvl.BlueprintBlackHoles) { var pp = ConvertUnits.ToDisplayUnits(farseerBullet.Position) - new Vector2(bh.X, bh.Y); var force = bh.Power / pp.LengthSquared(); var vecForce = pp.WithLength(force); farseerBullet.ApplyForce(ConvertUnits.ToSimUnits(vecForce)); } world.Step(1 / SIMULATION_UPS); // x UPS lifetime += 1 / SIMULATION_UPS; fullpath.Add(ConvertUnits2.ToDisplayUnitsPoint(farseerBullet.Position).ToVec2D()); if (collisionUserObject is PortalBlueprint) { var veloc = ConvertUnits.ToDisplayUnits(farseerBullet.LinearVelocity); world.RemoveBody(farseerBullet); var fPortal = (PortalBlueprint)collisionUserObject; Vector2 normal; FixedArray2 <Vector2> t; collisionContact.GetWorldManifold(out normal, out t); bool hit = FloatMath.DiffRadiansAbs(normal.ToAngle(), FloatMath.ToRadians(fPortal.Normal)) < FloatMath.RAD_POS_001; if (!hit) { return(none); } var dat = new List <Tuple <List <Vector2>, ICannonBlueprint, float> >(); foreach (var outportal in lvl.BlueprintPortals.Where(p => p.Side != fPortal.Side && p.Group == fPortal.Group)) { var stretch = outportal.Length / fPortal.Length; var cIn = new FPoint(fPortal.X, fPortal.Y); var cOut = new FPoint(outportal.X, outportal.Y); var cInVecNormal = Vector2.UnitX.RotateDeg(fPortal.Normal); var cInVecDirection = cInVecNormal.RotateWithLength(FloatMath.RAD_POS_090, fPortal.Length / 2f); var cOutVecNormal = Vector2.UnitX.RotateDeg(outportal.Normal); var cOutVecDirection = cOutVecNormal.RotateWithLength(FloatMath.RAD_POS_090, outportal.Length / 2f); var rot = FloatMath.ToRadians(outportal.Normal - fPortal.Normal) + FloatMath.RAD_POS_180; var projec = ConvertUnits.ToDisplayUnits(farseerBullet.Position).ProjectOntoLine(cIn, cInVecDirection); var newVelocity = ConvertUnits.ToDisplayUnits(farseerBullet.LinearVelocity).Rotate(rot); var newStart = cOut + cOutVecDirection * (-projec) + cOutVecNormal * (Portal.WIDTH / 2f) + newVelocity.WithLength(scale * Bullet.BULLET_DIAMETER / 2 + 4); var sub = FindBulletPaths(lvl, world, sourceID, newStart, newVelocity, fullpath, scale * stretch, lifetime); dat.AddRange(sub); } return(dat); } if (collisionUserObject is ICannonBlueprint) { world.RemoveBody(farseerBullet); var tgcannon = (ICannonBlueprint)collisionUserObject; if (tgcannon.CannonID == sourceID) { return(none); } var quality = Math2D.LinePointDistance(ConvertUnits2.ToDisplayUnitsPoint(farseerBullet.Position), ConvertUnits2.ToDisplayUnitsPoint(farseerBullet.Position) + ConvertUnits.ToDisplayUnits(farseerBullet.LinearVelocity), new FPoint(tgcannon.X, tgcannon.Y)); return(new List <Tuple <List <Vector2>, ICannonBlueprint, float> > { Tuple.Create(fullpath, tgcannon, quality) }); } bool oow = (farseerBullet.Position.X < 0 - 64) || (farseerBullet.Position.Y < 0 - 64) || (farseerBullet.Position.X > ConvertUnits.ToSimUnits(lvl.LevelWidth) + 64) || (farseerBullet.Position.Y > ConvertUnits.ToSimUnits(lvl.LevelHeight) + 64); bool ool = (lifetime >= Bullet.MAXIMUM_LIFETIME * LIFETIME_FAC); //if (collisionUserObject != null || oow || ool) //{ // world.RemoveBody(farseerBullet); // return new List<Tuple<List<Vector2>, CannonBlueprint, float>> { Tuple.Create(fullpath, new CannonBlueprint(farseerBullet.Position.X, farseerBullet.Position.Y, 64, 1, 0, FloatMath.GetRangedIntRandom(0, 9999999)), 1f) }; //} if (collisionUserObject is VoidWallBlueprint) { world.RemoveBody(farseerBullet); return(none); } if (collisionUserObject is VoidCircleBlueprint) { world.RemoveBody(farseerBullet); return(none); } if (collisionUserObject is BlackHoleBlueprint) { world.RemoveBody(farseerBullet); return(none); } if (oow || ool) { world.RemoveBody(farseerBullet); return(none); } if (lvl.WrapMode == LevelBlueprint.WRAPMODE_DONUT) { var pbullet = ConvertUnits.ToDisplayUnits(farseerBullet.Position); pbullet.X = (pbullet.X + lvl.LevelWidth) % lvl.LevelWidth; pbullet.Y = (pbullet.Y + lvl.LevelHeight) % lvl.LevelHeight; farseerBullet.Position = ConvertUnits.ToSimUnits(pbullet); } } }