Inheritance: MonoBehaviour
Example #1
0
 public PUMA(HelixViewport3D viewport, ModelVisual3D start, ModelVisual3D end)
 {
     startFrame = start;
     endFrame = end;
     converter = Singleton<EulerToQuaternionConverter>.Instance;
     mathHelper = Singleton<MathHelper>.Instance;
     Initialize(viewport);
 }
Example #2
0
        public static void CalculateDistance()
        {
            var math = new MathHelper();

            using (var context = new SmartBuyEntities())
            {
                var markets = context.Markets.Where(x => x.IsActive).ToList();
                for (int i = 0; i < markets.Count - 1; i++)
                {
                    double lat1 = markets[i].Latitude.Value;
                    double lng1 = markets[i].Longitude.Value;

                    for (int j = i + 1; j < markets.Count; j++)
                    {
                        if (markets[j].Latitude == null || markets[j].Longitude == null)
                        {
                            continue;
                        }
                        double lat2 = markets[j].Latitude.Value;
                        double lng2 = markets[j].Longitude.Value;

                        double distance = math.CalculateDistance(lat1, lng1, lat2, lng2);

                        int fromId = markets[i].Id;
                        int toId = markets[j].Id;

                        var mDis = context.MarketDistances
                            .FirstOrDefault(x => x.FromMarket == fromId && x.ToMarket == toId);
                        if (mDis == null)
                        {
                            var dis = new MarketDistance
                                          {
                                              FromMarket = markets[i].Id,
                                              ToMarket = markets[j].Id,
                                              Distance = distance
                                          };
                            context.MarketDistances.Add(dis);
                        }
                    }
                }
                context.SaveChanges();
            }
        }
        public static List<double> DistanceToAllMarket(string route, string[] ids, string type)
        {
            var math = new MathHelper();
            var result = new List<double>();
            var markets = new List<Market>();
            var model = JsonConvert.DeserializeObject<RouteModel>(route);

            using (var context = new SmartBuyEntities())
            {
                // Construct a market list
                foreach (string id in ids)
                {
                    int tmp = Int32.Parse(id);
                    var market = context.Markets.FirstOrDefault(x => x.Id == tmp);
                    if (market != null)
                    {
                        markets.Add(market);
                    }
                }
            }

            Coordinate point = new Coordinate();
            switch (type)
            {
                case "start":
                    point = model.Start;
                    break;
                case "end":
                    point = model.End;
                    break;
            }

            foreach (Market market in markets)
            {
                double distance = math.TravelDistance(point.Lat, point.Lng, market.Latitude.Value, market.Longitude.Value);
                result.Add(distance);
            }

            return result;
        }
Example #4
0
            public override void Update(GameTime gameTime)
            {
                Gameplay g = Sender.Parent.Parent;

                #region Gestion de la gravité
                float vx = Velocity.X;
                float vy = Velocity.Y;

                if (!_onFloor)
                {
                    vy = GRAVITY;
                }

                // Dans l'eau
                if (Position.Y > g.WaterLevel)
                {
                    Velocity.Normalize();
                    if (Position.Y > g.WaterLevel + g.WaterHeight)
                    {
                        Die(false);
                    }
                }
                #endregion

                #region Limitations de la vélocité
                vx       = MathHelper.Clamp(vx, -SPEED_MAX, SPEED_MAX);
                vy       = MathHelper.Clamp(vy, -SPEED_MAX, SPEED_MAX);
                Velocity = new Vector2(vx, vy);
                #endregion

                #region Récupération de l'ancienne position en 3 points en bas (Gauche / Centre / Droite) pour vérifier les collisions
                Vector2 previousPosMiddle = new Vector2(BoundingBox.Location.X, BoundingBox.Size.Y);
                Vector2 previousPosLeft   = new Vector2(BoundingBox.Left, BoundingBox.Bottom);
                Vector2 previousPosRight  = new Vector2(BoundingBox.Right, BoundingBox.Bottom);
                #endregion

                base.Update(gameTime);

                #region Collision avec le sol
                Vector2 newPosLeft   = new Vector2(Position.X - ImgBox.Value.Width / 2, Position.Y);
                Vector2 newPosMiddle = Position;
                Vector2 newPosRight  = new Vector2(Position.X + ImgBox.Value.Width / 2, Position.Y);

                if (g.IsSolid(newPosLeft, previousPosLeft) ||
                    g.IsSolid(newPosMiddle, previousPosMiddle) ||
                    g.IsSolid(newPosRight, previousPosRight))
                {
                    _onFloor = true;

                    // Récupère l'altitude en Y à position.X -20 et +20 afin d'en déterminer l'angle à partir d'un vecteur tracé entre ces deux points.
                    Vector2 center = g.FindHighestPoint(Position, 0);
                    Vector2 before = g.FindHighestPoint(Position, -BoundingBox.Width / 2);
                    Vector2 after  = g.FindHighestPoint(Position, BoundingBox.Width / 2);
                    Angle     = (float)utils.MathAngle(after - before);
                    Position += center;
                }
                else
                {
                    _onFloor = false;
                }
                RefreshBoundingBox();
                #endregion
            }
Example #5
0
        // GetSolutionBtn click event handler
        // Using TinyMath Library
        protected void GetSolutionBtn_Click(object sender, EventArgs e)
        {
            // Log file path
            string logfilepath = "MathHelper_log.txt";
            MathHelper mHelper = new MathHelper(logfilepath);

            // Input strings with linear equations
            string[] stringSeparators = new string[] {"\r\n"};
            string[] inputStrings = leSystem.Text.Split(stringSeparators, 
                            StringSplitOptions.RemoveEmptyEntries);

            // Try to solve the system
            lesSolutionText.Text
                = mHelper.TrySolveLinearEquationSystem(
                    Convert.ToInt32(EqutionsCount.Text),
                    Convert.ToInt32(UnknownCount.Text),
                    inputStrings.ToList<string>());

            // If wrong input data
            if (lesSolutionText.Text ==
                "Wrong input system. Check the input"
                + " data for pattern matching "
                + "(look at the example).")
                leSystem.BackColor = Color.FromArgb(0,255, 189, 189);
            else
                leSystem.BackColor = Color.FromArgb(160, 247, 247, 255);
            
            // Seting up controlls
            lesSolutionText.Visible = true;            
        }
Example #6
0
 public override void Update(float distance)
 {
     Current          = MathHelper.Clamp(distance, Min, Max);
     currentTransform = Matrix4.CreateFromAxisAngle(AxisRotation, Current);
 }
Example #7
0
 public static Vector2 AdjustInWorldBounds(this ICamera camera, Vector2 location, float width, float height, Vector2 origin)
 {
     location.X = MathHelper.Clamp(location.X, camera.Position.X + origin.X, camera.Position.X + camera.ViewPort.Width - width + origin.X);
     location.Y = MathHelper.Clamp(location.Y, camera.Position.Y + origin.Y, camera.Position.Y + camera.ViewPort.Height - height + origin.Y);
     return(location);
 }
Example #8
0
 public override void UpdateInventory(Player player)
 {
     if (player.HeldItem.modItem == this)
     {
         if (Main.time % 60 == 0)
         {
             int   direction = -1;
             float spirals   = 4;
             for (int i = 0; i < spirals; i++)
             {
                 float points = 120;
                 for (int j = 0; j < points; j++)
                 {
                     float   rotation     = Math.Sign(direction) * ((360f / spirals * i) + (360f / points * j));
                     Vector2 dustPosition = new Vector2(0f, -j * 2f).RotatedBy(MathHelper.ToRadians(rotation));
                     Dust    dust         = Dust.NewDustPerfect(player.Center + dustPosition, ModContent.DustType <PixelDust>(), new Vector2(0f, 0f), 0, Color.Lerp(Main.DiscoColor, Color.White, j / points), 1f);
                     dust.noGravity = true;
                 }
             }
         }
     }
 }
Example #9
0
        public override void Update(float deltaTime, Camera cam)
        {
            UpdateOnActiveEffects(deltaTime);

#if CLIENT
            light.SpriteScale = Vector2.One * item.Scale;
            light.ParentSub   = item.Submarine;
            if (item.Container != null)
            {
                light.Color = Color.Transparent;
                return;
            }
            light.Position = ParentBody != null ? ParentBody.Position : item.Position;
#endif

            PhysicsBody body = ParentBody ?? item.body;

            if (body != null)
            {
#if CLIENT
                light.Rotation          = body.Dir > 0.0f ? body.DrawRotation : body.DrawRotation - MathHelper.Pi;
                light.LightSpriteEffect = (body.Dir > 0.0f) ? SpriteEffects.None : SpriteEffects.FlipVertically;
#endif
                if (!body.Enabled)
                {
#if CLIENT
                    light.Color = Color.Transparent;
#endif
                    return;
                }
            }
            else
            {
#if CLIENT
                light.Rotation = -Rotation;
#endif
            }

            if (powerConsumption == 0.0f)
            {
                voltage = 1.0f;
            }
            else
            {
                currPowerConsumption = powerConsumption;
            }

            if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage))
            {
#if CLIENT
                if (voltage > 0.1f)
                {
                    SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull);
                }
#endif
                lightBrightness = 0.0f;
            }
            else
            {
                lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(voltage, 1.0f), 0.1f);
            }

            if (blinkFrequency > 0.0f)
            {
                blinkTimer = (blinkTimer + deltaTime * blinkFrequency) % 1.0f;
            }

            if (blinkTimer > 0.5f)
            {
#if CLIENT
                light.Color = Color.Transparent;
#endif
            }
            else
            {
#if CLIENT
                light.Color = lightColor * lightBrightness * (1.0f - Rand.Range(0.0f, Flicker));
                light.Range = range;
#endif
            }
            if (AITarget != null)
            {
                UpdateAITarget(AITarget);
            }
            if (item.AiTarget != null)
            {
                UpdateAITarget(item.AiTarget);
            }

            voltage -= deltaTime;
        }
		public override void AI()
		{
			Projectile P = projectile;
			Player O = Main.player[P.owner];
			Lead = Main.projectile[(int)P.ai[0]];
			
			float speed = 10f;//14f;
			
			if(Lead == null || !Lead.active || Lead.owner != P.owner || Lead.type != mod.ProjectileType("ChargeLead") || !O.controlUseItem)
			{
				P.Kill();
				return;
			}
			else
			{
				velocity = Vector2.Normalize(Lead.velocity)*speed;
			}
			
			if(!initialized)
			{
				/*if (P.owner == Main.myPlayer)
				{
					Main.PlaySound(2,(int)P.Center.X,(int)P.Center.Y,8);//43);
				}*/
				P.rotation = (float)Angle.ConvertToRadians(Main.rand.Next(36)*10);
				P.scale = 0f;
				damage = P.damage;
				P.damage = 0;
				
				Vector2 vel = P.velocity;
				vel = vel.RotatedBy(P.rotation, default(Vector2));
				P.velocity = Vector2.Normalize(vel)*(4f+Main.rand.Next(4));
				
				//P.timeLeft = 60+Main.rand.Next(61);
				
				P.ai[1] = -1;
				
				initialized = true;
				return;
			}
			
			if (P.owner == Main.myPlayer)
			{
				P.netUpdate = true;
				
				Vector2 point = Main.MouseWorld;
				
				//P.ai[1] = -1;
				for(int i = 0; i < Main.maxNPCs; i++)
				{
					if(Main.npc[i].active && Main.npc[i].lifeMax > 5 && !Main.npc[i].dontTakeDamage && !Main.npc[i].friendly)
					//if(Main.npc[i].active && Main.npc[i].CanBeChasedBy(P,false))
					{
						NPC npc = Main.npc[i];
						
						bool flag = (npc.Distance(point) < 500 && Collision.CanHit(P.position,P.width,P.height,npc.position,npc.width,npc.height));
						
						int numTarget = 0;
						if(flag)
						{
							for(int j = 0; j < Main.maxProjectiles; j++)
							{
								if(Main.projectile[j].active && Main.projectile[j].owner == P.owner && Main.projectile[j].type == P.type)
								{
									if(Main.projectile[j].ai[1] == i && j != P.whoAmI)
									{
										numTarget++;
									}
								}
							}
						}
						if(numTarget < 5)
						{
							if(P.ai[1] == -1)
							{
								if(flag)
								{
									P.ai[1] = i;
								}
							}
							else
							{
								if(!checkbreak && i != P.ai[1] && flag && npc.Distance(point) < Main.npc[(int)P.ai[1]].Distance(point))
								{
									P.ai[1] = i;
								}
							}
						}
						else if(P.ai[1] == -1 && Main.rand.Next(2) == 0 && !checkbreak)
						{
							P.ai[1] = i;
						}
					}
					if(i >= Main.maxNPCs-1)
					{
						checkbreak = true;
					}
				}
				if(P.ai[1] != -1)
				{
					if(!Main.npc[(int)P.ai[1]].active)
					{
						P.ai[1] = -1;
						checkbreak = false;
					}
					else if(Main.npc[(int)P.ai[1]].Distance(point) > 350)
					{
						P.ai[1] = -1;
						checkbreak = false;
					}
					else
					{
						Vector2 diff2 = Main.npc[(int)P.ai[1]].Center - P.Center;
						diff2.Normalize();
						if (float.IsNaN(diff2.X) || float.IsNaN(diff2.Y))
						{
							diff2 = -Vector2.UnitY;
						}
						velocity = diff2*speed;
					}
				}
				/*else
				{
					Vector2 diff2 = Main.MouseWorld - P.Center;
					diff2.Normalize();
					if (float.IsNaN(diff2.X) || float.IsNaN(diff2.Y))
					{
						diff2 = -Vector2.UnitY;
					}
					velocity = diff2*speed;
				}*/
			}
			
			Vector2 diff = Lead.Center - P.Center;
			diff.Normalize();
			if (float.IsNaN(diff.X) || float.IsNaN(diff.Y))
			{
				diff = -Vector2.UnitY;
			}
			P.velocity += diff*MathHelper.Lerp(0.1f,1f,Math.Max((Vector2.Distance(Lead.Center,P.Center)-300f)/300f,0f));
			
			Color color = MetroidMod.lumColor;
			Lighting.AddLight(P.Center, color.R/255f,color.G/255f,color.B/255f);
			
			//if(P.numUpdates == 0)
			//{
				int dust = Dust.NewDust(P.position, P.width, P.height, 229, 0, 0, 100, default(Color), P.scale);
				Main.dust[dust].noGravity = true;
				
				/*P.frame++;
				if(P.frame >= Main.projFrames[projectile.type])
				{
					P.frame = 0;
				}*/
				P.scale = Math.Min(P.scale + 0.05f, 0.5f);//1f);
				P.alpha = Math.Max(P.alpha - 15, 0);
				P.rotation -= 0.104719758f * 2f;
			//}
			
			P.position.X += (float)P.width/2f;
			P.position.Y += (float)P.height/2f;
			P.width = (int)(8f * P.scale);
			P.height = (int)(8f * P.scale);
			P.position.X -= (float)P.width/2f;
			P.position.Y -= (float)P.height/2f;
		}
Example #11
0
        /// <summary>
        /// Move Spacecraft by user key inputs (Up/Down/Left/Right keys)
        /// Fire missiles (Space key)
        /// </summary>
        /// <param name="gameTime"></param>
        private void UpdateUserInput(GameTime gameTime)
        {
            KeyboardState ks = Keyboard.GetState();

            if (ks.IsKeyDown(Keys.Right))
            {
                state = PlayerState.Right;
                Position.X += SPEED;
            }
            else if (ks.IsKeyDown(Keys.Left))
            {
                state = PlayerState.Left;
                Position.X -= SPEED;
            }
            else
            {
                state = PlayerState.Idle;
                currentFrame = 0;
            }

            if (ks.IsKeyDown(Keys.Up))
            {
                state = PlayerState.Idle;
                Position.Y -= SPEED;
                currentFrame = 0;
            }
            else if (ks.IsKeyDown(Keys.Down))
            {
                state = PlayerState.Idle;
                Position.Y += SPEED;
                currentFrame = 0;
            }

            // Space Key: Shoot Missile
            if (ks.IsKeyDown(Keys.Space))
            {
                // Check Shooting Time Inverval
                shootingTimer += gameTime.ElapsedGameTime.TotalSeconds;
                if(shootingTimer >= MISSILE_INTERVAL)
                {
                    if (Missile.missileLevel == 0)
                    {
                        // Create a Missile on the top of the player
                        Missile missile = new Missile(Game, new Vector2(Position.X + WIDTH / 2, Position.Y));
                        shootingTimer = 0;
                        parent.AddComponent(missile);
                    } else if (Missile.missileLevel == 1)
                    {
                        // Create a Missile on the top of the player
                        Missile missile1 = new Missile(Game, new Vector2(Position.X, Position.Y));
                        Missile missile2 = new Missile(Game, new Vector2(Position.X + WIDTH, Position.Y));
                        shootingTimer = 0;
                        parent.AddComponent(missile1);
                        parent.AddComponent(missile2);
                    } else if (Missile.missileLevel == 2) {
                        // Create a Missile on the top of the player
                        Missile missile1 = new Missile(Game, new Vector2(Position.X, Position.Y));
                        Missile missile2 = new Missile(Game, new Vector2(Position.X + WIDTH, Position.Y));
                        Missile missile3 = new Missile(Game, new Vector2(Position.X + WIDTH / 2, Position.Y));
                        shootingTimer = 0;
                        parent.AddComponent(missile1);
                        parent.AddComponent(missile2);
                        parent.AddComponent(missile3);

                    } else
                    {
                        // Create a Missile on the top of the player
                        Missile missile = new Missile(Game, new Vector2(Position.X + WIDTH / 2, Position.Y));
                        shootingTimer = 0;
                        parent.AddComponent(missile);
                    }
                    
                }
            }

            // Check Boundary, a player cannot go out of the screen
            int screenWidth = Game.GraphicsDevice.Viewport.Width;
            int screenHeight = Game.GraphicsDevice.Viewport.Height;
            Position.X = MathHelper.Clamp(Position.X, 0, screenWidth - WIDTH);
            Position.Y = MathHelper.Clamp(Position.Y, 0, screenHeight - HEIGHT);
        }
Example #12
0
        //Standard Guidance Routine
        #region RdavNav Missile Guidance #RFC#

        /*=================================================
         * RdavNav
         * ---------------------------------------     */
        void STD_GUIDANCE(MISSILE This_Missile)
        {
            //Finds Current Target
            Vector3D ENEMY_POS = EnemyScan(This_Missile);

            //---------------------------------------------------------------------------------------------------------------------------------

            //Sorts CurrentVelocities
            Vector3D MissilePosition     = This_Missile.GYRO.CubeGrid.WorldVolume.Center;
            Vector3D MissilePositionPrev = This_Missile.MIS_PREV_POS;
            Vector3D MissileVelocity     = (MissilePosition - MissilePositionPrev) / Global_Timestep;

            Vector3D TargetPosition     = ENEMY_POS;
            Vector3D TargetPositionPrev = This_Missile.TARGET_PREV_POS;
            Vector3D TargetVelocity     = (TargetPosition - This_Missile.TARGET_PREV_POS) / Global_Timestep;

            //Uses RdavNav Navigation APN Guidance System
            //-----------------------------------------------

            //Setup LOS rates and PN system
            Vector3D LOS_Old = Vector3D.Normalize(TargetPositionPrev - MissilePositionPrev);
            Vector3D LOS_New = Vector3D.Normalize(TargetPosition - MissilePosition);
            Vector3D Rel_Vel = Vector3D.Normalize(TargetVelocity - MissileVelocity);

            //And Assigners
            Vector3D am = new Vector3D(1, 0, 0); double LOS_Rate; Vector3D LOS_Delta;
            Vector3D MissileForwards = This_Missile.THRUSTERS[0].WorldMatrix.Backward;

            //Vector/Rotation Rates
            if (LOS_Old.Length() == 0)
            {
                LOS_Delta = new Vector3D(0, 0, 0); LOS_Rate = 0.0;
            }
            else
            {
                LOS_Delta = LOS_New - LOS_Old; LOS_Rate = LOS_Delta.Length() / Global_Timestep;
            }

            //-----------------------------------------------

            //Closing Velocity
            double Vclosing          = (TargetVelocity - MissileVelocity).Length();

            //If Under Gravity Use Gravitational Accel
            Vector3D GravityComp = -RC.GetNaturalGravity();

            //Calculate the final lateral acceleration
            Vector3D LateralDirection             = Vector3D.Normalize(Vector3D.Cross(Vector3D.Cross(Rel_Vel, LOS_New), Rel_Vel));
            Vector3D LateralAccelerationComponent = LateralDirection * PNGain * LOS_Rate * Vclosing + LOS_Delta * 9.8 * (0.5 * PNGain);     //Eases Onto Target Collision LOS_Delta * 9.8 * (0.5 * Gain)

            //If Impossible Solution (ie maxes turn rate) Use Drift Cancelling For Minimum T
            double OversteerReqt = (LateralAccelerationComponent).Length() / This_Missile.MissileAccel;

            if (OversteerReqt > 0.98)
            {
                LateralAccelerationComponent = This_Missile.MissileAccel * Vector3D.Normalize(LateralAccelerationComponent + (OversteerReqt * Vector3D.Normalize(-MissileVelocity)) * 40);
            }

            //Calculates And Applies Thrust In Correct Direction (Performs own inequality check)
            double ThrustPower = RdavUtils.Vector_Projection_Scalar(MissileForwards, Vector3D.Normalize(LateralAccelerationComponent));     //TESTTESTTEST

            ThrustPower = This_Missile.IsLargeGrid ? MathHelper.Clamp(ThrustPower, 0.9, 1) : ThrustPower;

            ThrustPower = MathHelper.Clamp(ThrustPower, 0.4, 1);     //for improved thrust performance on the get-go
            foreach (IMyThrust thruster in This_Missile.THRUSTERS)
            {
                if (thruster.ThrustOverride != (thruster.MaxThrust * ThrustPower))     //12 increment inequality to help conserve on performance
                {
                    thruster.ThrustOverride = (float)(thruster.MaxThrust * ThrustPower);
                }
            }

            //Calculates Remaining Force Component And Adds Along LOS
            double RejectedAccel = Math.Sqrt(This_Missile.MissileAccel * This_Missile.MissileAccel - LateralAccelerationComponent.LengthSquared());     //Accel has to be determined whichever way you slice it

            if (double.IsNaN(RejectedAccel))
            {
                RejectedAccel = 0;
            }
            LateralAccelerationComponent = LateralAccelerationComponent + LOS_New * RejectedAccel;

            //-----------------------------------------------

            //Guides To Target Using Gyros
            am = Vector3D.Normalize(LateralAccelerationComponent + GravityComp);
            double Yaw; double Pitch;

            GyroTurn6(am, 18, 0.3, This_Missile.THRUSTERS[0], This_Missile.GYRO as IMyGyro, This_Missile.PREV_Yaw, This_Missile.PREV_Pitch, out Pitch, out Yaw);

            //Updates For Next Tick Round
            This_Missile.TARGET_PREV_POS = TargetPosition;
            This_Missile.MIS_PREV_POS    = MissilePosition;
            This_Missile.PREV_Yaw        = Yaw;
            This_Missile.PREV_Pitch      = Pitch;

            //Detonates warheads in close proximity
            if ((TargetPosition - MissilePosition).LengthSquared() < 20 * 20 && This_Missile.WARHEADS.Count > 0)     //Arms
            {
                foreach (var item in This_Missile.WARHEADS)
                {
                    (item as IMyWarhead).IsArmed = true;
                }
            }
            if ((TargetPosition - MissilePosition).LengthSquared() < This_Missile.FuseDistance * This_Missile.FuseDistance && This_Missile.WARHEADS.Count > 0)     //A mighty earth shattering kaboom
            {
                (This_Missile.WARHEADS[0] as IMyWarhead).Detonate();
            }
        }
Example #13
0
        public void CalcMat()
        {
            LR.X = Wrap(LR.X);
            LR.Y = Wrap(LR.Y);
            LR.Z = Wrap(LR.Z);
            var     r = LR;
            Matrix4 t = Matrix4.CreateRotationY(MathHelper.DegreesToRadians(r.Y)) * Matrix4.CreateRotationX(MathHelper.DegreesToRadians(r.X)) * Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(r.Z));

            LocalTurn = t;
        }
        /// <summary>
        /// Computes a convex shape description for a TransformableShape.
        /// </summary>
        ///<param name="vA">First local vertex in the triangle.</param>
        ///<param name="vB">Second local vertex in the triangle.</param>
        ///<param name="vC">Third local vertex in the triangle.</param>
        ///<param name="collisionMargin">Collision margin of the shape.</param>
        /// <returns>Description required to define a convex shape.</returns>
        public static ConvexShapeDescription ComputeDescription(Vector3 vA, Vector3 vB, Vector3 vC, Fix64 collisionMargin)
        {
            ConvexShapeDescription description;
            // A triangle by itself technically has no volume, but shapes try to include the collision margin in the volume when feasible (e.g. BoxShape).
            //Plus, it's convenient to have a nonzero volume for buoyancy.
            var doubleArea = Vector3.Cross(vB - vA, vC - vA).Length();
            description.EntityShapeVolume.Volume = doubleArea * collisionMargin;

            //Compute the inertia tensor.
            var v = new Matrix3x3(
                vA.X, vA.Y, vA.Z,
                vB.X, vB.Y, vB.Z,
                vC.X, vC.Y, vC.Z);
            var s = new Matrix3x3(
				F64.C2, F64.C1, F64.C1,
				F64.C1, F64.C2, F64.C1,
				F64.C1, F64.C1, F64.C2);

            Matrix3x3.MultiplyTransposed(ref v, ref s, out description.EntityShapeVolume.VolumeDistribution);
            Matrix3x3.Multiply(ref description.EntityShapeVolume.VolumeDistribution, ref v, out description.EntityShapeVolume.VolumeDistribution);
            var scaling = doubleArea / F64.C24;
            Matrix3x3.Multiply(ref description.EntityShapeVolume.VolumeDistribution, -scaling, out description.EntityShapeVolume.VolumeDistribution);

            //The square-of-sum term is ignored since the parameters should already be localized (and so would sum to zero).
            var sums = scaling * (vA.LengthSquared() + vB.LengthSquared() + vC.LengthSquared());
            description.EntityShapeVolume.VolumeDistribution.M11 += sums;
            description.EntityShapeVolume.VolumeDistribution.M22 += sums;
            description.EntityShapeVolume.VolumeDistribution.M33 += sums;

            description.MinimumRadius = collisionMargin;
            description.MaximumRadius = collisionMargin + MathHelper.Max(vA.Length(), MathHelper.Max(vB.Length(), vC.Length()));
            description.CollisionMargin = collisionMargin;
            return description;
        }
Example #15
0
        //--------------------------------------------------------------
        #region Methods
        //--------------------------------------------------------------

        /// <summary>
        /// Called when the simulation wants this force effect to apply forces to rigid bodies.
        /// </summary>
        protected override void OnApply()
        {
            RigidBody chassis        = Vehicle.Chassis;
            Pose      chassisPose    = chassis.Pose;
            float     mass           = chassis.MassFrame.Mass;
            Vector3F  up             = chassisPose.ToWorldDirection(Vector3F.UnitY);
            float     deltaTime      = Simulation.Settings.Timing.FixedTimeStep;
            int       numberOfWheels = Vehicle.Wheels.Count;

            for (int i = 0; i < numberOfWheels; i++)
            {
                var wheel = Vehicle.Wheels[i];

                // Update contact info.
                wheel.PreviousSuspensionLength = wheel.SuspensionLength;
                wheel.UpdateContactInfo();

                float normalDotUp = Vector3F.Dot(wheel.GroundNormal, up);
                if (!wheel.HasGroundContact || Numeric.IsLessOrEqual(normalDotUp, 0))
                {
                    // -----  The simple case: The wheel is in the air.
                    // To keep it simple: The wheel continues spinning in the same direction.

                    // Damp angular velocity.
                    wheel.AngularVelocity *= 0.99f;

                    // Update rotation angle.
                    wheel.RotationAngle += wheel.AngularVelocity * deltaTime;

                    // TODO: Slow down or stop spin when braking.
                    // TODO: Reverse velocity when force reverses.
                    continue;
                }


                // ----- The wheel touches the ground.

                // ----- Suspension force
                float springForce = wheel.SuspensionStiffness
                                    * mass
                                    * (wheel.SuspensionRestLength - wheel.SuspensionLength)
                                    * normalDotUp;

                // The compression velocity:
                // (Note: Alternatively we could compute the  velocity from point velocities of chassis
                // and the hit body.)
                float compressionVelocity = (wheel.PreviousSuspensionLength - wheel.SuspensionLength) / deltaTime;
                float damping             = (compressionVelocity > 0) ? wheel.SuspensionCompressionDamping : wheel.SuspensionRelaxationDamping;
                float dampingForce        = damping * mass * compressionVelocity;

                // Force acting on chassis in up direction:
                float normalForce = MathHelper.Clamp(springForce + dampingForce, 0, wheel.MaxSuspensionForce);

                // If the suspension has reached the minimum length, we must add a large force
                // that stops any further compression.
                if (wheel.SuspensionLength <= wheel.MinSuspensionLength)
                {
                    // ComputeStopImpulse computes an impulse that stops any movement between the
                    // ground and the wheel in a given direction (up direction in this case).
                    float force = ComputeStopImpulse(wheel, up) / deltaTime; // force = impulse / dt

                    // force can be negative if the ground and the chassis are already separating.
                    // Only apply the force if is positive (= it pushes the chassis away from the ground).
                    if (force > 0)
                    {
                        normalForce += force;
                    }
                }

                AddForce(chassis, normalForce * up, wheel.GroundPosition);
                AddForce(wheel.TouchedBody, -normalForce * up, wheel.GroundPosition);

                // ----- Ground tangents
                Vector3F right         = chassisPose.ToWorldDirection(Matrix33F.CreateRotationY(wheel.SteeringAngle) * Vector3F.UnitX);
                Vector3F groundForward = Vector3F.Cross(wheel.GroundNormal, right).Normalized;
                Vector3F groundRight   = Vector3F.Cross(groundForward, wheel.GroundNormal).Normalized;

                // ----- Side force
                float sideForce = ComputeStopImpulse(wheel, groundRight) / deltaTime; // force = impulse / dt
                // Assume that all wheels act together:
                sideForce /= numberOfWheels;

                // ----- Forward force
                float rollingFrictionForce;
                if (Math.Abs(wheel.MotorForce) > wheel.BrakeForce)
                {
                    // If the motor is driving the car, assume that the friction force has the same
                    // magnitude (100% friction, the whole motor force is delivered to the ground.)
                    rollingFrictionForce = wheel.MotorForce - wheel.BrakeForce;
                }
                else
                {
                    // The motor is off, or we are braking.
                    // Compute a friction force that would stop the car.
                    rollingFrictionForce = ComputeStopImpulse(wheel, groundForward) / deltaTime;

                    // Limit the friction force by the wheel.RollingFrictionForce (can be 0) or the
                    // the current brake force.
                    float brakeForce  = wheel.BrakeForce - Math.Abs(wheel.MotorForce);
                    float maxFriction = Math.Max(wheel.RollingFrictionForce, brakeForce);
                    rollingFrictionForce = MathHelper.Clamp(rollingFrictionForce, -maxFriction, maxFriction);
                }

                // The current side force and rolling friction force assume perfect friction. But the
                // friction force is limited by the normal force that presses onto the ground:
                //   MaxFrictionForce = µ * NormalForce
                float maxFrictionForce = wheel.Friction * normalForce;

                // Compute combined force parallel to ground surface.
                Vector3F tangentForce       = rollingFrictionForce * groundForward + sideForce * groundRight;
                float    tangentForceLength = tangentForce.Length;
                if (tangentForceLength > maxFrictionForce)
                {
                    // Not enough traction - that means, we are sliding!
                    var skidForce    = tangentForceLength - maxFrictionForce;
                    var skidVelocity = skidForce * deltaTime / mass;
                    wheel.SkidEnergy = maxFrictionForce * skidVelocity * deltaTime;

                    // The friction forces must be scaled.
                    float factor = maxFrictionForce / tangentForceLength;
                    rollingFrictionForce *= factor;
                    sideForce            *= factor;
                }
                else
                {
                    // The force is within the friction cone. No sliding.
                    wheel.SkidEnergy = 0;
                }

                // Apply rolling friction force. This drives the car.
                AddForce(chassis, rollingFrictionForce * groundForward, wheel.GroundPosition);
                AddForce(wheel.TouchedBody, -rollingFrictionForce * groundForward, wheel.GroundPosition);

                // Apply side friction force
                // If we apply the side force on the ground position, the car starts rolling (tilt) in
                // tight curves. If we apply the force on a higher position, rolling is reduced.
                Vector3F sideForcePosition = wheel.GroundPosition + wheel.RollReduction * (wheel.SuspensionLength + wheel.Radius) * up;
                AddForce(chassis, sideForce * groundRight, sideForcePosition);
                AddForce(wheel.TouchedBody, -sideForce * groundRight, sideForcePosition);

                // ----- Update AngularVelocity and Rotation.
                // We set the angular velocity, so that the wheel matches the moving underground.
                Vector3F relativeContactVelocity = chassis.GetVelocityOfWorldPoint(wheel.GroundPosition)
                                                   - wheel.TouchedBody.GetVelocityOfWorldPoint(wheel.GroundPosition);
                float forwardVelocity = Vector3F.Dot(relativeContactVelocity, groundForward);
                wheel.AngularVelocity = forwardVelocity / wheel.Radius;
                wheel.RotationAngle  += wheel.AngularVelocity * deltaTime;

                // TODO: Use a more realistic AngularVelocity!
                // - Apply the skid energy to show sliding wheels.
                // - Set AngularVelocity to 0 when brakes are active - for more dramatic effect.
            }
        }
 public void SetFieldOfViewException5()
 {
   PerspectiveViewVolume frustum = new PerspectiveViewVolume();
   frustum.SetFieldOfView(MathHelper.ToRadians(60), 16.0f / 9.0f, 1, 0);
 }
 public void GetWidthAndHeightException3()
 {
   float width, height;
   PerspectiveViewVolume.GetWidthAndHeight(MathHelper.ToRadians(90), 1, -0.1f, out width, out height);
 }
Example #18
0
        private void UpdateCapture()
        {
            Array.Copy(uncompressedBuffer, 0, prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
            Array.Clear(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
            nativeBuffer = Marshal.AllocHGlobal(VoipConfig.BUFFER_SIZE * 2);
            try
            {
                while (capturing)
                {
                    int alcError;

                    if (CanDetectDisconnect)
                    {
                        Alc.GetInteger(captureDevice, Alc.EnumConnected, out int isConnected);
                        alcError = Alc.GetError(captureDevice);
                        if (alcError != Alc.NoError)
                        {
                            throw new Exception("Failed to determine if capture device is connected: " + alcError.ToString());
                        }

                        if (isConnected == 0)
                        {
                            DebugConsole.ThrowError("Capture device has been disconnected. You can select another available device in the settings.");
                            Disconnected = true;
                            break;
                        }
                    }

                    FillBuffer();

                    alcError = Alc.GetError(captureDevice);
                    if (alcError != Alc.NoError)
                    {
                        throw new Exception("Failed to capture samples: " + alcError.ToString());
                    }

                    double maxAmplitude = 0.0f;
                    for (int i = 0; i < VoipConfig.BUFFER_SIZE; i++)
                    {
                        uncompressedBuffer[i] = (short)MathHelper.Clamp((uncompressedBuffer[i] * Gain), -short.MaxValue, short.MaxValue);
                        double sampleVal = uncompressedBuffer[i] / (double)short.MaxValue;
                        maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
                    }
                    double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);

                    LastdB = dB;
                    LastAmplitude = maxAmplitude;

                    bool allowEnqueue = overrideSound != null;
                    if (GameMain.WindowActive)
                    {
                        ForceLocal = captureTimer > 0 ? ForceLocal : GameMain.Config.UseLocalVoiceByDefault;
                        bool pttDown = false;
                        if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
                                GUI.KeyboardDispatcher.Subscriber == null)
                        {
                            pttDown = true;
                            if (PlayerInput.KeyDown(InputType.LocalVoice))
                            {
                                ForceLocal = true;
                            }
                            else
                            {
                                ForceLocal = false;
                            }
                        }
                        if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Activity)
                        {
                            if (dB > GameMain.Config.NoiseGateThreshold)
                            {
                                allowEnqueue = true;
                            }
                        }
                        else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
                        {
                            if (pttDown)
                            {
                                allowEnqueue = true;
                            }
                        }
                    }

                    if (allowEnqueue || captureTimer > 0)
                    {
                        LastEnqueueAudio = DateTime.Now;
                        if (GameMain.Client?.Character != null)
                        {
                            var messageType = !ForceLocal && ChatMessage.CanUseRadio(GameMain.Client.Character, out _) ? ChatMessageType.Radio : ChatMessageType.Default;
                            GameMain.Client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
                        }
                        //encode audio and enqueue it
                        lock (buffers)
                        {
                            if (!prevCaptured) //enqueue the previous buffer if not sent to avoid cutoff
                            {
                                int compressedCountPrev = VoipConfig.Encoder.Encode(prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
                                EnqueueBuffer(compressedCountPrev);
                            }
                            int compressedCount = VoipConfig.Encoder.Encode(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
                            EnqueueBuffer(compressedCount);
                        }
                        captureTimer -= (VoipConfig.BUFFER_SIZE * 1000) / VoipConfig.FREQUENCY;
                        if (allowEnqueue)
                        {
                            captureTimer = GameMain.Config.VoiceChatCutoffPrevention;
                        }
                        prevCaptured = true;
                    }
                    else
                    {
                        captureTimer = 0;
                        prevCaptured = false;
                        //enqueue silence
                        lock (buffers)
                        {
                            EnqueueBuffer(0);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError($"VoipCapture threw an exception. Disabling capture...", e);
                capturing = false;
            }
            finally
            {
                Marshal.FreeHGlobal(nativeBuffer);
            }
        }
Example #19
0
        public override void PreUpdate()
        {
            #region Time Debug
            bool debugTime = false;
            if (debugTime)
            {
                float worldTime = ((float)Main.time / 3600);
                if (!Main.dayTime)
                {
                    worldTime = ((float)Main.time / 3600) + 15f;
                }

                float clockTime = MathHelper.Clamp(worldTime, 0f, 24f);

                Main.NewTextMultiline("Currently " + (Main.dayTime ? "daytime" : "nighttime") + ". " + "The time is " + Main.time + ".\n" + "Clock time is " + clockTime + ".");

                Vector2 axlePosition = new Vector2(Main.maxTilesX, Main.maxTilesY) * 16f * 0.5f + new Vector2(0f, -800f * 16f);
                Vector2 handPosition = axlePosition + new Vector2(0f, -256f).RotatedBy(MathHelper.ToRadians(clockTime * 30f));
                Dust    dust1        = Dust.NewDustPerfect(axlePosition, Terraria.ID.DustID.RainbowMk2, new Vector2(0f, 0f), 0, Color.White, 4f);
                dust1.noGravity = true;
                Dust dust2 = Dust.NewDustPerfect(handPosition, Terraria.ID.DustID.RainbowMk2, new Vector2(0f, 0f), 0, Color.White, 4f);
                dust2.noGravity = true;
            }
            #endregion
        }
Example #20
0
        public void DrawBar(SpriteBatch spriteBatch)
        {
            float     alpha          = 0.5f;
            Texture2D backGround1    = Main.colorBarTexture;
            Texture2D progressColor  = Main.colorBarTexture;
            Texture2D MMIcon         = Fargowiltas.Instance.GetTexture("MonsterMadhouse/MMIcon");
            float     scmp           = 0.5f + 0.75f * 0.5f;
            Color     descColor      = new Color(77, 39, 135);
            Color     waveColor      = new Color(255, 241, 51);
            const int offsetX        = 20;
            const int offsetY        = 20;
            int       width          = (int)(200f * scmp);
            int       height         = (int)(46f * scmp);
            Rectangle waveBackground = Utils.CenteredRectangle(new Vector2(Main.screenWidth - offsetX - 100f, Main.screenHeight - offsetY - 23f), new Vector2(width, height));

            Utils.DrawInvBG(spriteBatch, waveBackground, new Color(63, 65, 151, 255) * 0.785f);
            float  cleared  = MMWorld.MMPoints / MMWorld.MMWaveThreshhold;
            string waveText = "Cleared " + Math.Round(100 * cleared) + "%";

            Utils.DrawBorderString(spriteBatch, waveText, new Vector2(waveBackground.X + waveBackground.Width / 2, waveBackground.Y + 5), Color.White, scmp * 0.8f, 0.5f, -0.1f);
            Rectangle waveProgressBar    = Utils.CenteredRectangle(new Vector2(waveBackground.X + waveBackground.Width * 0.5f, waveBackground.Y + waveBackground.Height * 0.75f), new Vector2(progressColor.Width, progressColor.Height));
            Rectangle waveProgressAmount = new Rectangle(0, 0, (int)(progressColor.Width * MathHelper.Clamp(cleared, 0f, 1f)), progressColor.Height);
            Vector2   offset             = new Vector2((waveProgressBar.Width - (int)(waveProgressBar.Width * scmp)) * 0.5f, (waveProgressBar.Height - (int)(waveProgressBar.Height * scmp)) * 0.5f);

            spriteBatch.Draw(backGround1, waveProgressBar.Location.ToVector2() + offset, null, Color.White * alpha, 0f, new Vector2(0f), scmp, SpriteEffects.None, 0f);
            spriteBatch.Draw(backGround1, waveProgressBar.Location.ToVector2() + offset, waveProgressAmount, waveColor, 0f, new Vector2(0f), scmp, SpriteEffects.None, 0f);
            const int internalOffset    = 6;
            Vector2   descSize          = new Vector2(154, 40) * scmp;
            Rectangle barrierBackground = Utils.CenteredRectangle(new Vector2(Main.screenWidth - offsetX - 100f, Main.screenHeight - offsetY - 19f), new Vector2(width, height));
            Rectangle descBackground    = Utils.CenteredRectangle(new Vector2(barrierBackground.X + barrierBackground.Width * 0.5f, barrierBackground.Y - internalOffset - descSize.Y * 0.5f), descSize * .8f);

            Utils.DrawInvBG(spriteBatch, descBackground, descColor * alpha);
            int       descOffset = (descBackground.Height - (int)(32f * scmp)) / 2;
            Rectangle icon       = new Rectangle(descBackground.X + descOffset + 7, descBackground.Y + descOffset, (int)(32 * scmp), (int)(32 * scmp));

            spriteBatch.Draw(MMIcon, icon, Color.White);
            Utils.DrawBorderString(spriteBatch, "Monster Madhouse", new Vector2(barrierBackground.X + barrierBackground.Width * 0.5f, barrierBackground.Y - internalOffset - descSize.Y * 0.5f), Color.White, 0.8f, 0.3f, 0.4f);
        }
Example #21
0
        public override void AI()
        {
            projectile.hide = false;
            Vector2?vector78 = null;

            if (projectile.velocity.HasNaNs() || projectile.velocity == Vector2.Zero)
            {
                projectile.velocity = -Vector2.UnitY;
            }
            int ai1 = (int)projectile.ai[1];

            if (Main.npc[ai1].active && Main.npc[ai1].type == ModContent.NPCType <Zero>())
            {
                projectile.Center = Main.npc[ai1].Center - Vector2.UnitY * 6f;
            }
            else
            {
                projectile.Kill();
                return;
            }
            if (projectile.velocity.HasNaNs() || projectile.velocity == Vector2.Zero)
            {
                projectile.velocity = -Vector2.UnitY;
            }
            if (projectile.localAI[0] == 0f)
            {
                Main.PlaySound(29, (int)projectile.position.X, (int)projectile.position.Y, 104, 1f, 0f);
            }
            float num801 = 1f;

            projectile.localAI[0] += 1f;
            if (projectile.localAI[0] >= maxTime)
            {
                projectile.Kill();
                return;
            }
            projectile.scale = (float)Math.Sin(projectile.localAI[0] * 3.14159274f / maxTime) * 10f * num801;
            if (projectile.scale > num801)
            {
                projectile.scale = num801;
            }
            float num804 = projectile.velocity.ToRotation();

            num804 += projectile.ai[0];
            projectile.rotation = num804 - 1.57079637f;
            projectile.velocity = num804.ToRotationVector2();
            float   num805        = 3f;
            float   num806        = projectile.width;
            Vector2 samplingPoint = projectile.Center;

            if (vector78.HasValue)
            {
                samplingPoint = vector78.Value;
            }
            float[] array3 = new float[(int)num805];
            Collision.LaserScan(samplingPoint, projectile.velocity, num806 * projectile.scale, 3000f, array3);
            float num807 = 0f;
            int   num3;

            for (int num808 = 0; num808 < array3.Length; num808 = num3 + 1)
            {
                num807 += array3[num808];
                num3    = num808;
            }
            num807 /= num805;
            float amount = 0.5f;

            projectile.localAI[1] = MathHelper.Lerp(projectile.localAI[1], num807, amount);
            Vector2 vector79 = projectile.Center + projectile.velocity * (projectile.localAI[1] - 14f);

            for (int num809 = 0; num809 < 2; num809 = num3 + 1)
            {
                float   num810   = projectile.velocity.ToRotation() + ((Main.rand.Next(2) == 1) ? -1f : 1f) * 1.57079637f;
                float   num811   = (float)Main.rand.NextDouble() * 2f + 2f;
                Vector2 vector80 = new Vector2((float)Math.Cos(num810) * num811, (float)Math.Sin(num810) * num811);
                int     num812   = Dust.NewDust(vector79, 0, 0, 244, vector80.X, vector80.Y, 0, default, 1f);
Example #22
0
        public override void AI()
        {
            resist = false;

            if (!spawned) //just spawned
            {
                spawned = true;
                npc.TargetClosest(false);

                if (Main.netMode != NetmodeID.MultiplayerClient) //spawn segments
                {
                    int       prev = npc.whoAmI;
                    const int max  = 99;
                    for (int i = 0; i < max; i++)
                    {
                        int type = i == max - 1 ? ModContent.NPCType <TerraChampionTail>() : ModContent.NPCType <TerraChampionBody>();
                        int n    = NPC.NewNPC((int)npc.Center.X, (int)npc.Center.Y, type, npc.whoAmI);
                        if (n != Main.maxNPCs)
                        {
                            Main.npc[n].ai[1]    = prev;
                            Main.npc[n].ai[3]    = npc.whoAmI;
                            Main.npc[n].realLife = npc.whoAmI;
                            Main.npc[prev].ai[0] = n;

                            if (Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, n);
                            }

                            prev = n;
                        }
                        else //can't spawn all segments
                        {
                            npc.active = false;
                            if (Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, npc.whoAmI);
                            }
                            return;
                        }
                    }
                }
            }

            EModeGlobalNPC.championBoss = npc.whoAmI;

            Player  player = Main.player[npc.target];
            Vector2 targetPos;

            if (npc.HasValidTarget && player.Center.Y >= Main.worldSurface * 16 && !player.ZoneUnderworldHeight)
            {
                npc.timeLeft = 600;
            }

            if (npc.ai[1] != -1 && npc.life < npc.lifeMax / 10)
            {
                Main.PlaySound(SoundID.ForceRoar, player.Center, -1);
                npc.life       = npc.lifeMax / 10;
                npc.velocity   = Vector2.Zero;
                npc.ai[1]      = -1f;
                npc.ai[2]      = 0;
                npc.localAI[0] = 0;
                npc.localAI[1] = 0;
                npc.localAI[2] = 0;
                npc.localAI[3] = 0;
                npc.netUpdate  = true;
            }

            switch ((int)npc.ai[1])
            {
            case -1:                                                                                                          //flying head alone
                if (!player.active || player.dead || player.Center.Y < Main.worldSurface * 16 || player.ZoneUnderworldHeight) //despawn code
                {
                    npc.TargetClosest(false);
                    if (npc.timeLeft > 30)
                    {
                        npc.timeLeft = 30;
                    }
                    npc.velocity.Y += 1f;
                    break;
                }

                npc.scale = 3f;
                targetPos = player.Center;
                if (npc.Distance(targetPos) > 50)
                {
                    Movement(targetPos, 0.16f, 32f);
                }

                npc.rotation = npc.DirectionTo(player.Center).ToRotation();

                if (++npc.localAI[0] > 40)
                {
                    npc.localAI[0] = 0;

                    if (npc.localAI[1] > 30 && npc.localAI[1] < 330)     //dont shoot while orb is exploding
                    {
                        Main.PlaySound(SoundID.Item12, npc.Center);

                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            float   ai1New = Main.rand.Next(100);
                            Vector2 vel    = Vector2.Normalize(npc.DirectionTo(player.Center).RotatedBy(Math.PI / 4 * (Main.rand.NextDouble() - 0.5))) * 6f;
                            Projectile.NewProjectile(npc.Center, vel, ProjectileID.CultistBossLightningOrbArc,
                                                     npc.damage / 4, 0, Main.myPlayer, npc.rotation, ai1New);
                        }
                    }
                }

                if (--npc.localAI[1] < 0)
                {
                    npc.localAI[1] = 420;

                    if (Main.netMode != NetmodeID.MultiplayerClient)     //shoot orb
                    {
                        Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <TerraLightningOrb2>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI);
                    }
                }
                break;

            case 0:                                                                                                           //ripped from destroyer
            {
                if (!player.active || player.dead || player.Center.Y < Main.worldSurface * 16 || player.ZoneUnderworldHeight) //despawn code
                {
                    npc.TargetClosest(false);
                    if (npc.timeLeft > 30)
                    {
                        npc.timeLeft = 30;
                    }
                    npc.velocity.Y += 1f;
                    npc.rotation    = npc.velocity.ToRotation();
                    break;
                }

                float num14 = 18f;            //max speed?
                float num15 = 0.2f;           //turn speed?
                float num16 = 0.25f;          //acceleration?

                Vector2 target = player.Center;
                float   num17  = target.X;
                float   num18  = target.Y;

                float num21 = num17 - npc.Center.X;
                float num22 = num18 - npc.Center.Y;
                float num23 = (float)Math.Sqrt((double)num21 * (double)num21 + (double)num22 * (double)num22);

                //ground movement code but it always runs
                float num2 = (float)Math.Sqrt(num21 * num21 + num22 * num22);
                float num3 = Math.Abs(num21);
                float num4 = Math.Abs(num22);
                float num5 = num14 / num2;
                float num6 = num21 * num5;
                float num7 = num22 * num5;
                if ((npc.velocity.X > 0f && num6 > 0f || npc.velocity.X < 0f && num6 < 0f) && (npc.velocity.Y > 0f && num7 > 0f || npc.velocity.Y < 0f && num7 < 0f))
                {
                    if (npc.velocity.X < num6)
                    {
                        npc.velocity.X += num16;
                    }
                    else if (npc.velocity.X > num6)
                    {
                        npc.velocity.X -= num16;
                    }
                    if (npc.velocity.Y < num7)
                    {
                        npc.velocity.Y += num16;
                    }
                    else if (npc.velocity.Y > num7)
                    {
                        npc.velocity.Y -= num16;
                    }
                }
                if (npc.velocity.X > 0f && num6 > 0f || npc.velocity.X < 0f && num6 < 0f || npc.velocity.Y > 0f && num7 > 0f || npc.velocity.Y < 0f && num7 < 0f)
                {
                    if (npc.velocity.X < num6)
                    {
                        npc.velocity.X += num15;
                    }
                    else if (npc.velocity.X > num6)
                    {
                        npc.velocity.X -= num15;
                    }
                    if (npc.velocity.Y < num7)
                    {
                        npc.velocity.Y += num15;
                    }
                    else if (npc.velocity.Y > num7)
                    {
                        npc.velocity.Y -= num15;
                    }

                    if (Math.Abs(num7) < num14 * 0.2f && (npc.velocity.X > 0f && num6 < 0f || npc.velocity.X < 0f && num6 > 0f))
                    {
                        if (npc.velocity.Y > 0f)
                        {
                            npc.velocity.Y += num15 * 2f;
                        }
                        else
                        {
                            npc.velocity.Y -= num15 * 2f;
                        }
                    }
                    if (Math.Abs(num6) < num14 * 0.2f && (npc.velocity.Y > 0f && num7 < 0f || npc.velocity.Y < 0f && num7 > 0f))
                    {
                        if (npc.velocity.X > 0f)
                        {
                            npc.velocity.X += num15 * 2f;
                        }
                        else
                        {
                            npc.velocity.X -= num15 * 2f;
                        }
                    }
                }
                else if (num3 > num4)
                {
                    if (npc.velocity.X < num6)
                    {
                        npc.velocity.X += num15 * 1.1f;
                    }
                    else if (npc.velocity.X > num6)
                    {
                        npc.velocity.X -= num15 * 1.1f;
                    }

                    if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < num14 * 0.5f)
                    {
                        if (npc.velocity.Y > 0f)
                        {
                            npc.velocity.Y += num15;
                        }
                        else
                        {
                            npc.velocity.Y -= num15;
                        }
                    }
                }
                else
                {
                    if (npc.velocity.Y < num7)
                    {
                        npc.velocity.Y += num15 * 1.1f;
                    }
                    else if (npc.velocity.Y > num7)
                    {
                        npc.velocity.Y -= num15 * 1.1f;
                    }

                    if (Math.Abs(npc.velocity.X) + Math.Abs(npc.velocity.Y) < num14 * 0.5f)
                    {
                        if (npc.velocity.X > 0f)
                        {
                            npc.velocity.X += num15;
                        }
                        else
                        {
                            npc.velocity.X -= num15;
                        }
                    }
                }

                if (++npc.localAI[0] > 420)
                {
                    npc.ai[1]++;
                    npc.localAI[0] = 0;
                }
            }

                npc.rotation = npc.velocity.ToRotation();
                break;

            case 1:     //flee and prepare
                resist    = true;
                targetPos = player.Center + npc.DirectionFrom(player.Center) * 1600;
                if (++npc.localAI[0] < 120)
                {
                    Movement(targetPos, 0.4f, 18f);
                }
                else
                {
                    npc.ai[1]++;
                    npc.localAI[0] = 0;

                    for (int i = 0; i < Main.maxNPCs; i++)     //find all segments, bring them to self
                    {
                        if (Main.npc[i].active && Main.npc[i].ai[3] == npc.whoAmI &&
                            (Main.npc[i].type == ModContent.NPCType <TerraChampionBody>() || Main.npc[i].type == ModContent.NPCType <TerraChampionTail>()))
                        {
                            for (int j = 0; j < 15; j++)
                            {
                                int d = Dust.NewDust(Main.npc[i].position, Main.npc[i].width, Main.npc[i].height, 87, 0f, 0f, 100, default(Color), 1f);
                                Main.dust[d].noGravity = true;
                                Main.dust[d].velocity *= 1.4f;
                            }

                            float scaleFactor9 = 0.5f;
                            for (int j = 0; j < 3; j++)
                            {
                                int gore = Gore.NewGore(Main.npc[i].Center, default(Vector2), Main.rand.Next(61, 64));
                                Main.gore[gore].velocity   *= scaleFactor9;
                                Main.gore[gore].velocity.X += 1f;
                                Main.gore[gore].velocity.Y += 1f;
                            }

                            Main.npc[i].Center = npc.Center;
                            //if (Main.netMode == NetmodeID.Server) NetMessage.SendData(MessageID.SyncNPC, -1, -1, null, i);
                        }
                    }
                }

                npc.rotation = npc.velocity.ToRotation();
                break;

            case 2:     //dash
            {
                if (npc.localAI[1] == 0)
                {
                    Main.PlaySound(SoundID.Roar, player.Center, 0);
                    npc.localAI[1] = 1;
                    npc.velocity   = npc.DirectionTo(player.Center) * 24;
                }

                if (++npc.localAI[2] > 2)
                {
                    npc.localAI[2] = 0;
                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        Vector2 vel = npc.DirectionTo(player.Center) * 12;
                        Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <TerraFireball>(), npc.damage / 4, 0f, Main.myPlayer);

                        float offset = npc.velocity.ToRotation() - vel.ToRotation();

                        vel = Vector2.Normalize(npc.velocity).RotatedBy(offset) * 12;
                        Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <TerraFireball>(), npc.damage / 4, 0f, Main.myPlayer);
                    }
                }

                double angle = npc.DirectionTo(player.Center).ToRotation() - npc.velocity.ToRotation();
                while (angle > Math.PI)
                {
                    angle -= 2.0 * Math.PI;
                }
                while (angle < -Math.PI)
                {
                    angle += 2.0 * Math.PI;
                }

                if (++npc.localAI[0] > 240 || (Math.Abs(angle) > Math.PI / 2 && npc.Distance(player.Center) > 1200))
                {
                    npc.velocity = Vector2.Normalize(npc.velocity).RotatedBy(Math.PI / 2) * 18f;
                    npc.ai[1]++;
                    npc.localAI[0] = 0;
                    npc.localAI[1] = 0;
                }

                npc.rotation = npc.velocity.ToRotation();
            }
            break;

            case 3:
                goto case 0;

            case 4:     //reposition for sine
                /*if (npc.Distance(player.Center) < 1200)
                 * {
                 *  targetPos = player.Center + npc.DirectionFrom(player.Center) * 1200;
                 *  Movement(targetPos, 0.6f, 36f);
                 * }
                 * else //circle at distance to pull segments away
                 * {
                 *  npc.velocity = npc.DirectionTo(player.Center).RotatedBy(Math.PI / 2) * 36;
                 * }
                 *
                 * if (++npc.localAI[0] > 180)
                 * {
                 *  npc.ai[1]++;
                 *  npc.localAI[0] = 0;
                 * }
                 *
                 * npc.rotation = npc.velocity.ToRotation();
                 * break;*/
                goto case 1;

            case 5:     //sine wave dash
            {
                if (npc.localAI[0] == 0)
                {
                    npc.localAI[1] = npc.DirectionTo(player.Center).ToRotation();
                    npc.localAI[2] = npc.Center.X;
                    npc.localAI[3] = npc.Center.Y;
                    Main.PlaySound(SoundID.Roar, player.Center, 0);
                }

                const int end = 360;

                Vector2 offset;
                offset.X = 10f * npc.localAI[0];
                offset.Y = 600 * (float)Math.Sin(2f * Math.PI / end * 4 * npc.localAI[0]);

                npc.Center   = new Vector2(npc.localAI[2], npc.localAI[3]) + offset.RotatedBy(npc.localAI[1]);
                npc.velocity = Vector2.Zero;
                npc.rotation = (npc.position - npc.oldPosition).ToRotation();

                if (++npc.ai[2] > 6 && Math.Abs(offset.Y) > 595)
                {
                    npc.ai[2] = 0;

                    Main.PlaySound(SoundID.Item12, npc.Center);

                    if (Main.netMode != NetmodeID.MultiplayerClient)
                    {
                        /*Vector2 vel = Vector2.UnitX.RotatedBy(Math.PI / 4 * (Main.rand.NextDouble() - 0.5)) * 8f;
                         * Projectile.NewProjectile(npc.Center, vel.RotatedBy(npc.localAI[1] - Math.PI / 2 * Math.Sign(offset.Y)), ProjectileID.CultistBossLightningOrbArc,
                         *  npc.damage / 4, 0, Main.myPlayer, npc.localAI[1] - (float)Math.PI / 2 * Math.Sign(offset.Y), Main.rand.Next(100));*/

                        for (int j = -5; j <= 5; j++)
                        {
                            float rotationOffset = (float)Math.PI / 2 + (float)Math.PI / 2 / 5 * j;
                            rotationOffset *= Math.Sign(offset.Y);
                            Projectile.NewProjectile(npc.Center,
                                                     6f * Vector2.UnitX.RotatedBy(npc.localAI[1] + rotationOffset),
                                                     ProjectileID.CultistBossFireBall, npc.damage / 4, 0f, Main.myPlayer);
                        }

                        for (int i = -5; i <= 5; i++)
                        {
                            float ai1New         = Main.rand.Next(100);
                            float rotationOffset = (float)Math.PI / 2 + (float)Math.PI / 2 / 4.5f * i;
                            rotationOffset *= Math.Sign(offset.Y);
                            Vector2 vel2 = Vector2.UnitX.RotatedBy(Math.PI / 4 * (Main.rand.NextDouble() - 0.5)) * 8f;
                            Projectile.NewProjectile(npc.Center, vel2.RotatedBy(npc.localAI[1] + rotationOffset), ProjectileID.CultistBossLightningOrbArc,
                                                     npc.damage / 4, 0, Main.myPlayer, npc.localAI[1] + rotationOffset, ai1New);
                        }
                    }
                }

                if (++npc.localAI[0] > end)
                {
                    npc.ai[1]++;
                    npc.ai[2]      = 0;
                    npc.localAI[0] = 0;
                    npc.localAI[1] = 0;
                    npc.localAI[2] = 0;
                    npc.localAI[3] = 0;
                    npc.velocity   = npc.DirectionTo(player.Center).RotatedBy(-Math.PI / 2) * 18f;
                }
            }
            break;

            case 6:
                goto case 0;

            case 7:
                goto case 1;

            case 8:     //dash but u-turn
                if (npc.localAI[1] == 0)
                {
                    Main.PlaySound(SoundID.Roar, player.Center, 0);
                    npc.localAI[1] = 1;
                    npc.velocity   = npc.DirectionTo(player.Center) * 36;
                }

                if (npc.localAI[3] == 0)
                {
                    double angle = npc.DirectionTo(player.Center).ToRotation() - npc.velocity.ToRotation();
                    while (angle > Math.PI)
                    {
                        angle -= 2.0 * Math.PI;
                    }
                    while (angle < -Math.PI)
                    {
                        angle += 2.0 * Math.PI;
                    }

                    if (Math.Abs(angle) > Math.PI / 2)     //passed player, turn around
                    {
                        npc.localAI[3] = Math.Sign(angle);
                        npc.velocity   = Vector2.Normalize(npc.velocity) * 24;
                    }
                }
                else     //turning
                {
                    npc.velocity = npc.velocity.RotatedBy(MathHelper.ToRadians(2.5f) * npc.localAI[3]);

                    if (++npc.localAI[2] > 2)
                    {
                        npc.localAI[2] = 0;
                        if (Main.netMode != NetmodeID.MultiplayerClient)
                        {
                            Vector2 vel = 12f * Vector2.Normalize(npc.velocity).RotatedBy(Math.PI / 2);
                            Projectile.NewProjectile(npc.Center, vel, ModContent.ProjectileType <TerraFireball>(), npc.damage / 4, 0f, Main.myPlayer);
                            Projectile.NewProjectile(npc.Center, -vel, ModContent.ProjectileType <TerraFireball>(), npc.damage / 4, 0f, Main.myPlayer);
                        }
                    }

                    if (++npc.localAI[0] > 75)
                    {
                        npc.ai[1]++;
                        npc.localAI[0] = 0;
                        npc.localAI[1] = 0;
                    }
                }

                npc.rotation = npc.velocity.ToRotation();
                break;

            case 9:
                goto case 0;

            case 10:     //prepare for coil
                resist    = true;
                targetPos = player.Center + npc.DirectionFrom(player.Center) * 600;
                Movement(targetPos, 0.4f, 32f);
                if (++npc.localAI[0] > 300 || npc.Distance(targetPos) < 50f)
                {
                    npc.ai[1]++;
                    npc.localAI[0] = 0;
                    npc.localAI[1] = npc.Distance(player.Center);
                    npc.velocity   = 24f * npc.DirectionTo(player.Center).RotatedBy(-Math.PI / 2);
                    Main.PlaySound(SoundID.Roar, player.Center, 0);
                }
                npc.rotation = npc.velocity.ToRotation();
                break;

            case 11:     //coiling
            {
                npc.velocity += npc.velocity.RotatedBy(Math.PI / 2) * npc.velocity.Length() / npc.localAI[1];
                npc.rotation  = npc.velocity.ToRotation();

                Vector2 pivot = npc.Center;
                pivot += Vector2.Normalize(npc.velocity.RotatedBy(Math.PI / 2)) * 600;
                for (int i = 0; i < 20; i++)         //arena dust
                {
                    Vector2 offset = new Vector2();
                    double  angle  = Main.rand.NextDouble() * 2d * Math.PI;
                    offset.X += (float)(Math.Sin(angle) * 600);
                    offset.Y += (float)(Math.Cos(angle) * 600);
                    Dust d = Main.dust[Dust.NewDust(pivot + offset - new Vector2(4, 4), 0, 0, 87, 0, 0, 100, Color.White, 1f)];
                    d.velocity = Vector2.Zero;
                    if (Main.rand.Next(3) == 0)
                    {
                        d.velocity += Vector2.Normalize(offset) * 5f;
                    }
                    d.noGravity = true;
                }
                Player target = Main.player[npc.target];
                if (target.active && !target.dead)         //arena effect
                {
                    float distance = target.Distance(pivot);
                    if (distance > 600 && distance < 3000)
                    {
                        Vector2 movement   = pivot - target.Center;
                        float   difference = movement.Length() - 600;
                        movement.Normalize();
                        movement        *= difference < 17f ? difference : 17f;
                        target.position += movement;

                        for (int i = 0; i < 20; i++)
                        {
                            int d = Dust.NewDust(target.position, target.width, target.height, 87, 0f, 0f, 0, default(Color), 2f);
                            Main.dust[d].noGravity = true;
                            Main.dust[d].velocity *= 5f;
                        }
                    }
                }

                if (npc.localAI[0] == 0 && Main.netMode != NetmodeID.MultiplayerClient)         //shoot orb
                {
                    Projectile.NewProjectile(npc.Center, Vector2.Zero, ModContent.ProjectileType <TerraLightningOrb2>(), npc.damage / 4, 0f, Main.myPlayer, npc.whoAmI);
                }

                if (++npc.localAI[0] > 420)
                {
                    npc.ai[1]++;
                    npc.localAI[0] = 0;
                    npc.localAI[1] = 0;
                }
            }
            break;

            case 12:     //reset to get rid of troublesome coil
                goto case 1;

            default:
                npc.ai[1] = 0;
                goto case 0;
            }

            npc.netUpdate = true;

            Vector2 dustOffset = new Vector2(77, -41) * npc.scale; //dust from horns
            int     dust       = Dust.NewDust(npc.Center + npc.velocity - dustOffset.RotatedBy(npc.rotation), 0, 0, DustID.Fire, npc.velocity.X * .4f, npc.velocity.Y * 0.4f, 0, default(Color), 2f);

            Main.dust[dust].velocity *= 2;
            if (Main.rand.Next(2) == 0)
            {
                Main.dust[dust].scale++;
                Main.dust[dust].noGravity = true;
            }

            dustOffset.Y             *= -1f;
            dust                      = Dust.NewDust(npc.Center + npc.velocity - dustOffset.RotatedBy(npc.rotation), 0, 0, DustID.Fire, npc.velocity.X * .4f, npc.velocity.Y * 0.4f, 0, default(Color), 2f);
            Main.dust[dust].velocity *= 2;
            if (Main.rand.Next(2) == 0)
            {
                Main.dust[dust].scale++;
                Main.dust[dust].noGravity = true;
            }

            if (npc.ai[1] != -1 && Collision.SolidCollision(npc.position, npc.width, npc.height) && npc.soundDelay == 0)
            {
                npc.soundDelay = (int)(npc.Distance(player.Center) / 40f);
                if (npc.soundDelay < 10)
                {
                    npc.soundDelay = 10;
                }
                if (npc.soundDelay > 20)
                {
                    npc.soundDelay = 20;
                }
                Main.PlaySound(SoundID.Roar, npc.Center, 1);
            }
        }
        override public Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            using (RebuildLock())
            {
                Sides    = agg_basics.Clamp(Sides, 3, 360, ref valuesChanged);
                Height   = Math.Max(Height, .001);
                Diameter = Math.Max(Diameter, .1);

                using (new CenterAndHeightMantainer(this))
                {
                    if (!Advanced)
                    {
                        var path = new VertexStorage();
                        path.MoveTo(0, -Height / 2);
                        path.LineTo(Diameter / 2, -Height / 2);
                        path.LineTo(Diameter / 2, Height / 2);
                        path.LineTo(0, Height / 2);

                        Mesh = VertexSourceToMesh.Revolve(path, Sides);
                    }
                    else
                    {
                        var path = new VertexStorage();
                        path.MoveTo(0, -Height / 2);
                        path.LineTo(Diameter / 2, -Height / 2);
                        path.LineTo(DiameterTop / 2, Height / 2);
                        path.LineTo(0, Height / 2);

                        Mesh = VertexSourceToMesh.Revolve(path, Sides, MathHelper.DegreesToRadians(StartingAngle), MathHelper.DegreesToRadians(EndingAngle));
                    }
                }
            }

            if (valuesChanged)
            {
                Invalidate(InvalidateType.DisplayValues);
            }

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }
        private void InitAllEntries()
        {
            entries = new Dictionary <string, EventSimEntry>
            {
                {
                    "EventSimSE",
                    new EventSimEntry("Simulate Sound Effects", true)
                    {
                        SimulationFrameChangePerBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (evBox.WasJustEnteredDuringPlayback)
                            {
                                PlaySoundEffectOfBox(evBox);
                            }
                        },
                    }
                },
                {
                    "EventSimBasicBlending",
                    new EventSimEntry("Simulate Animation Blending", true)
                    {
                        SimulationFrameChangeDisabledAction = (entry, evBoxes, time) =>
                        {
                            if (Graph.ViewportInteractor.CurrentComboIndex >= 0)
                            {
                                return;
                            }

                            while (MODEL.AnimContainer.AnimationLayers.Count > 1)
                            {
                                MODEL.AnimContainer.AnimationLayers.RemoveAt(0);
                            }
                            if (MODEL.AnimContainer.AnimationLayers.Count > 0)
                            {
                                MODEL.AnimContainer.AnimationLayers[0].Weight = 1;
                            }
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            if (Graph.ViewportInteractor.CurrentComboIndex >= 0)
                            {
                                return;
                            }

                            if (MODEL.AnimContainer.AnimationLayers.Count > 1)
                            {
                                while (MODEL.AnimContainer.AnimationLayers.Count > 2)
                                {
                                    MODEL.AnimContainer.AnimationLayers.RemoveAt(0);
                                }

                                var blend = evBoxes.FirstOrDefault(b => b.MyEvent.Type == 16);
                                if (blend != null)
                                {
                                    float blendRatio = MathHelper.Clamp((((float)Graph.PlaybackCursor.CurrentTime - blend.MyEvent.StartTime) / (blend.MyEvent.EndTime - blend.MyEvent.StartTime)), 0, 1);
                                    MODEL.AnimContainer.AnimationLayers[0].Weight = 1 - blendRatio;
                                    MODEL.AnimContainer.AnimationLayers[1].Weight = blendRatio;
                                }
                                else
                                {
                                    while (MODEL.AnimContainer.AnimationLayers.Count > 1)
                                    {
                                        MODEL.AnimContainer.AnimationLayers.RemoveAt(0);
                                    }
                                }
                            }
                            else if (MODEL.AnimContainer.AnimationLayers.Count == 1)
                            {
                                MODEL.AnimContainer.AnimationLayers[0].Weight = 1;
                            }
                        },
                    }
                },

                {
                    "EventSimBasicBlending_Combos",
                    new EventSimEntry("Simulate Animation Blending (Combo Viewer)", true)
                    {
                        SimulationFrameChangeDisabledAction = (entry, evBoxes, time) =>
                        {
                            if (Graph.ViewportInteractor.CurrentComboIndex < 0)
                            {
                                return;
                            }

                            while (MODEL.AnimContainer.AnimationLayers.Count > 1)
                            {
                                MODEL.AnimContainer.AnimationLayers.RemoveAt(0);
                            }
                            if (MODEL.AnimContainer.AnimationLayers.Count > 0)
                            {
                                MODEL.AnimContainer.AnimationLayers[0].Weight = 1;
                            }
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            if (Graph.ViewportInteractor.CurrentComboIndex < 0)
                            {
                                return;
                            }

                            if (MODEL.AnimContainer.AnimationLayers.Count > 1)
                            {
                                while (MODEL.AnimContainer.AnimationLayers.Count > 2)
                                {
                                    MODEL.AnimContainer.AnimationLayers.RemoveAt(0);
                                }

                                var blend = evBoxes.FirstOrDefault(b => b.MyEvent.Type == 16);
                                if (blend != null)
                                {
                                    float blendRatio = MathHelper.Clamp((((float)Graph.PlaybackCursor.CurrentTime - blend.MyEvent.StartTime) / (blend.MyEvent.EndTime - blend.MyEvent.StartTime)), 0, 1);
                                    MODEL.AnimContainer.AnimationLayers[0].Weight = 1 - blendRatio;
                                    MODEL.AnimContainer.AnimationLayers[1].Weight = blendRatio;
                                }
                                else
                                {
                                    while (MODEL.AnimContainer.AnimationLayers.Count > 1)
                                    {
                                        MODEL.AnimContainer.AnimationLayers.RemoveAt(0);
                                    }
                                }
                            }
                            else if (MODEL.AnimContainer.AnimationLayers.Count == 1)
                            {
                                MODEL.AnimContainer.AnimationLayers[0].Weight = 1;
                            }
                        },
                    }
                },

                {
                    "EventSimAttackBehaviors",
                    new EventSimEntry("Simulate Hitbox Events", isEnabledByDefault: true,
                                      "InvokeAttackBehavior", "InvokePCBehavior", "InvokeCommonBehavior", "InvokeThrowDamageBehavior")
                    {
                        NewAnimSelectedAction = (entry, evBoxes) =>
                        {
                            MODEL.DummyPolyMan.HideAllHitboxes();

                            if (MODEL.ChrAsm?.RightWeaponModel != null)
                            {
                                MODEL.ChrAsm?.RightWeaponModel.DummyPolyMan.HideAllHitboxes();
                            }

                            if (MODEL.ChrAsm?.LeftWeaponModel != null)
                            {
                                MODEL.ChrAsm?.LeftWeaponModel.DummyPolyMan.HideAllHitboxes();
                            }
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            MODEL.DummyPolyMan.HideAllHitboxes();

                            if (MODEL.ChrAsm?.RightWeaponModel != null)
                            {
                                MODEL.ChrAsm?.RightWeaponModel.DummyPolyMan.HideAllHitboxes();
                            }

                            if (MODEL.ChrAsm?.LeftWeaponModel != null)
                            {
                                MODEL.ChrAsm?.LeftWeaponModel.DummyPolyMan.HideAllHitboxes();
                            }
                        },
                        SimulationFrameChangePerMatchingBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (!evBox.PlaybackHighlight)
                            {
                                return;
                            }

                            var atkParam = GetAtkParamFromEventBox(evBox);

                            if (atkParam != null)
                            {
                                var dmyPolySource = HitViewDummyPolySource;

                                if (atkParam.SuggestedDummyPolySource != ParamData.AtkParam.DummyPolySource.None)
                                {
                                    dmyPolySource = atkParam.SuggestedDummyPolySource;
                                }

                                if (dmyPolySource == ParamData.AtkParam.DummyPolySource.Body)
                                {
                                    MODEL.DummyPolyMan.SetAttackVisibility(
                                        atkParam, true, ParamData.AtkParam.DummyPolySource.Body);
                                }
                                else if (dmyPolySource == ParamData.AtkParam.DummyPolySource.RightWeapon &&
                                         MODEL.ChrAsm?.RightWeaponModel != null)
                                {
                                    MODEL.ChrAsm.RightWeaponModel.DummyPolyMan.SetAttackVisibility(
                                        atkParam, true, ParamData.AtkParam.DummyPolySource.Body);
                                }
                                else if (dmyPolySource == ParamData.AtkParam.DummyPolySource.LeftWeapon &&
                                         MODEL.ChrAsm?.LeftWeaponModel != null)
                                {
                                    MODEL.ChrAsm.LeftWeaponModel.DummyPolyMan.SetAttackVisibility(
                                        atkParam, true, ParamData.AtkParam.DummyPolySource.Body);
                                }

                                if (MODEL.ChrAsm?.RightWeaponModel != null)
                                {
                                    MODEL.ChrAsm.RightWeaponModel.DummyPolyMan.SetAttackVisibility(
                                        atkParam, true, ParamData.AtkParam.DummyPolySource.RightWeapon);
                                }

                                if (MODEL.ChrAsm?.LeftWeaponModel != null)
                                {
                                    MODEL.ChrAsm.LeftWeaponModel.DummyPolyMan.SetAttackVisibility(
                                        atkParam, true, ParamData.AtkParam.DummyPolySource.LeftWeapon);
                                }
                            }
                        },
                    }
                },

                {
                    "EventSimSpEffects",
                    new EventSimEntry("Simulate SpEffects", true,
                                      "InvokeSpEffectBehavior_Multiplayer",
                                      "InvokeSpEffectBehavior",
                                      "InvokeSpEffect",
                                      "InvokeSpEffect_Multiplayer")
                    {
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            SimulatedActiveSpEffects.Clear();

                            Graph.PlaybackCursor.ModPlaybackSpeed = 1;
                        },
                        SimulationFrameChangePerMatchingBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (!evBox.PlaybackHighlight)
                            {
                                return;
                            }

                            if (evBox.MyEvent.Parameters.Template.ContainsKey("SpEffectID"))
                            {
                                int spEffectID = Convert.ToInt32(evBox.MyEvent.Parameters["SpEffectID"]);

                                if (ParamManager.SpEffectParam.ContainsKey(spEffectID))
                                {
                                    var spEffect = ParamManager.SpEffectParam[spEffectID];

                                    if (GameDataManager.GameType == GameDataManager.GameTypes.DS1 || GameDataManager.GameType == GameDataManager.GameTypes.DS1R)
                                    {
                                        if (spEffect.GrabityRate > 0)
                                        {
                                            Graph.PlaybackCursor.ModPlaybackSpeed *= spEffect.GrabityRate;
                                        }
                                    }

                                    SimulatedActiveSpEffects.Add($"{spEffect.GetDisplayName()}");
                                }
                                else
                                {
                                    SimulatedActiveSpEffects.Add($"[Doesn't Exist] {spEffectID}");
                                }
                            }
                        },
                    }
                },

                {
                    "EventSimBulletBehaviors",
                    new EventSimEntry("Simulate Bullet Spawns", isEnabledByDefault: true,
                                      "InvokeBulletBehavior")
                    {
                        NewAnimSelectedAction = (entry, evBoxes) =>
                        {
                            MODEL.DummyPolyMan.ClearAllBulletSpawns();
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            MODEL.DummyPolyMan.ClearAllBulletSpawns();
                        },
                        SimulationFrameChangePerMatchingBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (!evBox.PlaybackHighlight)
                            {
                                return;
                            }

                            if (evBox.MyEvent.Parameters.Template.ContainsKey("DummyPolyID"))
                            {
                                var bulletParamID = GetBulletParamIDFromEvBox(evBox);
                                int dummyPolyID   = Convert.ToInt32(evBox.MyEvent.Parameters["DummyPolyID"]);

                                if (bulletParamID >= 0)
                                {
                                    MODEL.DummyPolyMan.SpawnBulletOnDummyPoly(bulletParamID, dummyPolyID);
                                }
                            }
                        },
                    }
                },

                {
                    "EventSimSFXSpawns",
                    new EventSimEntry("Simulate SFX Spawns", isEnabledByDefault: true,
                                      "N/A")
                    {
                        NewAnimSelectedAction = (entry, evBoxes) =>
                        {
                            MODEL.DummyPolyMan.ClearAllSFXSpawns();
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            MODEL.DummyPolyMan.ClearAllSFXSpawns();
                        },
                        SimulationFrameChangePerBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (!evBox.PlaybackHighlight)
                            {
                                return;
                            }

                            if (evBox.MyEvent.Template == null)
                            {
                                return;
                            }

                            if (evBox.MyEvent.Parameters.Template.ContainsKey("FFXID") &&
                                evBox.MyEvent.Parameters.Template.ContainsKey("DummyPolyID"))
                            {
                                // Using convert here since they might be various numeric
                                // value types.
                                int ffxid       = Convert.ToInt32(evBox.MyEvent.Parameters["FFXID"]);
                                int dummyPolyID = Convert.ToInt32(evBox.MyEvent.Parameters["DummyPolyID"]);

                                MODEL.DummyPolyMan.SpawnSFXOnDummyPoly(ffxid, dummyPolyID);
                            }
                        },
                    }
                },

                //{
                //    "EventSimSoundDummyPolySpawns", new EventSimEntry("Display")
                //},

                {
                    "EventSimMiscDummyPolySpawns",
                    new EventSimEntry("Simulate Misc. DummyPoly Spawn Events", isEnabledByDefault: true)
                    {
                        NewAnimSelectedAction = (entry, evBoxes) =>
                        {
                            MODEL.DummyPolyMan.ClearAllMiscSpawns();

                            if (MODEL.ChrAsm?.RightWeaponModel != null)
                            {
                                MODEL.ChrAsm?.RightWeaponModel.DummyPolyMan.ClearAllMiscSpawns();
                            }

                            if (MODEL.ChrAsm?.LeftWeaponModel != null)
                            {
                                MODEL.ChrAsm?.LeftWeaponModel.DummyPolyMan.ClearAllMiscSpawns();
                            }
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            MODEL.DummyPolyMan.ClearAllMiscSpawns();

                            if (MODEL.ChrAsm?.RightWeaponModel != null)
                            {
                                MODEL.ChrAsm?.RightWeaponModel.DummyPolyMan.ClearAllMiscSpawns();
                            }

                            if (MODEL.ChrAsm?.LeftWeaponModel != null)
                            {
                                MODEL.ChrAsm?.LeftWeaponModel.DummyPolyMan.ClearAllMiscSpawns();
                            }
                        },
                        SimulationFrameChangePerMatchingBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (!evBox.PlaybackHighlight)
                            {
                                return;
                            }

                            if (evBox.MyEvent.TypeName == "InvokeBulletBehavior" || evBox.MyEvent.TypeName.Contains("PlaySound"))
                            {
                                return;
                            }

                            if (!evBox.MyEvent.Parameters.Template.ContainsKey("FFXID") &&
                                evBox.MyEvent.Parameters.Template.ContainsKey("DummyPolyID"))
                            {
                                int dummyPolyID = Convert.ToInt32(evBox.MyEvent.Parameters["DummyPolyID"]);

                                if (evBox.MyEvent.TypeName == "SpawnFFX_ChrType")
                                {
                                    // This is way too long to show TypeName(Args) so just do TypeName
                                    GetCurrentDummyPolyMan()?.SpawnMiscOnDummyPoly(evBox.MyEvent.TypeName, dummyPolyID);
                                }
                                else
                                {
                                    GetCurrentDummyPolyMan()?.SpawnMiscOnDummyPoly(evBox.EventText.Text, dummyPolyID);
                                }
                            }
                        },
                    }
                },

                {
                    "EventSimOpacity",
                    new EventSimEntry("Simulate Opacity Change Events", isEnabledByDefault: true,
                                      "SetOpacityKeyframe")
                    {
                        NewAnimSelectedAction = (entry, evBoxes) =>
                        {
                            GFX.FlverOpacity = 1.0f;
                        },
                        //SimulationStartAction = (entry, evBoxes) =>
                        //{
                        //    GFX.FlverOpacity = 1.0f;
                        //},
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            GFX.FlverOpacity = 1;
                        },
                        SimulationFrameChangePerMatchingBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            if (!evBox.PlaybackHighlight)
                            {
                                return;
                            }

                            float fadeDuration       = evBox.MyEvent.EndTime - evBox.MyEvent.StartTime;
                            float timeSinceFadeStart = time - evBox.MyEvent.StartTime;
                            float fadeStartOpacity   = (float)evBox.MyEvent.Parameters["GhostVal1"];
                            float fadeEndOpacity     = (float)evBox.MyEvent.Parameters["GhostVal2"];

                            GFX.FlverOpacity = MathHelper.Lerp(fadeStartOpacity, fadeEndOpacity, timeSinceFadeStart / fadeDuration);
                        },
                        //DuringAction = (entry, evBox) =>
                        //{

                        //},
                        //SimulationEndAction = (entry, evBoxes) =>
                        //{
                        //    GFX.FlverOpacity = 1.0f;
                        //},
                    }
                },


                {
                    "EventSimDrawMasks",
                    new EventSimEntry("Simulate Draw Mask Changes", isEnabledByDefault: true,
                                      "ShowModelMask", "HideModelMask", "ChangeChrDrawMask", "HideEquippedWeapon")
                    {
                        NewAnimSelectedAction = (entry, evBoxes) =>
                        {
                            //entry.Vars.ClearAllData();

                            //MODEL.DefaultAllMaskValues();
                        },
                        SimulationStartAction = (entry, evBoxes) =>
                        {
                            //MODEL.DefaultAllMaskValues();
                        },
                        SimulationFrameChangePreBoxesAction = (entry, evBoxes, time) =>
                        {
                            MODEL.ResetDrawMaskToDefault();

                            if (MODEL.ChrAsm != null)
                            {
                                if (MODEL.ChrAsm.RightWeaponModel != null)
                                {
                                    MODEL.ChrAsm.RightWeaponModel.IsVisible = true;
                                }

                                if (MODEL.ChrAsm.LeftWeaponModel != null)
                                {
                                    MODEL.ChrAsm.LeftWeaponModel.IsVisible = true;
                                }
                            }
                        },
                        SimulationFrameChangePerBoxAction = (entry, evBoxes, evBox, time) =>
                        {
                            // Not checking if the box is active because the effects
                            // "accumulate" along the timeline.

                            // Only simulate until the current time.
                            if (evBox.MyEvent.StartTime > time)
                            {
                                return;
                            }

                            int maskLength = 32;

                            if (GameDataManager.GameType == GameDataManager.GameTypes.DS1)
                            {
                                maskLength = 8;
                            }

                            if (evBox.MyEvent.Template == null)
                            {
                                return;
                            }

                            if (evBox.MyEvent.TypeName == "ChangeChrDrawMask")
                            {
                                for (int i = 0; i < maskLength; i++)
                                {
                                    var maskByte = (byte)evBox.MyEvent.Parameters[$"Mask{(i + 1)}"];

                                    // Before you get out the torch, be aware that the game
                                    // uses some value other than 0 to SKIP
                                    if (maskByte == 0)
                                    {
                                        MODEL.DrawMask[i] = false;
                                    }
                                    else if (maskByte == 1)
                                    {
                                        MODEL.DrawMask[i] = true;
                                    }
                                }
                            }
                            else if (MODEL.ChrAsm != null && evBox.MyEvent.TypeName == "HideEquippedWeapon")
                            {
                                if (evBox.PlaybackHighlight)
                                {
                                    if ((bool)evBox.MyEvent.Parameters["RightHand"])
                                    {
                                        if (MODEL.ChrAsm.RightWeaponModel != null)
                                        {
                                            MODEL.ChrAsm.RightWeaponModel.IsVisible = false;
                                        }
                                    }

                                    if ((bool)evBox.MyEvent.Parameters["LeftHand"])
                                    {
                                        if (MODEL.ChrAsm.LeftWeaponModel != null)
                                        {
                                            MODEL.ChrAsm.LeftWeaponModel.IsVisible = false;
                                        }
                                    }
                                }
                            }
                            else if (evBox.PlaybackHighlight)
                            {
                                if (evBox.MyEvent.TypeName == "ShowModelMask")
                                {
                                    for (int i = 0; i < maskLength; i++)
                                    {
                                        if ((bool)evBox.MyEvent.Parameters[$"Mask{(i + 1)}"])
                                        {
                                            MODEL.DrawMask[i] = true;
                                        }
                                    }
                                }
                                else if (evBox.MyEvent.TypeName == "HideModelMask")
                                {
                                    for (int i = 0; i < maskLength; i++)
                                    {
                                        if ((bool)evBox.MyEvent.Parameters[$"Mask{(i + 1)}"])
                                        {
                                            MODEL.DrawMask[i] = false;
                                        }
                                    }
                                }
                            }
                        },
                        EnterAction = (entry, evBox) =>
                        {
                            //if (evBox.MyEvent.TypeName == "ShowModelMask" || evBox.MyEvent.TypeName == "HideModelMask")
                            //{
                            //    //if (entry.Vars["OriginalMask"] == null)
                            //    //entry.Vars["OriginalMask"] = new EventSimEntryVariableContainer();

                            //    //var maskVar = (EventSimEntryVariableContainer)(entry.Vars["OriginalMask"]);

                            //    //var newMaskCopy = maskVar[evBox] != null ? ((bool[])maskVar[evBox]) : new bool[MODEL.DrawMask.Length];

                            //    //Array.Copy(MODEL.DrawMask, newMaskCopy, MODEL.DrawMask.Length);
                            //    //maskVar[evBox] = newMaskCopy;
                            //}

                            //for (int i = 0; i < 32; i++)
                            //{
                            //    if (evBox.MyEvent.Parameters.Template.ContainsKey($"Mask{(i + 1)}"))
                            //    {
                            //        if (evBox.MyEvent.TypeName == "ChangeChrDrawMask")
                            //        {
                            //            var maskByte = (byte)evBox.MyEvent.Parameters[$"Mask{(i + 1)}"];

                            //            // Before you get out the torch, be aware that the game
                            //            // uses some value other than 0 to SKIP
                            //            if (maskByte == 0)
                            //                MODEL.DrawMask[i] = false;
                            //            else if (maskByte == 1)
                            //                MODEL.DrawMask[i] = true;
                            //        }
                            //    }
                            //}
                        },
                        DuringAction = (entry, evBox) =>
                        {
                            //for (int i = 0; i < 32; i++)
                            //{
                            //    if (evBox.MyEvent.Parameters.Template.ContainsKey($"Mask{(i + 1)}"))
                            //    {
                            //        if (evBox.MyEvent.TypeName == "ShowModelMask")
                            //        {
                            //            if ((bool)evBox.MyEvent.Parameters[$"Mask{(i + 1)}"])
                            //                MODEL.DrawMask[i] = true;
                            //        }
                            //        else if (evBox.MyEvent.TypeName == "HideModelMask")
                            //        {
                            //            if ((bool)evBox.MyEvent.Parameters[$"Mask{(i + 1)}"])
                            //                MODEL.DrawMask[i] = false;
                            //        }
                            //    }
                            //}
                        },
                        ExitAction = (entry, evBox) =>
                        {
                            //if (evBox.MyEvent.TypeName == "ShowModelMask" || evBox.MyEvent.TypeName == "HideModelMask")
                            //{
                            //    if (entry.Vars["OriginalMask"] != null)
                            //    {
                            //        var maskVar = (EventSimEntryVariableContainer)(entry.Vars["OriginalMask"]);
                            //        if (maskVar != null)
                            //        {
                            //            MODEL.DrawMask = (bool[])(maskVar[evBox]);
                            //        }

                            //    }
                            //}
                        },
                    }
                },

                // DEFAULT EVENT TEMPLATE FOR PASTING

                /*
                 * {
                 *  new[] { "EVENT_TYPE_NAME", },
                 *  new EventSimEntry("MENU_BAR_NAME")
                 *  {
                 *      NewAnimSelectedAction = (entry) =>
                 *      {
                 *
                 *      },
                 *      SimulationStartAction = (entry) =>
                 *      {
                 *
                 *      },
                 *      SimulationScrubAction = (entry) =>
                 *      {
                 *
                 *      },
                 *      EnterAction = (entry, evBox) =>
                 *      {
                 *
                 *      },
                 *      DuringAction = (entry, evBox) =>
                 *      {
                 *
                 *      },
                 *      ExitAction = (entry, evBox) =>
                 *      {
                 *
                 *      },
                 *      SimulationEndAction = (entry) =>
                 *      {
                 *
                 *      },
                 *  }
                 * },
                 */
            };
        }
Example #25
0
        private void SetupConstraint(int index, float position, Vector3F axis)
        {
            // Note: Cached constraint impulses are reset in Warmstart() if necessary.

            if (axis.IsNumericallyZero)
            {
                // The constraint is possibly violated so much that we could not compute valid euler angles
                // and constraint axis (The y angle must not be outside +/- π/2!)
                _limitStates[index] = LimitState.Inactive;
                return;
            }

            Constraint1D constraint = _constraints[index];
            float        minimum    = Minimum[index];
            float        maximum    = Maximum[index];
            Simulation   simulation = Simulation;
            float        deltaTime  = simulation.Settings.Timing.FixedTimeStep;

            // ----- Determine limit state.
            if (minimum > maximum)
            {
                _limitStates[index] = LimitState.Inactive;

                // Nothing more to do.
                return;
            }
            if (Numeric.AreEqual(minimum, maximum))
            {
                _limitStates[index] = LimitState.Locked;
            }
            else if (position <= minimum)
            {
                _limitStates[index] = LimitState.Min;
            }
            else if (position >= maximum)
            {
                _limitStates[index] = LimitState.Max;
            }
            else
            {
                _limitStates[index] = LimitState.Inactive;

                // Nothing more to do.
                return;
            }

            Debug.Assert(_limitStates[index] != LimitState.Inactive);

            // ----- Error correction
            float deviation        = 0;
            var   allowedDeviation = simulation.Settings.Constraints.AllowedAngularDeviation;

            if (_limitStates[index] == LimitState.Locked)
            {
                allowedDeviation = 0;
            }
            if (position > maximum + allowedDeviation)
            {
                deviation = maximum - position + allowedDeviation;
            }
            else if (position < minimum - allowedDeviation)
            {
                deviation = minimum - position - allowedDeviation;
            }

            float targetVelocity             = deviation * ErrorReduction[index] / deltaTime;
            float maxErrorCorrectionVelocity = simulation.Settings.Constraints.MaxErrorCorrectionVelocity;

            targetVelocity = MathHelper.Clamp(targetVelocity, -maxErrorCorrectionVelocity, maxErrorCorrectionVelocity);

            // ----- Restitution
            float restitution = Restitution[index];

            if (restitution > simulation.Settings.Constraints.RestitutionThreshold)
            {
                float velocity = constraint.GetRelativeVelocity(BodyA, BodyB);
                if (_limitStates[index] == LimitState.Min)
                {
                    if (velocity < -Simulation.Settings.Constraints.RestingVelocityLimit)
                    {
                        targetVelocity = Math.Max(targetVelocity, -velocity * restitution);
                    }
                }
                else if (_limitStates[index] == LimitState.Max)
                {
                    if (velocity > Simulation.Settings.Constraints.RestingVelocityLimit)
                    {
                        targetVelocity = Math.Min(targetVelocity, -velocity * restitution);
                    }
                }
            }
            constraint.TargetRelativeVelocity = targetVelocity;

            // ----- Impulse limits
            float impulseLimit = MaxForce[index] * deltaTime;

            if (_limitStates[index] == LimitState.Min)
            {
                _minImpulseLimits[index] = 0;
                _maxImpulseLimits[index] = impulseLimit;
            }
            else if (_limitStates[index] == LimitState.Max)
            {
                _minImpulseLimits[index] = -impulseLimit;
                _maxImpulseLimits[index] = 0;
            }
            else //if (_limitStates[index] == LimitState.Locked)
            {
                _minImpulseLimits[index] = -impulseLimit;
                _maxImpulseLimits[index] = impulseLimit;
            }

            // Note: Softness must be set before!
            constraint.Softness = Softness[index] / deltaTime;
            constraint.Prepare(BodyA, BodyB, Vector3F.Zero, -axis, Vector3F.Zero, axis);
        }
Example #26
0
        public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            var body0Pos = info.Skin0.Owner?.OldPosition ?? Vector3.Zero;
            var body1Pos = info.Skin1.Owner?.OldPosition ?? Vector3.Zero;


            var oldSphere0 = (Sphere)info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0);
            var newSphere0 = (Sphere)info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0);
            var oldSphere1 = (Sphere)info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1);
            var newSphere1 = (Sphere)info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1);

            var oldDelta = oldSphere0.Position - oldSphere1.Position;
            var newDelta = newSphere0.Position - oldSphere1.Position;

            var oldDistSq = oldDelta.LengthSquared();
            var newDistSq = newDelta.LengthSquared();

            var radSum = newSphere0.Radius + newSphere1.Radius;

            if (System.Math.Min(oldDistSq, newDistSq) < (radSum + collTolerance) * (radSum + collTolerance))
            {
                var oldDist = (float)System.Math.Sqrt(oldDistSq);
                var depth   = radSum - oldDist;

                if (oldDist > JiggleMath.Epsilon)
                {
                    oldDelta /= oldDist;
                }
                else
                {
                    oldDelta = Vector3.TransformNormal(Vector3.Backward, Matrix.CreateFromAxisAngle(Vector3.Up, MathHelper.ToRadians(random.Next(360))));
                }

                var worldPos = oldSphere1.Position + (oldSphere1.Radius - 0.5f * depth) * oldDelta;

                unsafe
                {
                    var collInfo = new SmallCollPointInfo(worldPos - body0Pos, worldPos - body1Pos, depth);

                    collisionFunctor.CollisionNotify(ref info, ref oldDelta, &collInfo, 1);
                }
            }
        }
        public override void AI()
        {
            // Slowly remove alpha as it is present
            if (projectile.alpha > 0)
            {
                projectile.alpha -= alphaReduction;
            }
            // If alpha gets lower than 0, set it to 0
            if (projectile.alpha < 0)
            {
                projectile.alpha = 0;
            }
            // If ai0 is 0f, run this code. This is the 'movement' code for the javelin as long as it isn't sticking to a target
            if (!isStickingToTarget)
            {
                targetWhoAmI += 1f;
                // For a little while, the javelin will travel with the same speed, but after this, the javelin drops velocity very quickly.
                if (targetWhoAmI >= maxTicks)
                {
                    // Change these multiplication factors to alter the javelin's movement change after reaching maxTicks
                    float velXmult = 0.98f;                     // x velocity factor, every AI update the x velocity will be 98% of the original speed
                    float
                        velYmult = 0.35f;                       // y velocity factor, every AI update the y velocity will be be 0.35f bigger of the original speed, causing the javelin to drop to the ground
                    targetWhoAmI          = maxTicks;           // set ai1 to maxTicks continuously
                    projectile.velocity.X = projectile.velocity.X * velXmult;
                    projectile.velocity.Y = projectile.velocity.Y + velYmult;
                }
                // Make sure to set the rotation accordingly to the velocity, and add some to work around the sprite's rotation
                projectile.rotation =
                    projectile.velocity.ToRotation() +
                    MathHelper.ToRadians(
                        90f);                         // Please notice the MathHelper usage, offset the rotation by 90 degrees (to radians because rotation uses radians) because the sprite's rotation is not aligned!

                // Spawn some random dusts as the javelin travels
                if (Main.rand.Next(3) == 0)
                {
                    Dust dust = Dust.NewDustDirect(projectile.position, projectile.height, projectile.width, mod.DustType <Dusts.Sparkle>(),
                                                   projectile.velocity.X * .2f, projectile.velocity.Y * .2f, 200, Scale: 1.2f);
                    dust.velocity += projectile.velocity * 0.3f;
                    dust.velocity *= 0.2f;
                }
                if (Main.rand.Next(4) == 0)
                {
                    Dust dust = Dust.NewDustDirect(projectile.position, projectile.height, projectile.width, mod.DustType <Dusts.Sparkle>(),
                                                   0, 0, 254, Scale: 0.3f);
                    dust.velocity += projectile.velocity * 0.5f;
                    dust.velocity *= 0.5f;
                }
            }
            // This code is ran when the javelin is sticking to a target
            if (isStickingToTarget)
            {
                // These 2 could probably be moved to the ModifyNPCHit hook, but in vanilla they are present in the AI
                projectile.ignoreWater = true;     // Make sure the projectile ignores water
                projectile.tileCollide = false;    // Make sure the projectile doesn't collide with tiles anymore
                int  aiFactor  = 15;               // Change this factor to change the 'lifetime' of this sticking javelin
                bool killProj  = false;            // if true, kill projectile at the end
                bool hitEffect = false;            // if true, perform a hit effect
                projectile.localAI[0] += 1f;
                // Every 30 ticks, the javelin will perform a hit effect
                hitEffect = projectile.localAI[0] % 30f == 0f;
                int projTargetIndex = (int)targetWhoAmI;
                if (projectile.localAI[0] >= (float)(60 * aiFactor) ||             // If it's time for this javelin to die, kill it
                    (projTargetIndex < 0 || projTargetIndex >= 200))                        // If the index is past its limits, kill it
                {
                    killProj = true;
                }
                else if (Main.npc[projTargetIndex].active && !Main.npc[projTargetIndex].dontTakeDamage)                 // If the target is active and can take damage
                {
                    // Set the projectile's position relative to the target's center
                    projectile.Center  = Main.npc[projTargetIndex].Center - projectile.velocity * 2f;
                    projectile.gfxOffY = Main.npc[projTargetIndex].gfxOffY;
                    if (hitEffect)                     // Perform a hit effect here
                    {
                        Main.npc[projTargetIndex].HitEffect(0, 1.0);
                    }
                }
                else                 // Otherwise, kill the projectile
                {
                    killProj = true;
                }

                if (killProj)                 // Kill the projectile
                {
                    projectile.Kill();
                }
            }
        }
Example #28
0
        public override void Update(GameTime gameTime, Map gameMap)
        {
            _target.X = Position.X + (_faceDir * 200);

            //if (_target.X < 0) _target.X = (gameMap.Width * gameMap.TileWidth) - _target.X;
            //if (_target.X >= (gameMap.Width * gameMap.TileWidth)) _target.X = _target.X - (gameMap.Width * gameMap.TileWidth);

            if (Helper.Random.Next(100) == 0)
            {
                _target.Y = Helper.RandomFloat(30f, (gameMap.TileHeight * gameMap.Height) - 30f);
            }

            //if (Helper.Random.Next(500) == 0)
            //    _faceDir = -_faceDir;

            for (int dist = 0; dist <= 150; dist += 50)
            {
                if (gameMap.CheckTileCollision(new Vector2(_target.X + (dist * -_faceDir), Position.Y)))
                {
                    _target.Y = Position.Y + (Position.Y < 260f ? -50f : 50f);
                    Speed.X   = MathHelper.Lerp(Speed.X, 0f, 0.1f);
                }
            }
            //if (gameMap.CheckTileCollision(_target + new Vector2(-_faceDir * 50, 0)))
            //{
            //    _target.Y += _target.Y < 260f ? -50f : 50f;
            //    Speed.X = MathHelper.Lerp(Speed.X, 0f, 0.1f);
            //}
            //if (gameMap.CheckTileCollision(_target + new Vector2(-_faceDir * 100, 0)))
            //{
            //    _target.Y += _target.Y < 260f ? -50f : 50f;
            //    Speed.X = MathHelper.Lerp(Speed.X, 0f, 0.1f);
            //}
            //if (gameMap.CheckTileCollision(_target + new Vector2(-_faceDir * 130, 0)))
            //{
            //    _target.Y += _target.Y < 260f ? -50f : 50f;
            //    Speed.X = MathHelper.Lerp(Speed.X, 0f, 0.1f);
            //}

            //if (Speed.Length() < 0.1f) _target = Position;

            //Rotation = Helper.V2ToAngle(Speed);

            Speed = Vector2.Lerp(Speed, Vector2.Zero, 0.05f);

            if (Vector2.Distance(_target, Position) > 5f)
            {
                Vector2 dir = _target - Position;
                dir.Normalize();
                Speed += dir * 0.2f;
            }

            Speed.X = MathHelper.Clamp(Speed.X, -3f, 3f);
            Speed.Y = MathHelper.Clamp(Speed.Y, -3f, 3f);


            if (Position.Y < 260f)
            {
                ParticleController.Instance.Add(Position + new Vector2(-_faceDir * 5f, 0f),
                                                new Vector2(Helper.RandomFloat(0f, -_faceDir * 1f), Helper.RandomFloat(-0.2f, 0.2f)),
                                                0, Helper.RandomFloat(500, 1000), 500,
                                                false, true,
                                                Position.Y < 260f ?new Rectangle(0, 0, 3, 3):new Rectangle(128, 0, 16, 16),
                                                new Color(new Vector3(1f) * (0.5f + Helper.RandomFloat(0.5f))),
                                                ParticleFunctions.Smoke,
                                                Position.Y >= 260f ? 0.3f : 1f, 0f, Helper.RandomFloat(-0.1f, 0.1f), 0, ParticleBlend.Alpha);
            }
            ParticleController.Instance.Add(Position + new Vector2(-_faceDir * 5f, 0f),
                                            new Vector2(Helper.RandomFloat(0f, -_faceDir * 0.2f), Helper.RandomFloat(-0.2f, 0.2f)),
                                            0, Helper.RandomFloat(50, 150), 50,
                                            false, true,
                                            Position.Y < 260f ? new Rectangle(0, 0, 3, 3) : new Rectangle(128, 0, 16, 16),
                                            Position.Y < 260f ? Color.LightGreen : Color.White,
                                            ParticleFunctions.FadeInOut,
                                            Position.Y >= 260f ? 0.3f : 1f, 0f, Helper.RandomFloat(-0.1f, 0.1f), 0, ParticleBlend.Alpha);

            projectileTime -= gameTime.ElapsedGameTime.TotalMilliseconds;
            if (_firing)
            {
                Vector2 screenPos = Vector2.Transform(Position, Camera.Instance.CameraMatrix);
                float   pan       = (screenPos.X - (Camera.Instance.Width / 2f)) / (Camera.Instance.Width / 2f);
                if (pan < -1f || pan > 1f)
                {
                    gunLoop.Volume = 0f;
                }
                else
                {
                    gunLoop.Volume = 0.3f;
                }
                if (Ship.Instance.Position.Y >= 260 && Position.Y < 260)
                {
                    gunLoop.Volume = 0f;
                }
                if (Ship.Instance.Position.Y < 260 && Position.Y >= 260)
                {
                    gunLoop.Volume = 0f;
                }
                gunLoop.Pan = MathHelper.Clamp(pan, -1f, 1f);

                if (projectileTime <= 0)
                {
                    projectileTime = projectileCoolDown;
                    ProjectileController.Instance.Spawn(entity =>
                    {
                        ((Projectile)entity).Type       = ProjectileType.Forward1;
                        ((Projectile)entity).SourceRect = new Rectangle(8, 8, 20, 8);
                        ((Projectile)entity).Life       = 1000;
                        ((Projectile)entity).EnemyOwner = true;
                        ((Projectile)entity).Damage     = 1f;
                        entity.Speed    = new Vector2(6f * _faceDir, 0f);
                        entity.Position = Position + entity.Speed;
                    });
                }

                if (Helper.Random.Next(20) == 0)
                {
                    _firing = false;
                    gunLoop.Pause();
                }
            }
            else
            {
                if (Helper.Random.Next(50) == 0)
                {
                    _firing = true;
                    gunLoop.Resume();
                }
            }

            if (Helper.Random.Next(200) == 0 && GameController.Wave >= 8)
            {
                AudioController.PlaySFX("seeker", 0.5f, -0.1f, 0.1f, Camera.Instance, Position);
                ProjectileController.Instance.Spawn(entity =>
                {
                    ((Projectile)entity).Type       = ProjectileType.Seeker;
                    ((Projectile)entity).SourceRect = new Rectangle(1, 18, 8, 4);
                    ((Projectile)entity).Life       = 2000;
                    ((Projectile)entity).Scale      = 1f;
                    ((Projectile)entity).EnemyOwner = true;
                    ((Projectile)entity).Damage     = 5f;
                    ((Projectile)entity).Target     = Position + new Vector2(_faceDir * 300, 0);
                    ;
                    entity.Speed    = new Vector2(0f, -0.5f);
                    entity.Position = Position + new Vector2(0, 0);
                });
            }

            //if (Vector2.Distance(Position, _target) < 1f)
            //{
            //    _idleAnim.Pause();
            //    _hitAnim.Pause();

            //    if (Helper.Random.Next(100) == 0)
            //    {
            //        _target = Position + new Vector2(Helper.RandomFloat(-30, 30), Helper.RandomFloat(-30, 30));
            //        if (_target.Y < 280) _target.Y = 280;

            //        Vector2 dir = _target - Position;
            //        dir.Normalize();
            //        Speed = dir*5f;

            //        _idleAnim.Play();
            //        _hitAnim.Play();
            //    }

            //    if (Vector2.Distance(Ship.Instance.Position, Position) < 100f)
            //    {
            //        _target = Ship.Instance.Position;
            //        if (_target.Y < 280) _target.Y = 280;

            //        Vector2 dir = _target - Position;
            //        dir.Normalize();
            //        Speed = dir * 5f;

            //        _idleAnim.Play();
            //        _hitAnim.Play();
            //    }
            //}
            //else
            //{
            //    ParticleController.Instance.Add(Position,
            //                       new Vector2(Helper.RandomFloat(-0.1f,0.1f), Helper.RandomFloat(-0.1f,0.1f)),
            //                       0, Helper.Random.NextDouble() * 1000, Helper.Random.NextDouble() * 1000,
            //                       false, false,
            //                       new Rectangle(128, 0, 16, 16),
            //                       new Color(new Vector3(1f) * (0.25f + Helper.RandomFloat(0.5f))),
            //                       ParticleFunctions.FadeInOut,
            //                       0.5f, 0f, 0f,
            //                       1, ParticleBlend.Alpha);
            //}



            base.Update(gameTime, gameMap);
        }
Example #29
0
        public void TilePallateWindow()
        {
            //Tile Pallate Window
            {
                ImGui.Begin("Tiles");
                //Draw Tile set
                ImGui.Image(tilePallateTexture, new Num.Vector2(tilePallateTextureSize.X, tilePallateTextureSize.Y) * tileSetZoom);

                //Get top left of window and draw rect around texture
                Num.Vector2 imageTopLeft    = ImGui.GetItemRectMin();
                Rectangle   tilePallateRect = new Rectangle((int)(imageTopLeft.X), (int)(imageTopLeft.Y), (int)tilePallateTextureSize.X * tileSetZoom, (int)tilePallateTextureSize.Y * tileSetZoom);
                Prim.DrawRectangle(tilePallateRect, Color.Black);

                Prim.DrawGrid(tilePallateRect, (16 * tileSetZoom), (16 * tileSetZoom), Color.Black);

                //Allow zoom on tileset
                ImGui.InputInt("Zoom", ref tileSetZoom, 1);
                tileSetZoom = MathHelper.Clamp(tileSetZoom, 1, 3);

                //MousePosition in tile pallate
                tilePallateMousePos   = (ImGui.GetMousePos() - imageTopLeft);
                tilePallateMousePos  /= (16 * tileSetZoom);
                tilePallateMousePos.X = (int)Math.Floor(tilePallateMousePos.X);
                tilePallateMousePos.Y = (int)Math.Floor(tilePallateMousePos.Y);
                tilePallateMousePos  *= (16 * tileSetZoom);

                int xdif = selectedTopRight.X - selectedTopLeft.X;
                int ydif = selectedTopRight.Y - selectedTopLeft.Y;
                xdif = Math.Max(1, xdif);
                ydif = Math.Max(1, ydif);

                Rectangle tileSelectedRect = new Rectangle((int)((selectedTopLeft.X * 16 * tileSetZoom) + imageTopLeft.X), (int)((selectedTopLeft.Y * 16 * tileSetZoom) + imageTopLeft.Y), (16 * tileSetZoom) * xdif, (16 * tileSetZoom) * ydif);
                Prim.DrawRectangle(tileSelectedRect, Color.Lime);

                //Select Rectangle of tiles
                Num.Vector2 flatMousePos = ImGui.GetMousePos();
                if (MathMore.PointInRectangle(new Vector2(flatMousePos.X, flatMousePos.Y), tilePallateRect))
                {
                    Num.Vector2 tilePos = (tilePallateMousePos / (16 * tileSetZoom));

                    Rectangle tileCursorRect = new Rectangle((int)((selectedTopLeft.X * 16 * tileSetZoom) + imageTopLeft.X), (int)((selectedTopLeft.Y * 16 * tileSetZoom) + imageTopLeft.Y), (16 * tileSetZoom) * xdif, (16 * tileSetZoom) * ydif);
                    Prim.DrawRectangle(tileCursorRect, Color.Maroon);

                    if (ImGui.IsMouseClicked(ImGuiMouseButton.Left))
                    {
                        selectedTopLeft = new Point((int)tilePos.X, (int)tilePos.Y);
                    }
                    else if (ImGui.IsMouseDown(ImGuiMouseButton.Left))
                    {
                        selectedTopRight = new Point((int)tilePos.X + 1, (int)tilePos.Y + 1);
                    }
                    else if (ImGui.IsMouseReleased(ImGuiMouseButton.Left))
                    {
                        SelectedTileBrush = new Point[xdif, ydif];

                        for (int xx = 0; xx < xdif; xx++)
                        {
                            for (int yy = 0; yy < ydif; yy++)
                            {
                                SelectedTileBrush[xx, yy] = new Point(xx + selectedTopLeft.X, yy + selectedTopLeft.Y);
                            }
                        }
                    }
                }
                //ImGui.Text($"Tile Pos: {SelectedTile.ToString()}");

                ImGui.End();
            }
        }
Example #30
0
 static void Main(string[] args)
 {
     IUserIO userIO = new ConsoleIO();
     MathHelper helper = new MathHelper(userIO);
     helper.FindProblem();
 }
        public static void CalculateDistance()
        {
            var model = DistanceConfigHelper.GetData();
            if (model.Status == (int)DistanceStatus.Finish)
            {
                return;
            }
            int i = model.From;
            int j = model.To;
            var math = new MathHelper();

            using (var context = new SmartBuyEntities())
            {
                var markets = context.Markets
                    .Where(x => x.IsActive && x.Latitude != null && x.Longitude != null)
                    .ToList();
                while (true)
                {
                    var lat1 = markets[i].Latitude.Value;
                    var lng1 = markets[i].Longitude.Value;
                    var lat2 = markets[j].Latitude.Value;
                    var lng2 = markets[j].Longitude.Value;
                    var distance = math.TravelDistance(lat1, lng1, lat2, lng2);

                    // OK
                    if (distance != -1)
                    {
                        var m1 = markets[i];
                        var m2 = markets[j];
                        var tmp = context.MarketDistances
                            .FirstOrDefault(x => x.FromMarket == m1.Id && x.ToMarket == m2.Id);
                        if (tmp != null)
                        {
                            tmp.Distance = distance;
                        }
                        else
                        {
                            var mDistance = new MarketDistance
                                                {
                                                    FromMarket = markets[i].Id,
                                                    ToMarket = markets[j].Id,
                                                    Distance = distance
                                                };
                            context.MarketDistances.Add(mDistance);
                        }

                        j++;
                        if (j == markets.Count)
                        {
                            i++;

                            // Finish
                            if (i == markets.Count - 1)
                            {
                                DistanceConfigHelper.Finish();
                                context.SaveChanges();
                                return;
                            }
                            j = i + 1;
                        }
                    }
                    else
                    {
                        // Something's wrong, out of quota
                        var savePoint = new DistanceConfigModel
                                            {
                                                From = i,
                                                To = j,
                                                Status = (int) DistanceStatus.Going
                                            };

                        // Save
                        DistanceConfigHelper.SetData(savePoint);
                        context.SaveChanges();
                        return;
                    }
                }
            }
        }
Example #32
0
        public static float GetAngle(Vector3D v1, Vector3D v2)
        {
            float radAngle = (float)Math.Acos((v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z) / (Math.Sqrt(v1.X * v1.X + v1.Y * v1.Y + v1.Z * v1.Z) * Math.Sqrt(v2.X * v2.X + v2.Y * v2.Y + v2.Z * v2.Z)));

            return((float)MathHelper.RadiansToDegrees(radAngle));
        }
        public void PerspectiveOffCenterTest()
        {
            Vector3        position       = new Vector3(1, 2, 3);
            Quaternion     orientation    = Quaternion.CreateFromRotationMatrix(new Vector3(2, 3, 6), 0.123f);
            CameraInstance cameraInstance = new CameraInstance(new Camera(new PerspectiveProjection()))
            {
                PoseLocal = new Pose(position, orientation),
            };

            ((PerspectiveProjection)cameraInstance.Camera.Projection).SetOffCenter(1, 5, 2, 5, 1, 10);

            Matrix projection = Matrix.CreatePerspectiveOffCenter(1, 5, 2, 5, 1, 10);

            Assert.AreEqual(position, cameraInstance.PoseWorld.Position);
            Assert.AreEqual(orientation.ToRotationMatrix33(), cameraInstance.PoseWorld.Orientation);
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(33.690067f), cameraInstance.Camera.Projection.FieldOfViewX));
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(15.255119f), cameraInstance.Camera.Projection.FieldOfViewY));
            Assert.AreEqual(4.0f / 3.0f, cameraInstance.Camera.Projection.AspectRatio);
            Assert.AreEqual(4, cameraInstance.Camera.Projection.Width);
            Assert.AreEqual(3, cameraInstance.Camera.Projection.Height);
            Assert.AreEqual(1, cameraInstance.Camera.Projection.Left);
            Assert.AreEqual(5, cameraInstance.Camera.Projection.Right);
            Assert.AreEqual(2, cameraInstance.Camera.Projection.Bottom);
            Assert.AreEqual(5, cameraInstance.Camera.Projection.Top);
            Assert.AreEqual(1, cameraInstance.Camera.Projection.Near);
            Assert.AreEqual(10, cameraInstance.Camera.Projection.Far);
            Assert.AreEqual(9, cameraInstance.Camera.Projection.Depth);
            Assert.IsTrue(Matrix.AreNumericallyEqual(projection, cameraInstance.Camera.Projection));
            Assert.IsTrue(Matrix.AreNumericallyEqual(projection.Inverse, cameraInstance.Camera.Projection.Inverse));
            Assert.IsNotNull(cameraInstance.BoundingShape);

            // Test shape using collision detection. Remove rotation to simplify test.
            cameraInstance.PoseWorld = new Pose(cameraInstance.PoseWorld.Position);
            CollisionDetection collisionDetection = new CollisionDetection();
            var             point = new PointShape();
            CollisionObject pointCollisionObject  = new CollisionObject(new GeometricObject(point));
            CollisionObject cameraCollisionObject = new CollisionObject(cameraInstance);

            point.Position = position + new Vector3(3, 3, -1);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(30, 30, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(3, 3, -0.9f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(30, 30, -10.1f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));

            point.Position = position + new Vector3(1, 2, -1);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0.9f, 2, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(1, 1.9f, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(5, 5, -1);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(5.1f, 5, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(5, 5.1f, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));

            point.Position = position + new Vector3(10, 20, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(9.9f, 20, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(10, 19.9f, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(50, 50, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(50.1f, 50, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(50, 50.1f, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
        }
Example #34
0
        /// <summary>
        ///     Pauses the game.
        /// </summary>
        internal void Pause(GameTime gameTime = null)
        {
            // Don't allow pausing if the play is already finished.
            if (IsPlayComplete)
                return;

            // Grab the casted version of the screenview.
            var screenView = (GameplayScreenView)View;

            // Handle pause.
            if (!IsPaused)
            {
                // Handle cases where someone (a developer) calls pause but there is not GameTime.
                // shouldn't ever happen though.
                if (gameTime == null)
                {
                    const string log = "Cannot pause if GameTime is null";
                    Logger.Error(log, LogType.Runtime);

                    throw new InvalidOperationException(log);
                }

                // Increase the time the pause key has been held.
                TimePauseKeyHeld += gameTime.ElapsedGameTime.TotalMilliseconds;

                screenView.Transitioner.Alpha = MathHelper.Lerp(screenView.Transitioner.Alpha, 1,
                    (float) Math.Min(gameTime.ElapsedGameTime.TotalMilliseconds / TimeToHoldPause, 1));

                // Make the user hold the pause key down before pausing.
                if (TimePauseKeyHeld < TimeToHoldPause)
                    return;

                IsPaused = true;
                IsResumeInProgress = false;
                PauseCount++;
                GameBase.Game.GlobalUserInterface.Cursor.Alpha = 1;

                if (!InReplayMode)
                {
                    // Show notification to the user that their score is invalid.
                    NotificationManager.Show(NotificationLevel.Warning, "WARNING! Your score will not be submitted due to pausing during gameplay!");

                    // Add the pause mod to their score.
                    if (!ModManager.IsActivated(ModIdentifier.Paused))
                    {
                        ModManager.AddMod(ModIdentifier.Paused);
                        ReplayCapturer.Replay.Mods |= ModIdentifier.Paused;
                        Ruleset.ScoreProcessor.Mods |= ModIdentifier.Paused;
                    }
                }

                try
                {
                    AudioEngine.Track.Pause();
                }
                catch (AudioEngineException)
                {
                    // ignored
                }

                DiscordHelper.Presence.State = $"Paused for the {StringHelper.AddOrdinal(PauseCount)} time";
                DiscordHelper.Presence.EndTimestamp = 0;
                DiscordRpc.UpdatePresence(ref DiscordHelper.Presence);

                OnlineManager.Client?.UpdateClientStatus(GetClientStatus());

                // Fade in the transitioner.
                screenView.Transitioner.Animations.Clear();
                screenView.Transitioner.Animations.Add(new Animation(AnimationProperty.Alpha, Easing.Linear, screenView.Transitioner.Alpha, 0.75f, 400));

                // Activate pause menu
                screenView.PauseScreen.Activate();
                return;
            }


            if (IsResumeInProgress)
                return;

            // Setting the resume time in this case allows us to give the user time to react
            // with a delay before starting the audio track again.
            // When that resume time is past the specific set offset, it'll unpause the game.
            IsResumeInProgress = true;
            ResumeTime = GameBase.Game.TimeRunning;

            // Fade screen transitioner
            screenView.Transitioner.Animations.Clear();
            var alphaTransformation = new Animation(AnimationProperty.Alpha, Easing.Linear, 0.75f, 0, 400);
            screenView.Transitioner.Animations.Add(alphaTransformation);

            // Deactivate pause screen.
            screenView.PauseScreen.Deactivate();
            SetRichPresence();
            OnlineManager.Client?.UpdateClientStatus(GetClientStatus());
        }
        public void PerspectiveTest()
        {
            Vector3        position       = new Vector3(1, 2, 3);
            Quaternion     orientation    = Quaternion.CreateFromRotationMatrix(new Vector3(2, 3, 6), 0.123f);
            CameraInstance cameraInstance = new CameraInstance(new Camera(new PerspectiveProjection()))
            {
                PoseLocal = new Pose(position, orientation),
            };

            ((PerspectiveProjection)cameraInstance.Camera.Projection).SetFieldOfView(MathHelper.ToRadians(60), 16.0f / 10.0f, 1, 10);
            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(60), 16.0f / 10.0f, 1, 10);

            Assert.AreEqual(position, cameraInstance.PoseWorld.Position);
            Assert.AreEqual(orientation.ToRotationMatrix33(), cameraInstance.PoseWorld.Orientation);
            Assert.AreEqual(MathHelper.ToRadians(60), cameraInstance.Camera.Projection.FieldOfViewY);
            Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(85.4601055f), cameraInstance.Camera.Projection.FieldOfViewX));
            Assert.AreEqual(16.0f / 10.0f, cameraInstance.Camera.Projection.AspectRatio);
            Assert.IsTrue(Numeric.AreEqual(1.8475209f, cameraInstance.Camera.Projection.Width));
            Assert.IsTrue(Numeric.AreEqual(1.1547005f, cameraInstance.Camera.Projection.Height));
            Assert.AreEqual(1, cameraInstance.Camera.Projection.Near);
            Assert.AreEqual(10, cameraInstance.Camera.Projection.Far);
            Assert.IsTrue(Numeric.AreEqual(-0.9237604f, cameraInstance.Camera.Projection.Left));
            Assert.IsTrue(Numeric.AreEqual(0.9237604f, cameraInstance.Camera.Projection.Right));
            Assert.IsTrue(Numeric.AreEqual(-0.5773503f, cameraInstance.Camera.Projection.Bottom));
            Assert.IsTrue(Numeric.AreEqual(0.5773503f, cameraInstance.Camera.Projection.Top));
            Assert.AreEqual(9, cameraInstance.Camera.Projection.Depth);
            Assert.IsTrue(Matrix.AreNumericallyEqual(projection, cameraInstance.Camera.Projection));
            Assert.IsTrue(Matrix.AreNumericallyEqual(projection.Inverse, cameraInstance.Camera.Projection.Inverse));
            Assert.IsNotNull(cameraInstance.BoundingShape);

            // Test shape using collision detection. Remove rotation to simplify test.
            cameraInstance.PoseWorld = new Pose(cameraInstance.PoseWorld.Position);
            CollisionDetection collisionDetection = new CollisionDetection();
            var             point = new PointShape();
            CollisionObject pointCollisionObject  = new CollisionObject(new GeometricObject(point));
            CollisionObject cameraCollisionObject = new CollisionObject(cameraInstance);

            point.Position = position + new Vector3(0, 0, -1);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0, 0, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0, 0, -0.9f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0, 0, -10.1f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));

            point.Position = position + new Vector3(-0.9237604f, -0.5773f, -1);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(-0.924f, -0.5773f, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(-0.9237604f, -0.58f, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0.9237604f, 0.5773f, -1);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0.924f, 0.5773f, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(0.9237604f, 0.58f, -1);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));

            point.Position = position + new Vector3(-9.237604f, -5.773f, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(-9.24f, -5.773f, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(-9.237604f, -5.8f, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(9.237604f, 5.773f, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(9.24f, 5.773f, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3(9.237604f, 5.8f, -10);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
        }
Example #36
0
        public void Create()
        {
            Stopwatch sw;

            int    width  = 2880;
            int    height = 1440;
            string elevationTextureSmallFilename = $@"Generated\Planets\Mars\Mars{width}x{height}.raw";

            if (!File.Exists(elevationTextureSmallFilename))
            {
                sw = Stopwatch.StartNew();
                var elevationTextureLarge = TextureHelper.LoadTiff16(@"Datasets\Planets\Mars\Mars_MGS_MOLA_DEM_mosaic_global_463m.tif");
                Console.WriteLine($"Loading texture used {sw.Elapsed}");

                sw = Stopwatch.StartNew();
                _elevationTextureSmall = Resampler.Resample(elevationTextureLarge, width, height);
                Console.WriteLine($"Resampling used {sw.Elapsed}");

                TextureHelper.SaveRaw16($@"Generated\Planets\Mars\Mars{_elevationTextureSmall.Width}x{_elevationTextureSmall.Height}.raw", _elevationTextureSmall);
            }
            else
            {
                _elevationTextureSmall = TextureHelper.LoadRaw16(elevationTextureSmallFilename, width, height);
            }
            TextureHelper.SavePng8($@"Generated\Planets\Mars\Mars{_elevationTextureSmall.Width}x{_elevationTextureSmall.Height}.png", _elevationTextureSmall);

            // var sw = Stopwatch.StartNew();
            // var elevationTextureLarge = TextureHelper.LoadTiff16(@"Datasets\Planets\Mars\Mars_MGS_MOLA_DEM_mosaic_global_463m.tif");
            // Console.WriteLine($"Loading texture used {sw.Elapsed}");

            // sw = Stopwatch.StartNew();
            // _elevationTextureSmall = Resampler.Resample(elevationTextureLarge, 2400, 1200);
            // Console.WriteLine($"Resampling used {sw.Elapsed}");

            // TextureHelper.SaveRaw16($@"Generated\Planets\Mars\Mars{_elevationTextureSmall.Width}x{_elevationTextureSmall.Height}.raw", _elevationTextureSmall);
            // TextureHelper.SavePng8($@"Generated\Planets\Mars\Mars{_elevationTextureSmall.Width}x{_elevationTextureSmall.Height}.png", _elevationTextureSmall);

            string elevationTextureBlurFilename = $@"Generated\Planets\Mars\MarsBlur{width}x{height}.raw";

            if (!File.Exists(elevationTextureBlurFilename))
            {
                sw = Stopwatch.StartNew();
                var blurFilter = new BlurFilter(PlanetProjection);
                _elevationTextureBlur = blurFilter.Blur3(_elevationTextureSmall, MathHelper.ToRadians(10));
                Console.WriteLine($"Blur used {sw.Elapsed}");

                TextureHelper.SaveRaw16($@"Generated\Planets\Mars\MarsBlur{_elevationTextureBlur.Width}x{_elevationTextureBlur.Height}.raw", _elevationTextureBlur);
            }
            else
            {
                _elevationTextureBlur = TextureHelper.LoadRaw16(elevationTextureBlurFilename, width, height);
            }
            TextureHelper.SavePng8($@"Generated\Planets\Mars\MarsBlur{_elevationTextureBlur.Width}x{_elevationTextureBlur.Height}.png", _elevationTextureBlur);

            // var blurFilter = new BlurFilter(PlanetProjection);
            // sw = Stopwatch.StartNew();
            // _elevationTextureBlur = blurFilter.Blur3(_elevationTextureSmall, MathHelper.ToRadians(10));
            // Console.WriteLine($"Blur used {sw.Elapsed}");

            // TextureHelper.SaveRaw16($@"Generated\Planets\Mars\MarsBlur{_elevationTextureBlur.Width}x{_elevationTextureBlur.Height}.raw", _elevationTextureBlur);
            // TextureHelper.SavePng8($@"Generated\Planets\Mars\MarsBlur{_elevationTextureBlur.Width}x{_elevationTextureBlur.Height}.png", _elevationTextureBlur);

            sw = Stopwatch.StartNew();
            CreatePlanetVertexes(RecursionLevel);
            Console.WriteLine($"Time used to create planet vertexes: {sw.Elapsed}");

            SaveSTL($@"Generated\Planets\Mars\Mars{RecursionLevel}.stl");
        }