/** * Take all cards from talon and put them back in the stock */ public void ReplinishStock(MoveTypes moveType = MoveTypes.NORMAL) { SnapManager talonSnapManager = talon.GetComponentInChildren <SnapManager>(); Card[] talonCards = talonSnapManager.GetCardSet(); if (DEBUG_MODE) { Debug.Log("Cards in talon:"); } // Need to iterate in reverse order so that the cards are drawn from the stock in the same order as before for (int i = talonCards.Length - 1; i >= 0; i--) { Card card = talonCards[i]; // Remove from talon card.transform.parent = null; // Move the card position from the talon to the stock card.transform.position = new Vector3( m_stockPile.position.x, m_stockPile.position.y, card.transform.position.z ); // Rotate the card to be face down again card.Flip(false); // Add the card to the stock card.transform.parent = m_stockPile; // Flip the first card from the stock pile over to the talon automatically if (i == 0) { // Don't track this move card.MoveTo(m_talonPile, null, MoveTypes.INCOGNITO); // Need to manually flip card because of not tracking if (card.IsFaceDown()) { card.Flip(); } } } // Track replinish event if (moveType.Equals(MoveTypes.NORMAL)) { Move move = new Move(); move.SetSpecial(true); Event ev = new Event(); ev.SetType(Event.EventType.REPLINISH); move.AddEvent(ev); AddMove(move, MoveTypes.NORMAL); } }
/** * Process undo and redo move actions */ private void ProcessMoveAction(MoveTypes moveType) { bool undoAction = moveType.Equals(MoveTypes.UNDO); CustomStack <Move> targetMoves = undoAction ? m_moves : m_undoneMoves; CustomStack <Move> altMoves = undoAction ? m_undoneMoves : m_moves; // Pop the last move from the moves list/stack Move move = targetMoves.Pop(); if (move.IsSpecial()) { // Special moves should only have one event Event ev = move.GetEvents()[0]; ev.Reverse(); // Swap the event type for proper redo Event.EventType evType = ev.GetEventType(); Event.EventType newEvType = Event.EventType.NONE; switch (evType) { case Event.EventType.REPLINISH: newEvType = Event.EventType.DEPLINISH; break; case Event.EventType.DEPLINISH: newEvType = Event.EventType.REPLINISH; break; } ev.SetType(newEvType); m_blocked = false; } else { // Take precedence over events in the move (execute them first) List <Event> events = move.GetEvents(); foreach (Event evt in events) { // Reverse the event evt.Reverse(); } // Perform the move; don't want to track changes so that undone moves are managed through here move.GetTopCard().MoveTo(undoAction ? move.GetPreviousParent() : move.GetNextParent(), move.GetCards(), moveType); } // Add the move to the redo stack altMoves.Push(move); }
/** * Used for reversing a replinishing event */ public void DeplinishStock(MoveTypes moveType = MoveTypes.NORMAL) { SnapManager stockSnapManager = stock.GetComponentInChildren <SnapManager>(); Card[] stockCards = stockSnapManager.GetCardSet(); for (int i = stockCards.Length - 1; i >= 0; i--) { Card card = stockCards[i]; // Remove from stock card.transform.parent = null; // Move the card position from the stock to the talon card.transform.position = new Vector3( m_talonPile.position.x, m_talonPile.position.y, card.transform.position.z ); // Rotate the card to be face up if (card.IsFaceDown()) { card.Flip(false); } // Add the card to the talon card.transform.parent = m_talonPile; } // Track deplinish event if (moveType.Equals(MoveTypes.NORMAL)) { Move move = new Move(); move.SetSpecial(true); Event ev = new Event(); ev.SetType(Event.EventType.DEPLINISH); move.AddEvent(ev); AddMove(move, MoveTypes.NORMAL); } }
// 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; } } }
private void HandleTranslation() { if (m_translating) { float zOffset = m_flipping ? GameManager.Z_OFFSET_DRAGGING / 2.0f : GameManager.Z_OFFSET_DRAGGING; if (m_draggedCards != null && m_draggedCards.Length > 1) { foreach (Card card in m_draggedCards) { // Ensure that the z-offset is applied to the target translation position to avoid clipping Vector3 modTargetPos = card.GetTargetTranslatePosition(); modTargetPos = new Vector3( modTargetPos.x, modTargetPos.y, -(Mathf.Abs(modTargetPos.z) + zOffset) ); // Use linear interpolation (lerp) to move from point a to point b within a specific amount of time card.transform.position = Vector3.Lerp( card.GetStartPos(), modTargetPos, m_totalTime ); // Stop translating once the total time has elapsed for linear interpolation m_translating = m_totalTime < 1.0f; } } else { // Ensure that the z-offset is applied to the target translation position to avoid clipping Vector3 modTargetPos = new Vector3( m_targetTranslatePos.x, m_targetTranslatePos.y, -(Mathf.Abs(m_targetTranslatePos.z) + zOffset) ); // Use linear interpolation (lerp) to move from point a to point b within a specific amount of time transform.position = Vector3.Lerp( GetStartPos(), modTargetPos, m_totalTime ); // Stop translating once the total time has elapsed for linear interpolation m_translating = m_totalTime < 1.0f; // Only flip card if it's face down and processing normal move if (currentState.Equals(CardState.FACE_DOWN) && m_moveType.Equals(Move.MoveTypes.NORMAL)) { SnapManager targetSnapManager = m_targetTranslateSnap.GetComponent <SnapManager>(); // Flip the card with an animation Flip(); // Stage the event Event evt = new Event(); evt.SetType(Event.EventType.FLIP); evt.SetCard(this); // Setting relative snap manager to this instance for locking when reversing event evt.SetRelativeSnapManager(targetSnapManager); GameManager.Instance.AddEventToLastMove(evt); } } // Accumulate total time with respect to the card translation speed m_totalTime += Time.deltaTime / GameManager.Instance.GetCardTranslationSpeed(); // Perform final steps after translation is complete if (!m_translating) { // Play the card set sound one shot so more than one clip can play at a time SettingsManager.Instance.cardSetSound.PlayOneShot(SettingsManager.Instance.cardSetSoundClip); SnapManager targetSnapManager = m_targetTranslateSnap.GetComponent <SnapManager>(); if (m_draggedCards != null && m_draggedCards.Length > 1) { // Don't need to check current state when dragging more than one card // since the only case when the card is face down is if it came from the // stock pile. foreach (Card card in m_draggedCards) { // Place the card in the respective snap parent (this ensures proper card order) card.transform.parent = m_targetTranslateSnap; // Re-enable the mesh colliders on the cards card.GetComponent <MeshCollider>().enabled = true; } } else { // Only reattach to parent here if this card is not presently flipping if (!m_flipping) { transform.parent = m_targetTranslateSnap; // Re-enable the mesh colliders on this card GetComponent <MeshCollider>().enabled = true; } } // Need to remove any locks and blocks on parent snap manager and game manager instance caused by events targetSnapManager.SetWaiting(false); GameManager.Instance.SetBlocked(false); // Also tell the original snap manager to stop waiting if it is if (m_startParent != null) { m_startParent.GetComponent <SnapManager>().SetWaiting(false); } // Reset the total time for correct linear interpolation (lerp) m_totalTime = 0.0f; } } }