RNNCode

EnmityVisionPlugin

Sep 18th, 2024 (edited)
402
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 27.26 KB | None | 0 0
  1. using System;
  2. using Turbo.Plugins.Default;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. using System.Threading;
  8.  
  9. namespace Turbo.Plugins.RNN
  10. {
  11.     public class EnmityVisionPlugin : BasePlugin, INewAreaHandler, IAfterCollectHandler, IInGameWorldPainter, IInGameTopPainter
  12.     {
  13.         public bool DebugEnabled { get; set; } = false;
  14.         private uint DebugTA { get; set; } = 0;
  15.         private Dictionary<IUiElement, BountyAct> DataUiEBountyAct { get; set; }
  16.         private Dictionary<uint,uint> Area_Waypoint_Dict { get; set; } = new Dictionary<uint,uint> // { Áreas, waypoint} recogidas de forma automática mediante el log, y añadidas por mí tras ser comprobadas (deben ser recorridas bajo ciertas condiciones)
  17.         {
  18.             {100854, 19943}, {445426, 19943}, {1199, 19943}, {135952, 19943}, {19940, 93632}, {82566, 93632}, {82567, 93632}, {80116, 93632}, {62726, 78572}, {83265, 72712}, {83264, 72712}, {154588, 72712}, {102300, 19952}, {165798, 19952},
  19.             {119893, 19952}, {134002, 19952}, {82372, 19952},  {82373, 19952}, {149669, 19952},  {60397, 19953}, {60396, 19953}, {101351, 91133}, {91324, 91133}, {60714, 19780}, {19938, 91133}, {19933, 91133}, {19929, 91133},  {19789, 19787},
  20.             {87907, 19783}, {19935, 119870}, {19825, 19835}, {148903, 19835}, {19826, 19835}, {195268, 19835}, {19839, 63666}, {464092, 456638}, {467383, 456638}, {19837, 19836}, {159588, 19836}, {220805, 19836}, {176058, 19800}, {19798, 19800},
  21.             {80592, 19800}, {19797, 19800}, {60194, 19800}, {196047, 53834}, {123182, 53834}, {111487, 53834}, {111671, 53834}, {218968, 53834}, {432994, 62752}, {432999, 62752}, {192694, 62752}, {433000, 62752}, {433002, 62752}, {465885, 460671},
  22.             {111516, 119306}, {139274, 119653}, {119656, 119653}, {112565, 155048}, {191078, 155048}, {221703, 155048}, {112580, 69504}, {80792, 80791}, {174666, 154644}, {221752, 154644}, {112548, 154644}, {92960, 93173}, {430336, 428494},
  23.             {436319, 428494}, {109531, 109526}, {464858, 464857}, {464865, 464857}, {464873, 464857}, {464867, 464857}, {464868, 464857}, {464870, 464857}, {464875, 464857}, {464874, 464857}, {464871, 464857}, {409375, 409001}, {464820, 464065},
  24.             {464810, 464065}, {464821, 464065}, {464822, 464065}, {109149, 109514}, {143648, 109514}, {201668, 409517}, {201670, 409517}, {198564, 109538}, {215396, 109538}, {205434, 109540}, {109563, 109540}, {153669, 109540},
  25.             {215235, 109540}, {464882, 464063}, {464890, 475854}, {464889, 475854}, {464886, 475854}, {464944, 475856}, {464943, 475856}, {464942, 475856}, {464940, 464066}, {464941, 464066}, {287220, 283567}, {245964, 258142}, {340533, 271234},
  26.             {448404, 338602}, {367831, 338602}, {339397, 338602}, {349787, 459863}, {330576, 459863}, {432439, 427763}, {432440, 427763}, {424374, 427763}, {276705, 263493}, {430876, 263493}, {430875, 263493}, {336217, 263493}, {357577, 263493},
  27.             {308487, 263493}, {336846, 261758}, {336847, 261758}, {314782, 261758}, {338956, 261758}, {158594, 57425}, {218511, 93103}, {129375, 93632}, {235003, 258142}, {336577, 258142}, {322645, 338602},
  28.             {170118, 19836}, {19838, 19836}, {182258, 154644}, {221753, 154644}, {111232, 136448}, {197623, 69504}, {85202, 80791}, {444307, 428494}, {445762, 428494}, {182274, 154644}, {221754, 154644}, {189345, 155048}, {220904, 154644},
  29.             {87832, 19775}, {94672, 19775}, {205424, 69504}, {169494, 57425}, {194239, 57425}, {221761, 155048}, {338931, 261758}, {338970, 261758}, {221702, 155048}, {220905, 154644},
  30.             {121418, 19836}, {148905, 19835}, {62575, 57425}, {194242, 57425}, {448011, 409001}, {351802, 261758}, {62574, 57425}, {161105, 57425}, {19801, 63666}, {222577, 63666}, {134920, 93632}, {111667, 53834}, {218969, 53834}, {201671, 409517},
  31.             {448375, 338602}, {445792, 409512}, {448411, 283567}, {179567, 19952}, {166127, 63666}, {135237, 19954}, {194232, 19954}, {90881, 19776}, {82326, 93632}, {82327, 93632}, {106757, 91133},
  32.             {257116, 119653}, {256767, 332339}, {374239, 332339}, {256106, 332339}, {256742, 332339}, // Ubers 446367 // BL {448391, 261758}, {448039, 109538}
  33.         };
  34.  
  35.         protected IUiElement SeasonalLeaf;
  36.  
  37.         protected IUiElement uiShowPortal;
  38.         protected IUiElement uiCountdownLabel;
  39.         protected IUiElement uiCountdownTimer;
  40.  
  41.         public WorldDecoratorCollection EnmityPortalLabel { get; set; }
  42.  
  43.         public bool ShowWaypoint { get; set; }
  44.  
  45.         public bool EnableSpeak { get; set; }
  46.  
  47.         public string SpeakOpenPortalUI { get; set; }
  48.         public string SpeakOpenPortalArea { get; set; }
  49.         public string SpeakClosingPortal { get; set; }
  50.         public string SpeakClosedPortal { get; set; }
  51.         public string SpeakChestFound { get; set; }
  52.         public string SpeakGoblinFound { get; set; }
  53.         public string SpeakFirstPortal { get; set; }
  54.         public string SpeakNextPortal { get; set; }
  55.         public string SpeakNextPortalOrder { get; set; }
  56.  
  57.         public string LabelFirstPortal { get; set; }
  58.         public string LabelNextPortal { get; set; }
  59.         public string LabelNextPortalOrder { get; set; }
  60.  
  61.         public bool EnableTextScreen { get; set; }
  62.  
  63.         public string TextScreen { get; set; }
  64.         public string TextLocUnKnown { get; set; }
  65.         public string TextNoPortal { get; set; }
  66.         public string TextMoreLeveles { get; set; }
  67.         public string TextClosing { get; set; }
  68.         public string TextTimeFormat { get; set; }
  69.         public string TextGoblin { get; set; }
  70.         public string TextChest { get; set; }
  71.         public string TextChestOpen { get; set; }
  72.         public string TextLevelMe { get; set; }
  73.         public string TextNoLevelMe { get; set; }
  74.  
  75.         public float OffsetX { get; set; } = 0;
  76.         public float OffsetY { get; set; } = 0;
  77.         public string TextLastVision { get; set; }
  78.  
  79.         public bool SoundEnabled { get; set; }
  80.         public string FileSound { get; set; }
  81.  
  82.         private int PortalCountFound { get; set;} = 0;
  83.         private int EnmityPortalStartTick { get; set;} = 0;
  84.         private int EnmityPortalState { get; set;} = 0;
  85.         private uint PortalAnnIdLast { get; set;} = 0;
  86.         private int LevelMe { get; set;} = 0;
  87.  
  88.         private int ClosedPortalUITick { get; set;} = 0;
  89.         private int OpenChestTick { get; set;} = 0;
  90.         private const int maxLevels = 15;
  91.         private const int TicksForAutoClose = 1920;         // OpenChestTick + 30 seg + 2 margen (32 * 60)
  92.         private const int TicksForDetectNewOPenUI = 900;    // El dialog que notifica sobre una nueva visión dura 8 seg aprox, con poner 10 seg (600 ticks) deberia bastar, aunque  pongo un poco más (15seg)
  93.         private const int ticksDelayUI = 30;                // Retrasar el anuncio de una nueva Visión mediante UI para dar tiempo a aparecer el portal de entrada cercano.
  94.         private int EnmityPortalAct { get; set; } = -1;
  95.         private string EnmityPortalArea { get; set; } = string.Empty;
  96.         private uint EnmityWaypoint { get; set; } = 0;
  97.  
  98.         private delegate int CounDownTime();
  99.         private CounDownTime CounDownTimeFunc;
  100.  
  101.         public IFont FontTextShow { get; set; }
  102.         public IFont FontTextHide { get; set; }
  103.         public uint TextureId { get; set; } = 3122228893;
  104.  
  105.         private bool _EnmityPortal { get; set; } = false;
  106.         public bool EnmityPortal
  107.         {
  108.             get { return _EnmityPortal; }
  109.             set
  110.             {
  111.                 if (_EnmityPortal != value)
  112.                 {
  113.                     _EnmityPortal = value;
  114.                     foreach(var d in EnmityAreasDicc.Keys.ToList()) { EnmityAreasDicc[d] = 0; }
  115.                     EnmityPortalsOrderDicc.Clear();
  116.                     PortalCountFound = 0;
  117.                     EnmityPortalState = 0;
  118.                     EnmityPortalAct = -1;
  119.                     EnmityPortalArea = string.Empty;
  120.                     EnmityWaypoint = 0;
  121.                     EnmityPortalStartTick = 0;
  122.                     PortalAnnIdLast = 0;
  123.                     LevelMe = 0;
  124.                 }
  125.             }
  126.         }
  127.  
  128.         private Dictionary<uint,int> EnmityAreasDicc { get; set; } = new Dictionary<uint,int>
  129.         {
  130.             {488740, 0 },   //  P76_NestingNewTristram_SeasonTheme
  131.             {488741, 0 },   //  P76_NestingOldTristram_SeasonTheme
  132.             {488742, 0 },   //  P76_NestingGraveyard_Act1_SeasonTheme
  133.             {488743, 0 },   //  P76_NestingBloodPit_SeasonTheme Normal
  134.             {488745, 0 },   //  P76_NestingBoneyard_SeasonTheme Normal
  135.             {488746, 0 },   //  P76_NestingMoor_Sacrifice_SeasonTheme
  136.             {488767, 0 },   //  P76_NestingAlcarnus_SeasonTheme
  137.             {488770, 0 },   //  P76_NestingChurch_SeasonTheme
  138.             {488799, 0 },   //  P76_NestingSescheron_SeasonTheme
  139.             {488800, 0 },   //  P76_NestingForestTower_SeasonTheme
  140.             {488870, 0 },   //  P76_NestingRam_SeasonTheme
  141.             {488871, 0 },   //  P76_NestingSpire_SeasonTheme
  142.             {488872, 0 },   //  P76_NestingHell_SeasonTheme
  143.             {488873, 0 },   //  P76_NestingGideonsCourt_SeasonTheme
  144.             {488874, 0 },   //  P76_NestingBog_SeasonTheme
  145.         };
  146.  
  147.         private HashSet<ActorSnoEnum> EnmityPortals { get; set; } = new HashSet<ActorSnoEnum> {
  148.             ActorSnoEnum._p76_portal_oldtristram_seasontheme,
  149.             ActorSnoEnum._p76_portal_newtristram_seasontheme,
  150.             ActorSnoEnum._p76_portal_graveyardact1_seasontheme,
  151.             ActorSnoEnum._p76_portal_bloodpit_seasontheme,
  152.             ActorSnoEnum._p76_portal_moors_sacrifice_seasontheme,
  153.             ActorSnoEnum._p76_portal_boneyard_seasontheme,
  154.             ActorSnoEnum._p76_portal_church_seasontheme,
  155.             ActorSnoEnum._p76_portal_alcarnus_seasontheme,
  156.             ActorSnoEnum._p76_portal_sescheron_seasontheme,
  157.             ActorSnoEnum._p76_portal_foresttower_seasontheme,
  158.             ActorSnoEnum._p76_portal_bog_seasontheme,
  159.             ActorSnoEnum._p76_portal_gideonscourt_seasontheme,
  160.             ActorSnoEnum._p76_portal_spire_seasontheme,
  161.             ActorSnoEnum._p76_portal_hell_seasontheme,
  162.             ActorSnoEnum._p76_portal_ram_seasontheme,
  163.         };
  164.  
  165.         private Dictionary<uint,int> EnmityPortalsOrderDicc { get; set; } = new Dictionary<uint,int>();
  166.  
  167.         public EnmityVisionPlugin()
  168.         {
  169.             Enabled = true;
  170.         }
  171.  
  172.         public override void Load(IController hud)
  173.         {
  174.             base.Load(hud);
  175.  
  176.             ShowWaypoint = true;
  177.  
  178.             SoundEnabled = true;                // Alert sound for a new Vision
  179.             FileSound = "notification_9.wav";   // File to be played. It must be in the Sounds\ folder
  180.  
  181.             EnableSpeak = true; // false to disable all speak
  182.             SpeakOpenPortalUI = "A portal opens away from you"; // null or empty not to speak, vision is detected via UI
  183.             SpeakOpenPortalArea = "A portal opens near you";    // null or empty not to speak, vision is detected via portal. A nearby portal is typically detected before the UI notification
  184.             SpeakClosingPortal = "The portal is closing";       // null or empty not to speak
  185.             SpeakClosedPortal = "The Portal is closed";         // null or empty not to speak
  186.             SpeakChestFound = "Chest of Visions";               // null or empty not to speak
  187.             SpeakGoblinFound = "Goblin of Visions";             // null or empty not to speak
  188.             SpeakFirstPortal = "Entrance Found";    // Speak when the entry portal is found after the vision is detected via UI
  189.             SpeakNextPortalOrder = "Level {0}";     // Speak portals , {0} = Level number
  190.             SpeakNextPortal  = "Next Level";        // Speak portals. Show When the number of levels cannot be set
  191.  
  192.             LabelFirstPortal = "Entrance";          // Show when the entry Portal has been found
  193.             LabelNextPortalOrder = "Level {0}";     // {0} = Level number
  194.             LabelNextPortal  = "Next Level";        // Show when the number of levels cannot be set
  195.  
  196.             EnableTextScreen = true;                    // Show TextScreen line
  197.             TextScreen  = "Enmity Vision: A{0} - {1} ({2} ago, {3}{4} levels, {5}). {6}"; // {0}=Act, {1}=Area NameLocalized, {2}=time, {3}=Levels, {4}=TextMoreLeveles, {5}=TextLevelMe/TextNoLevelMe, {6}=TextGoblin/TextChest/TextChestOpen/TextClosing
  198.             TextLocUnKnown  = "\"Location unknown\"";   // Portal opened but not detected.
  199.             TextNoPortal = "Untracked Visions.";        // No active portal.
  200.             TextMoreLeveles = " or more";               // show if there is a possibility of more levels
  201.             TextClosing = "Closing ... {0}s";           // show if the portal is closing. {0}=time
  202.             TextGoblin = "Goblin found";
  203.             TextChest = "Chest found";
  204.             TextChestOpen = "Chest open";
  205.             TextLevelMe = "in the {0}th";               // Shows the level you are at within the vision. {0}=level
  206.             TextNoLevelMe = "out";                      // You are not in an area of Vision
  207.  
  208.             TextTimeFormat = "{0:0}m{1:0}s";                // Format for Time since vision was detected // {0} = minutes, {1} = seconds
  209.  
  210.             OffsetX = 0.055f;   // 0f...1f Set the x coordinate for TextScreen
  211.             OffsetY = 0.001f;   // 0f...1f Set the y coordinate for TextScreen
  212.  
  213.             EnmityPortalLabel = new WorldDecoratorCollection(
  214.                 new GroundLabelDecorator(Hud)
  215.                 {
  216.                     ForceOnScreen= false,
  217.                     BorderBrush = Hud.Render.CreateBrush(255, 193, 226, 255, 1),
  218.                     BackgroundBrush = Hud.Render.CreateBrush(220, 73, 89, 255, 0),
  219.                     TextFont = Hud.Render.CreateFont("tahoma", 7, 220, 193, 226, 255, true, false, false)
  220.                 },
  221.                 new MapLabelDecorator(Hud)
  222.                 {
  223.                     LabelFont = Hud.Render.CreateFont("tahoma", 5, 220, 193, 226, 255, false, false, true),
  224.                     RadiusOffset = 18,
  225.                 }
  226.             );
  227.  
  228.             FontTextShow = Hud.Render.CreateFont("tahoma", 8f, 250, 0, 250, 0, false, false, 250, 0, 0, 0, true);
  229.             FontTextHide = Hud.Render.CreateFont("tahoma", 8f, 50, 0, 250, 0, false, false, false);
  230.  
  231.             uiShowPortal = Hud.Render.RegisterUiElement("Root.NormalLayer.game_notify_dialog_backgroundScreen.game_text_line0", null, null);
  232.             uiCountdownLabel = Hud.Render.RegisterUiElement("Root.NormalLayer.Countdown_main.count_down.timer_label", null, null);
  233.             uiCountdownTimer = Hud.Render.RegisterUiElement("Root.NormalLayer.Countdown_main.count_down.timer", null, null);
  234.  
  235.             CounDownTimeFunc = () => {
  236.                                         var t = 0;
  237.                                         if (uiCountdownTimer?.Visible == true)
  238.                                         {
  239.                                             Int32.TryParse(uiCountdownTimer.ReadText(Encoding.UTF8, true), out t);
  240.                                         }
  241.                                         return t;
  242.                                     };
  243.  
  244.             DataUiEBountyAct = new Dictionary<IUiElement, BountyAct>
  245.             {
  246.                 { Hud.Render.RegisterUiElement("Root.NormalLayer.WaypointMap_main.LayoutRoot.OverlayContainer.POI.entry 0.LayoutRoot.Town", null, null), BountyAct.A1 },
  247.                 { Hud.Render.RegisterUiElement("Root.NormalLayer.WaypointMap_main.LayoutRoot.OverlayContainer.POI.entry 19.LayoutRoot.Town", null, null), BountyAct.A2 },
  248.                 { Hud.Render.RegisterUiElement("Root.NormalLayer.WaypointMap_main.LayoutRoot.OverlayContainer.POI.entry 30.LayoutRoot.Town", null, null), BountyAct.A3 },
  249.                 { Hud.Render.RegisterUiElement("Root.NormalLayer.WaypointMap_main.LayoutRoot.OverlayContainer.POI.entry 44.LayoutRoot.Town", null, null), BountyAct.A4 },
  250.                 { Hud.Render.RegisterUiElement("Root.NormalLayer.WaypointMap_main.LayoutRoot.OverlayContainer.POI.entry 58.LayoutRoot.Town", null, null), BountyAct.A5 }
  251.             };
  252.             SeasonalLeaf = Hud.Render.RegisterUiElement("Root.NormalLayer.minimap_dialog_backgroundScreen.minimap_dialog_pve.BoostWrapper.BoostsDifficultyStackPanel.BoostsStackWrapper.BoostsStackPanel.Seasonal", null, null);
  253.         }
  254.  
  255.         public void Play_Sound(string playFile)
  256.         {
  257.             var playSonido = Hud.Sound.LoadSoundPlayer(playFile);
  258.             ThreadPool.QueueUserWorkItem(state =>
  259.             {
  260.                try  { playSonido.PlaySync(); }
  261.                catch (Exception)  {   }
  262.             });
  263.         }
  264.  
  265.         public void OnNewArea(bool newGame, ISnoArea area)
  266.         {
  267.             if (newGame)
  268.             {
  269.                 EnmityPortal = false;
  270.                 ClosedPortalUITick = 0;
  271.                 OpenChestTick = 0;
  272.             }
  273.  
  274.             if (!area.IsTown && area.Act != 0 /*&& !EnmityAreasDicc.ContainsKey(area.Sno)*/) // Recopila/aprende nuevas áreas en cada sesión de TH, las iré añadiendo de forma permanente tras ser comprobadas
  275.             {
  276.                 if (Hud.Game.ActMapWaypoints.FirstOrDefault(w => w.TargetSnoArea.Sno == Hud.Game.Me.SnoArea.Sno) != null)   DebugTA = area.Sno;
  277.                 else if (!Area_Waypoint_Dict.ContainsKey(area.Sno) && DebugTA != 0)
  278.                 {
  279.                     Area_Waypoint_Dict.Add(area.Sno, DebugTA); // Añade temporalmente al diccionario las nuevas áreas.
  280.                     if (DebugEnabled) // Serán añadidas al diccionario una vez comprobadas , las guardo en un log
  281.                     {
  282.                         Hud.TextLog.Log("EnmityAreasNEW",string.Format("{0}{2}, {3}{1}, // {4}, A{5} - {6}", "{", "}", area.Sno, DebugTA, Hud.Game.Me.WorldSno, Hud.Game.Me.Scene.SnoArea.Act, Hud.Game.Me.Scene.SnoArea.NameLocalized),false,true);
  283.                         Hud.Sound.Speak("Nueva área");
  284.                     }
  285.                 }
  286.             }
  287.         }
  288.  
  289.         public void AfterCollect()  // EnmityPortalState => 1- Visión detectada con Portal, 2- Vision detectada con UI, 3- Goblin Found, 4- Chest Found, 5- Chest Open, 6- Dialog UI Closing Vision
  290.         {
  291.             if (!Hud.Game.IsInGame || Hud.Game.IsLoading || Hud.Game.IsPaused || !Hud.Game.Me.Powers.BuffIsActive(488544)) return;
  292.  
  293.             var portal = Hud.Game.Portals.FirstOrDefault(p => p.ActorAvailable && EnmityPortals.Contains(p.SnoActor.Sno));      // p.ActorAvailable es mecesario (en ocasiones se detectan portales adicionales falsos en ubicaciones random)
  294.             if (portal != null && portal.AnnId != 0 && portal.Scene?.SnoArea != null && Hud.Game.CurrentGameTick > ClosedPortalUITick)  // Solo habrá uno, no es necesario usar un bucle
  295.             {
  296.                 if (EnmityAreasDicc.TryGetValue(portal.TargetArea.Sno, out var registered)) // el destino del portal es uno de las áreas de las visiones
  297.                 {
  298.                     if (!EnmityAreasDicc.ContainsKey(portal.Scene.SnoArea.Sno)) // es el portal de entrada (ha aparecido en un área que no coincide con ninguna de las áreas de visiones)
  299.                     {
  300.                         if (EnmityPortal && PortalAnnIdLast != 0 && portal.AnnId != PortalAnnIdLast)
  301.                         {  // Por precaución, por si la detección de cierre mediante Dialog UI (uiCountdownLabel) no funcionase correctamente. El AnnId del portal de entrada no puede coincidir con el de la anterior visión.
  302.                             EnmityPortal = false;
  303.                             registered = 0;
  304.                         }
  305.                         if (registered == 0) // portal no fue registrado anteriormente
  306.                         {
  307.                             if (EnmityPortal == false)
  308.                             {
  309.                                 EnmityPortal = true;
  310.                                 EnmityPortalState = 1;
  311.                                 EnmityPortalStartTick = Hud.Game.CurrentGameTick;
  312.                                 if (EnableSpeak)
  313.                                 {
  314.                                     if (!string.IsNullOrEmpty(SpeakOpenPortalArea))     Hud.Sound.Speak(SpeakOpenPortalArea);   // Detección de una nueva visión mediante un portal de entrada cercano
  315.                                     else if (!string.IsNullOrEmpty(SpeakFirstPortal))   Hud.Sound.Speak(SpeakFirstPortal);      // Si no se ha definido un mensaje para la detección cercana pasará a anunciar el portal de entrada
  316.                                 }
  317.                                 if (SoundEnabled) Play_Sound(FileSound);
  318.                             }
  319.                             else
  320.                             {
  321.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakFirstPortal))     Hud.Sound.Speak(SpeakFirstPortal);  // Anuncia un portal de entrada encontrado instantes despues de detectar la visión mediante UI
  322.                             }
  323.                             PortalCountFound = 1;
  324.                             PortalAnnIdLast = portal.AnnId;
  325.                             EnmityAreasDicc[portal.TargetArea.Sno] = PortalCountFound;
  326.                             EnmityPortalsOrderDicc[portal.AnnId] = 0;
  327.  
  328.                             EnmityPortalAct = portal.Scene.SnoArea.Act;
  329.                             EnmityPortalArea = portal.Scene.SnoArea.NameLocalized ?? "NULL";
  330.  
  331.                             if (Hud.Game.Me.SnoArea == null)
  332.                             {
  333.                                 if (DebugEnabled) Hud.Sound.Speak("ME SNOAREA NULL VISION");
  334.                                 EnmityWaypoint = 0;
  335.                             }
  336.                             else
  337.                             {
  338.                                 if (Hud.Game.ActMapWaypoints.FirstOrDefault(w => w.TargetSnoArea.Sno == Hud.Game.Me.SnoArea.Sno) != null)
  339.                                 {
  340.                                     EnmityWaypoint = Hud.Game.Me.SnoArea.Sno;
  341.                                 }
  342.                                 else if (Area_Waypoint_Dict.TryGetValue(Hud.Game.Me.SnoArea.Sno, out var r))
  343.                                 {
  344.                                     EnmityWaypoint = r;
  345.                                 }
  346.                                 else EnmityWaypoint = 0;
  347.                             }
  348.                         }
  349.                     }
  350.                     else
  351.                     {
  352.                         if (registered == 0)  // no hay portal registrado con el mismo área de destino
  353.                         {
  354.                             if (EnmityAreasDicc[portal.Scene.SnoArea.Sno] != 0) // sólo voy registrando portales consecutivos, en cadena (ya hubo un portal anterior con destino igual al área donde aparece éste)
  355.                             {
  356.                                 PortalCountFound++;
  357.                                 EnmityAreasDicc[portal.TargetArea.Sno] = PortalCountFound;
  358.                                 EnmityPortalsOrderDicc[portal.AnnId] = PortalCountFound;
  359.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakNextPortalOrder)) Hud.Sound.Speak(string.Format(SpeakNextPortalOrder, PortalCountFound));
  360.                             }
  361.                             else if (!EnmityPortalsOrderDicc.ContainsKey(portal.AnnId))
  362.                             {
  363.                                 EnmityPortalsOrderDicc.Add(portal.AnnId, -1);
  364.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakNextPortal))      Hud.Sound.Speak(SpeakNextPortal);
  365.                             }
  366.                         }
  367.                     }
  368.                 }
  369.             }
  370.             if (uiShowPortal?.Visible == true)
  371.             {
  372.                 var text = uiShowPortal.ReadText(Encoding.UTF8, true); // Root.NormalLayer.game_notify_dialog_backgroundScreen.game_text_line0
  373.                 if (!string.IsNullOrEmpty(text) && Regex.IsMatch(text,@"(reality!|realidad!|Realität|réalité|realtà!|rzeczywistości!|realidade!|форму!|현실로|一股恨意化為了現實!)"))
  374.                 {
  375.                     if (EnmityPortal && (Hud.Game.CurrentGameTick - EnmityPortalStartTick > TicksForDetectNewOPenUI) ) EnmityPortal = false; // Por precaución, por si la detección de cierre mediante Dialog UI (uiCountdownLabel) no funcionase correctamente.
  376.                     if (EnmityPortal == false)  // El dialog notificando una nueva visión dura 8 seg aproximadamente (y el de cierre 30seg). Con poner 10 seg (600 ticks) deberia bastar, aunque pondré un poco más (15seg, o sea 900 ticks)
  377.                     {
  378.                         if (EnmityPortalStartTick == 0) EnmityPortalStartTick = Hud.Game.CurrentGameTick;
  379.                         else if (Hud.Game.CurrentGameTick - EnmityPortalStartTick > ticksDelayUI) // Retrasar durante breves instantes (30 ticks por defecto) el anuncio de una nueva Visión mediante UI para dar tiempo a aparecer un portal de entrada cercano.
  380.                         {
  381.                             EnmityPortal = true;
  382.                             EnmityPortalStartTick = Hud.Game.CurrentGameTick;
  383.                             EnmityPortalAct = -1;
  384.                             EnmityPortalState = 2;
  385.                             if (EnableSpeak && !string.IsNullOrEmpty(SpeakOpenPortalUI))    Hud.Sound.Speak(SpeakOpenPortalUI); //  Detección de una nueva visión mediante UI, con casi toda probabilidad la puerta de entrada no es detectable aún.
  386.                             if (SoundEnabled) Play_Sound(FileSound);
  387.                         }
  388.                     }
  389.                 }
  390.             }
  391.             if (EnmityPortal)
  392.             {
  393.                 if (Hud.Game.Me.Scene?.SnoArea != null) // Para evitar posibles excepciones: Hud.Game.Me.Scene ser null, por ej cuando acabamos de cruzar un portal cualquiera.
  394.                 {
  395.                     if (EnmityAreasDicc.TryGetValue(Hud.Game.Me.Scene.SnoArea.Sno, out var mylevel))
  396.                     {
  397.                         LevelMe = mylevel;
  398.                         if (EnmityPortalState < 5) // Find Chest (Find Goblin)
  399.                         {
  400.                             var chest = Hud.Game.Actors.FirstOrDefault(c => c.SnoActor.Sno == ActorSnoEnum._p76_chest);
  401.                             if (chest != null )
  402.                             {
  403.                                 if (chest.IsDisabled || chest.IsOperated)
  404.                                 {
  405.                                     EnmityPortalState = 5;  // Chest Open
  406.                                     OpenChestTick = Hud.Game.CurrentGameTick;
  407.                                 }
  408.                                 else if (EnmityPortalState < 4)
  409.                                 {
  410.                                     EnmityPortalState = 4;  // Chest Found
  411.                                     if (EnableSpeak && !string.IsNullOrEmpty(SpeakChestFound)) Hud.Sound.Speak(SpeakChestFound);
  412.                                 }
  413.  
  414.                             }
  415.                             else if (EnmityPortalState < 3) // Find Goblin
  416.                             {
  417.                                 if (Hud.Game.AliveMonsters.Any(a => a.SnoActor.Sno == ActorSnoEnum._p76_treasuregoblin_a_noportal))
  418.                                 {
  419.                                     EnmityPortalState = 3;  // Goblin Found
  420.                                     if (EnableSpeak && !string.IsNullOrEmpty(SpeakGoblinFound)) Hud.Sound.Speak(SpeakGoblinFound); //105371
  421.                                 }
  422.                             }
  423.                         }
  424.                     }
  425.                     else LevelMe = 0;
  426.                 }
  427.                 if (EnmityPortalState == 5 && (Hud.Game.CurrentGameTick - OpenChestTick > TicksForAutoClose))   EnmityPortal = false; // Por precaución, por si la detección de cierre mediante Dialog UI no funcionase correctamente.
  428.                 if (uiCountdownLabel?.Visible == true)
  429.                 {
  430.                     if (EnmityPortalState != 6)
  431.                     {
  432.                         var text = uiCountdownLabel.ReadText(Encoding.UTF8, true); // Root.NormalLayer.Countdown_main.count_down.timer_label
  433.                         if (!string.IsNullOrEmpty(text) && Regex.IsMatch(text,@"\b(vision|visión|Visione|Wizja|visão|Видение|환영|幻象結束時間尚餘)\b", RegexOptions.IgnoreCase))
  434.                         {
  435.                             EnmityPortalState = 6;
  436.                             if (EnableSpeak && !string.IsNullOrEmpty(SpeakClosingPortal))   Hud.Sound.Speak(SpeakClosingPortal);
  437.                         }
  438.                     }
  439.                 }
  440.                 else  if (EnmityPortalState == 6)
  441.                 {
  442.                     EnmityPortal = false;
  443.                     ClosedPortalUITick =  Hud.Game.CurrentGameTick + 90;  // Tras cerrarse el dialog, el portal puede seguir detectándose durante unos instantes y así evito interpretarlo como una nueva visión. Normalmente sólo es detectable durante 2-6 ticks
  444.                     if (EnableSpeak && !string.IsNullOrEmpty(SpeakClosedPortal)) Hud.Sound.Speak(SpeakClosedPortal);
  445.                 }
  446.             }
  447.         }
  448.  
  449.         public void PaintTopInGame(ClipState clipState)
  450.         {
  451.             if (!Hud.Game.IsInGame || !Hud.Game.Me.Powers.BuffIsActive(488544)) return;
  452.             if (clipState == ClipState.AfterClip)
  453.             {
  454.                 if (EnmityPortal && ShowWaypoint && EnmityWaypoint != 0 && Hud.Game.MapMode == MapMode.WaypointMap )
  455.                 {
  456.                     var numBountyAct = Hud.Game.ActMapCurrentAct;
  457.                     if (numBountyAct == BountyAct.None) // Turbo Free Bug
  458.                     {
  459.                         foreach (var data in DataUiEBountyAct)
  460.                         {
  461.                             if (data.Key.Visible) { numBountyAct = data.Value; break; }
  462.                         }
  463.                     }
  464.                     var waypoint = Hud.Game.ActMapWaypoints.FirstOrDefault(w => w.BountyAct == numBountyAct && w.TargetSnoArea.Sno == EnmityWaypoint);
  465.                     if (waypoint != null)
  466.                     {
  467.                         var width = 220 * Hud.Window.HeightUiRatio; var height = 100 * Hud.Window.HeightUiRatio;
  468.                         var x = Hud.Render.WorldMapUiElement.Rectangle.X + waypoint.CoordinateOnMapUiElement.X * Hud.Window.HeightUiRatio + width * 0.315f;
  469.                         var y = Hud.Render.WorldMapUiElement.Rectangle.Y + waypoint.CoordinateOnMapUiElement.Y * Hud.Window.HeightUiRatio + height * 0.11f;
  470.                         var texture = Hud.Texture.GetTexture(TextureId);
  471.                         texture.Draw( x, y, width * 0.09f, width * 0.11f);
  472.                     }
  473.                 }
  474.             }
  475.             else if (clipState == ClipState.BeforeClip)
  476.             {
  477.                 if (EnableTextScreen && Hud.Game.Me.InGreaterRiftRank == 0)
  478.                 {
  479.                     if (EnmityPortal)
  480.                     {
  481.                         int t = (Hud.Game.CurrentGameTick - EnmityPortalStartTick)/ 60;
  482.                         string text = string.Format(TextScreen, // {0}=Act, {1}=Area NameLocalized, {2}=time, {3}=Levels, {4}=TextMoreLeveles, {5}=TextGoblin, {6}=TextChest/TextChestOpen, {7}=TextClosing, {8}=state (for debug)
  483.                             (EnmityPortalAct < 1)? "?" : EnmityPortalAct.ToString(),
  484.                             (EnmityPortalAct < 0)? TextLocUnKnown : EnmityPortalArea,
  485.                             (EnmityPortalStartTick == 0) ? "??" : string.Format(TextTimeFormat, t/60, t%60),
  486.                             (PortalCountFound == 0)? 1 : PortalCountFound,
  487.                             (EnmityPortalState < 3 && PortalCountFound < maxLevels)? TextMoreLeveles : "",
  488.                             (LevelMe == 0)? TextNoLevelMe : string.Format(TextLevelMe, LevelMe),
  489.                             (EnmityPortalState == 3)? TextGoblin
  490.                                 : EnmityPortalState == 4? TextChest
  491.                                     : EnmityPortalState == 5? TextChestOpen
  492.                                         : EnmityPortalState == 6? string.Format(TextClosing, CounDownTimeFunc())
  493.                                             : ""
  494.                         );
  495.                         FontTextShow.DrawText(FontTextShow.GetTextLayout(text), Hud.Window.Size.Width * OffsetX, Hud.Window.Size.Height * OffsetY);
  496.                     }
  497.                     else
  498.                     {
  499.                         FontTextHide.DrawText(FontTextHide.GetTextLayout(string.Format(TextNoPortal)), Hud.Window.Size.Width * OffsetX, Hud.Window.Size.Height * OffsetY);
  500.                     }
  501.                 }
  502.             }
  503.         }
  504.  
  505.         public void PaintWorld(WorldLayer layer)
  506.         {
  507.             if (layer != WorldLayer.Ground || !Hud.Game.IsInGame || !Hud.Game.Me.Powers.BuffIsActive(488544)) return;
  508.             var portal = Hud.Game.Portals.FirstOrDefault(p => p.ActorAvailable && EnmityPortals.Contains(p.SnoActor.Sno)); // Solo habrá uno, no es necesario usar un bucle
  509.             if (portal != null && portal.AnnId != 0)
  510.             {
  511.                 if (EnmityPortalsOrderDicc.TryGetValue(portal.AnnId, out var order))
  512.                 {
  513.                     string labelText = (order == -1)? LabelNextPortal : ((order == 0) ? LabelFirstPortal : string.Format(LabelNextPortalOrder,order));
  514.                     EnmityPortalLabel.Paint(WorldLayer.Ground, portal, portal.FloorCoordinate, labelText);
  515.                     EnmityPortalLabel.Paint(WorldLayer.Map, portal, portal.FloorCoordinate, labelText);
  516.                 }
  517.             }
  518.         }
  519.     }
  520. }
Advertisement
Add Comment
Please, Sign In to add comment