// Update is called once per frame void Update() { // Keep the list of attached cards updated m_attachedCards = gameObject.GetComponentsInChildren <Card>(); // Determine if there are some attached cards if (m_attachedCards.Length > 0) { // Need to turn off snap collision if there is at least one card on it // (fixes bug for clicking snaps instead of cards) if (m_snapCollider.enabled) { m_snapCollider.enabled = false; } float yOffsetSum = 0.0f; // If there are then we need to iterate them to perform some preprocesing steps for (int i = 0; i < m_attachedCards.Length; i++) { Card card = m_attachedCards[i]; //card.SetStartParent(card.transform.parent); // Need to set each card as non-stackable except for the last one in the stack card.SetStackable(i == m_attachedCards.Length - 1); // Need to flip the last card in the stack face up if it's face down (only applies to Tableau) if (i == m_attachedCards.Length - 1 && belongingSection.Equals(GameManager.Sections.TABLEAU) && !m_waiting) { // Only flip it face up if it's face down and the previous card move was valid if (card.IsFaceDown() && !card.IsAnimating()) { card.Flip(); // Stage the event Event evt = new Event(); evt.SetType(Event.EventType.FLIP); evt.SetCard(card); // Setting relative snap manager to this instance for locking when reversing event evt.SetRelativeSnapManager(this); GameManager.Instance.AddEventToLastMove(evt); } } else if (belongingSection.Equals(GameManager.Sections.STOCK) && !card.IsFaceDown()) { card.Flip(false); } else if (belongingSection.Equals(GameManager.Sections.TALON) && card.IsFaceDown()) { card.Flip(false); } bool belongsToTableau = belongingSection.Equals(GameManager.Sections.TABLEAU); float targetX = transform.position.x; float targetY = transform.position.y - (belongsToTableau ? yOffsetSum : 0); // Give precedence to translating cards so that there isn't any clipping float zOffset = card.IsFlipping() ? GameManager.Z_OFFSET_DRAGGING / 2.0f : GameManager.Z_OFFSET_DRAGGING; float targetZ = card.IsFlipping() || card.IsTranslating() ? -(zOffset + i) : -i; // Normalize x-pos, y-pos, and z-pos to ensure that all cards remain in the proper location if (card.transform.position.x != targetX || card.transform.position.y != targetY || card.transform.position.z != targetZ) { card.transform.position = new Vector3( targetX, targetY, targetZ ); } // Track the sum of y offset so that the proper y offset can be applied to the next card yOffsetSum += card.IsFaceDown() ? GameManager.FACE_DOWN_Y_OFFSET : GameManager.FOUNDATION_Y_OFFSET; card.SetStartPos(card.transform.position); } } else { // Turn snap collision back on if there are no cards attached if (!m_snapCollider.enabled) { m_snapCollider.enabled = true; } } }
/** * Move this card instance and/or other cards in it's card set to the specified target snap transform * @param Transform snap the target snap transform to move this card to * @param Card[] cardSet the set of dragged cards to handle translation all at once * with respect to this card instance. Defaults to null if a card set is not provided. * If the card set has only one card in it then it's assumed that the one card is * this card instance and will be processed as such. * @param MoveTypes moveType the type of move that determines how the move should be tracked in the GameManager. */ public void MoveTo(Transform snap, Card[] cardSet = null, Move.MoveTypes moveType = Move.MoveTypes.NORMAL) { // Prepare the move object m_move = new Move(); m_moveType = moveType; // Set the target card based on value of card set // (if card set is null then create a new card set with this card as the only element) m_move.SetCards(cardSet ?? (new Card[] { this })); // We know that the card has/had a parent m_move.SetPreviousParent(m_startParent); // Need to get what the snap belongs to so that the card is placed in the correct location SnapManager snapManager = snap.GetComponent <SnapManager>(); bool faceDownTarget = snapManager.HasCard() && snapManager.GetTopCard().IsFaceDown(); GameManager.Sections targetSection = snapManager.belongingSection; // Set the next parent in the move m_move.SetNextParent(snapManager.transform); // Need to target the top card in the respective tableau pile and offset the y and z positions Transform tableauHasCardTarget = targetSection.Equals(GameManager.Sections.TABLEAU) && snapManager.HasCard() ? snapManager.GetTopCard().transform : snap; // Setting for reference to new parent snap m_targetTranslateSnap = snap; m_targetTranslatePos = m_targetTranslateSnap.position; // Defaults to target snap position // Keep track of the starting position m_startPos = transform.position; m_draggedCards = cardSet; // Tell the snap manager currently associated with the card(s) to wait until animations are complete SnapManager currentSnap = GetComponentInParent <SnapManager>(); if (currentSnap != null) { // Set the start parent here so that the current snap can be told to stop waiting later SetStartParent(currentSnap.transform); currentSnap.SetWaiting(true); } // Process a bit differently if a card set has been provided if (m_draggedCards != null && m_draggedCards.Length > 1) { // Do a first pass-through to remove parent and bring z-value of each of the dragged cards // to the z-offset dragging value for (int i = 0; i < m_draggedCards.Length; i++) { Card draggedCard = m_draggedCards[i]; draggedCard.transform.parent = null; // Keep track of each card's starting position draggedCard.SetStartPos(draggedCard.transform.position); float yOffset; // Apply y-offset when dragging multiple cards (start without y-offset if there isn't a card on the snap) // Handle case when action was an undo and the top card in the target snap is facedown // (only the first card in the the set of dragged cards should have the face down y-offset applied in this case). if (faceDownTarget && i == 0) { yOffset = GameManager.FACE_DOWN_Y_OFFSET; } else { if (faceDownTarget) { // Need to compensate for the fact that the first card applied face down y-offset yOffset = (GameManager.FOUNDATION_Y_OFFSET * i) + GameManager.FACE_DOWN_Y_OFFSET; } else { // Process normally (e.g., not undoing a flip event) yOffset = GameManager.FOUNDATION_Y_OFFSET * (snapManager.HasCard() ? i + 1 : i); } } Vector3 newTargetPos = new Vector3( tableauHasCardTarget.position.x, tableauHasCardTarget.position.y - yOffset, tableauHasCardTarget.position.z - (i + 1) ); // Set the new translate position for the dragged card draggedCard.SetTargetTranslatePosition(newTargetPos); // Set the z-value of the transform to move to be high enough to hover over all other cards draggedCard.transform.position = new Vector3( draggedCard.transform.position.x, draggedCard.transform.position.y, -(GameManager.Z_OFFSET_DRAGGING + i) ); } } else // Otherwise, process on one card { // transform position is a special case for the Tableau cards due to y-offset in addition to z-offset if (targetSection.Equals(GameManager.Sections.TABLEAU) && snapManager.HasCard()) { Vector3 newTargetPos = new Vector3( tableauHasCardTarget.position.x, tableauHasCardTarget.position.y - (faceDownTarget ? GameManager.FACE_DOWN_Y_OFFSET : GameManager.FOUNDATION_Y_OFFSET), tableauHasCardTarget.position.z - 1 ); m_targetTranslatePos = newTargetPos; } transform.parent = null; // Temporarily detatch from the parent SetStartPos(transform.position); // Keep track of this card instance start position // Set the z-value of the transform to move to be high enough to hover over all other cards transform.position = new Vector3( transform.position.x, transform.position.y, -GameManager.Z_OFFSET_DRAGGING ); } // Add the move to the game manager instance (only if normal move and not undone or redone) if (moveType == Move.MoveTypes.NORMAL) { GameManager.Instance.AddMove(m_move, moveType); } // Track the total number of moves with stats manager StatsManager.Instance.TallyMove(); // Begin the translating animation m_translating = true; }