Advertisement
RNNCode

EnmityVisionPlugin

Apr 16th, 2024 (edited)
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 25.08 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<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)
  16.         {
  17.             {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},
  18.             {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},
  19.             {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},
  20.             {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},
  21.             {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},
  22.             {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},
  23.             {464810, 464065}, {464821, 464065}, {464822, 464065}, {109149, 109514}, {143648, 109514}, {446367, 409001}, {201668, 409517}, {201670, 409517}, {198564, 109538}, {215396, 109538}, {205434, 109540}, {109563, 109540}, {153669, 109540},
  24.             {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},
  25.             {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},
  26.             {308487, 263493}, {336846, 261758}, {336847, 261758}, {314782, 261758}, {338956, 261758}, {158594, 57425}, {218511, 93103}, {446550, 109540},   {129375, 93632}, {235003, 258142}, {336577, 258142}, {448368, 338602}, {322645, 338602},
  27.             {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},
  28.             {448391, 261758}, {448039, 109538}, {87832, 19775}, {94672, 19775}, {205424, 69504}, {169494, 57425}, {194239, 57425}, {182502, 155048}, {221761, 155048}, {338931, 261758}, {338970, 261758}, {448398, 283567}, {221702, 155048},
  29.             {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},
  30.             {448375, 338602}, {445792, 409512}, {448411, 283567}, {179567, 19952}, {166127, 63666},
  31.             {257116, 119653}, {256767, 332339}, {374239, 332339}, {256106, 332339}, {256742, 332339}, // Ubers 446367
  32.         };
  33.  
  34.         protected IUiElement uiShowPortal;
  35.         protected IUiElement uiCountdownLabel;
  36.         protected IUiElement uiCountdownTimer;
  37.  
  38.         public WorldDecoratorCollection EnmityPortalLabel { get; set; }
  39.  
  40.         public bool ShowWaypoint { get; set; }
  41.  
  42.         public bool EnableSpeak { get; set; }
  43.  
  44.         public string SpeakOpenPortalUI { get; set; }
  45.         public string SpeakOpenPortalArea { get; set; }
  46.         public string SpeakClosingPortal { get; set; }
  47.         public string SpeakClosedPortal { get; set; }
  48.         public string SpeakChestFound { get; set; }
  49.         public string SpeakGoblinFound { get; set; }
  50.         public string SpeakFirstPortal { get; set; }
  51.         public string SpeakNextPortal { get; set; }
  52.         public string SpeakNextPortalOrder { get; set; }
  53.  
  54.         public string LabelFirstPortal { get; set; }
  55.         public string LabelNextPortal { get; set; }
  56.         public string LabelNextPortalOrder { get; set; }
  57.  
  58.         public bool EnableTextScreen { get; set; }
  59.  
  60.         public string TextScreen { get; set; }
  61.         public string TextLocUnKnown { get; set; }
  62.         public string TextNoPortal { get; set; }
  63.         public string TextMoreLeveles { get; set; }
  64.         public string TextClosing { get; set; }
  65.         public string TextTimeFormat { get; set; }
  66.         public string TextGoblin { get; set; }
  67.         public string TextChest { get; set; }
  68.         public string TextChestOpen { get; set; }
  69.  
  70.         public float OffsetX { get; set; } = 0;
  71.         public float OffsetY { get; set; } = 0;
  72.         public string TextLastVision { get; set; }
  73.  
  74.         public bool SoundEnabled { get; set; }
  75.         public string FileSound { get; set; }
  76.  
  77.         private int PortalCountFound { get; set;} = 0;
  78.         private int EnmityPortalStartTick { get; set;} = 0;
  79.         private int EnmityPortalState { get; set;} = 0;
  80.         private uint PortalAnnIdLast { get; set;} = 0;
  81.  
  82.         private int ClosedPortalUITick { get; set;} = 0;
  83.         private int OpenChestTick { get; set;} = 0;
  84.         private const int maxLevels = 15;
  85.         private const int TicksForAutoClose = 1920;         // OpenChestTick + 30 seg + 2 margen (32 * 60)
  86.         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)
  87.         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.
  88.         private int EnmityPortalAct { get; set; } = -1;
  89.         private string EnmityPortalArea { get; set; } = string.Empty;
  90.         private uint EnmityWaypoint { get; set; } = 0;
  91.  
  92.         private delegate int CounDownTime();
  93.         private CounDownTime CounDownTimeFunc;
  94.  
  95.         public IFont FontTextShow { get; set; }
  96.         public IFont FontTextHide { get; set; }
  97.         public uint TextureId { get; set; } = 3122228893;
  98.  
  99.         private bool _EnmityPortal { get; set; } = false;
  100.         public bool EnmityPortal
  101.         {
  102.             get { return _EnmityPortal; }
  103.             set
  104.             {
  105.                 if (_EnmityPortal != value)
  106.                 {
  107.                     _EnmityPortal = value;
  108.                     foreach(var d in EnmityAreasDicc.Keys.ToList()) { EnmityAreasDicc[d] = false; }
  109.                     EnmityPortalsOrderDicc.Clear();
  110.                     PortalCountFound = 0;
  111.                     EnmityPortalState = 0;
  112.                     EnmityPortalAct = -1;
  113.                     EnmityPortalArea = string.Empty;
  114.                     EnmityWaypoint = 0;
  115.                     EnmityPortalStartTick = 0;
  116.                     PortalAnnIdLast = 0;
  117.                 }
  118.             }
  119.         }
  120.  
  121.         private Dictionary<uint,bool> EnmityAreasDicc { get; set; } = new Dictionary<uint,bool>
  122.         {
  123.             {488740, false },   //  P76_NestingNewTristram_SeasonTheme
  124.             {488741, false },   //  P76_NestingOldTristram_SeasonTheme
  125.             {488742, false },   //  P76_NestingGraveyard_Act1_SeasonTheme
  126.             {488743, false },   //  P76_NestingBloodPit_SeasonTheme Normal
  127.             {488745, false },   //  P76_NestingBoneyard_SeasonTheme Normal
  128.             {488746, false },   //  P76_NestingMoor_Sacrifice_SeasonTheme
  129.             {488767, false },   //  P76_NestingAlcarnus_SeasonTheme
  130.             {488770, false },   //  P76_NestingChurch_SeasonTheme
  131.             {488799, false },   //  P76_NestingSescheron_SeasonTheme
  132.             {488800, false },   //  P76_NestingForestTower_SeasonTheme
  133.             {488870, false },   //  P76_NestingRam_SeasonTheme
  134.             {488871, false },   //  P76_NestingSpire_SeasonTheme
  135.             {488872, false },   //  P76_NestingHell_SeasonTheme
  136.             {488873, false },   //  P76_NestingGideonsCourt_SeasonTheme
  137.             {488874, false },   //  P76_NestingBog_SeasonTheme
  138.         };
  139.  
  140.         private HashSet<ActorSnoEnum> EnmityPortals { get; set; } = new HashSet<ActorSnoEnum> {
  141.             ActorSnoEnum._p76_portal_oldtristram_seasontheme,
  142.             ActorSnoEnum._p76_portal_newtristram_seasontheme,
  143.             ActorSnoEnum._p76_portal_graveyardact1_seasontheme,
  144.             ActorSnoEnum._p76_portal_bloodpit_seasontheme,
  145.             ActorSnoEnum._p76_portal_moors_sacrifice_seasontheme,
  146.             ActorSnoEnum._p76_portal_boneyard_seasontheme,
  147.             ActorSnoEnum._p76_portal_church_seasontheme,
  148.             ActorSnoEnum._p76_portal_alcarnus_seasontheme,
  149.             ActorSnoEnum._p76_portal_sescheron_seasontheme,
  150.             ActorSnoEnum._p76_portal_foresttower_seasontheme,
  151.             ActorSnoEnum._p76_portal_bog_seasontheme,
  152.             ActorSnoEnum._p76_portal_gideonscourt_seasontheme,
  153.             ActorSnoEnum._p76_portal_spire_seasontheme,
  154.             ActorSnoEnum._p76_portal_hell_seasontheme,
  155.             ActorSnoEnum._p76_portal_ram_seasontheme,
  156.         };
  157.  
  158.         private Dictionary<uint,int> EnmityPortalsOrderDicc { get; set; } = new Dictionary<uint,int>();
  159.  
  160.         public EnmityVisionPlugin()
  161.         {
  162.             Enabled = true;
  163.         }
  164.  
  165.         public override void Load(IController hud)
  166.         {
  167.             base.Load(hud);
  168.  
  169.             ShowWaypoint = true;
  170.  
  171.             SoundEnabled = true;                // Alert sound for a new Vision
  172.             FileSound = "notification_9.wav";   // File to be played. It must be in the Sounds\ folder
  173.  
  174.             EnableSpeak = true; // false to disable all speak
  175.             SpeakOpenPortalUI = "A portal opens away from you"; // null or empty not to speak, vision is detected via UI
  176.             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
  177.             SpeakClosingPortal = "The portal is closing";       // null or empty not to speak
  178.             SpeakClosedPortal = "The Portal is closed";         // null or empty not to speak
  179.             SpeakChestFound = "Chest of Visions";               // null or empty not to speak
  180.             SpeakGoblinFound = "Goblin of Visions";             // null or empty not to speak
  181.             SpeakFirstPortal = "Entrance Found";    // Speak when the entry portal is found after the vision is detected via UI
  182.             SpeakNextPortalOrder = "Level {0}";     // Speak portals , {0} = Level number
  183.             SpeakNextPortal  = "Next Level";        // Speak portals. Show When the number of levels cannot be set
  184.  
  185.             LabelFirstPortal = "Entrance";          // Show when the entry Portal has been found
  186.             LabelNextPortalOrder = "Level {0}";     // {0} = Level number
  187.             LabelNextPortal  = "Next Level";        // Show when the number of levels cannot be set
  188.  
  189.             EnableTextScreen = true;                    // Show TextScreen line
  190.             TextScreen  = "Enmity Vision: A{0} - {1} ({2} ago, {3}{4} levels). {5}{6}{7}"; // {0}=Act, {1}=Area NameLocalized, {2}=time, {3}=Levels, {4}=TextMoreLeveles, {5}=TextGoblin, {6}=TextChest/TextChestOpen, {7}=TextClosing
  191.             TextLocUnKnown  = "\"Location unknown\"";   // Portal opened but not detected.
  192.             TextNoPortal = "Untracked Visions.";        // No active portal.
  193.             TextMoreLeveles = " or more";               // shown if there is a possibility of more levels
  194.             TextClosing = "Closing ... {0}s";           // show if the portal is closing. {0}=time
  195.             TextGoblin = "Goblin found";
  196.             TextChest = "Chest found";
  197.             TextChestOpen = "Chest open";
  198.  
  199.             TextTimeFormat = "{0:0}m{1:0}s";                // Format for Time since vision was detected // {0} = minutes, {1} = seconds
  200.  
  201.             OffsetX = 0.055f;   // 0f...1f Set the x coordinate for TextScreen
  202.             OffsetY = 0.001f;   // 0f...1f Set the y coordinate for TextScreen
  203.  
  204.             EnmityPortalLabel = new WorldDecoratorCollection(
  205.                 new GroundLabelDecorator(Hud)
  206.                 {
  207.                     ForceOnScreen= false,
  208.                     BorderBrush = Hud.Render.CreateBrush(255, 193, 226, 255, 1),
  209.                     BackgroundBrush = Hud.Render.CreateBrush(220, 73, 89, 255, 0),
  210.                     TextFont = Hud.Render.CreateFont("tahoma", 7, 220, 193, 226, 255, true, false, false)
  211.                 },
  212.                 new MapLabelDecorator(Hud)
  213.                 {
  214.                     LabelFont = Hud.Render.CreateFont("tahoma", 5, 220, 193, 226, 255, false, false, true),
  215.                     RadiusOffset = 18,
  216.                 }
  217.             );
  218.  
  219.             FontTextShow = Hud.Render.CreateFont("tahoma", 8f, 250, 0, 250, 0, false, false, 250, 0, 0, 0, true);
  220.             FontTextHide = Hud.Render.CreateFont("tahoma", 8f, 50, 0, 250, 0, false, false, false);
  221.  
  222.             uiShowPortal = Hud.Render.RegisterUiElement("Root.NormalLayer.game_notify_dialog_backgroundScreen.game_text_line0", null, null);
  223.             uiCountdownLabel = Hud.Render.RegisterUiElement("Root.NormalLayer.Countdown_main.count_down.timer_label", null, null);
  224.             uiCountdownTimer = Hud.Render.RegisterUiElement("Root.NormalLayer.Countdown_main.count_down.timer", null, null);
  225.  
  226.             CounDownTimeFunc = () => {
  227.                                         var t = 0;
  228.                                         if (uiCountdownTimer?.Visible == true)
  229.                                         {
  230.                                             Int32.TryParse(uiCountdownTimer.ReadText(Encoding.UTF8, true), out t);
  231.                                         }
  232.                                         return t;
  233.                                     };
  234.         }
  235.  
  236.         public void Play_Sound(string playFile)
  237.         {
  238.             var playSonido = Hud.Sound.LoadSoundPlayer(playFile);
  239.             ThreadPool.QueueUserWorkItem(state =>
  240.             {
  241.                try  { playSonido.PlaySync(); }
  242.                catch (Exception)  {   }
  243.             });
  244.         }
  245.  
  246.         public void OnNewArea(bool newGame, ISnoArea area)
  247.         {
  248.             if (newGame)
  249.             {
  250.                 EnmityPortal = false;
  251.                 ClosedPortalUITick = 0;
  252.                 OpenChestTick = 0;
  253.             }
  254.  
  255.             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
  256.             {
  257.                 if (Hud.Game.ActMapWaypoints.FirstOrDefault(w => w.TargetSnoArea.Sno == Hud.Game.Me.SnoArea.Sno) != null)   DebugTA = area.Sno;
  258.                 else if (!Area_Waypoint_Dict.ContainsKey(area.Sno) && DebugTA != 0)
  259.                 {
  260.                     Area_Waypoint_Dict.Add(area.Sno, DebugTA); // Añade temporalmente al diccionario las nuevas áreas.
  261.                     if (DebugEnabled) // Serán añadidas al diccionario una vez comprobadas , las guardo en un log
  262.                     {
  263.                         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);
  264.                         Hud.Sound.Speak("Nueva área");
  265.                     }
  266.                 }
  267.             }
  268.         }
  269.  
  270.         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
  271.         {
  272.             if (Hud.Game.IsLoading || Hud.Game.IsPaused || !Hud.Game.IsInGame || !Hud.Game.Me.Hero.Seasonal) return;
  273.  
  274.             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)
  275.             if (portal != null && portal.AnnId != 0 && portal.Scene != null && Hud.Game.CurrentGameTick > ClosedPortalUITick)   // Solo habrá uno, no es necesario usar un bucle
  276.             {
  277.                 if (EnmityAreasDicc.TryGetValue(portal.TargetArea.Sno, out var registered)) // el destino del portal es uno de las áreas de las visiones
  278.                 {
  279.                     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)
  280.                     {
  281.                         if (EnmityPortal && PortalAnnIdLast != 0 && portal.AnnId != PortalAnnIdLast)
  282.                         {  // 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.
  283.                             EnmityPortal = false;
  284.                             registered = false;
  285.                         }
  286.                         if (registered == false) // portal no fue registrado anteriormente
  287.                         {
  288.                             if (EnmityPortal == false)
  289.                             {
  290.                                 EnmityPortal = true;
  291.                                 EnmityPortalState = 1;
  292.                                 EnmityPortalStartTick = Hud.Game.CurrentGameTick;
  293.                                 if (EnableSpeak)
  294.                                 {
  295.                                     if (!string.IsNullOrEmpty(SpeakOpenPortalArea))     Hud.Sound.Speak(SpeakOpenPortalArea);   // Detección de una nueva visión mediante un portal de entrada cercano
  296.                                     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
  297.                                 }
  298.                                 if (SoundEnabled) Play_Sound(FileSound);
  299.                             }
  300.                             else
  301.                             {
  302.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakFirstPortal))     Hud.Sound.Speak(SpeakFirstPortal);  // Anuncia un portal de entrada encontrado instantes despues de detectar la visión mediante UI
  303.                             }
  304.                             PortalAnnIdLast = portal.AnnId;
  305.                             EnmityAreasDicc[portal.TargetArea.Sno] = true;
  306.                             EnmityPortalsOrderDicc[portal.AnnId] = 0;
  307.  
  308.                             PortalCountFound = 1;
  309.                             EnmityPortalAct = portal.Scene.SnoArea.Act;
  310.                             EnmityPortalArea = portal.Scene.SnoArea.NameLocalized;
  311.  
  312.                             if (Hud.Game.ActMapWaypoints.FirstOrDefault(w => w.TargetSnoArea.Sno == Hud.Game.Me.SnoArea.Sno) != null)
  313.                             {
  314.                                 EnmityWaypoint = Hud.Game.Me.SnoArea.Sno;
  315.                             }
  316.                             else if (Area_Waypoint_Dict.TryGetValue(Hud.Game.Me.SnoArea.Sno, out var r))
  317.                             {
  318.                                 EnmityWaypoint = r;
  319.                             }
  320.                             else EnmityWaypoint = 0;
  321.                         }
  322.                     }
  323.                     else
  324.                     {
  325.                         if (registered == false)  // no hay portal registrado con el mismo área de destino
  326.                         {
  327.                             if (EnmityAreasDicc[portal.Scene.SnoArea.Sno]) // sólo voy registrando portales consecutivos, en cadena (ya hubo un portal anterior con destino igual al área donde aparece éste)
  328.                             {
  329.                                 EnmityAreasDicc[portal.TargetArea.Sno] = true;
  330.                                 PortalCountFound++;
  331.                                 EnmityPortalsOrderDicc[portal.AnnId] = PortalCountFound;
  332.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakNextPortalOrder)) Hud.Sound.Speak(string.Format(SpeakNextPortalOrder, PortalCountFound));
  333.                             }
  334.                             else if (!EnmityPortalsOrderDicc.ContainsKey(portal.AnnId))
  335.                             {
  336.                                 EnmityPortalsOrderDicc.Add(portal.AnnId, -1);
  337.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakNextPortal))      Hud.Sound.Speak(SpeakNextPortal);
  338.                             }
  339.                         }
  340.                     }
  341.                 }
  342.             }
  343.             if (uiShowPortal?.Visible == true)
  344.             {
  345.                 var text = uiShowPortal.ReadText(Encoding.UTF8, true); // Root.NormalLayer.game_notify_dialog_backgroundScreen.game_text_line0
  346.                 if (!string.IsNullOrEmpty(text) && Regex.IsMatch(text,@"(reality!|realidad!|Realität|réalité|realtà!|rzeczywistości!|realidade!|форму!|현실로|一股恨意化為了現實!)"))
  347.                 {
  348.                     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.
  349.                     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)
  350.                     {
  351.                         if (EnmityPortalStartTick == 0) EnmityPortalStartTick = Hud.Game.CurrentGameTick;
  352.                         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.
  353.                         {
  354.                             EnmityPortal = true;
  355.                             EnmityPortalStartTick = Hud.Game.CurrentGameTick;
  356.                             EnmityPortalAct = -1;
  357.                             EnmityPortalState = 2;
  358.                             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.
  359.                             if (SoundEnabled) Play_Sound(FileSound);
  360.                         }
  361.                     }
  362.                 }
  363.             }
  364.             if (EnmityPortal)
  365.             {
  366.                 if (EnmityPortalState < 5) // Find Chest (Find Goblin)
  367.                 {
  368.                     if (Hud.Game.Me.Scene != null && EnmityAreasDicc.ContainsKey(Hud.Game.Me.Scene.SnoArea.Sno)) // Para evitar posibles excepciones: Hud.Game.Me.Scene em ocasiones puede ser null, por ejemplo cuando acabamos de cruzar un portal cualquiera.
  369.                     {
  370.                         var chest = Hud.Game.Actors.FirstOrDefault(c => c.SnoActor.Sno == ActorSnoEnum._p76_chest);
  371.                         if (chest != null )
  372.                         {
  373.                             if (chest.IsDisabled || chest.IsOperated)
  374.                             {
  375.                                 EnmityPortalState = 5;  // Chest Open
  376.                                 OpenChestTick = Hud.Game.CurrentGameTick;
  377.                             }
  378.                             else if (EnmityPortalState < 4)
  379.                             {
  380.                                 EnmityPortalState = 4;  // Chest Found
  381.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakChestFound)) Hud.Sound.Speak(SpeakChestFound);
  382.                             }
  383.  
  384.                         }
  385.                         else if (EnmityPortalState < 3) // Find Goblin
  386.                         {
  387.                             if (Hud.Game.AliveMonsters.Any(a => a.SnoActor.Sno == ActorSnoEnum._p76_treasuregoblin_a_noportal))
  388.                             {
  389.                                 EnmityPortalState = 3;  // Goblin Found
  390.                                 if (EnableSpeak && !string.IsNullOrEmpty(SpeakGoblinFound)) Hud.Sound.Speak(SpeakGoblinFound); //105371
  391.                             }
  392.                         }
  393.                     }
  394.                 }
  395.                 else 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.
  396.                 if (uiCountdownLabel?.Visible == true)
  397.                 {
  398.                     if (EnmityPortalState != 6)
  399.                     {
  400.                         var text = uiCountdownLabel.ReadText(Encoding.UTF8, true); // Root.NormalLayer.Countdown_main.count_down.timer_label
  401.                         if (!string.IsNullOrEmpty(text) && Regex.IsMatch(text,@"\b(vision|visión|Visione|Wizja|visão|Видение|환영|幻象結束時間尚餘)\b", RegexOptions.IgnoreCase))
  402.                         {
  403.                             EnmityPortalState = 6;
  404.                             if (EnableSpeak && !string.IsNullOrEmpty(SpeakClosingPortal))   Hud.Sound.Speak(SpeakClosingPortal);
  405.                         }
  406.                     }
  407.                 }
  408.                 else  if (EnmityPortalState == 6)
  409.                 {
  410.                     EnmityPortal = false;
  411.                     ClosedPortalUITick =  Hud.Game.CurrentGameTick + 60;  // 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
  412.                     if (EnableSpeak && !string.IsNullOrEmpty(SpeakClosedPortal)) Hud.Sound.Speak(SpeakClosedPortal);
  413.                 }
  414.             }
  415.         }
  416.  
  417.         public void PaintTopInGame(ClipState clipState)
  418.         {
  419.             if (!Hud.Game.IsInGame || !Hud.Game.Me.Hero.Seasonal) return;
  420.             if (clipState == ClipState.AfterClip)
  421.             {
  422.                 if (EnmityPortal && ShowWaypoint && EnmityWaypoint != 0 && Hud.Game.MapMode == MapMode.WaypointMap )
  423.                 {
  424.                     var waypoint = Hud.Game.ActMapWaypoints.FirstOrDefault(w => w.BountyAct == Hud.Game.ActMapCurrentAct && w.TargetSnoArea.Sno == EnmityWaypoint);
  425.                     if (waypoint != null)
  426.                     {
  427.                         var width = 220 * Hud.Window.HeightUiRatio; var height = 100 * Hud.Window.HeightUiRatio;
  428.                         var x = Hud.Render.WorldMapUiElement.Rectangle.X + waypoint.CoordinateOnMapUiElement.X * Hud.Window.HeightUiRatio + width * 0.315f;
  429.                         var y = Hud.Render.WorldMapUiElement.Rectangle.Y + waypoint.CoordinateOnMapUiElement.Y * Hud.Window.HeightUiRatio + height * 0.11f;
  430.                         var texture = Hud.Texture.GetTexture(TextureId);
  431.                         texture.Draw( x, y, width * 0.09f, width * 0.11f);
  432.                     }
  433.                 }
  434.             }
  435.             else if (clipState == ClipState.BeforeClip)
  436.             {
  437.                 if (EnableTextScreen)
  438.                 {
  439.                     if (EnmityPortal)
  440.                     {
  441.                         int t = (Hud.Game.CurrentGameTick - EnmityPortalStartTick)/ 60;
  442.                         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)
  443.                             (EnmityPortalAct < 1)? "?" : EnmityPortalAct.ToString(),
  444.                             (EnmityPortalAct < 0)? TextLocUnKnown : EnmityPortalArea,
  445.                             (EnmityPortalStartTick == 0) ? "??" : string.Format(TextTimeFormat, t/60, t%60),
  446.                             (PortalCountFound == 0)? 1 : PortalCountFound,
  447.                             (EnmityPortalState < 3 && PortalCountFound < maxLevels)? TextMoreLeveles : "",
  448.                             (EnmityPortalState == 3)? TextGoblin: "",
  449.                             (EnmityPortalState == 4)? TextChest : ((EnmityPortalState == 5)?TextChestOpen:""),
  450.                             (EnmityPortalState == 6)? string.Format(TextClosing, CounDownTimeFunc()) : "",
  451.                             EnmityPortalState
  452.                         );
  453.                         FontTextShow.DrawText(FontTextShow.GetTextLayout(text), Hud.Window.Size.Width * OffsetX, Hud.Window.Size.Height * OffsetY);
  454.                     }
  455.                     else
  456.                     {
  457.                         FontTextHide.DrawText(FontTextHide.GetTextLayout(string.Format(TextNoPortal)), Hud.Window.Size.Width * OffsetX, Hud.Window.Size.Height * OffsetY);
  458.                     }
  459.                 }
  460.             }
  461.         }
  462.  
  463.         public void PaintWorld(WorldLayer layer)
  464.         {
  465.             if (layer != WorldLayer.Ground || !Hud.Game.IsInGame || !Hud.Game.Me.Hero.Seasonal) return;
  466.             var portal = Hud.Game.Portals.FirstOrDefault(p => p.ActorAvailable && EnmityPortals.Contains(p.SnoActor.Sno)); // Solo habrá uno, no es necesario usar un bucle
  467.             if (portal != null && portal.AnnId != 0)
  468.             {
  469.                 if (EnmityPortalsOrderDicc.TryGetValue(portal.AnnId, out var order))
  470.                 {
  471.                     string labelText = (order == -1)? LabelNextPortal : ((order == 0) ? LabelFirstPortal : string.Format(LabelNextPortalOrder,order));
  472.                     EnmityPortalLabel.Paint(WorldLayer.Ground, portal, portal.FloorCoordinate, labelText);
  473.                     EnmityPortalLabel.Paint(WorldLayer.Map, portal, portal.FloorCoordinate, labelText);
  474.                 }
  475.             }
  476.         }
  477.     }
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement