Code:
using System;
using Turbo.Plugins.Default;
using System.Collections.Generic;
using System.Linq;
using SharpDX.DirectInput;
namespace Turbo.Plugins.RNN
{
public class BountiesTracking : BasePlugin, IKeyEventHandler, INewAreaHandler, IInGameTopPainter, IAfterCollectHandler, ICustomizer
{
public float xpos { get; set; }
public float ypos { get; set; }
private float x { get; set; }
private float y { get; set; }
private IFont DefaultFont { get; set; }
private IFont DefaultFontm { get; set; }
private IFont DefaultFontmTown { get; set; }
private IFont DefaultFontmBoss { get; set; }
private IFont SpecialFontm { get; set; }
private IFont GrisFont { get; set; }
private IFont VerdeFont { get; set; }
private IFont OrangeFont { get; set; }
private IFont RojoFont { get; set; }
private IFont SelecFont { get; set; }
private IFont BossFont { get; set; }
private IFont BossGoFont { get; set; }
private IFont BossWaitFont { get; set; }
private IFont ChestFont { get; set; }
private IBrush BrushTown { get; set; }
private IBrush BrushShadow { get; set; }
private Dictionary<uint, Tuple<string,string>> QuestBosses { get; set; }
private Dictionary<uint, int> ActFix { get; set; }
private List<uint> Chests100_Sno { get; set; }
private List<uint> EspecialMap { get; set; }
public bool BTr_On { get; set; }
public bool TurnOffWhenNewGameStarts { get; set; }
public int BossActive { get; set; }
public IKeyEvent ToggleKeyEvent { get; set; }
public Key Hot_Key
{
get { return ToggleKeyEvent.Key; }
set { ToggleKeyEvent = Hud.Input.CreateKeyEvent(true, value, false, false, false); }
}
public int [] OrderActs { get; set; }
public bool PlayerInTownGray { get; set; }
public bool MeInRiftOFF { get; set; }
private bool[] HCache { get; set; } = new bool[] { false, false, false, false, false, false };
private List<int> HCacheList { get; set; } = new List<int>();
private bool once { get; set; }
private int nCache { get; set; } = 0;
private float OffsetA { get; set; } = 0f;
private float OffsetB { get; set; } = 0f;
private float OffsetH { get; set; } = 0f;
private float pH { get; set; } = 1.1f;
private int MyIndex { get; set; } = -1;
private TopLabelDecorator BTtimersDecorator { get; set; }
public BountiesTracking()
{
Enabled = true;
}
public override void Load(IController hud) {
base.Load(hud);
Order = 31002;
xpos = 0.90f;
ypos = 0.79f;
Hot_Key = Key.F7;
OrderActs = new int[] { 2, 4, 1, 3, 5 }; // Orden en el que hay que completar los bosses para que todos los jugadores lo sigan.
PlayerInTownGray = true;
MeInRiftOFF = true;
TurnOffWhenNewGameStarts = false;
BTr_On = false;
BossActive = 0;
DefaultFont = Hud.Render.CreateFont("tahoma", 8f, 255, 190, 155, 115, false, false, 250, 0, 0, 0, true);
DefaultFontm = Hud.Render.CreateFont("tahoma", 7f, 200, 190, 155, 115, false, false, 250, 0, 0, 0, true);
DefaultFontmTown = Hud.Render.CreateFont("tahoma", 7f, 220, 135, 130, 125, false, false, 250, 0, 0, 0, true);
DefaultFontmBoss = Hud.Render.CreateFont("tahoma", 7f, 220, 255, 128, 0, false, false, 250, 0, 0, 0, true);
SpecialFontm = Hud.Render.CreateFont("tahoma", 7f, 50, 250, 250, 250, false, false, true);
VerdeFont = Hud.Render.CreateFont("tahoma", 8f, 250, 0, 250, 0, false, false, 250, 0, 0, 0, true);
OrangeFont = Hud.Render.CreateFont("tahoma", 8f, 250, 255, 128, 0, false, false, 250, 0, 0, 0, true);
RojoFont = Hud.Render.CreateFont("tahoma", 8f, 250, 255, 0, 0, false, false, 250, 0, 0, 0, true);
GrisFont = Hud.Render.CreateFont("tahoma", 8f, 255, 128, 128, 128, false, false, 250, 0, 0, 0, true);
BossGoFont = Hud.Render.CreateFont("tahoma", 7f, 250, 0, 250, 0, true, true, 160, 0, 0, 0, true);
BossWaitFont = Hud.Render.CreateFont("tahoma", 7f, 250, 255, 0, 0, true, true, 160, 0, 0, 0, true);
BossFont = Hud.Render.CreateFont("tahoma", 7f, 250, 0, 150, 0, true, true, 160, 0, 0, 0, true);
ChestFont = Hud.Render.CreateFont("tahoma", 7f, 250, 255, 128, 0, true, true, 160, 0, 0, 0, true);
BrushTown = hud.Render.CreateBrush(255, 255, 128, 0, 5);
BrushShadow = Hud.Render.CreateBrush(150, 0, 0, 0, (BrushTown.StrokeWidth < 0) ? BrushTown.StrokeWidth - 1: BrushTown.StrokeWidth + 1);
// SnoQuest.Sno de contratos en los que aparece un cofre y hay que matar 100 monstruos en 60 seg.
Chests100_Sno = new List<uint>
{
365381, 369789, 369944, 375191, 375201, //1
369800, 375257, 375261, 464596, 464598, 466835, //2
369825, 436269, 447218, //3
369878, 409897, 467798, 470608, 470561, //4
375268, 375275, 375278, 375348, 445139, 445158 //5
};
EspecialMap = new List<uint>
{
// 288482, 288684, 288686, 288797, 288799, 288801, 288803, 288809, 288812, 288813, // Rift, GRift level 1-10 . Finalmente usaré la doble comprobación con 288482
434650, // Cow
257116, 256767, 256106, 256742, 374239, // Ubers
409094, // Chupivilla
380773,380774, // Vault
483058,483085 // Vault Ancient
};
// (SnoArea.Sno,act) para conocer el acto al que pertenecen los mapas nuevos, al parecer no tienen asociado un acto en TH
ActFix = new Dictionary<uint, int>
{
{63666, 1}, {445426, 1}, //1
{456638, 2}, {460671, 2}, {464092, 2}, {464830, 2}, {465885, 2}, {467383, 2}, //2
{444307, 3}, {445762, 3}, //3
{444396, 4}, {445792, 4}, {446367, 4}, {446550, 4}, {448011, 4}, {448039, 4}, //4
{464063, 4}, {464065, 4}, {464066, 4},
{464810, 4}, {464820, 4}, {464821, 4}, {464822, 4}, {464857, 4}, {464858, 4},
{464865, 4}, {464867, 4}, {464868, 4}, {464870, 4}, {464871, 4}, {464873, 4},
{464874, 4}, {464875, 4}, {464882, 4}, {464886, 4}, {464889, 4}, {464890, 4},
{464940, 4}, {464941, 4}, {464942, 4}, {464943, 4}, {464944, 4},
{475854, 4}, {475856, 4},
{448391, 5}, {448368, 5}, {448375, 5}, {448398, 5}, {448404,5}, {448411,5}, //5
};
// SnoQuest.Sno de los Contratos en los que nos piden Matar a un Boss
QuestBosses = new Dictionary<uint, Tuple<string,string>>
{
{347032, new Tuple<string,string>("Butcher", "|90881|")}, {345528, new Tuple<string,string>("Araneae", "|62726|")}, //1
{361234, new Tuple<string,string>("Sk. King", "|19789|")},
{347656, new Tuple<string,string>("Kulle", "|60194|")}, {358353, new Tuple<string,string>("Belial", "|60757|")}, //2
{347558, new Tuple<string,string>("Maghda", "|195268|")}, {474066, new Tuple<string,string>("Vidian", "|467383|")},
{346166, new Tuple<string,string>("Ghom", "|111232|")}, {349242, new Tuple<string,string>("A. Beast", "|112580|")}, //3
{349244, new Tuple<string,string>("Azmodan", "|111516|")}, {349224, new Tuple<string,string>("Cydaea", "|119656|")},
{361421, new Tuple<string,string>("Izual", "|215396|")}, {349262, new Tuple<string,string>("Rakanoth", "|143648|")}, //4
{349288, new Tuple<string,string>("Diablo", "|109563|215235|153669|")},
{359915, new Tuple<string,string>("Adria", "|287220|")}, {359927, new Tuple<string,string>("Malthael", "|330576|")}, //5
{359919, new Tuple<string,string>("Urzael", "|308487|")},
};
BTtimersDecorator = new TopLabelDecorator(Hud)
{
TextFont = Hud.Render.CreateFont("tahoma", 6, 180, 255, 255, 0, false, false, false),
BackgroundTexture1 = Hud.Texture.ButtonTextureGray,
BackgroundTexture2 = Hud.Texture.BackgroundTextureGreen,
BackgroundTextureOpacity1 = 0.20f,
BackgroundTextureOpacity2 = 0.20f,
TextFunc = () => "?",
HintFunc = () => BTtimers(),
};
int l = 0; uint found = 0;
foreach(var qb in QuestBosses)
{
if (qb.Value.Item1.Length > l) { l = qb.Value.Item1.Length; found = qb.Key; }
}
OffsetB = VerdeFont.GetTextLayout(QuestBosses[found].Item1).Metrics.Width;
OffsetA = DefaultFont.GetTextLayout("[A5] 5 (+5)").Metrics.Width;
OffsetH = DefaultFont.GetTextLayout("[]").Metrics.Height * pH;
}
public void Customize()
{
x = Hud.Window.Size.Width * xpos;
y = Hud.Window.Size.Height * ypos;
}
public void OnKeyEvent(IKeyEvent keyEvent)
{
if (keyEvent.IsPressed && ToggleKeyEvent.Matches(keyEvent)) { BTr_On = !BTr_On; if (BTr_On == false) BossActive = 0 ; }
}
public string BTtimers()
{
long[,] createdon = new long[,] { {0,long.MaxValue,0},{0,long.MaxValue,0},{0,long.MaxValue,0},{0,long.MaxValue,0},{0,long.MaxValue,0},{0,long.MaxValue,0} };
foreach (var quest in Hud.Game.Quests.Where(quest => quest.SnoQuest.Type == QuestType.Bounty))
{
var acto = quest.SnoQuest.SnoAct.Index ;
if (quest.StartedOn.ElapsedMilliseconds > createdon[acto,0])
{
createdon[acto,0] = (long) quest.StartedOn.ElapsedMilliseconds ;
if (createdon[acto,0] > createdon[0,0]) { createdon[0,0] = createdon[acto,0]; }
}
if (quest.State == QuestState.completed)
{
createdon[acto,2] = createdon[acto,2] + 1;
if (createdon[acto,2] == 5) { createdon[0,2] = createdon[0,2] + 1; }
if (quest.CompletedOn.ElapsedMilliseconds < createdon[acto,1])
{
createdon[acto,1] = (long) quest.CompletedOn.ElapsedMilliseconds;
if (createdon[acto,1] < createdon[0,1]) { createdon[0,1] = createdon[acto,1]; }
}
}
}
string texto = string.Empty; long t = 0;
for (var i = 0; i < 6; i++)
{
if ((createdon[i,2] == 5) && (createdon[i,0] != 0)) { t = (createdon[i,0] - createdon[i,1]) / 1000; }
else { t = createdon[i,0] / 1000; }
if (i == 0) { texto = String.Format("# [{0:0}:{1:00}]", (int) (t / 60), t % 60); }
else { texto = String.Format("{0}\n{1}) {2:0}:{3:00}", texto, i, (int) (t / 60), t % 60); }
}
return texto;
}
public void OnNewArea(bool newGame, ISnoArea area)
{
if (newGame || (MyIndex != Hud.Game.Me.Index) ) // Fix partialment the newGame limitation
{
MyIndex = Hud.Game.Me.Index;
if (TurnOffWhenNewGameStarts)
{
BTr_On = false;
BossActive = 0;
}
once = true;
}
}
public void AfterCollect()
{
if (!Hud.Game.IsInGame) return;
if (once)
{
for (var i = 0; i < 6; i++)
{
HCache[i] = false;
}
nCache = 0;
HCacheList.Clear();
//HCacheList.Add(0);
var HoradricCaches = Hud.Game.Items.Where(x => x.SnoItem.MainGroupCode == "horadriccache");
foreach (var cache in HoradricCaches)
{
HCacheList.Add(cache.Seed);
}
once = false;
}
var InventoryHoradricCaches = Hud.Game.Items.Where(x => x.Location == ItemLocation.Inventory && x.SnoItem.MainGroupCode == "horadriccache");
foreach (var Cache in InventoryHoradricCaches)
{
if (Cache.Seed == 0) continue; // para evitar los .Seed == 0 en los alijos recién cobrados debido a inicialización tardía
if (!HCacheList.Contains(Cache.Seed))
{
HCacheList.Add(Cache.Seed);
if (Cache.SnoItem.Code.Contains("Act1")) { if (HCache[1] == false) { HCache[1] = true; nCache += 1; } }
else if (Cache.SnoItem.Code.Contains("Act2")) { if (HCache[2] == false) { HCache[2] = true; nCache += 1; } }
else if (Cache.SnoItem.Code.Contains("Act3")) { if (HCache[3] == false) { HCache[3] = true; nCache += 1; } }
else if (Cache.SnoItem.Code.Contains("Act4")) { if (HCache[4] == false) { HCache[4] = true; nCache += 1; } }
else if (Cache.SnoItem.Code.Contains("Act5")) { if (HCache[5] == false) { HCache[5] = true; nCache += 1; } }
else continue;
/* nCache = 0; for(var i = 1; i < 6; i++) { if (HCache[i] == true) nCache += 1; } // Hacerlo así sería infalible, pero no detectaría problemas de planteamiento */
}
}
}
public void PaintTopInGame(ClipState clipState) // public enum ClipState { BeforeClip, Inventory, AfterClip }
{
if (Hud.Render.UiHidden) return;
if (Hud.Game.IsInGame && BTr_On)
{
if (clipState == ClipState.BeforeClip)
{
if ( MeInRiftOFF && ((Hud.Game.Me.SnoArea.HostAreaSno == 288482) || (Hud.Game.Me.SnoArea.Sno == 288482)) ) { BossActive = 0; return; }
int [,] Cont_B = new int [6,2] { {0,0},{0,0},{0,0},{0,0},{0,0},{0,0} };
string [] Bosses = new string [6] { " ----" ," ----"," ----"," ----"," ----"," ----" };
int [] Bosses_State = new int [6] { 3,3,3,3,3,3 };
int [] Chests100_State = new int [6] { 0,0,0,0,0,0 };
string BossMap = string.Empty;
foreach (var quest in Hud.Game.Quests.Where(quest => quest.SnoQuest.Type == QuestType.Bounty))
{
var acto = quest.SnoQuest.SnoAct.Index ;
if (quest.State == QuestState.completed) { Cont_B[acto,0] = Cont_B[acto,0] + 1 ; Cont_B[0,0] = Cont_B[0,0] + 1 ; }
else if (quest.State == QuestState.started) { Cont_B[acto,1] = Cont_B[acto,1] + 1 ; Cont_B[0,1] = Cont_B[0,1] + 1 ; }
if (QuestBosses.ContainsKey(quest.SnoQuest.Sno))
{
Bosses[acto] = QuestBosses[quest.SnoQuest.Sno].Item1;
BossMap += QuestBosses[quest.SnoQuest.Sno].Item2;
Bosses_State[acto] = (quest.State == QuestState.completed)? 2 : ( (quest.State == QuestState.started)? 1 : 0 ) ;
}
else if (Chests100_Sno.Contains(quest.SnoQuest.Sno))
{
Chests100_State[acto] = (quest.State == QuestState.completed)? 1 : ( (quest.State == QuestState.started)? 3 : 2 ) ;
}
}
if ((Cont_B[0,0] == 25))
{
if (nCache == 5) { VerdeFont.DrawText(VerdeFont.GetTextLayout("! Bounties Completed !"), x , y ); }
else { OrangeFont.DrawText(OrangeFont.GetTextLayout("! Bounties Completed !"), x , y ); }
}
else { DefaultFont.DrawText(DefaultFont.GetTextLayout( (25 - Cont_B[0,0]) + " Remaining (" + Cont_B[0,1] + " Started)"), x , y ); }
BTtimersDecorator.Paint(x + OffsetA * 2.3f, y + 1, Hud.Window.Size.Width * 0.012f, Hud.Window.Size.Width * 0.01f, HorizontalAlign.Center);
int activo = 0 ;
foreach (int i in OrderActs)
{
if (Bosses_State[i] < 2) { activo = i; break; }
}
BossActive = activo;
var players = Hud.Game.Players;
string [] Players_Act = new string [6] {string.Empty,string.Empty,string.Empty,string.Empty,string.Empty,string.Empty};
string [] Players_ActTown = new string [6] {string.Empty,string.Empty,string.Empty,string.Empty,string.Empty,string.Empty};
string [] Players_Boss = new string [6] {string.Empty,string.Empty,string.Empty,string.Empty,string.Empty,string.Empty};
foreach (var player in players)
{
if ((player.SnoArea.HostAreaSno == 288482) || (player.SnoArea.Sno == 288482) ) continue;
if (EspecialMap.Contains(player.SnoArea.Sno))
{
Players_ActTown[0] += player.BattleTagAbovePortrait + " ";
}
else
{
int acto = player.SnoArea.Act;
if ( (acto > 0) || (ActFix.TryGetValue(player.SnoArea.Sno, out acto)) )
{
if (player.IsInTown && PlayerInTownGray)
{
Players_ActTown[acto] += player.BattleTagAbovePortrait + " ";
}
else if (( Bosses_State[acto] == 1) && BossMap.Contains("|" + player.SnoArea.Sno + "|") )
{
Players_Boss[acto] += player.BattleTagAbovePortrait + " ";
}
else
{
Players_Act[acto] += player.BattleTagAbovePortrait + " ";
}
}
else
{
DefaultFont.DrawText(DefaultFont.GetTextLayout("Fix: " + player.BattleTagAbovePortrait + "-" + player.SnoArea.Sno ), Hud.Window.Size.Width * 0.93f, Hud.Window.Size.Height * 0.97f);
}
}
}
if (Players_ActTown[0] != string.Empty)
{
var t = SpecialFontm.GetTextLayout(Players_ActTown[0]);
SpecialFontm.DrawText(t, x - t.Metrics.Width - t.Metrics.Height , y + 1);
}
for (int j = 1; j < 6; j++)
{
var texto = string.Format("{0} {1} (+{2}) ",HCache[j]? "[A" + j + "]": " A" + j + (Cont_B[j,0] == 5 ? "!":" "),Cont_B[j,0],Cont_B[j,1] );
DefaultFont.DrawText(DefaultFont.GetTextLayout(texto), x , (y) + j * OffsetH );
SelecFont = (Bosses_State[j] > 1)? GrisFont: (activo == j)? VerdeFont : RojoFont ;
SelecFont.DrawText(SelecFont.GetTextLayout(Bosses[j]), x + OffsetA + OffsetH , (y) + j * OffsetH );
if (Bosses_State[j] == 1) { SelecFont.DrawText(SelecFont.GetTextLayout("🡄"), x + OffsetA + OffsetB + 1.6f * OffsetH, (y) + j * OffsetH ); }
var pos = x - DefaultFontmTown.GetTextLayout("-").Metrics.Width;
if (Players_ActTown[j] != string.Empty)
{
pos -= DefaultFontmTown.GetTextLayout("-" + Players_ActTown[j]).Metrics.Width;
DefaultFontmTown.DrawText(DefaultFontmTown.GetTextLayout(Players_ActTown[j]), pos , y + (float) j * OffsetH + 1);
}
if (Players_Boss[j] != string.Empty)
{
pos -= DefaultFontmBoss.GetTextLayout("-" + Players_Boss[j]).Metrics.Width;
DefaultFontmBoss.DrawText(DefaultFontm.GetTextLayout(Players_Boss[j]), pos , y + (float) j * OffsetH + 1);
}
if (Players_Act[j] != string.Empty)
{
pos -= DefaultFontm.GetTextLayout("-" + Players_Act[j]).Metrics.Width;
DefaultFontm.DrawText(DefaultFontm.GetTextLayout(Players_Act[j]), pos , y + (float) j * OffsetH + 1);
}
if (Chests100_State[j] > 1)
{
if (Chests100_State[j] == 3) DefaultFontm.DrawText(DefaultFontm.GetTextLayout("►"), x + OffsetA + OffsetB + 2.6f * OffsetH , (y) + j * OffsetH );
else DefaultFont.DrawText(DefaultFont.GetTextLayout("+"), x + OffsetA + OffsetB + 2.6f * OffsetH , (y) + (float) j * OffsetH );
}
}
}
else if (clipState == ClipState.AfterClip)
{
if (!Hud.Render.WorldMapUiElement.Visible || Hud.Render.ActMapUiElement.Visible) return;
if (Hud.Game.ActMapCurrentAct == BountyAct.None) return;
var w = 220 * Hud.Window.HeightUiRatio; var h = 100 * Hud.Window.HeightUiRatio;
foreach (var waypoint in Hud.Game.ActMapWaypoints.Where(x => x.BountyAct == Hud.Game.ActMapCurrentAct))
{
var x = Hud.Render.WorldMapUiElement.Rectangle.X + waypoint.CoordinateOnMapUiElement.X * Hud.Window.HeightUiRatio;
var y = Hud.Render.WorldMapUiElement.Rectangle.Y + waypoint.CoordinateOnMapUiElement.Y * Hud.Window.HeightUiRatio;
if (waypoint.TargetSnoArea.IsTown)
{
BrushShadow.DrawEllipse(x + w * 0.5f, y + h * 0.3f, h * 0.20f ,h * 0.20f );
BrushTown.DrawEllipse(x + w * 0.5f, y + h * 0.3f, h * 0.20f ,h * 0.20f );
}
var quest = Hud.Game.Bounties.FirstOrDefault(q => q.SnoQuest.BountySnoArea == waypoint.TargetSnoArea);
if ((quest != null) && quest.State != QuestState.completed)
{
if (QuestBosses.ContainsKey(quest.SnoQuest.Sno)) SelecFont = (BossActive == 0)? BossFont:(BossActive == quest.SnoQuest.SnoAct.Index)? BossGoFont:BossWaitFont ;
else if (Chests100_Sno.Contains(quest.SnoQuest.Sno)) SelecFont = ChestFont;
else continue;
var layout = SelecFont.GetTextLayout(quest.SnoQuest.NameLocalized) ;
SelecFont.DrawText(layout, x + (w - layout.Metrics.Width) / 2, y + (float)Math.Ceiling(h * 0.32f));
}
}
}
}
}
}
}