예제 #1
0
    public void UpdatePositionAndSaveConnections(PiecePrefab piece, IBoardService boardService)
    {
        var uniqueRootPositions = new List <IntVector2>();

        foreach (var connectedPiece in piece.connectedPieces)
        {
            var rootPositionForPiece = _gameState.rootPositionsForEachPiece[connectedPiece.BoardPosition];

            if (!uniqueRootPositions.Contains(rootPositionForPiece))
            {
                uniqueRootPositions.Add(rootPositionForPiece);
            }
        }

        for (int i = 1; i < uniqueRootPositions.Count; ++i)
        {
            MergeRoots(uniqueRootPositions[0], uniqueRootPositions[i]);
        }

        var rootPosition = _gameState.rootPositionsForEachPiece[piece.BoardPosition];

        _gameState.rootsByBoardPosition[rootPosition].worldPosition = boardService.GetWorldPositionForPiece(rootPosition);

        CheckIfWon();
    }
예제 #2
0
        /// <summary>
        ///     Checks if a custom piece is valid (i.e. has a prefab, a target PieceTable is set,
        ///     has a <see cref="global::Piece"/> component and that component has an icon).
        /// </summary>
        /// <returns>true if all criteria is met</returns>
        public bool IsValid()
        {
            bool valid = true;

            if (!PiecePrefab)
            {
                Logger.LogError($"CustomPiece {this} has no prefab");
                valid = false;
            }
            if (!PiecePrefab.IsValid())
            {
                valid = false;
            }
            if (Piece == null)
            {
                Logger.LogError($"CustomPiece {this} has no Piece component");
                valid = false;
            }
            if (Piece.m_icon == null)
            {
                Logger.LogError($"CustomPiece {this} has no icon");
                valid = false;
            }
            if (string.IsNullOrEmpty(PieceTable))
            {
                Logger.LogError($"CustomPiece {this} has no PieceTable");
                valid = false;
            }

            return(valid);
        }
예제 #3
0
    public static bool IsWithinSnappingDistance(PiecePrefab a, PiecePrefab b)
    {
        var adjacency = IsAdjacent(a, b);

        switch (adjacency)
        {
        case Adjacency.ToRight:
        {
            var verticalMatch = IsApproximately(a.transform.position.y, b.transform.position.y, SNAP_TOLERANCE_Y);
            return(verticalMatch && OverlapsToRight(a, b));
        }

        case Adjacency.ToLeft:
        {
            var verticalMatch = IsApproximately(a.transform.position.y, b.transform.position.y, SNAP_TOLERANCE_Y);
            return(verticalMatch && OverlapsToLeft(a, b));
        }

        case Adjacency.ToTop:
        {
            var horizontalMatch = IsApproximately(a.transform.position.x, b.transform.position.x, SNAP_TOLERANCE_X);
            return(horizontalMatch && OverlapsToTop(a, b));
        }

        case Adjacency.ToBottom:
        {
            var horizontalMatch = IsApproximately(a.transform.position.x, b.transform.position.x, SNAP_TOLERANCE_X);
            return(horizontalMatch && OverlapsToBottom(a, b));
        }
        }

        return(false);
    }
예제 #4
0
    public void ConnectPiecesWithinSnappingDistanceTo(PiecePrefab piece)
    {
        if (_piecesWithinSnappingDistance.Count > 0)
        {
            foreach (var pieceToSnap in _piecesWithinSnappingDistance)
            {
                pieceToSnap.HideHighlight();
                var connectedPieces = new List <PiecePrefab>(piece.connectedPieces);
                foreach (var connectedPiece in connectedPieces)
                {
                    SnapToPieceAt(connectedPiece, pieceToSnap);
                    ConnectPieces(connectedPiece, pieceToSnap);
                    connectedPiece.HideHighlight();
                }
            }
        }

        _piecesWithinSnappingDistance.Clear();
        _pieceBeingDragged = new IntVector2(-1, -1);

        _gameStateService.UpdatePositionAndSaveConnections(piece, this);

        if (_gameStateService.HasWon)
        {
            OnPlayerHasWon();
        }
    }
예제 #5
0
 public void ConnectTo(PiecePrefab other)
 {
     if (IsNotYetConnectedTo(other))
     {
         connectedPieces.Add(other);
         IsFullySurrounded = IsFullySurrounded || CheckIfFullySurrounded();
     }
 }
예제 #6
0
        public PlanPiecePrefab(Piece piece) : base(piece.gameObject.name + PlannedSuffix, piece.gameObject.name, PlanHammerPieceTableName)
        {
            this.originalPiece                  = piece;
            Piece.m_name                        = Localization.instance.Localize("$item_plan_piece_name", originalPiece.m_name);
            Piece.m_description                 = Localization.instance.Localize("$item_plan_piece_description", originalPiece.m_name);
            Piece.m_resources                   = new Piece.Requirement[0];
            Piece.m_craftingStation             = null;
            Piece.m_placeEffect.m_effectPrefabs = new EffectList.EffectData[0];
            Piece.m_comfort                     = 0;
            Piece.m_canBeRemoved                = true;

            Piece.m_category                = originalPiece.m_category;
            Piece.m_groundOnly              = originalPiece.m_groundOnly;
            Piece.m_groundPiece             = originalPiece.m_groundPiece;
            Piece.m_icon                    = originalPiece.m_icon;
            Piece.m_inCeilingOnly           = originalPiece.m_inCeilingOnly;
            Piece.m_isUpgrade               = originalPiece.m_isUpgrade;
            Piece.m_haveCenter              = originalPiece.m_haveCenter;
            Piece.m_dlc                     = originalPiece.m_dlc;
            Piece.m_allowAltGroundPlacement = originalPiece.m_allowAltGroundPlacement;
            Piece.m_allowedInDungeons       = originalPiece.m_allowedInDungeons;

            this.PieceTable = PlanHammerPieceTableName;

            WearNTear wearNTear = PiecePrefab.GetComponent <WearNTear>();

            if (wearNTear == null)
            {
                wearNTear = PiecePrefab.AddComponent <WearNTear>();
            }

            wearNTear.m_noSupportWear       = true;
            wearNTear.m_noRoofWear          = false;
            wearNTear.m_autoCreateFragments = false;
            wearNTear.m_supports            = true;
            wearNTear.m_hitEffect           = new EffectList();
            wearNTear.m_destroyedEffect     = new EffectList();
            wearNTear.m_destroyNoise        = 0f;
            wearNTear.m_hitNoise            = 0f;

            PlanPiece planPieceScript = PiecePrefab.AddComponent <PlanPiece>();

            planPieceScript.originalPiece = originalPiece;
            planToOriginalMap.Add(Piece, originalPiece);
            if (logComponents)
            {
                StringBuilder sb = new StringBuilder("Components in prefab: " + PiecePrefab.name + "\n");
                sb.Append("Components in prefab: " + PiecePrefab.name + "\n");
                sb.Append($" Prefab: {PiecePrefab.name} -> {PiecePrefab.gameObject}\n");
                foreach (Component component in PiecePrefab.GetComponents <Component>())
                {
                    sb.Append($" {component.GetType()} -> {component.name}\n");
                }
                Jotunn.Logger.LogWarning(sb.ToString());
            }

            DisablePiece(PiecePrefab);
        }
예제 #7
0
 /// <summary>
 ///     Custom piece created as a copy of a vanilla Valheim prefab.<br />
 ///     Will be added to the <see cref="global::PieceTable"/> provided by name.
 /// </summary>
 /// <param name="name">The new name of the prefab after cloning.</param>
 /// <param name="baseName">The name of the base prefab the custom item is cloned from.</param>
 /// <param name = "pieceTable" >
 ///     Name of the <see cref="global::PieceTable"/> the custom piece should be added to.
 ///     Can by the "internal" or the <see cref="GameObject"/>s name (e.g. "_PieceTableHammer" or "Hammer")
 /// </param>
 public CustomPiece(string name, string baseName, string pieceTable)
 {
     PiecePrefab = PrefabManager.Instance.CreateClonedPrefab(name, baseName);
     if (PiecePrefab)
     {
         Piece = PiecePrefab.GetComponent <Piece>();
     }
     PieceTable = pieceTable;
 }
예제 #8
0
    private void SnapToPieceAt(PiecePrefab pieceToKeepSteady, PiecePrefab pieceToMove)
    {
        var positionDifference = pieceToMove.BoardPosition - pieceToKeepSteady.BoardPosition;

        var delta = new Vector3(positionDifference.x * BoardContext.PieceWidthInWorldUnits,
                                positionDifference.y * BoardContext.PieceHeightInWorldUnits);

        pieceToMove.MoveTo(pieceToKeepSteady.transform.position + delta);
    }
예제 #9
0
 /// <summary>
 ///     Custom piece created as an "empty" primitive.<br />
 ///     Will be added to the <see cref="global::PieceTable"/> provided by name.
 /// </summary>
 /// <param name="name">Name of the new prefab. Must be unique.</param>
 /// <param name="addZNetView">If true a ZNetView component will be added to the prefab for network sync.</param>
 /// <param name = "pieceTable" >
 ///     Name of the <see cref="global::PieceTable"/> the custom piece should be added to.
 ///     Can by the "internal" or the <see cref="GameObject"/>s name (e.g. "_PieceTableHammer" or "Hammer")
 /// </param>
 public CustomPiece(string name, bool addZNetView, string pieceTable)
 {
     PiecePrefab = PrefabManager.Instance.CreateEmptyPrefab(name, addZNetView);
     if (PiecePrefab)
     {
         Piece        = PiecePrefab.AddComponent <Piece>();
         Piece.m_name = name;
     }
     PieceTable = pieceTable;
 }
예제 #10
0
 /// <summary>
 ///     Custom piece from a prefab loaded from an <see cref="AssetBundle"/>.<br />
 ///     Will be added to the <see cref="global::PieceTable"/> provided by name.<br />
 ///     Can fix references from <see cref="Entities.Mock{T}"/>s or not.
 /// </summary>
 /// <param name="assetBundle">A preloaded <see cref="AssetBundle"/></param>
 /// <param name="assetName">Name of the prefab in the bundle.</param>
 /// <param name = "pieceTable" >
 ///     Name of the <see cref="global::PieceTable"/> the custom piece should be added to.
 ///     Can by the "internal" or the <see cref="GameObject"/>s name (e.g. "_PieceTableHammer" or "Hammer")
 /// </param>
 /// <param name="fixReference">If true references for <see cref="Entities.Mock{T}"/> objects get resolved at runtime by Jötunn.</param>
 public CustomPiece(AssetBundle assetBundle, string assetName, string pieceTable, bool fixReference)
 {
     PiecePrefab = (GameObject)assetBundle.LoadAsset(assetName);
     if (PiecePrefab)
     {
         Piece = PiecePrefab.GetComponent <Piece>();
     }
     PieceTable   = pieceTable;
     FixReference = fixReference;
 }
예제 #11
0
        /// <summary>
        ///     Custom piece created as a copy of a vanilla Valheim prefab with a <see cref="PieceConfig"/> attached.<br />
        ///     The members and references from the <see cref="PieceConfig"/> will be referenced by Jötunn at runtime.
        /// </summary>
        /// <param name="name">The new name of the prefab after cloning.</param>
        /// <param name="baseName">The name of the base prefab the custom item is cloned from.</param>
        /// <param name="pieceConfig">The <see cref="PieceConfig"/> for this custom piece.</param>
        public CustomPiece(string name, string baseName, PieceConfig pieceConfig)
        {
            PiecePrefab = PrefabManager.Instance.CreateClonedPrefab(name, baseName);
            if (PiecePrefab)
            {
                Piece      = PiecePrefab.GetComponent <Piece>();
                PieceTable = pieceConfig.PieceTable;
                FixConfig  = true;

                pieceConfig.Apply(PiecePrefab);
            }
        }
예제 #12
0
        /// <summary>
        ///     Custom piece created as an "empty" primitive with a <see cref="PieceConfig"/> attached.<br />
        ///     The members and references from the <see cref="PieceConfig"/> will be referenced by Jötunn at runtime.
        /// </summary>
        /// <param name="name">Name of the new prefab. Must be unique.</param>
        /// <param name="addZNetView">If true a ZNetView component will be added to the prefab for network sync.</param>
        /// <param name="pieceConfig">The <see cref="PieceConfig"/> for this custom piece.</param>
        public CustomPiece(string name, bool addZNetView, PieceConfig pieceConfig)
        {
            PiecePrefab = PrefabManager.Instance.CreateEmptyPrefab(name, addZNetView);
            if (PiecePrefab)
            {
                Piece      = PiecePrefab.AddComponent <Piece>();
                PieceTable = pieceConfig.PieceTable;
                FixConfig  = true;

                pieceConfig.Apply(PiecePrefab);
            }
        }
예제 #13
0
    public static Adjacency IsAdjacent(PiecePrefab a, PiecePrefab b)
    {
        var boardDistance = a.BoardPosition - b.BoardPosition;

        if (boardDistance.x == 0 && (Mathf.Abs(boardDistance.y) == 1))
        {
            return(boardDistance.y > 0 ? Adjacency.ToBottom : Adjacency.ToTop);
        }

        if (boardDistance.y == 0 && (Mathf.Abs(boardDistance.x) == 1))
        {
            return(boardDistance.x > 0 ? Adjacency.ToLeft : Adjacency.ToRight);
        }

        return(Adjacency.None);
    }
예제 #14
0
        //TODO: constructors for cloned / empty prefabs with configs.


        /// <summary>
        ///     Custom piece created as an "empty" primitive.<br />
        ///     Will be added to the <see cref="global::PieceTable"/> provided by name.<br />
        ///     At least the name and the icon of the ItemDrop must be edited after creation.
        /// </summary>
        /// <param name="name">Name of the new prefab. Must be unique.</param>
        /// <param name = "pieceTable" >
        ///     Name of the <see cref="global::PieceTable"/> the custom piece should be added to.
        ///     Can by the "internal" or the <see cref="GameObject"/>s name (e.g. "_PieceTableHammer" or "Hammer")
        /// </param>
        /// <param name="addZNetView">If true a ZNetView component will be added to the prefab for network sync.</param>
        public CustomPiece(string name, string pieceTable, bool addZNetView = true)
        {
            PiecePrefab = PrefabManager.Instance.CreateEmptyPrefab(name, addZNetView);
            if (PiecePrefab)
            {
                Piece = PiecePrefab.AddComponent <Piece>();
                if (name[0] != LocalizationManager.TokenFirstChar)
                {
                    Piece.m_name = LocalizationManager.TokenFirstChar + name;
                }
                else
                {
                    Piece.m_name = name;
                }
            }
            PieceTable = pieceTable;
        }
예제 #15
0
 private bool IsNotYetConnectedTo(PiecePrefab other)
 {
     return(!connectedPieces.Contains(other));
 }
예제 #16
0
 private void ConnectPieces(PiecePrefab a, PiecePrefab b)
 {
     a.ConnectTo(b);
     b.ConnectTo(a);
 }
예제 #17
0
 public void MarkPieceInPool(PiecePrefab piece)
 {
     _piecesOnBoard.Remove(piece);
     _gameStateService.RemoveFromPlayField(piece.BoardPosition);
 }
예제 #18
0
 public void MarkPieceOnPlayField(PiecePrefab piece)
 {
     _piecesOnBoard.Add(piece);
     _gameStateService.AddToPlayField(piece.BoardPosition, piece.transform.position);
 }
예제 #19
0
 /// <summary>
 ///     Checks if a custom piece is valid (i.e. has a prefab, a target PieceTable is set,
 ///     has a <see cref="global::Piece"/> component and that component has an icon set).
 /// </summary>
 /// <returns>true if all criteria is met</returns>
 public bool IsValid()
 {
     return(PiecePrefab && PiecePrefab.IsValid() && Piece && Piece.IsValid() && !string.IsNullOrEmpty(PieceTable));
 }
예제 #20
0
 public static bool OverlapsToBottom(PiecePrefab a, PiecePrefab b)
 {
     return(a.Bottom < b.Top && a.Bottom > (b.Top - ((b.Top - b.Bottom) / 5f)));
 }
예제 #21
0
 public static bool OverlapsToTop(PiecePrefab a, PiecePrefab b)
 {
     return(a.Top > b.Bottom && a.Top < ((b.Top - b.Bottom) / 5f) + b.Bottom);
 }
예제 #22
0
 public static bool OverlapsToRight(PiecePrefab a, PiecePrefab b)
 {
     return(a.Right > b.Left && a.Right < ((b.Right - b.Left) / 5f) + b.Left);
 }
예제 #23
0
 public static bool OverlapsToLeft(PiecePrefab a, PiecePrefab b)
 {
     return(a.Left < b.Right && a.Left > (b.Right - ((b.Right - b.Left) / 5f)));
 }