Objects/GiftCarrier.cs
using System;
using Braxnet;
using Clover.Data;
using Clover.Interfaces;
using Clover.Persistence;
namespace Clover.Objects;
public class GiftCarrier : Component, IShootable
{
[Property] public float Speed = 50f;
[Property] public GameObject GiftInHolderVisual { get; set; }
// [Property] public GameObject GiftFallingScene { get; set; }
[Property] public GameObject GiftModelSpawn { get; set; }
[Property] public ItemData GiftItem { get; set; }
[Property] public SoundEvent WingSound { get; set; }
public List<PersistentItem> Items { get; set; } = new();
private bool _hasDroppedGift;
private SoundHandle _wingSoundHandle;
protected override void OnStart()
{
_wingSoundHandle = GameObject.PlaySound( WingSound );
}
protected override void OnDestroy()
{
_wingSoundHandle?.Stop();
}
protected override void OnFixedUpdate()
{
WorldPosition += WorldRotation.Forward * Speed * Time.Delta;
if ( WorldPosition.x < -1000 || WorldPosition.x > 5000 || WorldPosition.z < -1000 || WorldPosition.z > 5000 )
{
DestroyGameObject();
}
}
public static void SpawnRandom()
{
Log.Info( "Spawning random gift carrier" );
var world = NodeManager.WorldManager.GetWorld( "island" );
if ( world == null )
{
Log.Error( "No active world" );
return;
}
var giftCarrierGameObject = SceneUtility.GetPrefabScene(
ResourceLibrary.Get<PrefabFile>( "objects/stork/stork.prefab" )
)
.Clone();
giftCarrierGameObject.SetParent( world.GameObject );
var worldLayerObject = giftCarrierGameObject.GetComponent<WorldLayerObject>();
worldLayerObject.Layer = world.Layer;
worldLayerObject.RebuildVisibility( world.Layer );
var giftCarrier = giftCarrierGameObject.GetComponent<GiftCarrier>();
var height = 256f;
var westOrEast = Random.Shared.Next() % 2 == 0 ? -500 : 4500;
var NorthOrSouth = Random.Shared.Next() % 2 == 0 ? -500 : 4500;
giftCarrier.WorldPosition = new Vector3( westOrEast, NorthOrSouth, height );
Log.Info( $"Spawned at {giftCarrier.WorldPosition}" );
var midpoint = new Vector3( 2000, 2000, 0 );
// face the midpoint
giftCarrier.WorldRotation = Rotation.LookAt( midpoint - giftCarrier.WorldPosition, Vector3.Up );
// giftCarrier.RotateObjectLocal( Vector3.Up, Mathf.Pi );
Log.Info(
$"Facing {midpoint} ({giftCarrier.WorldRotation}) ({giftCarrier.WorldRotation.Forward}) ({giftCarrier.WorldRotation.Yaw()})" );
giftCarrier.Items = GenerateRandomItems();
}
public void OnShot( Pellet pellet )
{
if ( _hasDroppedGift ) return;
Log.Info( "Shot" );
var world = NodeManager.WorldManager.ActiveWorld;
var endPosGrid = world.WorldToItemGrid( WorldPosition );
var endPosWorld = world.ItemGridToWorld( endPosGrid );
var giftModel = GiftModelSpawn.Clone( GiftInHolderVisual.WorldPosition, GiftInHolderVisual.WorldRotation );
/*var tween = GetTree().CreateTween();
var p = tween.TweenProperty( giftModel, "global_position", endPosWorld, 2f );
p.SetTrans( Tween.TransitionType.Bounce );
p.SetEase( Tween.EaseType.Out );
tween.TweenCallback( Callable.From( () =>
{
giftModel.QueueFree();
SpawnGift( endPosWorld );
} ) );*/
// SpawnGift( endPosWorld );
CameraMan.Instance.AddTarget( giftModel );
var tween = TweenManager.CreateTween();
tween.AddPosition( giftModel, endPosWorld, 2f ).SetEasing( Sandbox.Utility.Easing.BounceOut );
tween.OnFinish += () =>
{
giftModel.Destroy();
SpawnGift( endPosWorld );
};
// LookAtWhenShotTarget = giftModel;
// QueueFree();
GiftInHolderVisual.Enabled = false;
_hasDroppedGift = true;
Speed *= 2f;
// AnimationPlayer.SpeedScale = 2f;
}
public void SpawnGift( Vector3 position )
{
var world = NodeManager.WorldManager.ActiveWorld;
var gridPos = world.WorldToItemGrid( position );
var pItem = PersistentItem.Create( GiftItem );
pItem.SetSaveData( "Items", Items );
var nodeLink = world.SpawnPlacedItem( pItem, gridPos, World.ItemRotation.North );
}
private static List<PersistentItem> GenerateRandomItems()
{
var catalogue = ResourceLibrary.Get<CatalogueData>( "catalogues/stork_items.cata" );
var itemData = Random.Shared.FromList( catalogue.Items );
return new List<PersistentItem> { itemData.CreatePersistentItem() }; // TODO: give maybe multiple items?
}
}