cards/CardPolice.cs
using Sandbox;
using System.Threading.Tasks;
public class CardPolice : Card
{
public override bool IsAlive => true;
public override void Init(CardType cardType)
{
base.Init(cardType);
HP = GetMaxHP( CardType );
}
public override bool ShouldHandleEvent( EventType eventType )
{
return (eventType == EventType.LevelStartBoss && CardTypeID == 0) || ( eventType == EventType.Mismatch && Manager.Instance.ChosenCards.Contains( this ) && !Manager.Instance.IsMismatchALockedMatch) || eventType == EventType.HurtCards && Manager.Instance.ChosenCards[1] == this;
}
public override async Task HandleEventAsync( EventType eventType )
{
if ( eventType == EventType.LevelStartBoss )
{
var camera = Scene.Camera;
var ray = camera.ScreenPixelToRay( new Vector3( Screen.Width / 2, Screen.Height * 0.65f, 0f ) );
var tr = Scene.Trace.Ray( ray, 10000f ).Run();
Manager.Instance.SpawnFloaterImage(
pos: tr.EndPosition,
filename: Card.GetIconFilename( CardType.Police ),
lifetime: 1f,
velocity: new Vector2( 0f, 100f ),
deceleration: 0.5f
);
Manager.Instance.SpawnFloaterText(
pos: tr.EndPosition + new Vector3( 0f, -70f, 0f ),
text: $"Boss",
emojiText: "",
lifetime: 1f,
color: new Color( 1f, 1f, 1f ),
velocity: new Vector2( 0f, 100f ),
deceleration: 0.5f,
fontSize: 45f
);
Manager.Instance.SpawnFloaterText(
pos: tr.EndPosition + new Vector3( 0f, -86f, 0f ),
text: $"{Card.GetName( CardType.Police )}",
emojiText: "",
lifetime: 1f,
color: new Color( 0.4f, 0.4f, 1f ),
velocity: new Vector2( 0f, 100f ),
deceleration: 0.5f,
fontSize: 60f
);
var hpText = "";
for ( int i = 0; i < Card.GetMaxHP( CardType.Police ); i++ )
hpText += "❤️";
Manager.Instance.SpawnFloaterText(
pos: tr.EndPosition + new Vector3( 0f, -103f, 0f ),
text: $"",
emojiText: hpText,
lifetime: 1f,
color: new Color( 1f, 1f, 1f ),
velocity: new Vector2( 0f, 100f ),
deceleration: 0.5f,
fontSize: 35f
);
Manager.Instance.PlaySfxCenter( "police_siren", volume: 0.7f, pitch: Game.Random.Float( 0.9f, 0.95f ) );
await Task.DelayRealtime( 875 );
}
else if (eventType == EventType.Mismatch)
{
var nearbyCards = Manager.Instance.GetNearbyCards( GridPos ).Where( x => !x.IsRevealed ).ToList();
if ( nearbyCards.Count == 0 )
return;
Manager.Instance.PushEventMessage( this, eventType );
await Task.DelayRealtime( 150 );
Manager.Instance.PlayCardSfx( "police_radio", this, volume: 1.2f, pitch: Game.Random.Float( 0.95f, 1.05f ) );
await Task.DelayRealtime( 150 );
Card cardToReveal = nearbyCards[Game.Random.Int( 0, nearbyCards.Count - 1 )]; ;
await Manager.Instance.RevealCard( cardToReveal );
await Task.DelayRealtime( 600 );
//Manager.Instance.PlayCardSfx( "police_radio", this, volume: 1.2f, pitch: Game.Random.Float( 0.95f, 1.05f ) );
await Task.DelayRealtime( 250 );
Manager.Instance.HideCard( cardToReveal );
await Task.DelayRealtime( 250 );
await Manager.Instance.LockCard( cardToReveal, 2 );
await Task.DelayRealtime( 200 );
Manager.Instance.PopEventMessage();
}
else if(eventType == EventType.HurtCards)
{
if( HP > 0 )
{
Manager.Instance.PushEventMessage( this, eventType );
await Task.DelayRealtime( 300 );
List<Card> cardsToShuffle = new() { Manager.Instance.ChosenCards[1], Manager.Instance.ChosenCards[0] };
// todo: if no nearby cards, it doesnt shuffle at all
// either shuffle with non-nearby cards, or change description
var nearbyCards1 = Manager.Instance.GetNearbyCards( Manager.Instance.ChosenCards[1].GridPos ).Where( x => !x.IsRevealed ).ToList();
nearbyCards1.Shuffle();
for ( int i = 0; i < Math.Min( 2, nearbyCards1.Count() ); i++ )
{
cardsToShuffle.Add( nearbyCards1[i] );
await Manager.Instance.LockCard( nearbyCards1[i], 1 );
}
var nearbyCards0 = Manager.Instance.GetNearbyCards( Manager.Instance.ChosenCards[0].GridPos ).Where( x => !x.IsRevealed && !nearbyCards1.Contains(x) ).ToList();
nearbyCards0.Shuffle();
for ( int i = 0; i < Math.Min( 2, nearbyCards0.Count() ); i++ )
{
cardsToShuffle.Add( nearbyCards0[i] );
await Manager.Instance.LockCard( nearbyCards0[i], 1 );
}
if ( nearbyCards0.Count > 0 || nearbyCards1.Count > 0 )
{
await Task.DelayRealtime( 200 );
Manager.Instance.PlayCardSfx( "police_radio", this, volume: 1.3f, pitch: Game.Random.Float( 0.98f, 1.05f ) );
await Task.DelayRealtime( 100 );
MoveToPos( Manager.GetCardPos( this.GridPos ).WithZ( 100f ), 0.2f, EasingType.SineOut );
await Task.DelayRealtime( 200 );
Manager.Instance.HideCard( Manager.Instance.ChosenCards[1] );
await Task.DelayRealtime( Game.Random.Int( 0, 150 ) );
Manager.Instance.HideCard( Manager.Instance.ChosenCards[0] );
// todo: move sfx
// move other cards to self
int cardNum = 0;
foreach ( var card in cardsToShuffle )
{
if ( card == this )
continue;
card.MoveToPos( Manager.GetCardPos( this.GridPos ).WithZ( 50f - cardNum * 0.2f ), 0.6f, EasingType.SineInOut );
cardNum++;
}
await Task.DelayRealtime( 700 );
Manager.Instance.PlayCardSfx( "card_flip", this, volume: 0.9f, pitch: Game.Random.Float( 0.65f, 0.75f ) );
await Task.DelayRealtime( 200 );
MoveToPos( Manager.GetCardPos( GridPos ).WithZ( Game.Random.Float( 48f, 50f ) ), 0.2f, EasingType.SineOut );
await Task.DelayRealtime( 200 );
List<IntVector2> newGridPositions = new();
foreach ( var card in cardsToShuffle )
newGridPositions.Add( card.GridPos );
newGridPositions.Shuffle();
foreach ( var card in cardsToShuffle )
Manager.Instance.RemoveCardGridPos( card );
Manager.Instance.PlayCardSfx( "police_radio", this, volume: 1.3f, pitch: Game.Random.Float( 0.88f, 0.94f ) );
await Task.DelayRealtime( 200 );
// todo: move sfx
// move self and others to new positions
int count = 0;
foreach ( Card card in cardsToShuffle )
{
card.MoveToPos( Manager.GetCardPos( newGridPositions[count] ).WithZ( Globals.CARD_DEFAULT_HEIGHT + (card.IsRevealed ? Globals.CARD_ADD_HEIGHT_REVEALED_OR_HOVERED : 0f) ), 0.6f, EasingType.QuadInOut );
count++;
}
await Task.DelayRealtime( 700 );
count = 0;
foreach ( Card card in cardsToShuffle )
{
await Manager.Instance.SetCardGridPos( card, newGridPositions[count] );
card.IsMovementControlled = false;
count++;
}
await Task.DelayRealtime( 200 );
Manager.Instance.PopEventMessage();
await Manager.Instance.EventHappened( EventType.AfterCardsMoved );
}
else
{
await Task.DelayRealtime( 1200 );
Manager.Instance.PopEventMessage();
}
}
else
{
await Task.DelayRealtime( 800 );
// todo: death sfx
}
}
}
public override string GetEventText( EventType eventType )
{
if ( eventType == EventType.Mismatch )
{
return "❌Mismatch: Reveal and lock a nearby card for 2 turns";
}
else
{
return "💔Damage Police: Lock some nearby cards for 1 turn, then shuffle";
}
}
public override void PlayHurtSfx( Card card0, Card card1 )
{
Manager.Instance.PlayCardSfxBetween( "police_hurt", card0, card1, volume: 1.5f, pitch: Utils.Map(HP, GetMaxHP(CardType), 0, 1.2f, 0.7f));
}
}