private void UpdatePrebuilding(float elapsed)
        {
            if (IsAttacked)
            {
                StopBuilding();
            }

            if (Player.IsIdle)
            {
                // Wait for the player to walk to position. If execute StartCrouch immediately, player will roll instead
                // WaitDestinationReached not working btw
                m_prepareTimer += elapsed;
                if (m_prepareTimer >= 150)
                {
                    Player.AddCommand(new PlayerCommand(PlayerCommandType.StartCrouch));

                    if (m_targetPlaceholder == null)
                    {
                        m_state        = EngineerState.Building;
                        m_prepareTimer = 0f;
                        Actor.CreateNewTurret();
                    }
                    else
                    {
                        // Execute first hit before changing state to occupy placeholder
                        Player.AddCommand(new PlayerCommand(PlayerCommandType.AttackOnce));
                        ScriptHelper.Timeout(() =>
                        {
                            m_state        = EngineerState.Building;
                            m_prepareTimer = 0f;
                        }, HitTime);
                    }
                }
            }
        }
 private void CheckArriveTargetPlaceholder()
 {
     if (m_targetPlaceholder.GetAABB().Intersects(Player.GetAABB()) && Actor.HasEquipment)
     {
         // At the time the builder arrives, another builder may arrived first and already started building
         if (!WeaponManager.GetUntouchedTurretPlaceholders()
             .Where((p) => p.Key == m_targetPlaceholder.UniqueID)
             .Any())
         {
             if (!IsInactive)
             {
                 m_state = EngineerState.Analyzing;
             }
             else
             {
                 if (!ShouldBuildTurretHere())
                 {
                     Player.SetGuardTarget(null);
                     m_state = EngineerState.Normal;
                 }
             }
         }
         else
         {
             StartBuildingTurret(m_targetPlaceholder.Direction);
         }
     }
 }
        private void StopBuilding()
        {
            m_hitTimer          = 0f;
            m_targetPlaceholder = null;

            Player.AddCommand(new PlayerCommand(PlayerCommandType.StopCrouch));
            Player.SetInputEnabled(true);
            m_state = EngineerState.Normal;
        }
        private void GoToExistingPlaceholder()
        {
            var bs = Player.GetBotBehaviorSet();

            Player.SetGuardTarget(m_targetPlaceholder.RepresentedObject);
            bs.GuardRange = 1f;
            bs.ChaseRange = 1f;
            Player.SetBotBehaviorSet(bs);
            m_state = EngineerState.GoingToPlaceholder;
        }
        private void StartBuildingTurret(TurretDirection direction)
        {
            Player.SetInputEnabled(false);
            if (Player.CurrentWeaponDrawn != WeaponItemType.Melee)
            {
                Player.AddCommand(new PlayerCommand(PlayerCommandType.DrawMelee));
            }
            Player.AddCommand(new PlayerCommand(PlayerCommandType.Walk, direction == TurretDirection.Left ?
                                                PlayerCommandFaceDirection.Left : PlayerCommandFaceDirection.Right, 10));

            m_state = EngineerState.PreBuilding;
        }
        public override void OnUpdate(float elapsed)
        {
            Actor.LogDebug(m_state, Actor.BuildProgress);

            switch (m_state)
            {
            case EngineerState.Normal:
                if (Actor.HasEnoughEnergy && Actor.HasEquipment)
                {
                    m_state = EngineerState.Analyzing;
                }
                break;

            case EngineerState.Analyzing:
                if (ScriptHelper.IsElapsed(m_analyzePlaceCooldown, 300))
                {
                    m_analyzePlaceCooldown = Game.TotalElapsedGameTime;

                    if (CheckExistingPlaceholder())
                    {
                        GoToExistingPlaceholder();
                    }
                    else if (ShouldBuildTurretHere())
                    {
                        StartBuildingTurret();
                    }
                }
                break;

            case EngineerState.GoingToPlaceholder:
                CheckArriveTargetPlaceholder();
                break;

            case EngineerState.PreBuilding:
                UpdatePrebuilding(elapsed);
                break;

            case EngineerState.Building:
                UpdateBuildingTurret();
                break;
            }
        }