Advertisement
Guest User

Telegraph Map

a guest
Dec 31st, 2024
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.28 KB | None | 0 0
  1. using DG.Tweening;
  2. using Entities.Spells;
  3. using Entities.UI;
  4. using Extensions;
  5. using FishNet;
  6. using FMODUnity;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. using Entities.Spells.Components;
  10. using TickManagement;
  11. using Tombstone.Extensions;
  12. using Tombstone.Utilities;
  13. using UnityEngine;
  14. using UnityEngine.AddressableAssets;
  15. using UnityEngine.SceneManagement;
  16. using UnityEngine.Tilemaps;
  17.  
  18. namespace Tombstone.Mapping
  19. {
  20.  
  21.     public class TelegraphMap : MonoBehaviour
  22.     {
  23.  
  24.         [SerializeField] private TileBase _telegraphTile;
  25.         [SerializeField] private EventReference _telegraphSound;
  26.  
  27.         [SerializeField] private Tilemap _telegraphTilemap;
  28.         [SerializeField] private Tilemap _aoeTilemap;
  29.  
  30.         private Tween _tweener;
  31.  
  32.         private void Awake()
  33.         {
  34.             _telegraphTilemap.color = Color.red * 0.1f;
  35.             Color loopColor = Color.red * 0.5f;
  36.  
  37.             _tweener = DOTween.To(
  38.                 () => _telegraphTilemap.color,
  39.                 (color) => _telegraphTilemap.color = color,
  40.                 loopColor,
  41.                 TickManager.TICK / 2f)
  42.                     .SetLoops(-1, LoopType.Yoyo);
  43.  
  44.             InstanceFinder.RegisterInstance(this);
  45.  
  46.             InstanceFinder.ClientManager.RegisterBroadcast<TelegraphBroadcast>(OnTelegraphBroadcast);
  47.            
  48.             SceneManager.sceneUnloaded+=SceneManager_sceneUnloaded;
  49.         }
  50.  
  51.         private void OnDestroy()
  52.         {
  53.             _tweener.Kill();
  54.  
  55.             SceneManager.sceneUnloaded-=SceneManager_sceneUnloaded;
  56.             InstanceFinder.UnregisterInstance<TelegraphMap>();
  57.  
  58.             if (InstanceFinder.ClientManager != null)
  59.                 InstanceFinder.ClientManager.UnregisterBroadcast<TelegraphBroadcast>(OnTelegraphBroadcast);
  60.         }
  61.  
  62.         private void SceneManager_sceneUnloaded(Scene arg0)
  63.         {
  64.             // stop removal coroutines
  65.             StopAllCoroutines();
  66.            
  67.             // removal all tiles so they don't persist, to the login screen for example
  68.             _telegraphTilemap.ClearAllTiles();
  69.         }
  70.  
  71.         private void OnTelegraphBroadcast(TelegraphBroadcast broadcast)
  72.         {
  73. #if UNITY_EDITOR
  74.             Debug.Log($"<color=yellow>ReceivedTelegraph Broadcast</color>: {broadcast}");
  75. #endif
  76.            
  77.             var tilePos = new Vector2Int(broadcast.X, broadcast.Y);
  78.  
  79.             switch (broadcast.Type)
  80.             {
  81.                 default:
  82.                 case TelegraphBroadcast.TelegraphType.Point:
  83.                     TelegraphTiles(new List<Vector2Int> { tilePos }, broadcast.Duration);
  84.                     break;
  85.  
  86.                 case TelegraphBroadcast.TelegraphType.Linear:
  87.                     var tiles = TileUtils.GetLinearTilePositions(tilePos, broadcast.Distance, new Vector2Int(broadcast.DirX, broadcast.DirY));
  88.                     TelegraphTiles(tiles, broadcast.Duration);
  89.                     break;
  90.  
  91.                 case TelegraphBroadcast.TelegraphType.Spell:
  92.                     // TODO
  93.                     break;
  94.  
  95.                 case TelegraphBroadcast.TelegraphType.Target:
  96.                     if (broadcast.Target != null)
  97.                     {
  98.                         // the little arrow thing above the player head
  99.                         if (broadcast.Target.TryGetComponentInChildren(out UiEntityTelegraph uiTelegraph))
  100.                             uiTelegraph.Show(broadcast.Duration);
  101.                     }
  102.                     break;
  103.  
  104.                 case TelegraphBroadcast.TelegraphType.SpellArea:
  105.                     string spellGuid = broadcast.SpellGuid;
  106.                     if (string.IsNullOrEmpty(spellGuid))
  107.                     {
  108.                         Debug.LogError("Spell guid cannot be null");
  109.                         return;
  110.                     }
  111.  
  112.                     byte duration = broadcast.Duration;
  113.  
  114.                     Addressables.LoadAssetAsync<SpellBase>(spellGuid).Completed += handle =>
  115.                     {
  116.                         Addressables.Release(handle);
  117.  
  118.                         if (this == null) return;
  119.                         if (handle.OperationException != null)
  120.                         {
  121.                             Debug.LogException(handle.OperationException);
  122.                             return;
  123.                         }
  124.  
  125.                         SpellBase spell = handle.Result;
  126.                         EventReference spellSound = spell.CastSound;
  127.  
  128.                         if (!spell.TryGetSpellComponent(out AoeSpellComponent aoeSpellComponent)) return;
  129.                        
  130.                         // custom AOE shape
  131.                         if (aoeSpellComponent.AoeShape != 0)
  132.                         {
  133.                             List<Vector2Int> tilePositions = MapUtils.UnpackSpellAreaToTiles(aoeSpellComponent.AoeShape, tilePos);
  134.  
  135.                             if (aoeSpellComponent.AoeTile.RuntimeKeyIsValid())
  136.                             {
  137.                                 string guid = aoeSpellComponent.AoeTile.RuntimeKey.ToString();
  138.  
  139.                                 // start a typical telegraph
  140.                                 TelegraphTiles(tilePositions, duration, null, null,
  141.                                     // when telegraph ends, play the attack tiles
  142.                                     onEnd: () =>
  143.                                     {
  144.                                         if (this == null) return;
  145.                                            
  146.                                         TelegraphTiles(
  147.                                             tilePositions,
  148.                                             2,
  149.                                             guid,
  150.                                             onPlay: () =>
  151.                                             {
  152.                                                 // play sound in center of AOE
  153.                                                 Vector3 pos = tilePositions[tilePositions.Count / 2].Center();
  154.  
  155.                                                 // play the sound when attack AOE tiles play
  156.                                                 RuntimeManager.PlayOneShot(spellSound, pos);
  157.                                             });
  158.                                     });
  159.                             }
  160.                             else
  161.                             {
  162.                                 // typical telegraph
  163.                                 TelegraphTiles(tilePositions, duration);
  164.                             }
  165.                         }
  166.                         // regular radius
  167.                         else
  168.                         {
  169.                             List<Vector2Int> area = new();
  170.  
  171.                             int radius = aoeSpellComponent.AoeRadius;
  172.  
  173.                             for (int x = -radius; x <= radius; x++)
  174.                             {
  175.                                 for (int y = -radius; y <= radius; y++)
  176.                                 {
  177.                                     var pos = tilePos + Vector2Int.FloorToInt(new Vector2(x, y));
  178.  
  179.                                     // make circular-ish
  180.                                     if (Vector2.Distance(tilePos, pos) > radius) continue;
  181.  
  182.                                     area.Add(pos);
  183.                                 }
  184.                             }
  185.  
  186.                             TelegraphTiles(area, duration);
  187.                         }
  188.                     };
  189.                     break;
  190.             }
  191.  
  192.         }
  193.  
  194.         private void TelegraphTiles(List<Vector2Int> tilePositions, uint duration,
  195.             string aoeTileGuid = null,
  196.             System.Action onPlay = null, System.Action onEnd = null
  197.             )
  198.         {
  199.             PlayTelegraphSound(tilePositions);
  200.             StartCoroutine(RemoveTilesCo(tilePositions, duration, aoeTileGuid, null, null, onPlay, onEnd));
  201.         }
  202.  
  203.         private void PlayTelegraphSound(List<Vector2Int> tilePositions)
  204.         {
  205.             // find the center of the bounds and play the sound there
  206.             Bounds bounds = new(tilePositions[0].Center(), Vector2.one);
  207.  
  208.             for (int i = 1; i < tilePositions.Count; i++)
  209.             {
  210.                 bounds.Expand((Vector2)tilePositions[i]);
  211.             }
  212.  
  213.             RuntimeManager.PlayOneShot(_telegraphSound, bounds.center);
  214.         }
  215.  
  216.         private IEnumerator RemoveTilesCo(List<Vector2Int> tilePositions, uint duration, string aoeTileGuid,
  217.             TileBase telegraphedTile = null, Tilemap tilemap = null,
  218.             System.Action onPlay = null, System.Action onEnd = null
  219.             )
  220.         {
  221.             if (telegraphedTile == null)
  222.                 telegraphedTile = _telegraphTile;
  223.             if (tilemap == null)
  224.                 tilemap = _telegraphTilemap;
  225.  
  226.             foreach (var item in tilePositions)
  227.             {
  228.                 tilemap.SetTile((Vector3Int)item, telegraphedTile);
  229.             }
  230.  
  231.             onPlay?.Invoke();
  232.  
  233.  
  234.             yield return new WaitForGameTicks(duration);
  235.  
  236.  
  237.             foreach (var item in tilePositions)
  238.             {
  239.                 tilemap.SetTile((Vector3Int)item, null);
  240.             }
  241.  
  242.  
  243.             // play animated tiles for a bit
  244.             if (!string.IsNullOrEmpty(aoeTileGuid))
  245.             {
  246.                 Addressables.LoadAssetAsync<TileBase>(aoeTileGuid).Completed += handle =>
  247.                 {
  248.                     if (this == null)
  249.                     {
  250.                         Addressables.Release(handle);
  251.                         return;
  252.                     }
  253.                    
  254.                     if (handle.OperationException!=null)
  255.                     {
  256.                         Debug.LogError($"Error loading tile: {handle.OperationException}");
  257.                         Addressables.Release(handle);
  258.                         return;
  259.                     }
  260.                    
  261.                     // invoke later since loading may take a bit of time
  262.                     // and seems less awkward
  263.                     onEnd?.Invoke();
  264.  
  265.                     StartCoroutine(RemoveTilesCo(tilePositions, 2, null, handle.Result, _aoeTilemap));
  266.                     Addressables.Release(handle);
  267.                 };
  268.             }
  269.             else
  270.             {
  271.                 onEnd?.Invoke();
  272.             }
  273.         }
  274.  
  275.     }
  276.  
  277. }
  278.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement