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(); }
/// <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); }
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); }
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(); } }
public void ConnectTo(PiecePrefab other) { if (IsNotYetConnectedTo(other)) { connectedPieces.Add(other); IsFullySurrounded = IsFullySurrounded || CheckIfFullySurrounded(); } }
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); }
/// <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; }
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); }
/// <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; }
/// <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; }
/// <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); } }
/// <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); } }
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); }
//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; }
private bool IsNotYetConnectedTo(PiecePrefab other) { return(!connectedPieces.Contains(other)); }
private void ConnectPieces(PiecePrefab a, PiecePrefab b) { a.ConnectTo(b); b.ConnectTo(a); }
public void MarkPieceInPool(PiecePrefab piece) { _piecesOnBoard.Remove(piece); _gameStateService.RemoveFromPlayField(piece.BoardPosition); }
public void MarkPieceOnPlayField(PiecePrefab piece) { _piecesOnBoard.Add(piece); _gameStateService.AddToPlayField(piece.BoardPosition, piece.transform.position); }
/// <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)); }
public static bool OverlapsToBottom(PiecePrefab a, PiecePrefab b) { return(a.Bottom < b.Top && a.Bottom > (b.Top - ((b.Top - b.Bottom) / 5f))); }
public static bool OverlapsToTop(PiecePrefab a, PiecePrefab b) { return(a.Top > b.Bottom && a.Top < ((b.Top - b.Bottom) / 5f) + b.Bottom); }
public static bool OverlapsToRight(PiecePrefab a, PiecePrefab b) { return(a.Right > b.Left && a.Right < ((b.Right - b.Left) / 5f) + b.Left); }
public static bool OverlapsToLeft(PiecePrefab a, PiecePrefab b) { return(a.Left < b.Right && a.Left > (b.Right - ((b.Right - b.Left) / 5f))); }