objectdef ActorToMonitor { variable string ID variable string Name variable int Health variable string TargetName variable int ThreatToNext variable float Distance method Initialize(string id, string name, int health, string targetName, int threatToNext, float distance) { ID:Set["${id}"] Name:Set["${name}"] Health:Set[${health}] TargetName:Set["${targetName}"] ThreatToNext:Set[${threatToNext}] Distance:Set[${distance}] } method FromJSON(jsonvalueref jo) { ID:Set["${jo.Get[ID]~}"] Name:Set["${jo.Get[Name]~}"] Health:Set["${jo.Get[Health]~}"] TargetName:Set["${jo.Get[Health]~}"] ThreatToNext:Set["${jo.Get[ThreatToNext]~}"] Distance:Set["${jo.Get[Distance]~}"] } member:jsonvalueref AsJSON() { variable jsonvalue jo="{}" jo:SetString[ID, "${ID~}"] jo:SetString[Name, "${Name~}"] jo:SetString[Health, "${Health~}"] jo:SetString[TargetName, "${TargetName~}"] jo:SetString[ThreatToNext, "${ThreatToNext~}"] jo:SetString[Distance, "${Distance}"] return jo } } objectdef OSAController { variable string SelectedItem variable collection:ActorToMonitor ActorsWithTarget variable string locationStorageFile = "${LavishScript.HomeDirectory}/Scripts/mr/saves/osa/location.json" variable string windowName = "mr.osa.window" method Initialize() { variable jsonvalue location location:ParseFile["${locationStorageFile}"] LGUI2:LoadPackageFile[osa.json] LGUI2.Element["${windowName}"]:ApplyStyleJSON["${location.AsJSON~}"] } method Shutdown() { variable jsonvalue location = ${LGUI2.Element["${windowName}"].StorePlacement[1]} location:WriteFile["${locationStorageFile}"] LGUI2:UnloadPackageFile[osa.json] } method OnClose() { Script:End } method OnChangeTarget() { Actor[${SelectedItem}]:DoTarget Context:SetHandled[1] } method RefreshMobs() { variable index:actor Actors variable iterator ActorIterator variable set CurrentActors variable bool FireRefreshEvent=FALSE EQ2:QueryActors[Actors, Type =- "NPC" && Target != NULL] Actors:GetIterator[ActorIterator] if ${ActorIterator:First(exists)} { do { if ${ActorIterator.Value.Target.Name.NotNULLOrEmpty} { ; TODO: Maybe implement group/raid only checkbox instead of that being the default? if ${Me.Name.Equal[${ActorIterator.Value.Target.Name}]} || ${Me.Group[${ActorIterator.Value.Target.Name}](exists)} || ${Me.Raid[${ActorIterator.Value.Target.Name}](exists)} { if !${ActorsWithTarget.Element[${ActorIterator.Value.ID}](exists)} { ActorsWithTarget:Set["${ActorIterator.Value.ID}", "${ActorIterator.Value.ID}", "${ActorIterator.Value.Name}", ${ActorIterator.Value.Health}, "${ActorIterator.Value.Target.Name}", ${ActorIterator.Value.ThreatToNext}, ${ActorIterator.Value.Distance}] } else { ActorsWithTarget.Element["${ActorIterator.Value.ID}"].TargetName:Set["${ActorIterator.Value.Target.Name}"] ActorsWithTarget.Element["${ActorIterator.Value.ID}"].Health:Set["${ActorIterator.Value.Health}"] ActorsWithTarget.Element["${ActorIterator.Value.ID}"].ThreatToNext:Set["${ActorIterator.Value.ThreatToNext}"] ActorsWithTarget.Element["${ActorIterator.Value.ID}"].Distance:Set["${ActorIterator.Value.Distance}"] } FireRefreshEvent:Set[TRUE] CurrentActors:Add["${ActorIterator.Value.ID}"] } } } while ${ActorIterator:Next(exists)} } if ${ActorsWithTarget.FirstKey(exists)} { do { if !${CurrentActors.Contains[${ActorsWithTarget.CurrentKey}]} { ActorsWithTarget:Erase[${ActorsWithTarget.CurrentKey}] FireRefreshEvent:Set[TRUE] } } while ${ActorsWithTarget.NextKey(exists)} } if ${FireRefreshEvent} { LGUI2.Element[MrOSAController.events]:FireEventHandler[onUpdateActors] } } } variable(global) OSAController MrOSAController function main() { while 1 { MrOSAController:RefreshMobs wait 5 } }