Lmao

mail@pastecode.io avatar
unknown
csharp
2 years ago
12 kB
31
Indexable
Never
#define PAYLOAD_ESCORT_DEBUG

using Pocket.Assets.Scripts.Runtime.Data;
using Pocket.Assets.Scripts.Runtime.SceneObjects.Resources;
using Pocket.Common;
using Pocket.Data;
using Pocket.EventsDispatcher;
using Pocket.Networking;
using Pocket.SceneObjects;
using Pocket.UI;
using Pocket.Util;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.U2D;

namespace Pocket
{
    public class PEPayloadEscortHandler : MonoBehaviour
    {
		List<SceneObjectBase> tempObjectData = new List<SceneObjectBase>
		{
			new SceneObjectBase
			{
				Id = "Player",
				Oid = 6,
				PivotPosition = new Util.Vector3Norm
				{
					X = -17,
					Y = 1,
					Z = 3
				}
			}
		};
		
		List<ResourceNodeDefinition> tmpResourceData = new List<ResourceNodeDefinition>
		{
			new ResourceNodeDefinition
            {
				Id = "PELumberTree",
				Oid = 0,
				PivotPosition = new Util.Vector3Norm
                {
					X = -15,
					Y = 1,
					Z = 5
                },
				Job = new PlantJob
                {
					PlantedItemId = "PEWood",
					FullyGrownTime = Utility.GetCurrentTime(),
					NextSpeedUpTime = Utility.GetCurrentTime(),
					GrownStartedAt = Utility.GetCurrentTime(),
					Persistent = false,
					Id = ""
				}
            },			
			new ResourceNodeDefinition
			{
				Id = "PERockDeposit",
				Oid = 0,
				PivotPosition = new Util.Vector3Norm
				{
					X = -12,
					Y = 1,
					Z = 8
				},
				Job = new PlantJob
				{
					PlantedItemId = "PEStone",
					FullyGrownTime = Utility.GetCurrentTime(),
					NextSpeedUpTime = Utility.GetCurrentTime(),
					GrownStartedAt = Utility.GetCurrentTime(),
					Persistent = false,
					Id = ""
				}
			},
			new ResourceNodeDefinition
			{
				Id = "PERockDeposit",
				Oid = 0,
				PivotPosition = new Util.Vector3Norm
				{
					X = -20,
					Y = 1,
					Z = 3
				},
				Job = new PlantJob
				{
					PlantedItemId = "PEStone",
					FullyGrownTime = Utility.GetCurrentTime(),
					NextSpeedUpTime = Utility.GetCurrentTime(),
					GrownStartedAt = Utility.GetCurrentTime(),
					Persistent = false,
					Id = ""
				}
			}
		};
		
		[SerializeField] private PayloadEscortData data;
		[SerializeField] private Transform sceneObjectsRoot;
		[SerializeField] private Transform pickableResourcesRoot;
		[Header("Graphics assets")]
		[SerializeField] private AssetReferenceT<SpriteAtlas> iconsAtlasAsset;
		[SerializeField] private Sprite emptySprite;

		private AsyncOperationHandle<SpriteAtlas> iconsAtlasHandle;
		private SpriteAtlas iconAtlas;

		private bool[] resourceOwned;
		private HUDPayloadEscort ui;

		private bool hasNeededItem;
		private GameObject neededItemInstance;
		PayloadEscortDataSource.PayloadEscortData dataSourceData;
		PoolManager poolManager;

		private float elapsedTime = 0f;
		private bool started = false;
		public bool Started => started;

		public void Setup()
        {
			poolManager = ServiceLocator.Instance.GetService<PoolManager>();

			SetupSceneObjectBase();
			SetupResourceDataObjects();
			CreateDataSourceData(data);

			resourceOwned = new bool[data.requirements.Count];
			ui = ServiceLocator.Instance.GetService<UIManager>().Show<HUDPayloadEscort>();
			ui.SetNeededResources(data.requirements);

			EventDispatcher.Get().Subscribe<string, PEResourcePlot>(PublicEventEvent.PEResourceGathered, OnPEResourceGathered);

			iconsAtlasHandle = iconsAtlasAsset.LoadAssetAsync<SpriteAtlas>();
			iconsAtlasHandle.Completed += OnLoadComplete;


			StartCountdown(); //TEMP UNTIL WE HAVE NPC TO INTERACT WITH
		}

		public void StartCountdown()
        {
			StartCoroutine(CountdownCoroutine());
        }

		private void OnPEResourceGathered(string resourceId, PEResourcePlot resourcePlot)
		{
#if PAYLOAD_ESCORT_DEBUG
			Debug.Log("Collected resource " + resourceId);
#endif
			int index = GetIndexOfResource(resourceId);
			if (index == -1)
				return;

			if(resourceOwned[index] == true)
            {
				//We already own this resource, let's spawn it in the world!
#if PAYLOAD_ESCORT_DEBUG
				Debug.Log("Resource already owned, spawn it in the world");
#endif
				var prefab = poolManager.GetById(resourceId);
				if(prefab == null)
                {
#if PAYLOAD_ESCORT_DEBUG
					Debug.Log("Don't have a prefab for the resource");
#endif
					return;
				}


				GameObject resourceInstance = poolManager.Spawn(prefab.Obj, resourcePlot.transform.position + new Vector3(0, 2, 0), Quaternion.identity, pickableResourcesRoot);
				PEPickableResource pickableResource = resourceInstance.GetComponent<PEPickableResource>();
				if(pickableResource != null)
                {
					pickableResource.SetCanBeCollected(false);
					pickableResource.AddRandomForce();
                }
			}
			else
            {
				//Add it to local collection
#if PAYLOAD_ESCORT_DEBUG
				Debug.Log("Added resource");
#endif
				resourceOwned[index] = true;

				Sprite s = iconAtlas.GetSprite(GetSpriteId(resourceId));
				if (index == 0)
					dataSourceData.Res1Sprite.SetValue(s);
				else if (index == 1)
					dataSourceData.Res2Sprite.SetValue(s);

				SpawnEffectFor(resourcePlot);

				PEPickableResource[] allPickables = pickableResourcesRoot.GetComponentsInChildren<PEPickableResource>();
				for (int i = 0; i < allPickables.Length; i++)
                {
					if(allPickables[i].ResourceData.Job.PlantedItemId == resourceId)
						allPickables[i].SetCanBeCollected(false);
				}

				//Now check if we have everything
				if (AllResourceOwned())
                {
					//Yes, let's start crafting!
#if PAYLOAD_ESCORT_DEBUG
					Debug.Log("Got everything, start crafting");
#endif
					EventDispatcher.Get().Subscribe<PlayerCraftState.CraftData>(EventId.CraftEnded, OnCraftEnded);

					PlayerCraftState.CraftData craftData = new PlayerCraftState.CraftData(data.craftingTime, data.resultItemId);
					EventDispatcher.Get().Invoke(EventId.CraftRequest, craftData);
				}
			}
		}

		private void OnCraftEnded(PlayerCraftState.CraftData craftData)
		{
			EventDispatcher.Get().Unsubscribe<PlayerCraftState.CraftData>(EventId.CraftEnded, OnCraftEnded);

			poolManager = ServiceLocator.Instance.GetService<PoolManager>();
			var prefab = poolManager.GetById(craftData.itemToCraft);
			if(prefab != null)
            {
				neededItemInstance = poolManager.Spawn(prefab.Obj, Vector3.zero, Quaternion.identity, null);
				EventDispatcher.Get().Subscribe<GameObject>(EventId.ObjectDropped, OnObjectDropped);
				EventDispatcher.Get().Invoke(EventId.ObjectPickedUp, neededItemInstance);
			}

			dataSourceData.HasCrafteditem.SetValue(true);
			dataSourceData.CraftedItemSprite.SetValue(iconAtlas.GetSprite(GetSpriteId(data.resultItemId)));
			hasNeededItem = true;
		
		}

        private void OnObjectDropped(GameObject obj)
        {
			if (neededItemInstance != obj)
				return;

			EventDispatcher.Get().Unsubscribe<GameObject>(EventId.ObjectDropped, OnObjectDropped);
			//For now let's just destroy it.
			Destroy(neededItemInstance);
			hasNeededItem = false;
			neededItemInstance = null;
			dataSourceData.HasCrafteditem.SetValue(false);

			ResetCollectedResources();
		}

		private int GetIndexOfResource(string resourceId)
        {
			for(int i = 0; i < data.requirements.Count; i++)
            {
				if (data.requirements[i].itemId == resourceId)
					return i;
            }

			Debug.LogError("Resource not found in requirements " + resourceId);
			return -1;
        }

		private bool AllResourceOwned()
        {
			for(int i = 0; i < resourceOwned.Length; i++)
            {
				if (resourceOwned[i] == false)
					return false;
            }

			return true;
        }

		private void SetupSceneObjectBase()
		{			
			foreach (var item in tempObjectData)
			{
				var prefab = poolManager.GetById(item.Id);

				if (prefab != null)
				{
					var obj = poolManager.Spawn(prefab.Obj, item.PivotPosition.ToVector3(), prefab.Obj.transform.rotation, null);
					item.Object = obj.GetComponent<SceneObject>();
					item.Object.Oid = item.Oid;
				}
			}
		}

		private void SetupResourceDataObjects()
		{
			foreach (var item in tmpResourceData)
			{
				var prefab = poolManager.GetById(item.Id);

				if (prefab != null)
				{
					var obj = poolManager.Spawn(prefab.Obj, item.PivotPosition.ToVector3(), prefab.Obj.transform.rotation, sceneObjectsRoot);

					var resourcePlot = obj.GetComponent<ResourcePlot>();
					if (resourcePlot != null)
					{
						resourcePlot.ResourceData = item;
						resourcePlot.Oid = item.Oid;
						item.Object = resourcePlot;
					}
				}
			}
		}

        private void OnDestroy()
        {
			Addressables.Release(iconsAtlasHandle);
			EventDispatcher.Get().Unsubscribe<string, PEResourcePlot>(PublicEventEvent.PEResourceGathered, OnPEResourceGathered);
		}
	
		private void SpawnEffectFor(PEResourcePlot forResource)
        {
			GameObject newEffect = ServiceLocator.Instance.GetService<EffectsManager>().AddEffect(forResource.HarvestEffectName, forResource.transform.position + new Vector3(0, 2, 0));
			if (newEffect != null)
			{
				ResourceGatherEffect resourceGatherEffect = newEffect.GetComponent<ResourceGatherEffect>();
				if (resourceGatherEffect != null && forResource.Interactable.CurrentInteractor != null)
				{
					resourceGatherEffect.SetTarget(forResource.Interactable.CurrentInteractor.Character.transform);
				}
			}
		}	
	
		private void ResetCollectedResources()
        {
			for(int i = 0; i < resourceOwned.Length; i++)
            {
				resourceOwned[i] = false;
			}

			dataSourceData.Res1Sprite.SetValue(emptySprite);
			dataSourceData.Res2Sprite.SetValue(emptySprite);

			PEPickableResource[] allPickables = pickableResourcesRoot.GetComponentsInChildren<PEPickableResource>();
			for (int i = 0; i < allPickables.Length; i++)
				allPickables[i].SetCanBeCollected(true);
		}
	
		private void CreateDataSourceData(PayloadEscortData from)
        {
			dataSourceData = PayloadEscortDataSource.Instance.PayloadEscortInfo.GetTypedValue();
			if (dataSourceData == null)
			{
				dataSourceData = new PayloadEscortDataSource.PayloadEscortData();
				dataSourceData.CraftedItemName.SetValue(from.resultItemId);
				dataSourceData.HasCrafteditem.SetValue(false);

				dataSourceData.Res1Name.SetValue(from.requirements[0].itemId);
				dataSourceData.Res2Name.SetValue(from.requirements[1].itemId);

				dataSourceData.Res1Sprite.SetValue(emptySprite);
				dataSourceData.Res2Sprite.SetValue(emptySprite);

				dataSourceData.ElapsedTime.SetValue(0);

				PayloadEscortDataSource.Instance.PayloadEscortInfo.SetValue(dataSourceData);
			}
		}

		private string GetSpriteId(string from)
		{
			if (from.Contains("PE"))
			{
				return from.Replace("PE", "");
			}

			return from;
		}

		private void OnLoadComplete(AsyncOperationHandle<SpriteAtlas> obj)
		{
			iconAtlas = obj.Result;
		}

		private IEnumerator CountdownCoroutine()
        {
			for(int i = 0; i <= 2; i++)
            {
				ui.UpdateCountdownTimer(3 - i);
				yield return new WaitForSeconds(1f);
            }

			ui.HideTimer();

			started = true;
        }

        private void Update()
        {
            if(started)
            {
				elapsedTime += Time.deltaTime;
				dataSourceData.ElapsedTime.SetValue(Mathf.FloorToInt(elapsedTime));
			}
		}
    }
}