Carriable/Paintbrush.cs
using System.IO;
using System.Text;
using Braxnet;
using Clover.Items;
using Clover.Persistence;
using Clover.Player;
using Clover.Ui;
using Clover.Utilities;
namespace Clover.Carriable;
[Category( "Clover/Carriable" )]
public class Paintbrush : BaseCarriable
{
[Property] public SoundEvent PaintSound { get; set; }
[Property] public SoundEvent TextureChangeSound { get; set; }
public string CurrentTextureName { get; set; }
public string CurrentTexturePath => $"decals/{CurrentTextureName}.decal";
public override void OnUseDown()
{
var itemColliders = Player.PlayerInteract.InteractCollider.Touching;
foreach ( var itemCollider in itemColliders )
{
if ( itemCollider.GameObject.Components.TryGet<PictureFrame>( out var pictureFrame ) )
{
if ( string.IsNullOrWhiteSpace( CurrentTexturePath ) )
{
Player.Notify( Notifications.NotificationType.Error, "No texture selected" );
return;
}
pictureFrame.TexturePath = CurrentTexturePath;
SoundEx.Play( PaintSound, Player.WorldPosition );
ParticleManager.PoofAt( pictureFrame.WorldPosition );
return;
}
if ( itemCollider.GameObject.Components.TryGet<Pumpkin>( out var pumpkin ) )
{
if ( string.IsNullOrWhiteSpace( CurrentTexturePath ) )
{
Player.Notify( Notifications.NotificationType.Error, "No texture selected" );
return;
}
pumpkin.TexturePath = CurrentTexturePath;
SoundEx.Play( PaintSound, Player.WorldPosition );
ParticleManager.PoofAt( pumpkin.WorldPosition );
return;
}
if ( itemCollider.GameObject.Components.TryGet<SnowmanPiece>( out var snowmanPiece ) )
{
if ( string.IsNullOrWhiteSpace( CurrentTexturePath ) )
{
Player.Notify( Notifications.NotificationType.Error, "No texture selected" );
return;
}
snowmanPiece.TexturePath = CurrentTexturePath;
SoundEx.Play( PaintSound, Player.WorldPosition );
ParticleManager.PoofAt( snowmanPiece.WorldPosition );
return;
}
}
var pos = Player.GetAimingGridPosition();
if ( pos == Vector2Int.Zero )
{
Log.Error( "Invalid position" );
return;
}
var item = Player.World.GetItem<FloorDecal>( pos, 16f );
if ( item != null )
{
if ( string.IsNullOrWhiteSpace( CurrentTexturePath ) || CurrentTexturePath == item.TexturePath )
{
Log.Info( $"Removing decal {item.TexturePath}" );
item.WorldItem.RemoveFromWorld();
}
else
{
Log.Info( $"Updating decal {item.TexturePath} -> {CurrentTexturePath}" );
item.TexturePath = CurrentTexturePath;
item.UpdateDecal();
}
SoundEx.Play( PaintSound, Player.WorldPosition );
ParticleManager.PoofAt( item.WorldPosition );
}
else
{
if ( string.IsNullOrWhiteSpace( CurrentTexturePath ) )
{
Player.Notify( Notifications.NotificationType.Error, "No texture selected" );
return;
}
var playerRotation = World.GetItemRotationFromDirection(
World.Get4Direction( Player.PlayerController.Yaw ) );
Log.Info( $"Spawning decal at {pos} with texture {CurrentTexturePath}" );
/*var newItem = PersistentItem.Create<Persistence.FloorDecal>( Data.ItemData.GetById( "floor_decal" ) );
if ( newItem == null ) throw new System.Exception( "Failed to create floor decal" );
newItem.TexturePath = CurrentTexturePath;
var node = World.SpawnPersistentNode( newItem, pos, playerRotation, World.ItemPlacement.FloorDecal, false );*/
var newPItem = PersistentItem.Create( Data.ItemData.Get( "floor_decal" ) );
newPItem.SetSaveData( "TexturePath", CurrentTexturePath );
WorldItem worldItem;
try
{
worldItem = Player.World.SpawnPlacedItem( newPItem, pos, playerRotation );
}
catch ( System.Exception e )
{
Player.Notify( Notifications.NotificationType.Error, $"Failed to spawn decal: {e.Message}" );
return;
}
SoundEx.Play( PaintSound, Player.WorldPosition );
ParticleManager.PoofAt( worldItem.WorldPosition );
// fade in the decal
/* if ( node is Items.FloorDecal decal2 )
{
decal2.Decal.Modulate = new Godot.Color( 1, 1, 1, 0f );
var tween = GetTree().CreateTween();
tween.TweenProperty( decal2.Decal, "modulate:a", 1f, 0.1f );
} */
}
}
public override string GetUseName()
{
return "Paint";
}
public override IEnumerable<MainUi.InputData> GetInputs()
{
yield return new MainUi.InputData( "WheelUp", "Next texture" );
yield return new MainUi.InputData( "WheelDown", "Previous texture" );
}
protected override void OnStart()
{
CurrentTextureName = Decals.GetAllDecals().FirstOrDefault();
}
protected override void OnFixedUpdate()
{
if ( IsProxy ) return;
if ( Input.MouseWheel.y != 0 )
{
var decals = Decals.GetAllDecals();
if ( !decals.Any() )
{
Player.Notify( Notifications.NotificationType.Error, "No decals found" );
return;
}
var index = decals.IndexOf( CurrentTextureName );
index += Input.MouseWheel.y > 0 ? 1 : -1;
if ( index < 0 ) index = decals.Count - 1;
if ( index >= decals.Count ) index = 0;
CurrentTextureName = decals[index];
if ( string.IsNullOrEmpty( CurrentTextureName ) )
{
Log.Warning( "No texture selected" );
return;
}
Sound.Play( TextureChangeSound );
Log.Info( $"Selected texture: {CurrentTextureName}" );
// Player.Notify( Notifications.NotificationType.Info, $"Selected texture: {CurrentTexture}" );
}
}
}