Пример #1
0
        public void Update()
        {
            if (!Status.IsLiving)
            {
                return;
            }

            #region begin

            //gather current data
            float oldPosX   = Properties.Position.X;
            float oldPosY   = Properties.Position.Y;
            float oldPosZ   = Properties.Position.Z;
            float oldFacing = Agk.GetObjectWorldAngleY(Properties.ResourceNumber);

            var animSet = AnimationHandler.GetAnimationSet(Properties.Filebase + ".anim");

            //a character should NEVER not have an animation.
            if (AnimationQ.Count == 0)
            {
                var tAnim = new AppliedAnimation(this, animSet, "0000L") //add basic idle
                {
                    IsLoop = true,
                    Speed  = 1.0f
                };
                AnimationQ.Add(tAnim);
            }

            string tAnimState = AnimationQ[0].Animation.Name.Substring(0, 4).ToLower();
            string tAnimStage = AnimationQ[0].Animation.Name.Substring(4, 1).ToLower(); //I L O
            #endregion

            #region handle vitals
            if (Status.Health.Max > 0)
            {
                if (App.Timing.Timer - Status.Health.RegenMark > Status.Health.RegenInterval)
                {
                    Status.Health.Current += (int)Math.Floor(Status.Health.RegenAmount);
                    if (Status.Health.Current > Status.Health.Max)
                    {
                        Status.Health.Current = Status.Health.Max;
                    }
                    Status.Health.RegenMark = App.Timing.Timer;
                }
            }
            if (Status.Stamina.Max > 0)
            {
                if (App.Timing.Timer - Status.Stamina.RegenMark > Status.Stamina.RegenInterval)
                {
                    //stamina if affected by locomotion and exhaustion
                    if (Status.MotionState == MotionStates.Sprinting)
                    {
                        //sprint costs stamina
                        Status.Stamina.Current -= 2;
                    }
                    else if (Status.MotionState != MotionStates.Running)
                    {
                        //run suppresses regen, otherwise recover
                        Status.Stamina.Current += (int)Math.Floor(Status.Stamina.RegenAmount);
                    }
                    if (Status.Stamina.Current > Status.Stamina.Max)
                    {
                        Status.Stamina.Current = Status.Stamina.Max;
                    }
                    if (Status.Stamina.Current > Status.Stamina.Max * 0.2f)
                    {
                        //clear exhaustion if stamina has recovered > 1/5 of max
                        Status.IsExhausted = false;
                    }
                    if (Status.Stamina.Current <= 0)
                    {
                        //if stamina runs out, apply exhaustion
                        Status.Stamina.Current = 0;
                        Status.IsExhausted     = true;
                        if (Status.MotionState == MotionStates.Sprinting)
                        {
                            //drop out of sprint if exhausted
                            if (Status.IsRunLocked)
                            {
                                Status.MotionState = MotionStates.Running;
                            }
                            else
                            {
                                Status.MotionState = MotionStates.Walking;
                            }
                        }
                    }
                }
            }
            #endregion

            #region handle position

            bool mustCalcPosition = true;

            //update speed
            switch (Status.ActionState)
            {
            case ActionStates.Idle:

                if (Status.MotionState == MotionStates.Walking)
                {
                    //immediate stop when walking cus aint no body got time for iceskating
                    Properties.Speed = 0.0f;
                }

                if (Properties.Speed > 0.0f)
                {
                    //new state is idle, meaning we stopped, but we have speed meaning we were moving
                    //immediately drop from sprint to run, but if running transition to walk over time.
                    //this means if speed remains, we also have to enforce a moving state
                    if (Properties.Speed > CharacterHandler3d.Config.NormalMaxSpeed)
                    {
                        Properties.Speed   = MathUtil.CurveValue(10.0f, Properties.Speed, Agk.ScreenFPS() * CharacterHandler3d.Config.NormalDeceleration * 0.5f);
                        Status.MotionState = MotionStates.Running;
                        Status.ActionState = ActionStates.Moving;
                    }
                    else if (OldStatus.MotionState == MotionStates.Running)
                    {
                        Properties.Speed   = MathUtil.CurveValue(10.0f, Properties.Speed, Agk.ScreenFPS() * CharacterHandler3d.Config.NormalDeceleration);
                        Status.MotionState = MotionStates.Walking;
                        Status.ActionState = ActionStates.Moving;
                    }
                    else
                    {
                        Properties.Speed = 0.0f;
                    }
                }
                if (Properties.Speed < 25.0)
                {
                    //cut the curve transitions short if they get low enough, it feels better
                    Properties.Speed   = 0.0f;
                    Status.MotionState = MotionStates.Stationary;
                    Status.ActionState = ActionStates.Idle;
                }
                break;

            case ActionStates.Moving:

                switch (Status.MotionState)
                {
                case MotionStates.Walking:
                    if (Status.StanceState == StanceStates.Sneaking)
                    {
                        Properties.Speed = MathUtil.CurveValue(CharacterHandler3d.Config.SneakMaxSpeed * Properties.SlopeModifier, Properties.Speed, Agk.ScreenFPS() * CharacterHandler3d.Config.SneakAcceleration);
                    }
                    else
                    {
                        Properties.Speed = MathUtil.CurveValue(CharacterHandler3d.Config.NormalMaxSpeed * Properties.SlopeModifier, Properties.Speed, Agk.ScreenFPS() * CharacterHandler3d.Config.NormalAcceleration);
                    }
                    break;

                case MotionStates.Running:
                    Properties.Speed = MathUtil.CurveValue(CharacterHandler3d.Config.RunMaxSpeed * Properties.SlopeModifier, Properties.Speed, Agk.ScreenFPS() * CharacterHandler3d.Config.NormalAcceleration);
                    break;

                case MotionStates.Sprinting:
                    Properties.Speed = MathUtil.CurveValue(CharacterHandler3d.Config.SprintMaxSpeed * Properties.SlopeModifier, Properties.Speed, Agk.ScreenFPS() * CharacterHandler3d.Config.SprintAcceleration);
                    break;
                }

                if (Status.MotionState != MotionStates.Forced)
                {
                    //if a slope or other effect has reduced our speed to less than half of the max run speed, enforce a walking state. it looks weird to run or sprint in slow motion...
                    if (Properties.Speed <= (CharacterHandler3d.Config.RunMaxSpeed * 0.5f) && (Status.MotionState == MotionStates.Running || Status.MotionState == MotionStates.Sprinting))
                    {
                        Status.MotionState = MotionStates.Walking;
                    }

                    //if slope is too steep to maintain forward speed, enforce stoppage. we don't want to crawl glacially slow up a steep hill and we don't want to generate a bunch of collision data
                    if (Properties.Speed < (CharacterHandler3d.Config.SneakMaxSpeed * 1.5f) && Properties.SlopeModifier < 1.0f)
                    {
                        //TODO: apply slide downslope instead of just stopping
                        //NOTE: slide down will need to set to a forced state / ability animation which takes the character far enough down to avoid jitter
                        //			handling this through a forced move ability can probably deprecate the need for slopeLock. can just use the falling animation key

                        Properties.Speed     = 0.0f;
                        Status.MotionState   = MotionStates.Stationary;
                        Status.ActionState   = ActionStates.Idle;
                        Status.IsSlopeLocked = true;
                    }

                    if (Properties.SlopeModifier > 1.00f)
                    {
                        Status.IsSlopeLocked = false;
                    }
                }

                break;

            case ActionStates.Jumping:

                //jumps are complex and composed of multiple stages
                if (OldStatus.ActionState == ActionStates.Jumping)
                {
                    //if jump is in a prep stage, position is controlled by character handler. while in flight/fall position is controlled by arc handler
                    if (tAnimStage != "i")
                    {
                        mustCalcPosition    = false;
                        Properties.Position = Properties.ArcPath.GetPosition(App.Timing.Timer, App.Timing.PauseElapsed);

                        //jump is in flight/fall -- are we ascending or descending?
                        if (Properties.Position.Y < oldPosY)
                        {
                            Status.ActionState = ActionStates.Falling;
                        }
                    }
                }
                break;

            case ActionStates.Falling:
                mustCalcPosition    = false;
                Properties.Position = Properties.ArcPath.GetPosition(App.Timing.Timer, App.Timing.PauseElapsed);
                break;
            }

            if (mustCalcPosition)
            {
                Properties.Position.X += Agk.Sin(Properties.Heading) * Properties.Speed * (App.Timing.Delta * 0.001f); //speed is in terms of units per second, delta is in ms
                Properties.Position.Z += Agk.Cos(Properties.Heading) * Properties.Speed * (App.Timing.Delta * 0.001f);
            }

            #endregion

            #region handle collision

            /*
             * var colRay = new CollisionRay();
             * int collisionState = 0;
             *
             * //lateral slide
             * if(Status.ActionState > ActionStates.Idle)
             * {
             *  colRay.SphereCast
             *  (
             *      new AGKVector3(oldPosX, oldPosY + (Properties.Height * 0.5f), oldPosZ),
             *      new AGKVector3(Properties.Position.X, Properties.Position.Y + (Properties.Height * 0.5f), Properties.Position.Z),
             *      CharacterHandler3d.Config.CollisionBufferDistance, true
             *  );
             *  if (colRay.HitObjectNumber > 0)
             *  {
             *      Properties.Position.X = colRay.HitPosition.X;
             *      Properties.Position.Z = colRay.HitPosition.Z;
             *      collisionState = 1;
             *  }
             * }
             *
             * //vertical down
             *
             * float tHeight = 0.0f;
             * //TODO: tHeight = get terrain height
             *
             * colRay.RayCast
             * (
             *  new AGKVector3(Properties.Position.X, Properties.Position.Y + 100.0f, Properties.Position.Z),
             *  new AGKVector3(Properties.Position.X, Properties.Position.Y - 100.0f, Properties.Position.Z)
             * );
             *
             * //TODO: compare collision height to terrain height
             * //TEMP: just use col
             * if (colRay.HitObjectNumber > 0)
             * {
             *  tHeight = colRay.HitPosition.Y;
             * }
             *
             * if (Properties.Position.Y < tHeight)
             * {
             *  Properties.Position.Y = tHeight;
             *  collisionState = 2;
             * }
             *
             * if (Properties.ArcPath != null)
             * {
             *  if (collisionState == 1)
             *  {
             *      //hit a vertical surface, change arc to fall straight down
             *      Properties.ArcPath.Dispose();
             *      Properties.ArcPath = ArcHandler.Create(this, 400.0f, 270.0f, Properties.Heading);
             *      Status.ActionState = ActionStates.Falling;
             *  }
             *  else if(collisionState == 2)
             *  {
             *      //hit a horizontal surface, end the arc
             *      Properties.ArcPath.Dispose();
             *      Status.ActionState = ActionStates.Idle;
             *      Status.MotionState = MotionStates.Stationary;
             *  }
             * }
             * else
             * {
             *  //no arc, just force to horizontal surface
             *  Properties.Position.Y = tHeight;
             *
             *  //slope / cliff ?
             *  var tDiff = oldPosY - Properties.Position.Y;
             *  if(tDiff < 0.0f && Status.IsSlopeLocked)
             *  {
             *      //negative diff means ascending
             *
             *      if(App.Timing.Timer - Status.SlopeMark > 200)
             *      {
             *          Properties.SlopeModifier = 0.0f;
             *      }
             *      Properties.Speed = 0.0f;
             *      Status.ActionState = ActionStates.Idle;
             *      Status.MotionState = MotionStates.Stationary;
             *      Properties.Position.X = oldPosX;
             *      Properties.Position.Y = oldPosY;
             *      Properties.Position.Z = oldPosZ;
             *  }
             *  else if(tDiff > Properties.Height * 0.5f)
             *  {
             *      //positive diff means descending, if descending more than waist height, change to falling
             *
             *      Properties.Position.Y = oldPosY;
             *      Properties.ArcPath = ArcHandler.Create(this, 100.0f + Properties.Speed, 30.0f, Properties.Heading);
             *      Status.ActionState = ActionStates.Falling;
             *      Status.StanceState = StanceStates.Basic;
             *      Status.MotionState = MotionStates.Forced;
             *  }
             *  else
             *  {
             *      //NOTE: negative tDiff# indicates character moved uphill, larger the negative, the steeper the hill.
             *      //NOTE: slopeMod is a speed increase 1.3 = speed * 1.3, 0.0 = stop.
             *      //TODO: use a fixed length sample, currently rate of movement and framerate affect the slope result.
             *      //NOTE: slopeMark / threshold smooth against jitter
             *      if(App.Timing.Timer - Status.SlopeMark > 200)
             *      {
             *          float slopeThreshold = -0.4f;
             *          if(tDiff > 0.0f || tDiff < slopeThreshold)
             *          {
             *              Properties.SlopeModifier = 1.0f + tDiff;
             *              if(Properties.SlopeModifier < 0.0f) { Properties.SlopeModifier = 0.0f; }
             *              if(Properties.SlopeModifier < 1.3f) { Properties.SlopeModifier = 1.3f; }
             *          }
             *          else
             *          {
             *              Properties.SlopeModifier = 1.0f;
             *          }
             *      }
             *
             *      //TEMP: disable slopeMod
             *      Properties.SlopeModifier = 1.0f;
             *  }
             * }
             */
            #endregion

            #region apply to object

            Agk.SetObjectRotation(Properties.ResourceNumber, 0.0f, MathUtil.CurveAngle(Properties.Facing, oldFacing, Agk.ScreenFPS() * CharacterHandler3d.Config.NormalTurnSpeed), 0.0f);
            Agk.SetObjectPosition(Properties.ResourceNumber, Properties.Position.X, Properties.Position.Y, Properties.Position.Z);

            #endregion

            #region handle animation

            //get new animation state
            string tState                  = ((int)Status.StanceState).ToString() + ((int)Status.ActionState).ToString() + ((int)Status.MotionState).ToString() + ((int)Status.DirectionState).ToString();
            string tOldState               = ((int)OldStatus.StanceState).ToString() + ((int)OldStatus.ActionState).ToString() + ((int)OldStatus.MotionState).ToString() + ((int)OldStatus.DirectionState).ToString();
            string tBaseStance             = ((int)Status.StanceState).ToString();
            string oldBaseStance           = ((int)OldStatus.StanceState).ToString();
            string tBaseState              = tBaseStance + "000";
            string keyBaseIdleStationaryUp = ((int)ActionStates.Idle).ToString() + ((int)MotionStates.Stationary).ToString() + ((int)DirectionStates.Standard).ToString(); //for convenience

            if (tState != tAnimState && tAnimState + "O" != AnimationQ[0].Animation.Name && tAnimState + "I" != AnimationQ[0].Animation.Name)
            {
                //animation state has changed, clear the current animation stack and rebuild under the new state
                AnimationQ.Clear();

                if (tState == tBaseState && tBaseStance == oldBaseStance)
                {
                    //transition old state out
                    var tAnimO = new AppliedAnimation(this, animSet, tAnimState + "O")
                    {
                        IsLoop = false,
                    };
                    AnimationQ.Add(tAnimO);

                    //transition new state in
                    if (Status.StanceState != OldStatus.StanceState)
                    {
                        var tAnimI = new AppliedAnimation(this, animSet, tState + "I")
                        {
                            IsLoop = false,
                        };
                        AnimationQ.Add(tAnimI);
                    }
                }
                else
                {
                    //dont need to transition old state out, just transition new state in

                    if (Status.ActionState == ActionStates.Jumping)
                    {
                        float tJumpAngle;
                        if (Properties.Speed > 0.0f)
                        {
                            tJumpAngle = 30.0f;
                        }
                        else
                        {
                            tJumpAngle = 90.0f;
                        }
                        dynamic jumpArgs = new
                        {
                            Angle = tJumpAngle,
                            Speed = 400.0f + Properties.Speed,
                            Owner = this
                        };
                        if (Properties.Speed > CharacterHandler3d.Config.NormalMaxSpeed)
                        {
                            //if running/sprinting, skip stage i and go straight into jump proper
                            AddJump(jumpArgs);
                        }
                        else
                        {
                            //walking or stationary, we need a bit of animation prep. for the feels.
                            var tAnimI = new AppliedAnimation(this, animSet, tState + "I")
                            {
                                IsLoop       = false,
                                Callback     = "CharacterEntity3d.AddJump",
                                CallbackArgs = JsonConvert.SerializeObject(jumpArgs)
                            };
                            AnimationQ.Add(tAnimI);
                        }
                    }
                    else
                    {
                        if (Status.StanceState != OldStatus.StanceState)
                        {
                            var tAnimII = new AppliedAnimation(this, animSet, tState + "I")
                            {
                                IsLoop = false,
                            };
                            AnimationQ.Add(tAnimII);
                        }
                    }
                }

                //always proceed into state Loop -> characters should never be static!
                var tAnimL = new AppliedAnimation(this, animSet, tState + "L")
                {
                    IsLoop = true,
                };
                AnimationQ.Add(tAnimL);
            }

            //update animation frame
            bool isDone = AnimationQ[0].Update();
            if (isDone)
            {
                AnimationQ.RemoveAt(0);
            }

            #endregion
        }
Пример #2
0
        public static void GetGameplayInput(object rArgs)
        {
            App.Log("controls3d", LogLevel.Notice, "main", "> Begin GetGameplayInput");

            //reset forced
            UserInterface.Status.MouseModeForced = "";
            UserInterface.Status.KeyModeForced   = "";

            //exit early if user does not have control

            /*
             * if(App.Status.LoadState < 3)
             * {
             *  return;
             * }
             */

            if (CharacterHandler3d.MyCharacter == null)
            {
                return;
            }

            if (!CharacterHandler3d.MyCharacter.Status.IsLiving)
            {
                return;
            }

            if (UserInterface.Status.KeyMode != "gameplay" || CharacterHandler3d.MyCharacter.Status.MotionState == CharacterEntity3d.MotionStates.Forced)
            {
                return;
            }

            if (ActiveCamera.ControlMode != Camera3d.CameraMode.Anchored)
            {
                return;
            }

            bool animWait = false;

            if (CharacterHandler3d.MyCharacter.AnimationQ.Count > 0)
            {
                animWait = CharacterHandler3d.MyCharacter.AnimationQ.First().Animation.Wait;
            }

            //grab old state
            CharacterHandler3d.MyCharacter.OldStatus = JsonConvert.DeserializeObject <CharacterEntity3d.CharacterStatus>(JsonConvert.SerializeObject(CharacterHandler3d.MyCharacter.Status));

            //reset states that need to be held by user
            if (CharacterHandler3d.MyCharacter.Status.StanceState == CharacterEntity3d.StanceStates.Sneaking)
            {
                CharacterHandler3d.MyCharacter.Status.StanceState = CharacterEntity3d.StanceStates.Basic;
            }

            if (CharacterHandler3d.MyCharacter.Status.ActionState == CharacterEntity3d.ActionStates.Moving)
            {
                CharacterHandler3d.MyCharacter.Status.ActionState = CharacterEntity3d.ActionStates.Idle;
            }

            if (CharacterHandler3d.MyCharacter.Status.MotionState != CharacterEntity3d.MotionStates.Forced)
            {
                CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Stationary;
            }

            CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;

            //get mouse input
            if (UserInterface.Status.MouseMode == "gameplay")
            {
            }

            //get keyboard input
            if (UserInterface.Status.KeyMode == "gameplay" && !animWait)
            {
                if (CharacterHandler3d.MyCharacter.Status.MotionState != CharacterEntity3d.MotionStates.Forced)
                {
                    //toggle strafelock
                    if (Hardware.IsKeyDown(MovementKey.StrafeToggle) && UserInterface.Status.InputReady)
                    {
                        UserInterface.Status.InputMark = App.Timing.Timer;
                        CharacterHandler3d.MyCharacter.Status.IsStrafeLocked = !CharacterHandler3d.MyCharacter.Status.IsStrafeLocked;
                    }

                    //toggle runlock
                    if (Hardware.IsKeyDown(MovementKey.RunToggle) && UserInterface.Status.InputReady)
                    {
                        UserInterface.Status.InputMark = App.Timing.Timer;
                        CharacterHandler3d.MyCharacter.Status.IsRunLocked = !CharacterHandler3d.MyCharacter.Status.IsRunLocked;
                    }

                    //apply run if locked
                    if (CharacterHandler3d.MyCharacter.Status.IsRunLocked &&
                        CharacterHandler3d.MyCharacter.OldStatus.StanceState == CharacterEntity3d.StanceStates.Basic
                        )
                    {
                        if (CharacterHandler3d.MyCharacter.OldStatus.ActionState == CharacterEntity3d.ActionStates.Moving &&
                            CharacterHandler3d.MyCharacter.OldStatus.MotionState < CharacterEntity3d.MotionStates.Sprinting
                            )
                        {
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Running;
                        }
                    }

                    //sneak
                    if (Hardware.IsKeyDown(MovementKey.SpeedSlow))
                    {
                        CharacterHandler3d.MyCharacter.Status.StanceState = CharacterEntity3d.StanceStates.Sneaking;
                    }

                    //sprint
                    if (Hardware.IsKeyDown(MovementKey.SpeedBoost))
                    {
                        if (CharacterHandler3d.MyCharacter.Status.StanceState == CharacterEntity3d.StanceStates.Basic &&
                            CharacterHandler3d.MyCharacter.OldStatus.ActionState == CharacterEntity3d.ActionStates.Moving &&
                            CharacterHandler3d.MyCharacter.Status.MotionState != CharacterEntity3d.MotionStates.Forced
                            )
                        {
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Sprinting;
                        }
                    }

                    //jump
                    if (Hardware.IsKeyDown(MovementKey.Upward) && UserInterface.Status.InputReady)
                    {
                        //don't allow a jump if sneaking or already in a jump
                        if (CharacterHandler3d.MyCharacter.Status.StanceState == CharacterEntity3d.StanceStates.Basic &&
                            CharacterHandler3d.MyCharacter.Status.ActionState < CharacterEntity3d.ActionStates.Jumping
                            )
                        {
                            UserInterface.Status.InputMark = App.Timing.Timer;
                            CharacterHandler3d.MyCharacter.Status.ActionState = CharacterEntity3d.ActionStates.Jumping;
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Forced;
                        }
                    }

                    float camY = MathUtil.Wrap(Agk.GetCameraAngleY(1) + 180.0f, 0.0f, 360.0f);

                    //forward
                    if (Hardware.IsKeyDown(MovementKey.Forward))
                    {
                        CharacterHandler3d.MyCharacter.Status.ActionState = CharacterEntity3d.ActionStates.Moving;
                        if (CharacterHandler3d.MyCharacter.Status.MotionState == CharacterEntity3d.MotionStates.Stationary)
                        {
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Walking;
                        }
                        CharacterHandler3d.MyCharacter.Properties.Facing  = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                        CharacterHandler3d.MyCharacter.Properties.Heading = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                    }

                    //backward
                    if (Hardware.IsKeyDown(MovementKey.Backward))
                    {
                        CharacterHandler3d.MyCharacter.Status.ActionState = CharacterEntity3d.ActionStates.Moving;
                        if (CharacterHandler3d.MyCharacter.Status.MotionState == CharacterEntity3d.MotionStates.Stationary)
                        {
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Walking;
                        }
                        if (CharacterHandler3d.MyCharacter.Status.IsStrafeLocked)
                        {
                            CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                            CharacterHandler3d.MyCharacter.Properties.Heading    = camY;
                            CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Backward;
                        }
                        else
                        {
                            CharacterHandler3d.MyCharacter.Properties.Facing  = camY;
                            CharacterHandler3d.MyCharacter.Properties.Heading = camY;
                        }
                    }

                    //left
                    if (Hardware.IsKeyDown(MovementKey.Left))
                    {
                        CharacterHandler3d.MyCharacter.Status.ActionState = CharacterEntity3d.ActionStates.Moving;
                        if (CharacterHandler3d.MyCharacter.Status.MotionState == CharacterEntity3d.MotionStates.Stationary)
                        {
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Walking;
                        }
                        if (CharacterHandler3d.MyCharacter.Status.IsStrafeLocked)
                        {
                            if (Hardware.IsKeyDown(MovementKey.Forward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 180.0f - 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                            else if (Hardware.IsKeyDown(MovementKey.Backward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Backward;
                            }
                            else
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 90.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Left;
                            }
                        }
                        else
                        {
                            if (Hardware.IsKeyDown(MovementKey.Forward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f - 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 180.0f - 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                            else if (Hardware.IsKeyDown(MovementKey.Backward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                            else
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 90.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 90.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                        }
                    }

                    //right
                    if (Hardware.IsKeyDown(MovementKey.Right))
                    {
                        CharacterHandler3d.MyCharacter.Status.ActionState = CharacterEntity3d.ActionStates.Moving;
                        if (CharacterHandler3d.MyCharacter.Status.MotionState == CharacterEntity3d.MotionStates.Stationary)
                        {
                            CharacterHandler3d.MyCharacter.Status.MotionState = CharacterEntity3d.MotionStates.Walking;
                        }
                        if (CharacterHandler3d.MyCharacter.Status.IsStrafeLocked)
                        {
                            if (Hardware.IsKeyDown(MovementKey.Forward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 180.0f + 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                            else if (Hardware.IsKeyDown(MovementKey.Backward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY - 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Backward;
                            }
                            else
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY - 90.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Right;
                            }
                        }
                        else
                        {
                            if (Hardware.IsKeyDown(MovementKey.Forward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY + 180.0f + 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY + 180.0f + 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                            else if (Hardware.IsKeyDown(MovementKey.Backward))
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY - 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY - 45.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                            else
                            {
                                CharacterHandler3d.MyCharacter.Properties.Facing     = MathUtil.Wrap(camY - 90.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Properties.Heading    = MathUtil.Wrap(camY - 90.0f, 0.0f, 360.0f);
                                CharacterHandler3d.MyCharacter.Status.DirectionState = CharacterEntity3d.DirectionStates.Standard;
                            }
                        }
                    }
                }
            }

            //mouse steers character if moving and not strafe locked
            if (UserInterface.Status.MouseMode == "gameplay")
            {
                if (CharacterHandler3d.MyCharacter.Status.ActionState == CharacterEntity3d.ActionStates.Moving &&
                    !CharacterHandler3d.MyCharacter.Status.IsStrafeLocked
                    )
                {
                    CharacterHandler3d.MyCharacter.Properties.Facing = MathUtil.CurveAngle(CharacterHandler3d.MyCharacter.Properties.Facing + Hardware.Mouse.MoveX, CharacterHandler3d.MyCharacter.Properties.Facing, ActiveCamera.Precision);
                }
            }

            //sprint camera effect
            if (CharacterHandler3d.MyCharacter.Status.MotionState == CharacterEntity3d.MotionStates.Sprinting)
            {
                ActiveCamera.FOV = MathUtil.CurveValue(65.0f, ActiveCamera.FOV, Agk.ScreenFPS() * CharacterHandler3d.Config.SprintAcceleration);
            }
            else if (ActiveCamera.FOV != Camera3dHandler.DefaultFOV)
            {
                ActiveCamera.FOV = MathUtil.CurveValue(Camera3dHandler.DefaultFOV, ActiveCamera.FOV, Agk.ScreenFPS() * CharacterHandler3d.Config.SprintAcceleration);
            }



            //TEMP:
            if (Hardware.IsKeyDown((int)Keys.Y))
            {
                Controls3d.ActiveCamera.Offset.Y += 0.1f;
            }
            if (Hardware.IsKeyDown((int)Keys.H))
            {
                Controls3d.ActiveCamera.Offset.Y -= 0.1f;
            }

            //TEMP: toggle active
            if (Hardware.IsKeyDown((int)Keys.C) && UserInterface.Status.InputReady)
            {
                UserInterface.Status.InputMark = App.Timing.Timer;
                Controls3d.SetActiveCamera(Camera3dHandler.CameraList.FirstOrDefault(c => c.Name != Controls3d.ActiveCamera.Name));
            }
            //ENDTEMP



            App.Log("Controls3d", LogLevel.Notice, "main", "> End GetGameplayInput");
        }
Пример #3
0
        static void Main(string[] args)
        {
            //--------------------------------------------
            #region boilerplate inits

            var attrs = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false).FirstOrDefault() as AssemblyTitleAttribute;

            //init Agk
            if (!App.Init(args, attrs.Title))
            {
                return;
            }

            //init modules
            new Hardware();
            new Media();
            new Devkit3d();
            new AnimationHandler();
            new CharacterHandler3d();
            new World3d();
            new Controls3d();
            new Camera3dHandler();
            new ArcHandler();

            new UI.UserInterface();
            UI.UserInterface.ControllerList.Add(new UI.CommonController());
            UI.UserInterface.ControllerList.Add(new UI.GameMenuController());
            UI.UserInterface.PreloadImages();

            //clean up
            UpdateHandler.SortUpdateList();

            //init 3D physics
            Agk.Create3DPhysicsWorld();

            App.Log("Program.cs", 3, "main", "> Init Complete");

            #endregion
            //--------------------------------------------

            //TEMP setups

            var floorObj = Agk.CreateObjectBox(40.0f, 2.0f, 40.0f);
            var floorEnt = new WorldEntity3d();
            floorEnt.Properties.ResourceNumber = floorObj;
            floorEnt.Properties.IsObject       = true;
            var floorFx = Media.GetShaderAsset("media/shaders/SurfaceColorLit.vs", "media/shaders/SurfaceColorLit.ps", true);
            floorEnt.SetShader(floorFx);
            Agk.SetShaderConstantByName(floorFx.ResourceNumber, "u_color", 0.8f, 0.8f, 0.8f, 0);
            floorEnt.Properties.Position.Y = -1.0f;
            World3d.WorldEntityList.Add(floorEnt);
            Agk.Create3DPhysicsStaticBody(floorEnt.Properties.ResourceNumber);

            /*
             * var ent = new WorldEntity3d();
             * var tObj = Media.LoadObjectAsset("media/characters/woman.dae", true, false, Guid.NewGuid().ToString());
             * Agk.SetObjectScalePermanent(tObj.ResourceNumber, 30.0f, 30.0f, 30.0f);
             * Agk.FixObjectPivot(tObj.ResourceNumber);
             * var tImg = Media.GetImageAsset("media/characters/woman_d.png", 1.0f, 1.0f);
             * Agk.SetObjectImage(tObj.ResourceNumber, tImg.ResourceNumber, 0);
             * tImg = Media.GetImageAsset("media/characters/woman_n.png", 1.0f, 1.0f);
             * Agk.SetObjectImage(tObj.ResourceNumber, tImg.ResourceNumber, 1);
             * tImg = Media.GetImageAsset("media/characters/woman_s.png", 1.0f, 1.0f);
             * Agk.SetObjectImage(tObj.ResourceNumber, tImg.ResourceNumber, 2);
             * ent.Properties.ResourceNumber = tObj.ResourceNumber;
             * ent.Properties.IsObject = true;
             * ent.Properties.Filebase = "media/characters/woman";
             * var wFx = Media.GetShaderAsset("media/shaders/SurfaceDiffSpec.vs", "media/shaders/SurfaceDiffSpec.ps", true);
             * ent.SetShader(wFx);
             * World3d.WorldEntityList.Add(ent);
             */

            //var tChar = new CharacterEntity3d("media/characters/automata");
            var tChar = new CharacterEntity3d("media/characters/adventurer-carliet");
            CharacterHandler3d.MyCharacter = tChar;

            //Agk.SetObjectVisible(tChar.Properties.ResourceNumber, false);


            var cam0 = new Camera3d("main");
            cam0.UpdateFromAgk();
            cam0.ControlMode = Camera3d.CameraMode.Anchored;
            cam0.Anchor      = floorEnt;
            cam0.Target      = floorEnt;

            var cam1 = new Camera3d("myOtherCam");
            cam1.UpdateFromAgk();
            cam1.Position.X = 0.0f;
            cam1.Position.Y = 10.0f;
            cam1.Position.Z = -20.0f;
            cam1.ApplyToAgk();

            Controls3d.SetActiveCamera(cam0);

            //ENDTEMP

            //App main
            while (App.LoopAGK())
            {
                App.Log("Program.cs", 1, "main", "--- Begin main loop ---");

                //Always update timing, and do it first
                App.UpdateTiming();

                //sync internal physics
                Agk.Step3DPhysicsWorld();

                App.Log("Program.cs", 1, "main", "Processing " + App.UpdateList.Count.ToString() + " updates in queue");

                foreach (var u in App.UpdateList)
                {
                    if (!App.Status.IsRunning)
                    {
                        break;
                    }
                    if (App.Timing.PauseState != 1 || u.IgnorePause)
                    {
                        App.Log("Program.cs", 1, "main", "Process from queue " + u.FunctionName);

                        Dispatcher.Invoke(u.FunctionName, null);
                    }
                }
                if (!App.Status.IsRunning)
                {
                    break;
                }

                Agk.Print(Agk.ScreenFPS().ToString() + " " + App.Timing.Delta.ToString());
                Agk.Print("Camera: " + Controls3d.ActiveCamera.Name);
                Agk.Print("Cam Pos: " + Controls3d.ActiveCamera.Position.X + ", " + Controls3d.ActiveCamera.Position.Y + ", " + Controls3d.ActiveCamera.Position.Z);
                Agk.Print("Cam P/T: " + Controls3d.ActiveCamera.Phi + ", " + Controls3d.ActiveCamera.Theta);
                Agk.Print(CharacterHandler3d.MyCharacter.Properties.Position.AsString());
                Agk.Print(CharacterHandler3d.MyCharacter.Properties.Heading.ToString() + " " + CharacterHandler3d.MyCharacter.Properties.Facing.ToString());
                Agk.Print(CharacterHandler3d.MyCharacter.Properties.Speed.ToString());

                Agk.Print("Press C to toggle active camera");
                Agk.Print("F1 to debug light");
                Agk.Print("Esc to quit");

                /*
                 * var anim = CharacterHandler3d.MyCharacter.AnimationQ.First();
                 * Agk.Print(anim.Animation.Name);
                 *
                 * string animName = Agk.GetObjectAnimationName((uint)anim.Owner.Properties.ResourceNumber, 1);
                 * float totalTime = Agk.GetObjectAnimationDuration((uint)anim.Owner.Properties.ResourceNumber, animName);
                 * int totalFrame = (int)Math.Floor(totalTime * anim.Animation.Framerate);
                 * float animTime = (anim.CurrentFrame * totalTime) / totalFrame;
                 *
                 * Agk.Print(Math.Floor((double)anim.CurrentFrame).ToString() + " / " + totalFrame.ToString());
                 * Agk.Print(animTime.ToString("0.00") + " / " + totalTime.ToString("0.00"));
                 */

                App.Sync();
            }

            App.CleanUp();
        }