Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using DG.Tweening;
- using Entities.Spells;
- using Entities.UI;
- using Extensions;
- using FishNet;
- using FMODUnity;
- using System.Collections;
- using System.Collections.Generic;
- using Entities.Spells.Components;
- using TickManagement;
- using Tombstone.Extensions;
- using Tombstone.Utilities;
- using UnityEngine;
- using UnityEngine.AddressableAssets;
- using UnityEngine.SceneManagement;
- using UnityEngine.Tilemaps;
- namespace Tombstone.Mapping
- {
- public class TelegraphMap : MonoBehaviour
- {
- [SerializeField] private TileBase _telegraphTile;
- [SerializeField] private EventReference _telegraphSound;
- [SerializeField] private Tilemap _telegraphTilemap;
- [SerializeField] private Tilemap _aoeTilemap;
- private Tween _tweener;
- private void Awake()
- {
- _telegraphTilemap.color = Color.red * 0.1f;
- Color loopColor = Color.red * 0.5f;
- _tweener = DOTween.To(
- () => _telegraphTilemap.color,
- (color) => _telegraphTilemap.color = color,
- loopColor,
- TickManager.TICK / 2f)
- .SetLoops(-1, LoopType.Yoyo);
- InstanceFinder.RegisterInstance(this);
- InstanceFinder.ClientManager.RegisterBroadcast<TelegraphBroadcast>(OnTelegraphBroadcast);
- SceneManager.sceneUnloaded+=SceneManager_sceneUnloaded;
- }
- private void OnDestroy()
- {
- _tweener.Kill();
- SceneManager.sceneUnloaded-=SceneManager_sceneUnloaded;
- InstanceFinder.UnregisterInstance<TelegraphMap>();
- if (InstanceFinder.ClientManager != null)
- InstanceFinder.ClientManager.UnregisterBroadcast<TelegraphBroadcast>(OnTelegraphBroadcast);
- }
- private void SceneManager_sceneUnloaded(Scene arg0)
- {
- // stop removal coroutines
- StopAllCoroutines();
- // removal all tiles so they don't persist, to the login screen for example
- _telegraphTilemap.ClearAllTiles();
- }
- private void OnTelegraphBroadcast(TelegraphBroadcast broadcast)
- {
- #if UNITY_EDITOR
- Debug.Log($"<color=yellow>ReceivedTelegraph Broadcast</color>: {broadcast}");
- #endif
- var tilePos = new Vector2Int(broadcast.X, broadcast.Y);
- switch (broadcast.Type)
- {
- default:
- case TelegraphBroadcast.TelegraphType.Point:
- TelegraphTiles(new List<Vector2Int> { tilePos }, broadcast.Duration);
- break;
- case TelegraphBroadcast.TelegraphType.Linear:
- var tiles = TileUtils.GetLinearTilePositions(tilePos, broadcast.Distance, new Vector2Int(broadcast.DirX, broadcast.DirY));
- TelegraphTiles(tiles, broadcast.Duration);
- break;
- case TelegraphBroadcast.TelegraphType.Spell:
- // TODO
- break;
- case TelegraphBroadcast.TelegraphType.Target:
- if (broadcast.Target != null)
- {
- // the little arrow thing above the player head
- if (broadcast.Target.TryGetComponentInChildren(out UiEntityTelegraph uiTelegraph))
- uiTelegraph.Show(broadcast.Duration);
- }
- break;
- case TelegraphBroadcast.TelegraphType.SpellArea:
- string spellGuid = broadcast.SpellGuid;
- if (string.IsNullOrEmpty(spellGuid))
- {
- Debug.LogError("Spell guid cannot be null");
- return;
- }
- byte duration = broadcast.Duration;
- Addressables.LoadAssetAsync<SpellBase>(spellGuid).Completed += handle =>
- {
- Addressables.Release(handle);
- if (this == null) return;
- if (handle.OperationException != null)
- {
- Debug.LogException(handle.OperationException);
- return;
- }
- SpellBase spell = handle.Result;
- EventReference spellSound = spell.CastSound;
- if (!spell.TryGetSpellComponent(out AoeSpellComponent aoeSpellComponent)) return;
- // custom AOE shape
- if (aoeSpellComponent.AoeShape != 0)
- {
- List<Vector2Int> tilePositions = MapUtils.UnpackSpellAreaToTiles(aoeSpellComponent.AoeShape, tilePos);
- if (aoeSpellComponent.AoeTile.RuntimeKeyIsValid())
- {
- string guid = aoeSpellComponent.AoeTile.RuntimeKey.ToString();
- // start a typical telegraph
- TelegraphTiles(tilePositions, duration, null, null,
- // when telegraph ends, play the attack tiles
- onEnd: () =>
- {
- if (this == null) return;
- TelegraphTiles(
- tilePositions,
- 2,
- guid,
- onPlay: () =>
- {
- // play sound in center of AOE
- Vector3 pos = tilePositions[tilePositions.Count / 2].Center();
- // play the sound when attack AOE tiles play
- RuntimeManager.PlayOneShot(spellSound, pos);
- });
- });
- }
- else
- {
- // typical telegraph
- TelegraphTiles(tilePositions, duration);
- }
- }
- // regular radius
- else
- {
- List<Vector2Int> area = new();
- int radius = aoeSpellComponent.AoeRadius;
- for (int x = -radius; x <= radius; x++)
- {
- for (int y = -radius; y <= radius; y++)
- {
- var pos = tilePos + Vector2Int.FloorToInt(new Vector2(x, y));
- // make circular-ish
- if (Vector2.Distance(tilePos, pos) > radius) continue;
- area.Add(pos);
- }
- }
- TelegraphTiles(area, duration);
- }
- };
- break;
- }
- }
- private void TelegraphTiles(List<Vector2Int> tilePositions, uint duration,
- string aoeTileGuid = null,
- System.Action onPlay = null, System.Action onEnd = null
- )
- {
- PlayTelegraphSound(tilePositions);
- StartCoroutine(RemoveTilesCo(tilePositions, duration, aoeTileGuid, null, null, onPlay, onEnd));
- }
- private void PlayTelegraphSound(List<Vector2Int> tilePositions)
- {
- // find the center of the bounds and play the sound there
- Bounds bounds = new(tilePositions[0].Center(), Vector2.one);
- for (int i = 1; i < tilePositions.Count; i++)
- {
- bounds.Expand((Vector2)tilePositions[i]);
- }
- RuntimeManager.PlayOneShot(_telegraphSound, bounds.center);
- }
- private IEnumerator RemoveTilesCo(List<Vector2Int> tilePositions, uint duration, string aoeTileGuid,
- TileBase telegraphedTile = null, Tilemap tilemap = null,
- System.Action onPlay = null, System.Action onEnd = null
- )
- {
- if (telegraphedTile == null)
- telegraphedTile = _telegraphTile;
- if (tilemap == null)
- tilemap = _telegraphTilemap;
- foreach (var item in tilePositions)
- {
- tilemap.SetTile((Vector3Int)item, telegraphedTile);
- }
- onPlay?.Invoke();
- yield return new WaitForGameTicks(duration);
- foreach (var item in tilePositions)
- {
- tilemap.SetTile((Vector3Int)item, null);
- }
- // play animated tiles for a bit
- if (!string.IsNullOrEmpty(aoeTileGuid))
- {
- Addressables.LoadAssetAsync<TileBase>(aoeTileGuid).Completed += handle =>
- {
- if (this == null)
- {
- Addressables.Release(handle);
- return;
- }
- if (handle.OperationException!=null)
- {
- Debug.LogError($"Error loading tile: {handle.OperationException}");
- Addressables.Release(handle);
- return;
- }
- // invoke later since loading may take a bit of time
- // and seems less awkward
- onEnd?.Invoke();
- StartCoroutine(RemoveTilesCo(tilePositions, 2, null, handle.Result, _aoeTilemap));
- Addressables.Release(handle);
- };
- }
- else
- {
- onEnd?.Invoke();
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement