Example #1
0
    IEnumerator MakeMoveCoroutine(Move move, System.Action callback)
    {
        var pawnDisplay = GetPawnDisplay(move.PawnPos);
        var pawn        = pawnDisplay.Pawn;

        var newPos = move.NewPos.ToVector2();

        pawnDisplay.MoveToFront();

        var movementCoroutine = MovementCoroutines.SmoothlyMove(pawnDisplay.transform.position, newPos, 0.5f);

        foreach (var pos in movementCoroutine)
        {
            pawnDisplay.transform.position = pos;
            yield return(new WaitForEndOfFrame());
        }

        pawnDisplay.MoveToBack();
        pawnDisplay.transform.position = newPos;

        if (move.NewPos.y == 0 && Gameplay.Instance.LowerPawnsColor != pawn.Color ||
            move.NewPos.y == 7 && Gameplay.Instance.LowerPawnsColor == pawn.Color)
        {
            pawnDisplay.SetKing();
        }

        if (move.IsATake)
        {
            var takenPawn = GetPawnDisplay(move.TakePos.Value, tryGet: true);
            pawns.Remove(takenPawn);
            takenPawn.TakeDown();
        }

        callback();
    }
Example #2
0
    IEnumerator ResetCamera(float Duration, Vector3 newCamPosition = default(Vector3))
    {
        IsMovingInternal = true;

        StartCoroutine(
            MovementCoroutines.MoveLerpTo(gameObject, newCamPosition, Duration)
            );
        StartCoroutine(
            MovementCoroutines.MoveLerpLocalTo(
                CameraObject,
                new Vector3(0, 0, OriginalZoomAxis),
                Duration
                )
            );

        Quaternion OriginalVerticalQuat   = Quaternion.Euler(new Vector3(OriginalVerticalAxis, 0, 0));
        Quaternion OriginalHorizontalQuat = Quaternion.Euler(new Vector3(0, OriginalHorizontalAxis, 0));

        StartCoroutine(
            MovementCoroutines.RotateLerpLocalTo(VerticalRig, OriginalVerticalQuat, Duration)
            );
        StartCoroutine(
            MovementCoroutines.RotateLerpTo(gameObject, OriginalHorizontalQuat, Duration)
            );

        ZoomAxis       = OriginalZoomAxis;
        VerticalAxis   = OriginalVerticalAxis;
        HorizontalAxis = OriginalHorizontalAxis;
        ElevateAxis    = OriginalElevateAxis;

        yield return(new WaitForSeconds(Duration));

        IsMovingInternal = false;
    }
Example #3
0
        public float GoTo(Vector3 position)
        {
            IsActionLocked = true;
            Timing.KillCoroutines(MovementCoroutines.ToArray());
            Vector3 heading = (position - NPCPlayer.Position);

            heading.y = 0;
            Quaternion lookRot = Quaternion.LookRotation(heading.normalized);
            float      dist    = heading.magnitude;

            NPCPlayer.Rotations = new Vector2(lookRot.eulerAngles.x, lookRot.eulerAngles.y);
            Move(MovementDirection.FORWARD);
            float eta = Plugin.Instance.Config.MovementUpdateFrequency * (dist / (NPCPlayer.CameraTransform.forward / 10 * MovementSpeed).magnitude);

            position.y = NPCPlayer.Position.y;
            MovementCoroutines.Add(Timing.CallDelayed(eta, () =>
            {
                Move(MovementDirection.NONE);
                if (Vector3.Distance(NPCPlayer.Position, position) >= 2f)
                {
                    NPCPlayer.ReferenceHub.playerMovementSync.OverridePosition(position, 0f, true);
                }
                IsActionLocked = false;
            }));
            return(eta);
        }
Example #4
0
 public void Stop()
 {
     ClearNavTargets();
     FollowTarget             = null;
     CurrentAIRoomTarget      = null;
     CurrentAIItemNodeTarget  = null;
     CurrentAIItemGroupTarget = null;
     Timing.KillCoroutines(MovementCoroutines.ToArray());
     Move(MovementDirection.NONE);
 }
Example #5
0
        private void OnDestroy()
        {
            Dictionary.Remove(this.gameObject);
            Timing.KillCoroutines(MovementCoroutines.ToArray());
            Timing.KillCoroutines(AttachedCoroutines.ToArray());

            Log.SendRaw($"NPC {NPCPlayer.Nickname} ({NPCPlayer.Id}) deconstructed", ConsoleColor.Green);

            Player.IdsCache.Remove(NPCPlayer.Id);
            Player.Dictionary.Remove(NPCPlayer.GameObject);
        }
Example #6
0
    //Move Tween
    IEnumerator MoveTo(Vector3 Point, float Duration)
    {
        IsMovingInternal = true;

        StartCoroutine(
            MovementCoroutines.MoveLerpTo(gameObject, Point, Duration)
            );

        yield return(new WaitForSeconds(Duration));

        IsMovingInternal = false;
    }
Example #7
0
    public IEnumerator Spawn(EnemySpawn Spawn)
    {
        GameObject   EnemyObject = Instantiate(Spawn.Prefab, Spawn.MovePath[0].position, Spawn.MovePath[0].rotation) as GameObject;
        EnemyHandler Enemy       = EnemyObject.GetComponent <EnemyHandler>();

        Master.Enemies.Add(Enemy);
        for (int i = 1; i < Spawn.MovePath.Length - 1; i++)
        {
            yield return(StartCoroutine(
                             MovementCoroutines.MoveLerpWithRotaTo(
                                 EnemyObject,
                                 Spawn.MovePath[i].position,
                                 Spawn.MovePath[i].rotation,
                                 Spawn.LerpTime
                                 )
                             ));
        }
        Enemy.IsQueuedForDestruct = true;
    }
Example #8
0
    IEnumerator ZoomTo(Vector3 Point, float Duration, float ZoomOffset)
    {
        IsMovingInternal = true;

        StartCoroutine(
            MovementCoroutines.MoveLerpTo(gameObject, Point, Duration)
            );
        StartCoroutine(
            MovementCoroutines.MoveLerpLocalTo(
                CameraObject,
                new Vector3(0, 0, ZoomMin + ZoomOffset),
                Duration
                )
            );

        yield return(new WaitForSeconds(Duration));

        ZoomAxis         = ZoomMin + ZoomOffset;
        ElevateAxis      = transform.position.y;
        IsMovingInternal = false;
    }
Example #9
0
        private IEnumerator <float> NavCoroutine()
        {
            Queue <Vector3> FollowTargetPosCache = new Queue <Vector3>();
            int             eta = 0;
            int             dormant_cache_update = 0;

            for (; ;)
            {
                if (FollowTarget != null)
                {
                    if (FollowTarget.IsAlive)
                    {
                        float dist = Vector3.Distance(FollowTarget.Position, NPCPlayer.Position);

                        //If we are far away...
                        if (dist >= Plugin.Instance.Config.MaxFollowDistance)
                        {
                            if (OnTargetLostBehaviour == TargetLostBehaviour.TELEPORT)
                            {
                                //... Teleport to player if allowed
                                NPCPlayer.Position = FollowTarget.Position;
                                eta = 0;
                                FollowTargetPosCache.Clear();
                            }
                            else
                            {
                                //Stop or try to search otherwise

                                FireEvent(new NPCTargetLostEvent(this, FollowTarget));

                                FollowTargetPosCache.Clear();
                                eta = 0;
                                Stop();
                                if (OnTargetLostBehaviour == TargetLostBehaviour.SEARCH)
                                {
                                    Room r = FollowTarget.CurrentRoom;
                                    if (r != null)
                                    {
                                        GotoRoom(r);
                                    }
                                }
                                continue;
                            }
                        }

                        //If target is not near
                        if (dist >= 1.5f)
                        {
                            //Update Pos cache each third tick
                            if (dormant_cache_update > 2)
                            {
                                FollowTargetPosCache.Enqueue(FollowTarget.Position);
                                dormant_cache_update = 0;
                            }
                            dormant_cache_update++;
                        }
                        else
                        {
                            //Otherwise just dont move
                            FollowTargetPosCache.Clear();
                            eta = 0;
                            Timing.KillCoroutines(MovementCoroutines.ToArray());
                            Move(MovementDirection.NONE);
                        }
                    }
                    else
                    {
                        // Target dead, reset
                        FollowTargetPosCache.Clear();
                        eta = 0;
                        FireEvent(new NPCFollowTargetDiedEvent(this, FollowTarget));
                        Stop();
                        continue;
                    }

                    //If we reached predicted target
                    if (eta <= 0)
                    {
                        //Schedule next position
                        if (!FollowTargetPosCache.IsEmpty())
                        {
                            float full_eta = GoTo(FollowTargetPosCache.Dequeue());
                            eta = (int)(full_eta / Plugin.Instance.Config.NavUpdateFrequency) - 1;
                        }
                    }
                    else
                    {
                        eta--;
                    }
                }
                else
                {
                    //Noone to follow, try taking nodes from nav queue

                    eta = 0;
                    FollowTargetPosCache.Clear();

                    if (CurrentNavTarget != null)
                    {
                        IsRunning = !DisableRun;
                        //There is current
                        float distance = Vector3.Distance(CurrentNavTarget.Position, NPCPlayer.Position);

                        if (distance < 3f && (!ProcessSCPLogic || NPCPlayer.Role != RoleType.Scp106))
                        {
                            //Try to open the door if there is one, so we wont collide with it
                            if (CurrentNavTarget.AttachedDoor != null && !CurrentNavTarget.AttachedDoor.NetworkisOpen)
                            {
                                ItemType prev = ItemHeld;
                                bool     open = NPCPlayer.IsBypassModeEnabled || (CurrentNavTarget.AttachedDoor.CheckpointDoor && NPCPlayer.ReferenceHub.characterClassManager.IsAnyScp());
                                if (!open)
                                {
                                    if (!CurrentNavTarget.AttachedDoor.CanBeOpenedWith(ItemHeld))
                                    {
                                        foreach (ItemType keycard in AvailableKeycards)
                                        {
                                            if (CurrentNavTarget.AttachedDoor.CanBeOpenedWith(keycard))
                                            {
                                                ItemHeld = keycard;
                                                open     = true;
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        open = true;
                                    }
                                }
                                if (open)
                                {
                                    //All is good
                                    Timing.KillCoroutines(MovementCoroutines.ToArray());
                                    Move(MovementDirection.NONE);
                                    while (CurrentNavTarget.AttachedDoor.locked)
                                    {
                                        yield return(0f);
                                    }
                                    yield return(Timing.WaitForSeconds(0.2f));

                                    CurrentNavTarget.AttachedDoor.NetworkisOpen = true;
                                    yield return(Timing.WaitForSeconds(0.1f));

                                    GoTo(CurrentNavTarget.Position);
                                    ItemHeld = prev;
                                }
                                else
                                {
                                    //Stop otherwise
                                    Stop();
                                    continue;
                                }
                            }
                        }

                        if (distance < 6)
                        {
                            NavigationNode NextNavTarget = NavigationQueue.First?.Value;

                            NavigationNode lift_node = null;
                            if (NextNavTarget != null)
                            {
                                if (NextNavTarget.AttachedElevator != null)
                                {
                                    lift_node = NextNavTarget;
                                }
                            }
                            //If there is an elevator, try to use it
                            if (CurrentNavTarget.AttachedElevator == null && lift_node != null)
                            {
                                bool val = lift_node.AttachedElevator.Value.Value.IsClosed(lift_node.AttachedElevator.Value.Key);
                                if (val)
                                {
                                    lift_node.AttachedElevator.Value.Value.UseLift();

                                    Timing.KillCoroutines(MovementCoroutines.ToArray());
                                    Move(MovementDirection.NONE);

                                    while (!lift_node.AttachedElevator.Value.Value.operative)
                                    {
                                        yield return(0.0f);
                                    }

                                    GoTo(CurrentNavTarget.Position);
                                }
                            }
                        }

                        if (CurMovementDirection == MovementDirection.NONE)
                        {
                            //Target reached - force position to it so we wont stuck
                            Vector3 forced = new Vector3(CurrentNavTarget.Position.x, NPCPlayer.Position.y, CurrentNavTarget.Position.z);
                            NPCPlayer.ReferenceHub.playerMovementSync.OverridePosition(forced, 0f, true);

                            //If we have AI item target reached, try to find and take item
                            if (CurrentAIItemNodeTarget != null && CurrentAIItemNodeTarget == CurrentNavTarget)
                            {
                                CurrentAIItemNodeTarget = null;
                                IEnumerable <Pickup> pickups = FindObjectsOfType <Pickup>().Where(pk => Vector3.Distance(pk.Networkposition, NPCPlayer.Position) <= 5f);
                                foreach (Pickup p in pickups)
                                {
                                    if (Utils.Utils.CheckItemType(CurrentAIItemGroupTarget, p.ItemId))
                                    {
                                        yield return(Timing.WaitForSeconds(GoTo(p.position)));

                                        TakeItem(p);
                                        break;
                                    }
                                }
                                CurrentAIItemGroupTarget = null;
                            }
                            CurrentNavTarget = null;
                        }
                    }
                    else if (NavigationQueue.Count > 0)
                    {
                        //No current, but there are pending targets
                        CurrentNavTarget = NavigationQueue.First.Value;
                        NavigationQueue.RemoveFirst();
                        if (CurrentNavTarget.AttachedElevator != null && Math.Abs(CurrentNavTarget.AttachedElevator.Value.Key.target.position.y - NPCPlayer.Position.y) > 2f)
                        {
                            CurrentNavTarget.AttachedElevator.Value.Value.UseLift();
                            while (CurrentNavTarget.AttachedElevator.Value.Value.status == Lift.Status.Moving)
                            {
                                yield return(0f);
                            }

                            CurrentNavTarget = null;
                        }
                        else
                        {
                            GoTo(CurrentNavTarget.Position);
                        }
                    }
                    else if (CurrentAIRoomTarget != null)
                    {
                        //No current, no pending - room reached
                        CurrentAIRoomTarget = null;
                    }
                }
                yield return(Timing.WaitForSeconds(Plugin.Instance.Config.NavUpdateFrequency));
            }
        }