CellComponent.cs
using System;
namespace Battlebugs;
public sealed class CellComponent : Component
{
[Property] ModelRenderer Renderer { get; set; }
public BoardManager Board { get; set; }
public Vector2 Position { get; set; }
public bool IsHovering { get; private set; } = false;
public bool IsSelected { get; set; } = false;
[Sync] public bool WasOccupied { get; set; } = false;
[Sync] public bool IsOccupied { get; set; } = false;
[Sync] public bool IsHit { get; set; } = false;
[Sync] bool IsOdd { get; set; } = false;
Color BaseColor => IsOdd ? Color.White : Color.Gray;
protected override void OnStart()
{
WorldRotation = new Angles( 0, Random.Shared.Int( 0, 3 ) * 90f + Random.Shared.Float( -3f, 3f ), 0 );
UpdateHighlight();
}
public void Init( BoardManager board, Vector2 position, int index )
{
Board = board;
Position = position;
IsOdd = index % 2 == 0;
}
public void MousePressed()
{
}
public void MouseReleased()
{
}
public void MouseEnter()
{
IsHovering = true;
var bugs = Scene.GetAllComponents<BugSegment>();
var cellBug = bugs.FirstOrDefault( x => x.Cell == this );
if ( cellBug is not null )
{
bugs = bugs.Where( x => x.GameObject.Name == cellBug.GameObject.Name ).ToList();
foreach ( var bug in bugs )
{
bug.AddHighlight( Color.Red );
}
}
if ( IsSelected ) return;
UpdateHighlight();
}
public void MouseExit()
{
IsHovering = false;
var bugs = Scene.GetAllComponents<BugSegment>();
var cellBug = bugs.FirstOrDefault( x => x.Cell == this );
if ( cellBug is not null )
{
bugs = bugs.Where( x => x.GameObject.Name == cellBug.GameObject.Name ).ToList();
foreach ( var bug in bugs )
{
bug.RemoveHighlight();
}
}
if ( IsSelected ) return;
UpdateHighlight();
}
public void Select()
{
IsSelected = true;
PlacementInput.Instance.SelectedCells.Add( this );
Sound.Play( "ui-select" );
foreach ( var cell in PlacementInput.Instance.SelectedCells )
{
cell.UpdateHighlight();
}
}
public void Deselect( bool remove = true )
{
IsSelected = false;
if ( remove )
{
PlacementInput.Instance.SelectedCells.Remove( this );
Sound.Play( "ui-select-bug" );
UpdateHighlight();
}
foreach ( var cell in PlacementInput.Instance.SelectedCells )
{
cell.UpdateHighlight();
}
}
public bool IsAdjacent( CellComponent other )
{
// Above/below
if ( Position.x == other.Position.x && MathF.Abs( Position.y - other.Position.y ) == 1 )
return true;
// Left/right
if ( Position.y == other.Position.y && MathF.Abs( Position.x - other.Position.x ) == 1 )
return true;
return false;
}
public List<CellComponent> GetNeighbors()
{
var neighbors = new List<CellComponent>();
var cells = Scene.GetAllComponents<CellComponent>();
foreach ( var cell in cells )
{
if ( cell == this ) continue;
if ( IsAdjacent( cell ) )
{
neighbors.Add( cell );
}
}
return neighbors;
}
void UpdateHighlight()
{
if ( IsHit )
{
Renderer.Tint = Color.Lerp( BaseColor, IsOccupied ? Color.Orange : (WasOccupied ? Color.Green : Color.Red), 0.95f );
}
else if ( IsSelected )
{
var color = Color.Yellow;
var placing = PlacementInput.Instance.AttemptingToPlace;
if ( placing is not null )
{
if ( BoardManager.Local.BugInventory.FirstOrDefault( x => x.Key.ResourcePath == placing.ResourcePath ).Value <= 0 ) color = Color.Yellow;
else color = placing.Color;
}
Renderer.Tint = Color.Lerp( BaseColor, color, 0.8f );
}
else if ( IsHovering )
{
Renderer.Tint = IsOccupied ? Color.Lerp( BaseColor, Color.Red, 0.95f ) : Color.Lerp( BaseColor, Color.Yellow, 0.95f );
}
else
{
Renderer.Tint = BaseColor;
}
}
[Rpc.Owner]
public void BroadcastHit()
{
if ( !IsHit && Random.Shared.Float() < 0.3f )
{
var otherBoard = Scene.GetAllComponents<BoardManager>().FirstOrDefault( x => x.Network.OwnerId != Network.OwnerId );
otherBoard.GiveCellCoins( WorldPosition );
}
IsHit = true;
BroadcastUpdateHighlight();
}
[Rpc.Owner]
public void BroadcastClear()
{
if ( IsProxy ) return;
IsHit = true;
WasOccupied = IsOccupied;
IsOccupied = false;
BroadcastUpdateHighlight();
}
[Rpc.Broadcast]
public void BroadcastUpdateHighlight()
{
UpdateHighlight();
if ( IsHit && !Network.IsOwner && BoardManager.Local.IsValid() )
{
if ( IsOccupied )
HintPanel.Instance.YellowCellNotification();
else if ( !WasOccupied )
HintPanel.Instance.RedCellNotification();
else
HintPanel.Instance.GreenCellNotification();
}
}
}