cards/CardRock.cs
using Sandbox;
using System.Threading.Tasks;
public class CardRock : Card
{
private Dictionary<IntVector2, Card> _cardBelowPositions = new();
public override bool ValidateStartingGridPos()
{
if ( GridPos.y > 0 )
return true;
int NUM_TRIES = 100;
for ( int i = 0; i < NUM_TRIES; i++ )
{
var newGridPos = Manager.Instance.GetRandomGridPos( except: GridPos );
var otherCard = Manager.Instance.GetCardAtGridPos( newGridPos );
if ( newGridPos.y > 0 && otherCard.CardType != CardType.Chipmunk && otherCard.CardType != CardType.Spider && otherCard.CardType != CardType.Rock && otherCard.CardType != CardType.Balloon && otherCard.CardType != CardType.Pawn )
{
Manager.Instance.SwapCardPositionsNonAsync( this, otherCard );
break;
}
}
return false;
}
public override bool ShouldHandleEvent( EventType eventType )
{
if ( CardType == CardType.Rock && ( eventType == EventType.TurnStart || eventType == EventType.AfterCardsMoved ) )
{
return ShouldFall();
}
if ( CardType == CardType.Gem && eventType == EventType.Match && Manager.Instance.ChosenCards[1] == this )
return true;
return false;
}
public override async Task HandleEventAsync( EventType eventType )
{
if( eventType == EventType.TurnStart || eventType == EventType.AfterCardsMoved )
{
if ( IsRevealed )
{
Manager.Instance.PushEventMessage( this, eventType );
await Task.DelayRealtime( 300 );
}
await Task.DelayRealtime( 300 );
while ( ShouldFall() )
{
Manager.Instance.PlayCardSfx( "card_move", this, volume: 1.1f, pitch: Game.Random.Float( 0.85f, 1.15f ) );
_cardBelowPositions.Clear();
RemoveCurrentGridPositions();
await MoveDownward( this, setGridPos: false );
await MoveDownward( this, setGridPos: true );
await Task.DelayRealtime( 400 );
}
await Task.DelayRealtime( 300 );
if ( IsRevealed )
Manager.Instance.PopEventMessage();
await Manager.Instance.EventHappened( EventType.AfterCardsMoved );
}
else if(eventType == EventType.Match)
{
Manager.Instance.PushEventMessage( this, eventType );
await Task.DelayRealtime( 150 );
Manager.Instance.PlayCardSfxBetween( "gem", Manager.Instance.ChosenCards[0], Manager.Instance.ChosenCards[1], volume: 1.3f, pitch: Game.Random.Float( 0.9f, 1.1f ) );
await Task.DelayRealtime( 50 );
int moneyAmount = 4 + (int)Manager.Instance.Stats[StatType.EarnExtraMoney];
Manager.Instance.SpawnGainMoneyFloater( moneyAmount, WorldPosition );
await Manager.Instance.GainMoney( moneyAmount );
await Task.DelayRealtime( 700 );
Manager.Instance.PopEventMessage();
}
}
bool ShouldFall()
{
var currGridPos = GridPos + new IntVector2( 0, -1 );
while ( Manager.Instance.IsGridPosInBounds( currGridPos ) )
{
var existingCard = Manager.Instance.GetCardAtGridPos( currGridPos );
if ( existingCard != null && existingCard.CantBeMoved )
return false;
if ( Manager.Instance.IsGridPosEmpty( currGridPos ) )
return true;
currGridPos += new IntVector2( 0, -1 );
}
return false;
}
async Task MoveDownward(Card card, bool setGridPos)
{
var gridPosBelow = card.GridPos + new IntVector2( 0, -1 );
Card cardBelow = _cardBelowPositions.ContainsKey( gridPosBelow ) ? _cardBelowPositions[gridPosBelow] : null;
if( setGridPos )
{
await Manager.Instance.SetCardGridPos( card, gridPosBelow );
card.IsMovementControlled = false;
}
else
{
card.MoveToPos( Manager.GetCardPos( gridPosBelow ), 0.3f, EasingType.SineOut );
}
if(cardBelow != null )
{
await MoveDownward(cardBelow, setGridPos);
}
}
void RemoveCurrentGridPositions()
{
var currGridPos = GridPos;
while ( Manager.Instance.IsGridPosInBounds( currGridPos ) )
{
var card = Manager.Instance.GetCardAtGridPos( currGridPos );
_cardBelowPositions.Add( currGridPos, card );
Manager.Instance.RemoveCardGridPos( card );
currGridPos += new IntVector2( 0, -1 );
var cardBelow = Manager.Instance.GetCardAtGridPos( currGridPos );
if ( cardBelow == null )
break;
}
}
}