├── IC_AreaHandler ├── Addon.json ├── IC_AreaHandler_Component.ahk ├── README.md └── _AreaHandler.ahk ├── IC_Azaka_Extra ├── Addon.json ├── IC_Azaka_Component.ahk └── README.md ├── IC_NERDs_Extra ├── Addon.json ├── IC_NERDs_Component.ahk ├── IC_NERDs_Run.ahk └── README.md ├── IC_NoModronLvling_Extra ├── Addon.json ├── IC_NoModronLvling_Component.ahk ├── IC_NoModronLvling_Functions.ahk └── README.md └── README.md /IC_AreaHandler/Addon.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name":"Area Handler", 3 | "Version": "v1.0.0", 4 | "Includes" : "IC_AreaHandler_Component.ahk", 5 | "Author" : "mikebaldi1980", 6 | "Url" : "", 7 | "Info" : "This Addon uses memory writes to make all transitions quick, all monsters basic (melee if possible), and enable skipping bosses on variants.", 8 | "Dependencies" : {} 9 | } -------------------------------------------------------------------------------- /IC_AreaHandler/IC_AreaHandler_Component.ahk: -------------------------------------------------------------------------------- 1 | #include %A_LineFile%\..\_AreaHandler.ahk 2 | 3 | GUIFunctions.AddTab("Area Handler") 4 | 5 | Gui, ICScriptHub:Tab, Area Handler 6 | Gui, ICScriptHub:Font, w700 7 | Gui, ICScriptHub:Add, Text, x15 y80, Area Handler 8 | Gui, ICScriptHub:Font, w400 9 | Gui, ICScriptHub:Add, Text, x15 y+5 w450, This Addon uses memory writes to make all transitions quick, all monsters basic (melee if possible), and enable skipping bosses on variants. 10 | 11 | Gui, ICScriptHub:Add, Button, x15 y+10 w160 gAreaHandler_Run, Run 12 | 13 | AreaHandler_Run() 14 | { 15 | areaHandler := new _AreaHandler 16 | msgbox, The Area Handler has completed updating memory values. 17 | } -------------------------------------------------------------------------------- /IC_AreaHandler/README.md: -------------------------------------------------------------------------------- 1 | # Area Handler 2 | ## Description: 3 | This Addon uses memory writes to make all transitions quick, all monsters basic (melee if possible), and enable skipping bosses on variants. 4 | Memory writes may violate CNE TOS and EULA. -------------------------------------------------------------------------------- /IC_AreaHandler/_AreaHandler.ahk: -------------------------------------------------------------------------------- 1 | class _AreaHandler 2 | { 3 | ; offsets for items that should probably be added to imports, until then placing them here for fast updating 4 | offsets := {"ActiveCampaignData.currentObjective.Repeatable":0xCC, "ActiveCampaignData.adventureDef":16 5 | , "ActiveCampaignData.adventureDef.areas":168, "ActiveCampaignData.adventureDef.areas.Monsters":0x20 6 | , "ActiveCampaignData.adventureDef.areas.BackgroundDefID":204, "ActiveCampaignData.adventureDef.areas.isFixed":252 7 | , "ActiveCampaignData.adventureDef.areas.backgroundDef":144, "ActiveCampaignData.adventureDef.areas.backgroundDef.ID":16 8 | , "ActiveCampaignData.adventureDef.areas.backgroundDef.IsFixed":105, "ActiveCampaignData.adventureDef.areas.Bosses":0x28 9 | , "ActiveCampaignData.adventureDef.areas.StaticMonsters":0x48 10 | , "Controller.area.activeMonsters.monsterDef":856, "Controller.area.activeMonsters.monsterDef.ID":16 11 | , "Controller.area.activeMonsters.monsterDef.availableAttacks":0x20 12 | , "Controller.area.activeMonsters.monsterDef.availableAttacks.AttackDef":0x10 13 | , "Controller.area.activeMonsters.monsterDef.availableAttacks.AttackDef.ID":0x10} 14 | 15 | __new() 16 | { 17 | this.BackGroundsToSet := {} 18 | g_SF.Memory.OpenProcessReader() ; standard starting step to enable memory reading 19 | g_SF.ToggleAutoProgress(0) ; disable autoprogress, errors can occur if levels progress before all data is gathered. 20 | 21 | this.classMemory := g_SF.Memory.GameManager.Main ; just an easier location to access classMemory instance 22 | 23 | ; set memory value at Repeatable to a number greater than 0 24 | ; this should enable boss skips 25 | ; TO DO, add Repeatable to scripthub game objects 26 | repeatable := new GameObjectStructure(g_SF.Memory.GameManager.game.gameInstances.ActiveCampaignData.currentObjective, "Int" 27 | , [this.offsets["ActiveCampaignData.currentObjective.Repeatable"]]) 28 | this.classMemory.write(repeatable.baseAddress, 1, "Int", repeatable.GetGameObjectFromListValues(0).GetOffsets()*) 29 | 30 | ; set up our parent game object, this.Areas 31 | ; this is the last game object set up in script hub, but we need ActiveCampaignData.adventureDef.areas, which is a list of all 50 zones 32 | ; TO DO, add areas to scripthub game objects 33 | activeCampaignData := g_SF.Memory.GameManager.game.gameInstances.ActiveCampaignData.GetGameObjectFromListValues(0) ; take the list out of GameInstances 34 | ; 0x10 corresponds to the offset of the collected items in the list 35 | ; list collected items will have offsets starting at 0x20 and occur every 0x8 36 | ; this list has 50 items, one for each zone 37 | this.Areas := new GameObjectStructure(activeCampaignData, g_SF.Memory.ptrType 38 | , [this.offsets["ActiveCampaignData.adventureDef"], this.offsets["ActiveCampaignData.adventureDef.areas"], 0x10]) 39 | 40 | ; this method determines the background and monster ids by analyzing data in the current zone 41 | ; looks through the current zone for monsters with meleee attacks. 42 | ; if it does not find a monster with a melee attack it will use the last id analyzed. 43 | ; the monster choosen from this method will be set for all monsters on the adventure. 44 | this.SetDefIDs() 45 | if (this.MonsterDefID < 0 or this.MonsterDefID > 10000) 46 | { 47 | this.ThrowException("Bad Monster Def ID. ID: " . this.MonsterDefID) 48 | } 49 | 50 | ; this method sets various values in each area def 51 | ; background defs within area def do not populate until that area has been seen 52 | ; so this area also tracks which background defs have not been populated 53 | this.SetAreaDefValues() 54 | 55 | return this 56 | } 57 | 58 | SetAreaDefValues() 59 | { 60 | ; we are going to do a lot of reading and the list shouldn't move in memory while we sit on one zone 61 | areasAddress := this.classMemory.getAddressFromOffsets(this.Areas.baseAddress, this.Areas.GetOffsets()*) 62 | 63 | ; go through each area and set various values 64 | ; track which areas that can't be set now 65 | outer: 66 | loop, 50 67 | { 68 | skipAreaDef := false ; a flag to skip changing area defs if there is a static monster, since it could be a blockade 69 | areaAddress := this.classMemory.getAddressFromOffsets(areasAddress, 0x20 + (0x8 * (A_Index - 1))) 70 | 71 | ; next set of code is setting monsters to all be the same 72 | ; start by setting static monsters because messing with blocade area defs can mess things up 73 | ; StaticMonsters is a dictionary of static monsters , actually defined as 74 | ; a static monster is a dictionary of properties , actually defined as 75 | ; 0x40 corresponds to dictionary count value 76 | countStaticMonsters := this.classMemory.read(areaAddress, "Int", [this.offsets["ActiveCampaignData.adventureDef.areas.StaticMonsters"], 0x40]*) 77 | if (countStaticMonsters AND countStaticMonsters < 100 AND countStaticMonsters > 0) ; reality check the read 78 | { 79 | skipAreaDef := true 80 | i := 0 81 | loop, %countStaticMonsters% 82 | { 83 | ; 0x18 corresponds to offset of the collected key value pairs in the dictionary 84 | ; the first key is at 0x28, with the next 0x18 away 85 | ; the first value is at 0x30, with the next 0x18 away 86 | ; 0x40 corresponds to the dictionary count 87 | countProperties := this.classMemory.read(areaAddress, "Int" 88 | , [this.offsets["ActiveCampaignData.adventureDef.areas.StaticMonsters"], 0x18, 0x30 + (0x18 * i), 0x40]*) 89 | if (countProperties AND countProperties < 100 AND countProperties > 0) ; reality check the read 90 | { 91 | j := 0 92 | loop, %countProperties% 93 | { 94 | string := this.classMemory.readString(areaAddress, 0, "UTF-16" 95 | , [this.offsets["ActiveCampaignData.adventureDef.areas.StaticMonsters"], 0x18, 0x30 + (0x18 * i), 0x18, 0x28 + (0x18 * j), 0x14]*) 96 | if (string == "monster_id") 97 | { 98 | this.classMemory.write(areaAddress, this.MonsterDefID, "Int" 99 | , [this.offsets["ActiveCampaignData.adventureDef.areas.StaticMonsters"], 0x18, 0x30 + (0x18 * i), 0x18, 0x30 + (0x18 * j), 0x10]*) 100 | } 101 | j++ 102 | } 103 | } 104 | else if countProperties 105 | { 106 | this.ThrowException("Static Monsters Properties collection count read returned unexpected value. Value Read: " . countProperties) 107 | } 108 | i++ 109 | } 110 | } 111 | else if countStaticMonsters 112 | { 113 | this.ThrowException("Static Monsters collection count read returned unexpected value. Value Read: " . countStaticMonsters) 114 | } 115 | ; next is bosses, which is actually a list of list of id 116 | ; 0x18 corresponds to the list size value 117 | _size := this.classMemory.read(areaAddress, "Int", [this.offsets["ActiveCampaignData.adventureDef.areas.Bosses"], 0x18]*) 118 | if (_size AND _size < 100 AND _size > 0) ; reality check the read 119 | { 120 | i := 0 121 | ; 0x10 corresponds to the collected list items 122 | bossListAddress := this.classMemory.getAddressFromOffsets(areaAddress, [this.offsets["ActiveCampaignData.adventureDef.areas.Bosses"], 0x10]*) 123 | loop, %_size% 124 | { 125 | ; 0x20 is the first list item, second is 0x8 off 126 | ; 0x18 corresponds to the list size value 127 | _size2 := this.classMemory.read(bossListAddress, "Int", [0x20 + (0x8 * i), 0x18]*) 128 | if (_size2 AND _size2 < 100) ; reality check the read 129 | { 130 | j := 0 131 | loop, %_size2% 132 | { 133 | ; list items start at 0x20, for reference type lists they are spaced 0x8 apart 134 | ; 0x10 corresponds to the second list collection set 135 | ; the second list of ids are int32, so they are 4 bytes apart 136 | this.classMemory.write(bossListAddress, this.MonsterDefID, "Int", [0x20 + (0x8 * i), 0x10, 0x20 + (0x4 * j)]*) 137 | j++ 138 | } 139 | } 140 | else if _size_2 141 | { 142 | this.ThrowException("Bosses Waves collection count read returned unexpected value. Value Read: " . _size2) 143 | } 144 | i++ 145 | } 146 | } 147 | else if _size 148 | { 149 | this.ThrowException("Bosses collection count read returned unexpected value. Value Read: " . _size) 150 | } 151 | ; finally, set standard monsters 152 | ; 0x18 corresponds to the list size value 153 | _size := this.classMemory.read(areaAddress, "Int", [this.offsets["ActiveCampaignData.adventureDef.areas.Monsters"], 0x18]*) 154 | if (_size AND _size < 100) ; reality check the read 155 | { 156 | i := 0 157 | loop, %_size% 158 | { 159 | ; 0x10 corresponds to the collected list items 160 | ; first item is offset 0x20, then second is 0x4 since it is a collection of int32 161 | this.classMemory.write(areaAddress, this.MonsterDefID, "Int" 162 | , [this.offsets["ActiveCampaignData.adventureDef.areas.Monsters"], 0x10, 0x20 + (0x4 * i)]*) 163 | i++ 164 | } 165 | } 166 | else if _size 167 | { 168 | this.ThrowException("Monsters collection count read returned unexpected value. Value Read: " . _size) 169 | } 170 | 171 | ; next set of code is to force quick transitions 172 | if skipAreaDef 173 | { 174 | continue outer 175 | } 176 | ; next two lines set a nullable boolean to true, this probably could be done with a single two byte write 177 | this.classMemory.write(areaAddress, 1, "Char", this.offsets["ActiveCampaignData.adventureDef.areas.isFixed"]) 178 | this.classMemory.write(areaAddress, 1, "Char", this.offsets["ActiveCampaignData.adventureDef.areas.isFixed"] + 1) 179 | ; check to see if the background def is set and set or mark as to be set as appropriate 180 | backgroundDefID := this.classMemory.read(areaAddress, "Int", this.offsets["ActiveCampaignData.adventureDef.areas.BackgroundDefID"]) 181 | if (backgroundDefID != this.BackGroundDefID OR this.BackGroundsToSet[A_Index]) 182 | { 183 | this.classMemory.write(areaAddress, this.BackGroundDefID, "Int", this.offsets["ActiveCampaignData.adventureDef.areas.BackgroundDefID"]) 184 | backGroundDefAddress := this.classMemory.getAddressFromOffsets(areaAddress, this.offsets["ActiveCampaignData.adventureDef.areas.backgroundDef"]) 185 | ; check to see if background def has been populated 186 | if (backGroundDefAddress > 0) 187 | { 188 | id := this.classMemory.read(backGroundDefAddress, "Int", this.offsets["ActiveCampaignData.adventureDef.areas.backgroundDef.ID"]) 189 | if (id != this.BackGroundDefID) 190 | { 191 | this.classMemory.write(backGroundDefAddress, this.BackGroundDefID, "Int", this.offsets["ActiveCampaignData.adventureDef.areas.BackgroundDef.ID"]) 192 | } 193 | ; I don't think we need to set this as true, the getter will pull from Area defs. 194 | ; TODO check DLL for the isfixed getter to see if these are needed. 195 | isFixed := this.classMemory.read(backGroundDefAddress, "Char", this.offsets["ActiveCampaignData.adventureDef.areas.backgroundDef.IsFixed"]) 196 | if !isFixed 197 | { 198 | this.classMemory.write(backGroundDefAddress, 1, "Char", this.offsets["ActiveCampaignData.adventureDef.areas.backgroundDef.IsFixed"]) 199 | } 200 | } 201 | ; TODO create method to use this data. 202 | else 203 | { 204 | this.BackGroundsToSet[A_Index] := A_Index 205 | } 206 | } 207 | } 208 | return 209 | } 210 | 211 | SetDefIDs() 212 | { 213 | ; set currentZone so we know which item in the areas list to look at 214 | currentZone := mod(g_SF.Memory.ReadCurrentZone(), 50) 215 | currentZone := currentZone == 0 ? 50 : currentZone 216 | if (!(currentZone > 0) AND !(currentZone < 51)) 217 | { 218 | this.ThrowException("Bad memory read of current zone. Current Zone Read: " . currentZone) 219 | } 220 | 221 | if (!mod(currentZone, 5)) 222 | { 223 | this.ThrowException("Cannot initilaize script when on boss zone.") 224 | } 225 | 226 | ; we will need to set these background id and isfixed properties uniquely 227 | this.BackGroundsToSet[currentZone] := currentZone 228 | this.BackGroundsToSet[currentZone + 1] := currentZone + 1 229 | 230 | ; we are going to do a lot of reading and the list shouldn't move in memory while we sit on one zone 231 | areasAddress := this.classMemory.getAddressFromOffsets(this.Areas.baseAddress, this.Areas.GetOffsets()*) 232 | areaAddress := this.classMemory.getAddressFromOffsets(areasAddress, 0x20 + (0x8 * (currentZone - 1))) 233 | 234 | ; set the background def id value to be used for all backgrounds that have already been set 235 | ; background defs are set as they are moved through, so by using the current area, we can avoid an additional write 236 | this.BackGroundDefID := this.classMemory.read(areaAddress, "Int", this.offsets["ActiveCampaignData.adventureDef.areas.BackgroundDefID"]) 237 | if (!(this.BackGroundDefID) OR this.BackGroundDefID < 1 OR this.BackGroundDefID > 10000) 238 | { 239 | this.BackGroundDefID := 9 ; zone 1 of cursed farmer 240 | } 241 | 242 | ; set the monster def id value to be used for all monsters in the adventure 243 | ; create a collection of id's of all monsters that can spawn on the current area 244 | ; using adventureDef.areas.Monsters, a list of monsters that can spawn on this area 245 | monsters := {} ; an object to store the id's of monster that can spawn on this area 246 | _size := this.classMemory.read(areaAddress, "Int", [this.offsets["ActiveCampaignData.adventureDef.areas.Monsters"], 0x18]*) 247 | if (!_size OR _size > 100 OR _size < 0) 248 | { 249 | this.ThrowException("Monster list size read returned unexpecte value. Value Read: " . _size) 250 | } 251 | i := 0 252 | monstersAddress := this.classMemory.getAddressFromOffsets(areaAddress, [this.offsets["ActiveCampaignData.adventureDef.areas.Monsters"], 0x10]*) 253 | loop, %_size% 254 | { 255 | id := this.classMemory.read(monstersAddress, "Int", 0x20 + (0x4 * i)) 256 | if id 257 | { 258 | monsters[id] := id 259 | this.MonsterDefID := id ; set to last monster in list in case none have a basic melee as only attack 260 | } 261 | i++ 262 | } 263 | 264 | ; no valid id was read 265 | if !(this.MonsterDefID) 266 | { 267 | this.ThrowException("Monster Def ID failed to set propertly.") 268 | } 269 | 270 | ; now we will look through the active monsters spawning for one with a melee attack 271 | ; as we check an id, we will remove it from the monsters list we created above 272 | ; same reasoning as above to reduce reads 273 | activeMonsters := g_SF.Memory.GameManager.game.gameInstances.Controller.area.activeMonsters.GetGameObjectFromListValues(0) ; take the list out of GameInstances 274 | activeMonstersAddress := this.classMemory.getAddressFromOffsets(activeMonsters.baseAddress, activeMonsters.GetOffsets()*) 275 | ;activeMonstersList := new GameObjectStructure(activeMonsters, g_SF.Memory.ptrType, [0x10]) 276 | ;activeMonstersListAddress := this.classMemory.getAddressFromOffsets(activeMonstersList.baseAddress, activeMonstersList.GetOffsets()*) 277 | failedReadCount := 0 ; in case something happens so we don't get in an endless loop 278 | while monsters.Count() 279 | { 280 | ; we are only ever going to look at the first item in the list since click damage will kill so fast 281 | ; we need to pull the monsterDef address since the monster may be removed from the active list before we finish 282 | monsterDefAddress := this.classMemory.getAddressFromOffsets(activeMonstersAddress, [0x20, this.offsets["Controller.area.activeMonsters.monsterDef"]]*) 283 | activeId := this.classMemory.read(monsterDefAddress, "Int", this.offsets["Controller.area.activeMonsters.monsterDef.ID"]) 284 | if !activeId 285 | { 286 | failedReadCount++ 287 | if failedReadCount > 9 288 | { 289 | return 290 | } 291 | } 292 | else if monsters.HasKey(activeId) 293 | { 294 | monsters.Delete(activeId) 295 | availableAttacksAddress := this.classMemory.getAddressFromOffsets(monsterDefAddress, this.offsets["Controller.area.activeMonsters.monsterDef.availableAttacks"]) 296 | _size := this.classMemory.read(availableAttacksAddress, "Int", 0x18) 297 | ; available attacks is a list, but we only want melee, so only check if the list is 1 item 298 | if (_size == 1) 299 | { 300 | attackId := this.classMemory.read(availableAttacksAddress, "Int" 301 | , [0x10, 0x20, this.offsets["Controller.area.activeMonsters.monsterDef.availableAttacks.AttackDef"] 302 | , this.offsets["Controller.area.activeMonsters.monsterDef.availableAttacks.AttackDef.ID"]]*) 303 | if (attackId == 21) ; id for basic melee attack 304 | { 305 | this.MonsterDefID := activeId 306 | return 307 | } 308 | } 309 | } 310 | } 311 | } 312 | 313 | ThrowException(reason) 314 | { 315 | MsgBox, % reason . "`n`nExiting App." 316 | ExitApp 317 | } 318 | } -------------------------------------------------------------------------------- /IC_Azaka_Extra/Addon.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name":"Azaka", 3 | "Version": "v1.0.3", 4 | "Includes" : "IC_Azaka_Component.ahk", 5 | "Author" : "mikebaldi1980", 6 | "Url" : "", 7 | "Info" : "This AddOn will spam Azaka and other champion's ults at a set Omin number of contracts fulfilled value.", 8 | "Dependencies" : {} 9 | } -------------------------------------------------------------------------------- /IC_Azaka_Extra/IC_Azaka_Component.ahk: -------------------------------------------------------------------------------- 1 | GUIFunctions.AddTab("Azaka") 2 | 3 | global g_AzakaSettings := g_SF.LoadObjectFromJSON( A_LineFile . "\..\Settings.json" ) 4 | if !IsObject(g_AzakaSettings) 5 | g_AzakaSettings := {} 6 | 7 | Gui, ICScriptHub:Tab, Azaka 8 | Gui, ICScriptHub:Font, w700 9 | Gui, ICScriptHub:Add, Text, x15 y80, Azaka 10 | Gui, ICScriptHub:Font, w400 11 | Gui, ICScriptHub:Add, Text, x15 y+5, This AddOn will spam Azaka and other champion's ults at a set Omin number of contracts fulfilled value. 12 | 13 | if ( g_AzakaSettings.NumContracts == "" ) 14 | g_AzakaSettings.NumContracts := 95 15 | Gui, ICScriptHub:Add, Text, x15 y+15, Ult. on this many Contracts Fulfilled: 16 | Gui, ICScriptHub:Add, Edit, vAzaka_Contracts x+5 w50, % g_AzakaSettings.NumContracts 17 | Gui, ICScriptHub:Add, Text, x+5 vAzaka_Contracts_Saved w200, % "Saved value: " . g_AzakaSettings.NumContracts 18 | 19 | if ( g_AzakaSettings.Loops == "" ) 20 | g_AzakaSettings.Loops := 5 21 | Gui, ICScriptHub:Add, Text, x15 y+15, Ult. this many times: 22 | Gui, ICScriptHub:Add, Edit, vAzaka_Loops x+5 w50, % g_AzakaSettings.Loops 23 | Gui, ICScriptHub:Add, Text, x+5 vAzaka_Loops_Saved w200, % "Saved value: " . g_AzakaSettings.Loops 24 | 25 | if ( g_AzakaSettings.Ult == "" ) 26 | { 27 | g_AzakaSettings.Ult := {} 28 | loop, 10 29 | { 30 | g_AzakaSettings.Ult[A_Index] := 0 31 | } 32 | } 33 | 34 | Gui, ICScriptHub:Add, Text, x15 y+15, Use the following ultimates: 35 | loop, 10 36 | { 37 | chk := g_AzakaSettings.Ult[A_Index] 38 | Gui, ICScriptHub:Add, Checkbox, vAzaka_CB%A_Index% Checked%chk% x15 y+10, % A_Index 39 | Gui, ICScriptHub:Add, Text, x+5 vAzaka_CB%A_Index%_Saved w200, % chk == 1 ? "Saved value: Checked":"Saved value: Unchecked" 40 | } 41 | 42 | Gui, ICScriptHub:Add, Button, x15 y+10 w160 gAzaka_Save, Save Settings 43 | Gui, ICScriptHub:Add, Button, x15 y+10 w160 gAzaka_Run, Run 44 | 45 | Gui, ICScriptHub:Add, Text, x15 y+10 vAzaka_Running w300, 46 | Gui, ICScriptHub:Add, Text, x15 y+5 vAzaka_CurrentContracts w300, 47 | Gui, ICScriptHub:Add, Text, x15 y+5 vAzaka_UltsUsed w300, 48 | 49 | Azaka_Save() 50 | { 51 | global 52 | Gui, ICScriptHub:Submit, NoHide 53 | g_AzakaSettings.NumContracts := Azaka_Contracts 54 | GuiControl, ICScriptHub:, Azaka_Contracts_Saved, % "Saved value: " . g_AzakaSettings.NumContracts 55 | 56 | g_AzakaSettings.Loops := Azaka_Loops 57 | GuiControl, ICScriptHub:, Azaka_Loops_Saved, % "Saved value: " . g_AzakaSettings.Loops 58 | 59 | loop, 10 60 | { 61 | g_AzakaSettings.Ult[A_Index] := Azaka_CB%A_Index% 62 | GuiControl, ICScriptHub:, Azaka_CB%A_Index%_Saved, % Azaka_CB%A_Index% == 1 ? "Saved value: Checked":"Saved value: Unchecked" 63 | } 64 | 65 | g_SF.WriteObjectToJSON(A_LineFile . "\..\Settings.json" , g_AzakaSettings) 66 | } 67 | 68 | Azaka_Run() 69 | { 70 | GuiControl, ICScriptHub:, Azaka_Running, Azaka farm is running. 71 | ;initialize shared functions for memory reads and directed inputs 72 | g_SF.Hwnd := WinExist("ahk_exe " . g_UserSettings[ "ExeName" ]) 73 | g_SF.Memory.OpenProcessReader() 74 | ;create object for azaka class to update gui 75 | guiData := {} 76 | guiData.guiName := "ICScriptHub:" 77 | guiData.guiControlIDcont := "Azaka_CurrentContracts" 78 | guiData.guiControlIDults := "Azaka_UltsUsed" 79 | 80 | azaka := new AzakaFarm(g_AzakaSettings, guiData) 81 | azaka.AzakaFarm() 82 | 83 | GuiControl, ICScriptHub:, Azaka_Running, Azaka farm is complete. 84 | GuiControl, ICScriptHub:, Azaka_CurrentContracts, 85 | GuiControl, ICScriptHub:, Azaka_UltsUsed, 86 | msgbox, Azaka farm is complete. 87 | } 88 | 89 | class AzakaFarm 90 | { 91 | omin := {} 92 | inputs := {} 93 | loops := {} 94 | useGUI := false 95 | 96 | __new(settings, guiData) 97 | { 98 | this.omin := g_SF.Memory.ActiveEffectKeyHandler.OminContractualObligationsHandler ;new OminContractualObligationsHandler 99 | loop, 10 100 | { 101 | if (settings.Ult[A_Index] AND A_Index < 10) 102 | this.inputs.Push(A_Index . "") 103 | else if (settings.Ult[A_Index] AND A_Index == 10) 104 | this.inputs.Push(0 . "") 105 | } 106 | this.loops := settings.Loops 107 | this.numContracts := settings.NumContracts 108 | if IsObject(guiData) 109 | { 110 | this.useGUI := true 111 | this.guiName := guiData.guiName 112 | this.guiControlIDcont := guiData.guiControlIDcont 113 | this.guiControlIDults := guiData.guiControlIDults 114 | } 115 | return this 116 | } 117 | 118 | AzakaFarm() 119 | { 120 | if (this.useGUI) 121 | GuiControl, % this.guiName, % this.guiControlIDults, % "Ultimates Used: 0" 122 | loops := this.Loops 123 | loop, %loops% 124 | { 125 | wait := true 126 | while wait 127 | { 128 | if this.farm() 129 | wait := false 130 | sleep, 100 131 | } 132 | if (this.useGUI) 133 | GuiControl, % this.guiName, % this.guiControlIDults, % "Ultimates Used: " . A_Index 134 | } 135 | } 136 | 137 | farm() 138 | { 139 | g_SF.Memory.ActiveEffectKeyHandler.Refresh() 140 | num := ActiveEffectKeySharedFunctions.Omin.OminContractualObligationsHandler.ReadNumContractsFulfilled() 141 | if (this.useGUI) 142 | GuiControl, % this.guiName, % this.guiControlIDcont, % "Current No. Contracts Fulfilled: " . num 143 | if (num > this.numContracts) 144 | { 145 | while (num > this.numContracts) 146 | { 147 | num := ActiveEffectKeySharedFunctions.Omin.OminContractualObligationsHandler.ReadNumContractsFulfilled() 148 | g_SF.DirectedInput(,, this.inputs*) 149 | sleep, 100 150 | } 151 | return true 152 | } 153 | return false 154 | } 155 | } -------------------------------------------------------------------------------- /IC_Azaka_Extra/README.md: -------------------------------------------------------------------------------- 1 | # Azaka 2 | ## Description: 3 | This AddOn will spam Azaka and other champion's ults at a set Omin number of contracts fulfilled value. 4 | 5 | ## Note: 6 | Changing the settings after the run button is pressed will not change anything for that run, reload the script and start again. 7 | 8 | ## Change Log: 9 | v1.0.2, 5/21/22 10 | 11 | Update to Auto Offsets v2 Script Hub, for real this time. Maybe. 12 | 13 | v1.0.1, 5/12/22 14 | 15 | Updated to Auto Offset v2 Script Hub. 16 | 17 | v1.0.0, 2/4/2022 18 | 19 | Initial release. 20 | 21 | -------------------------------------------------------------------------------- /IC_NERDs_Extra/Addon.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name":"NERDs Shake the Box", 3 | "Version": "v1.0.3", 4 | "Includes" : "IC_NERDs_Component.ahk", 5 | "Author" : "mikebaldi1980", 6 | "Url" : "", 7 | "Info" : "This AddOn will launch a seaparte script that will spam NERDs ultimate until you get the desired set of three NERDs.", 8 | "Dependencies" : {} 9 | } -------------------------------------------------------------------------------- /IC_NERDs_Extra/IC_NERDs_Component.ahk: -------------------------------------------------------------------------------- 1 | GUIFunctions.AddTab("NERDs") 2 | 3 | global g_NERDsSettings := g_SF.LoadObjectFromJSON( A_LineFile . "\..\Settings.json" ) 4 | if !IsObject(g_NERDsSettings) 5 | g_NERDsSettings := {} 6 | 7 | Gui, ICScriptHub:Tab, NERDs 8 | Gui, ICScriptHub:Font, w700 9 | Gui, ICScriptHub:Add, Text, x15 y80, NERDs 10 | Gui, ICScriptHub:Font, w400 11 | Gui, ICScriptHub:Add, Text, x15 y+5 w450 wrap, This AddOn will launch a seaparte script that will spam NERDs ultimate until you get the desired set of three NERDs. 12 | Gui, ICScriptHub:Add, Text, x15 y+15, Select the NERDs you would like in your wagon: 13 | loop, 6 14 | { 15 | if (g_NERDsSettings[A_Index] == "") 16 | g_NERDsSettings[A_Index] := 0 17 | chk := g_NERDsSettings[A_Index] 18 | Gui, ICScriptHub:Add, Checkbox, vNERDs_CB%A_Index% Checked%chk% x15 y+10 gNERDs_CB_Clicked, % ActiveEffectKeySharedFunctions.Nerds.NerdWagonHandler.NerdType[A_Index] 19 | Gui, ICScriptHub:Add, Text, x+5 vNERDs_CB%A_Index%_Saved w200, % chk == 1 ? "Saved value: Checked":"Saved value: Unchecked" 20 | } 21 | NERDs_CB_Clicked() 22 | 23 | ;Gui, ICScriptHub:Add, Button, x15 y+10 w160 gNERDs_Save, Save Settings 24 | Gui, ICScriptHub:Add, Button, x15 y+20 w160 gNERDs_Run, Run 25 | 26 | NERDs_Save() 27 | { 28 | Gui, ICScriptHub:Submit, NoHide 29 | nerdCount := 0 30 | loop, 6 31 | { 32 | g_NERDsSettings[A_Index] := NERDs_CB%A_Index% 33 | if NERDs_CB%A_Index% 34 | ++nerdCount 35 | GuiControl, ICScriptHub:, NERDs_CB%A_Index%_Saved, % NERDs_CB%A_Index% == 1 ? "Saved value: Checked":"Saved value: Unchecked" 36 | } 37 | 38 | g_NERDsSettings.nerdCount := nerdCount 39 | 40 | g_SF.WriteObjectToJSON(A_LineFile . "\..\Settings.json" , g_NERDsSettings) 41 | } 42 | 43 | NERDs_Run() 44 | { 45 | scriptLocation := A_LineFile . "\..\IC_NERDs_Run.ahk" 46 | Run, %A_AhkPath% "%scriptLocation%" 47 | } 48 | 49 | NERDs_CB_Clicked() 50 | { 51 | Gui, ICScriptHub:Submit, NoHide 52 | nerdCount := 0 53 | loop, 6 54 | { 55 | if (nerdCount >= 3) 56 | { 57 | GuiControl, ICScriptHub:, NERDs_CB%A_Index%, 0 58 | GuiControl, ICScriptHub:Disable, NERDs_CB%A_Index% 59 | } 60 | else 61 | { 62 | GuiControl, ICScriptHub:Enable, NERDs_CB%A_Index% 63 | } 64 | if NERDs_CB%A_Index% 65 | ++nerdCount 66 | } 67 | if (nerdCount >= 3) 68 | { 69 | loop, 6 70 | { 71 | if !(NERDs_CB%A_Index%) 72 | GuiControl, ICScriptHub:Disable, NERDs_CB%A_Index% 73 | } 74 | } 75 | NERDs_Save() 76 | } -------------------------------------------------------------------------------- /IC_NERDs_Extra/IC_NERDs_Run.ahk: -------------------------------------------------------------------------------- 1 | #SingleInstance, Force 2 | 3 | ;======================= 4 | ;Script Optimization 5 | ;======================= 6 | #HotkeyInterval 1000 ; The default value is 2000 (milliseconds). 7 | #MaxHotkeysPerInterval 70 ; The default value is 70 8 | #NoEnv ; Avoids checking empty variables to see if they are environment variables (recommended for all new scripts). Default behavior for AutoHotkey v2. 9 | SetWorkingDir %A_ScriptDir% 10 | SetWinDelay, 33 ; Sets the delay that will occur after each windowing command, such as WinActivate. (Default is 100) 11 | SetControlDelay, 0 ; Sets the delay that will occur after each control-modifying command. -1 for no delay, 0 for smallest possible delay. The default delay is 20. 12 | ;SetKeyDelay, 0 ; Sets the delay that will occur after each keystroke sent by Send or ControlSend. [SetKeyDelay , Delay, PressDuration, Play] 13 | SetBatchLines, -1 ; How fast a script will run (affects CPU utilization).(Default setting is 10ms - prevent the script from using any more than 50% of an idle CPU's time. 14 | ; This allows scripts to run quickly while still maintaining a high level of cooperation with CPU sensitive tasks such as games and video capture/playback. 15 | ListLines Off 16 | Process, Priority,, High 17 | CoordMode, Mouse, Client 18 | 19 | Gui, MyWindow:New 20 | Gui, MyWindow:+Resize -MaximizeBox 21 | Gui, MyWindow:Add, Text, x15 y15, NERDs add on is running. 22 | Gui, MyWindow:Add, Text, x15 y+5, When the correct NERDs are in the wagon, this window will close and the script will end. 23 | Gui, MyWindow:Add, Text, x15 y+5, To end the script early, just close this window. 24 | Gui, MyWindow:Add, Text, x15 y+15, What is happening: 25 | Gui, MyWindow:Add, Text, x+5 vNERDs_Status w300, 26 | Gui, MyWindow:Add, Text, x15 y+5 vNERDs_UltKey w200, 27 | 28 | Gui, MyWindow:Show, x0 y0, Running NERDs... 29 | ;Gui, MyWindow:Show 30 | /* 31 | 32 | 33 | #include %A_LineFile%\..\..\..\SharedFunctions\MemoryRead\EffectKeyHandlers\NerdWagonHandler.ahk 34 | global g_Nerds := new NerdWagonHandler 35 | if !IsObject(g_Nerds) 36 | { 37 | msgBox, Failed to load NERDs Wagon Handler, ending script. 38 | ExitApp 39 | } 40 | */ 41 | 42 | 43 | 44 | #include %A_LineFile%\..\..\..\SharedFunctions\IC_SharedFunctions_Class.ahk 45 | global g_SF := new IC_SharedFunctions_Class 46 | 47 | #include %A_LineFile%\..\..\..\SharedFunctions\MemoryRead\IC_ActiveEffectKeyHandler_Class.ahk 48 | 49 | #include %A_LineFile%\..\..\..\SharedFunctions\IC_KeyHelper_Class.ahk 50 | global g_KeyMap := KeyHelper.BuildVirtualKeysMap() 51 | 52 | #include %A_LineFile%\..\..\..\SharedFunctions\json.ahk 53 | global g_NERDsSettings := g_SF.LoadObjectFromJSON( A_LineFile . "\..\Settings.json" ) 54 | 55 | global g_UserSettings := g_SF.LoadObjectFromJSON( A_LineFile . "\..\..\..\Settings.json" ) 56 | if !IsObject(g_NERDsSettings) 57 | { 58 | msgBox, Failed to load settings, ending script. 59 | ExitApp 60 | } 61 | 62 | if (g_NERDsSettings.nerdCount > 3) 63 | g_NERDsSettings.nerdCount := 3 64 | 65 | loop 66 | { 67 | ;initialize shared functions for inputs and memory reads, every loop incase game closes/crashes 68 | g_SF.Hwnd := WinExist("ahk_exe " . g_UserSettings[ "ExeName" ]) 69 | existingProcessID := g_userSettings[ "ExeName"] 70 | Process, Exist, %existingProcessID% 71 | g_SF.PID := ErrorLevel 72 | g_SF.Memory.OpenProcessReader() 73 | nerdCount := 0 74 | if (g_SF.Hwnd AND g_SF.PID) 75 | { 76 | if g_NERDsSettings[ ActiveEffectKeySharedFunctions.Nerds.NerdWagonHandler.ReadNerd0() ] 77 | ++nerdCount 78 | if g_NERDsSettings[ ActiveEffectKeySharedFunctions.Nerds.NerdWagonHandler.ReadNerd1() ] 79 | ++nerdCount 80 | if g_NERDsSettings[ ActiveEffectKeySharedFunctions.Nerds.NerdWagonHandler.ReadNerd2() ] 81 | ++nerdCount 82 | GuiControl, MyWindow:, NERDs_Status, % "Trying to load the correct NERDs. Matches: " . nerdCount 83 | if (nerdCount >= g_NERDsSettings.nerdCount) 84 | { 85 | msgBox, The correct NERDs are loaded, ending script. 86 | ExitApp 87 | } 88 | ultKey := g_SF.GetUltimateButtonByChampID(87) 89 | if (ultKey == -1) 90 | { 91 | msgbox, 5,, Cannot find NERDs ultimate. Make sure they are in the formation and leveled up prior to clicking 'Retry'. Click 'Cancel' to end script. 92 | IfMsgBox, Retry 93 | Continue 94 | IfMsgBox, Cancel 95 | ExitApp 96 | } 97 | GuiControl, MyWindow:, NERDs_UltKey, % "Ult Key: " . ultKey 98 | g_SF.DirectedInput(,, ultKey) 99 | } 100 | else 101 | GuiControl, MyWindow:, NERDs_Status, Waiting for another script to open IC... 102 | sleep, 250 103 | } 104 | 105 | MyWindowGuiClose() 106 | { 107 | MsgBox 4,, Are you sure you want to `exit? 108 | IfMsgBox Yes 109 | ExitApp 110 | IfMsgBox No 111 | return True 112 | } -------------------------------------------------------------------------------- /IC_NERDs_Extra/README.md: -------------------------------------------------------------------------------- 1 | # NERDs 2 | ## Description: 3 | This AddOn will launch a seaparte script that will spam NERDs ultimate until you get the desired set of three NERDs. 4 | 5 | ## Change Log: 6 | v1.0.2, 5/21/22 7 | 8 | Update to Auto Offsets v2 Script Hub. Maybe. 9 | 10 | v1.0.1, 2/19/2022 11 | 12 | Pop up window will now start in upper left corner. 13 | 14 | v1.0.0, 2/16/2022 15 | 16 | Initial release. -------------------------------------------------------------------------------- /IC_NoModronLvling_Extra/Addon.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name":"No Modron Leveling", 3 | "Version": "v0.0.3", 4 | "Includes" : "IC_NoModronLvling_Component.ahk", 5 | "Author" : "mikebaldi1980 & Antilectual", 6 | "Url" : "", 7 | "Info" : "An add on that will level and specialize champions without Modron Automation.", 8 | "Dependencies" : {} 9 | } -------------------------------------------------------------------------------- /IC_NoModronLvling_Extra/IC_NoModronLvling_Component.ahk: -------------------------------------------------------------------------------- 1 | #include %A_LineFile%\..\IC_NoModronLvling_Functions.ahk 2 | 3 | GUIFunctions.AddTab("No Modron Leveling") 4 | 5 | global g_HeroDefines 6 | 7 | global g_SpecSettings := g_SF.LoadObjectFromJSON( A_LineFile . "\..\SpecSettings.json" ) 8 | if !IsObject(g_SpecSettings) 9 | { 10 | g_SpecSettings := {} 11 | g_SpecSettings.TimeStamp := "" 12 | } 13 | global g_MaxLvl := g_SF.LoadObjectFromJSON( A_LineFile . "\..\MaxLvl.json" ) 14 | if !IsObject(g_MaxLvl) 15 | { 16 | g_MaxLvl := {} 17 | g_MaxLvl.TimeStamp := "" 18 | } 19 | 20 | Gui, ICScriptHub:Tab, No Modron Leveling 21 | Gui, ICScriptHub:Font, w700 22 | Gui, ICScriptHub:Add, Text, x15 y80, BETA No Modron Leveling and Specializing 23 | Gui, ICScriptHub:Font, w400 24 | Gui, ICScriptHub:Add, Text, x15 y+5, An add on that will level to soft cap and specialize champions without Modron Automation. 25 | Gui, ICScriptHub:Add, Text, x15 y+5, To pause this script, press the PAUSE key. 26 | Gui, ICScriptHub:Add, Text, x15 y+5, NOTE: This add on will take control of the mouse to select specializations and assumes sufficient gold to soft cap. 27 | Gui, ICScriptHub:Add, Text, x15 y+10, Specialization Settings Status: 28 | Gui, ICScriptHub:Add, Text, x+5 vNML_Settings w300, % g_SpecSettings.TimeStamp ? "Loaded and dated " . g_SpecSettings.TimeStamp : "Not Loaded" 29 | Gui, ICScriptHub:Add, Button, x15 y+10 w160 gNML_SpecSettings, Select/Create Spec. Settings 30 | Gui, ICScriptHub:Add, Text, x15 y+10, Max. Level Data Status: 31 | Gui, ICScriptHub:Add, Text, x+5 vNML_MaxLvl w300, % g_MaxLvl.TimeStamp ? "Loaded and dated " . g_MaxLvl.TimeStamp : "Not Loaded" 32 | Gui, ICScriptHub:Add, Button, x15 y+10 w160 gNML_BuildMaxLvlData, Load Max. Level Data 33 | Gui, ICScriptHub:Add, Text, x15 y+15, Select the formations to level and specialize 34 | Gui, ICScriptHub:Add, Checkbox, vNML_CB1 x15 y+5, "Q" 35 | Gui, ICScriptHub:Add, Checkbox, vNML_CB2 x+15, "W" 36 | Gui, ICScriptHub:Add, Checkbox, vNML_CB3 x+15, "E" 37 | Gui, ICScriptHub:Add, Button, x15 y+10 w160 gNML_LevelAndSpec, Level and Specialize 38 | 39 | Gui, ICScriptHub:Add, Text, x15 y+15 vNML_Formation w300, 40 | Gui, ICScriptHub:Add, Text, x15 y+5 vNML_Champ w300, 41 | 42 | NML_LevelAndSpec() 43 | { 44 | global 45 | if !(g_MaxLvl.TimeStamp) 46 | { 47 | msgbox, Max level data not found, click Load Max. Level Data prior to running this script. 48 | return 49 | } 50 | if !(g_SpecSettings.TimeStamp) 51 | { 52 | msgbox, Specialization settings not found, click Select/Create Spec. Settings prior to running this script. 53 | return 54 | } 55 | g_SF.Hwnd := WinExist("ahk_exe " . g_UserSettings[ "ExeName" ]) 56 | g_SF.Memory.OpenProcessReader() 57 | lvlObj := new IC_NML_Functions 58 | Gui, ICScriptHub:Submit, NoHide 59 | formationKey := {1:"q", 2:"w", 3:"e"} 60 | index := 1 61 | loop, 3 62 | { 63 | if (NML_CB%index%) 64 | { 65 | loop, 3 66 | g_SF.DirectedInput(,, formationKey[index]) 67 | champArray := g_SF.Memory.GetFormationByFavorite(index) 68 | GuiControl, ICScriptHub:, NML_Formation, % "Formation " . formationKey[index] . ": " . ArrFnc.GetDecFormattedArrayString(champArray) 69 | for k, v in champArray 70 | { 71 | if (v == -1 OR !v) 72 | continue 73 | seat := g_SF.Memory.ReadChampSeatByID(v) 74 | inputKey := "{F" . seat . "}" 75 | name := g_SF.Memory.ReadChampNameByID(v) 76 | if !name 77 | name := v 78 | champLvl := g_SF.Memory.ReadChampLvlByID(v) 79 | GuiControl, ICScriptHub:, NML_Champ, % "Leveling " . name . " (" . inputKey . ") " . champLvl . " / " . g_MaxLvl[v] 80 | while (g_MaxLvl[v] > champLvl) 81 | { 82 | g_SF.DirectedInput(,, inputKey, formationKey[index]) 83 | sleep, 33 84 | champLvl := g_SF.Memory.ReadChampLvlByID(v) 85 | if lvlObj.IsSpec(v, champLvl, g_SpecSettings) 86 | lvlObj.PickSpec(v, champLvl, g_SpecSettings) 87 | GuiControl, ICScriptHub:, NML_Champ, % "Leveling " . name . " (" . inputKey . ") " . champLvl . " / " . g_MaxLvl[v] 88 | } 89 | } 90 | } 91 | ++index 92 | } 93 | GuiControl, ICScriptHub:, NML_Formation, 94 | GuiControl, ICScriptHub:, NML_Champ, 95 | msgbox, Leveling and Specializing Complete. 96 | } 97 | 98 | NML_SpecSettings() 99 | { 100 | GuiControl, ICScriptHub:, NML_Settings, Processing data, please wait... 101 | g_HeroDefines := IC_NML_Functions.GetHeroDefines() 102 | NML_BuildSpecSettingsGUI() 103 | Gui, SpecSettingsGUI:Show 104 | GuiControl, ICScriptHub:, NML_Settings, % g_SpecSettings.TimeStamp ? "Loaded and dated " . g_SpecSettings.TimeStamp : "Not Loaded" 105 | } 106 | 107 | NML_BuildMaxLvlData() 108 | { 109 | GuiControl, ICScriptHub:, NML_MaxLvl, Processing data, please wait... 110 | g_HeroDefines := IC_NML_Functions.GetHeroDefines() 111 | g_MaxLvl := {} 112 | for k, v in g_HeroDefines 113 | { 114 | if v.MaxLvl 115 | g_MaxLvl[k] := v.MaxLvl 116 | } 117 | g_MaxLvl.TimeStamp := A_MMMM . " " . A_DD . ", " . A_YYYY . ", " . A_Hour . ":" . A_Min . ":" . A_Sec 118 | g_SF.WriteObjectToJSON(A_LineFile . "\..\MaxLvl.JSON", g_MaxLvl) 119 | GuiControl, ICScriptHub:, NML_MaxLvl, % g_MaxLvl.TimeStamp ? "Loaded and dated " . g_MaxLvl.TimeStamp : "Not Loaded" 120 | } 121 | 122 | NML_BuildSpecSettingsGUI() 123 | { 124 | global 125 | Gui, SpecSettingsGUI:New 126 | Gui, SpecSettingsGUI:+Resize -MaximizeBox 127 | Gui, SpecSettingsGUI:Font, q5 128 | Gui, SpecSettingsGUI:Add, Button, x554 y25 w60 gNML_SaveClicked, Save 129 | Gui, SpecSettingsGUI:Add, Button, x554 y+25 w60 gNML_CloseClicked, Close 130 | Gui, SpecSettingsGUI:Add, Tab3, x5 y5 w539, Seat 1|Seat 2|Seat 3|Seat 4|Seat 5|Seat 6|Seat 7|Seat 8|Seat 9|Seat 10|Seat 11|Seat 12| 131 | seat := 1 132 | loop, 12 133 | { 134 | Gui, Tab, Seat %seat% 135 | Gui, SpecSettingsGUI:Font, w700 s11 136 | Gui, SpecSettingsGUI:Add, Text, x15 y35, Seat %Seat% Champions: 137 | Gui, SpecSettingsGUI:Font, w400 s9 138 | for champID, define in g_HeroDefines 139 | { 140 | if (define.Seat == seat) 141 | { 142 | name := define.HeroName 143 | Gui, SpecSettingsGUI:Font, w700 144 | Gui, SpecSettingsGUI:Add, Text, x15 y+10, Name: %name% `ID: %champID% 145 | Gui, SpecSettingsGUI:Font, w400 146 | prevUpg := 0 147 | for key, set in define.SpecDefines.setList 148 | { 149 | reqLvl := set.reqLvl 150 | ddlString := define.SpecDefines.DDL[reqLvl, prevUpg] 151 | choice := 0 152 | for k, v in g_SpecSettings[champID] 153 | { 154 | if (v.requiredLvl == reqLvl) 155 | choice := v.Choice 156 | } 157 | if !choice 158 | choice := 1 159 | Gui, SpecSettingsGUI:Add, DropDownList, x15 y+5 vNML_%champID%Spec%reqLvl% Choose%choice% AltSubmit gNML_UpdateDDL, %ddlString% 160 | prevUpg := define.SpecDefines.SpecDefineList[reqLvl, prevUpg][choice].UpgradeID 161 | } 162 | } 163 | } 164 | ++seat 165 | } 166 | Return 167 | } 168 | 169 | ;close spec settings GUI 170 | NML_CloseClicked() 171 | { 172 | Gui, SpecSettingsGUI:Hide 173 | Return 174 | } 175 | 176 | ;save button function from GUI built as part of NML_BuildSpecSettingsGUI() 177 | NML_SaveClicked() 178 | { 179 | Gui, SpecSettingsGUI:Submit, NoHide 180 | For champID, define in g_HeroDefines 181 | { 182 | g_SpecSettings[champID] := {} 183 | prevUpg := 0 184 | for k, v in define.SpecDefines.setList 185 | { 186 | reqLvl := v.reqLvl 187 | choice := NML_%champID%Spec%reqLvl% 188 | position := g_SpecSettings[champID].Push(define.SpecDefines.SpecDefineList[reqLvl, prevUpg][choice].Clone()) 189 | g_SpecSettings[champID][position].Choice := choice 190 | g_SpecSettings[champID][position].Choices := define.SpecDefines.SpecDefineList[reqLvl, prevUpg].Count() 191 | prevUpg := g_SpecSettings[champID][position].UpgradeID 192 | } 193 | } 194 | g_SpecSettings.TimeStamp := A_MMMM . " " . A_DD . ", " . A_YYYY . ", " . A_Hour . ":" . A_Min . ":" . A_Sec 195 | g_SF.WriteObjectToJSON(A_LineFile . "\..\SpecSettings.JSON", g_SpecSettings) 196 | GuiControl, ICScriptHub:, NML_Settings, % g_SpecSettings.TimeStamp ? "Loaded and dated " . g_SpecSettings.TimeStamp : "Not Loaded" 197 | Return 198 | } 199 | 200 | NML_UpdateDDL() 201 | { 202 | Gui, SpecSettingsGUI:Submit, NoHide 203 | choice := %A_GuiControl% 204 | foundPos := InStr(A_GuiControl, "S") 205 | champID := SubStr(A_GuiControl, 5, foundPos - 5) + 0 206 | foundPos := InStr(A_GuiControl, "Spec") 207 | reqLvl := SubStr(A_GuiControl, foundPos + 4) + 0 208 | ;need previous upgrade id to get current upgrade id 209 | prevUpg := 0 210 | for k, v in g_SpecSettings[champID] 211 | { 212 | if (v.requiredLvl < reqLvl) 213 | prevUpg := v.UpgradeID 214 | } 215 | prevUpg := g_HeroDefines[champID].SpecDefines.SpecDefineList[reqLvl, prevUpg][choice].UpgradeID 216 | for k, v in g_HeroDefines[champID].SpecDefines.setList 217 | { 218 | requiredLvl := v.reqLvl 219 | if (v.listCount > 1 AND requiredLvl > reqLvl) 220 | { 221 | ddlString := "|" 222 | ddlString .= g_HeroDefines[champID].SpecDefines.DDL[requiredLvl, prevUpg] 223 | GuiControl, SpecSettingsGUI:, NML_%champID%Spec%requiredLvl%, %ddlString% 224 | GuiControl, SpecSettingsGUI:Choose, NML_%champID%Spec%requiredLvl%, 1 225 | prevUpg := g_HeroDefines[champID].SpecDefines.SpecDefineList[requiredLvl, prevUpg][1].UpgradeID 226 | } 227 | } 228 | } 229 | 230 | ;$SC045:: 231 | ;Pause 232 | 233 | Hotkey, SC045, NML_Pause 234 | 235 | NML_Pause() 236 | { 237 | Pause 238 | } -------------------------------------------------------------------------------- /IC_NoModronLvling_Extra/IC_NoModronLvling_Functions.ahk: -------------------------------------------------------------------------------- 1 | class IC_NML_Functions 2 | { 3 | endScript := false 4 | 5 | ;requires single param == simple array of champ IDs. returns an array of obj where obj key == champ ID and obj has fields maxLvl == max level and fKey := Fkey string. 6 | GetMaxLvlArray(arrayIn) 7 | { 8 | arrayOut := {} 9 | g_SF.Memory.OpenProcessReader() 10 | for k, v in arrayIn 11 | { 12 | if !IsObject(arrayOut[v]) 13 | { 14 | arrayOut[v] := {} 15 | arrayOut[v].fKey := "{F" . g_SF.Memory.ReadChampSeatByID(v) . "}" 16 | } 17 | upgradeCount := g_SF.Memory.GenericGetValue(g_SF.Memory.GameManager.Game.gameInstances.Controller.UserData.HeroHandler.heroes.allUpgradesOrdered.size.GetGameObjectFromListValues(0, v - 1)) 18 | upgIndex := 0 19 | ;iterate through every upgrade for that hero 20 | loop %upgradeCount% 21 | { 22 | orderedUpgradesObject := g_SF.Memory.GetHeroOrderedUpgrade(v-1, upgIndex) 23 | requiredLvl := g_SF.Memory.GenericGetValue(orderedUpgradesObject.requiredLvl.GetGameObjectFromListValues(0)) 24 | ;some upgrades with required level of 9999 25 | if (requiredLvl < 9999) 26 | arrayOut[v].maxLvl := Max(requiredLvl, arrayOut[v].maxLvl) 27 | ++upgIndex 28 | } 29 | } 30 | return arrayOut 31 | } 32 | 33 | ;requires single param == array returned from GetMaxLvlArray(). returns inputs == array of Fkey strings of champs not at max lvl. 34 | GetFkeys(maxLvlArray) 35 | { 36 | inputs := {} 37 | for k, v in maxLvlArray 38 | { 39 | if (g_SF.Memory.ReadChampLvlByID(k) < v.maxLvl) 40 | inputs.Push(v.Fkey) 41 | } 42 | return inputs 43 | } 44 | 45 | BuildSpecSettingsGUI(defines, settings) 46 | { 47 | static 48 | isBuilt := false 49 | if !isBuilt 50 | { 51 | Gui, SpecSettingsGUI:New 52 | Gui, SpecSettingsGUI:+Resize -MaximizeBox 53 | Gui, SpecSettingsGUI:Font, q5 54 | Gui, SpecSettingsGUI:Add, Button, x554 y25 w60 gNML_SaveClicked, Save 55 | Gui, SpecSettingsGUI:Add, Button, x554 y+25 w60 gNML_CloseClicked, Close 56 | Gui, SpecSettingsGUI:Add, Tab3, x5 y5 w539, Seat 1|Seat 2|Seat 3|Seat 4|Seat 5|Seat 6|Seat 7|Seat 8|Seat 9|Seat 10|Seat 11|Seat 12| 57 | seat := 1 58 | loop, 12 59 | { 60 | Gui, Tab, Seat %seat% 61 | Gui, SpecSettingsGUI:Font, w700 s11 62 | Gui, SpecSettingsGUI:Add, Text, x15 y35, Seat %Seat% Champions: 63 | Gui, SpecSettingsGUI:Font, w400 s9 64 | for champID, define in defines 65 | { 66 | if (define.Seat == seat) 67 | { 68 | name := define.HeroName 69 | Gui, SpecSettingsGUI:Font, w700 70 | Gui, SpecSettingsGUI:Add, Text, x15 y+10, Name: %name% `ID: %champID% 71 | Gui, SpecSettingsGUI:Font, w400 72 | prevUpg := 0 73 | for key, set in define.SpecDefines.setList 74 | { 75 | reqLvl := set.reqLvl 76 | ddlString := define.SpecDefines.DDL[reqLvl, prevUpg] 77 | choice := 0 78 | for k, v in settings[champID] 79 | { 80 | if (v.requiredLvl == reqLvl) 81 | choice := v.Choice 82 | } 83 | if !choice 84 | choice := 1 85 | ;var := "Champ" . champID . "Spec" . reqLvl . "Drop" 86 | ;static %var% 87 | Gui, SpecSettingsGUI:Add, DropDownList, x15 y+5 vChamp%champID%Spec%reqLvl%Drop Choose%choice% AltSubmit gNML_ChangedDDL, %ddlString% 88 | prevUpg := define.SpecDefines.SpecDefinesList[set.reqLvl, prevUpg][choice].UpgradeID 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | GetHeroDefines() 97 | { 98 | start := A_TickCount 99 | defines := {} 100 | g_SF.Memory.OpenProcessReader() 101 | ;iterate through every hero in memory 102 | heroCount := g_SF.Memory.GenericGetValue(g_SF.Memory.GameManager.Game.gameInstances.Controller.UserData.HeroHandler.heroes.size.GetGameObjectFromListValues(0)) 103 | if (heroCount < 100) 104 | msgbox, "There may have been an error loading data. Reloading the script may fix the error. Error: Unexpected heroCount" 105 | champID := 0 106 | loop %heroCount% 107 | { 108 | ++champID 109 | ;only include owned heroes 110 | isOwned := g_SF.Memory.GenericGetValue(g_SF.Memory.GameManager.Game.gameInstances.Controller.UserData.HeroHandler.heroes.Owned.GetGameObjectFromListValues(0, champID - 1)) 111 | if !isOwned 112 | Continue 113 | name := g_SF.Memory.ReadChampNameByID(champID) 114 | seat := g_SF.Memory.ReadChampSeatByID(champID) 115 | defines[champID] := new IC_NML_Functions.HeroDefine(champID, name, seat) 116 | upgradesObject := g_SF.Memory.GameManager.Game.gameInstances.Controller.UserData.HeroHandler.heroes.allUpgradesOrdered.List.GetFullGameObjectFromListOrDictValues("List", 0, champID - 1) 117 | upgradesObject := upgradesObject.GetFullGameObjectFromListOrDictValues("Dict", 0) 118 | upgradesObject.ValueType := "List" 119 | upgradeCount := g_SF.Memory.GenericGetValue(upgradesObject.size) 120 | upgIndex := 0 121 | ;iterate through every upgrade for that hero 122 | loop %upgradeCount% 123 | { 124 | orderedUpgrade := g_SF.Memory.GetHeroOrderedUpgrade(champID-1, upgIndex) 125 | requiredLvl := g_SF.Memory.GenericGetValue(orderedUpgrade.RequiredLevel) 126 | ;some upgrades with required level of 9999 127 | if (requiredLvl < 9999) 128 | defines[champID].MaxLvl := Max(requiredLvl, defines[champID].MaxLvl) 129 | ;look to see if upgrade define has spec graphic id, easiest way to know it is a spec upgrade and appears to work 100% so far. 130 | ;trying to use upgrade type field was just wrong in a lot of cases. the type spec was commonly overrided by stuff like upgrade ability type. 131 | isSpec := g_SF.Memory.GenericGetValue(orderedUpgrade.defaultSpecGraphic) 132 | if isSpec 133 | { 134 | upgradeID := g_SF.Memory.GenericGetValue(orderedUpgrade.ID) 135 | requiredUpgradeID := g_SF.Memory.GenericGetValue(orderedUpgrade.RequiredUpgradeID) 136 | specName := g_SF.Memory.GenericGetValue(orderedUpgrade.SpecializationName) 137 | defines[champID].SpecDefines.AddSpec(upgradeID, requiredLvl, requiredUpgradeID, specName) 138 | } 139 | ++upgIndex 140 | } 141 | defines[champID].SpecDefines.SortSpecList() 142 | } 143 | ;defines.Loaded := 1 144 | defines.TimeStamp := A_MMMM . " " . A_DD . ", " . A_YYYY . " at " . A_Hour . ":" . A_Min . ":" . A_Sec 145 | defines.LoadTime := A_TickCount - start 146 | ;a bit easier to debug from json file 147 | g_SF.WriteObjectToJSON(A_LineFile . "\..\HeroDefines.JSON", defines) 148 | return defines 149 | } 150 | 151 | class HeroDefine 152 | { 153 | __new(heroID, heroName, seat) 154 | { 155 | this.HeroID := heroID 156 | this.HeroName := heroName 157 | this.MaxLvl := 1 158 | this.Seat := seat 159 | this.SpecDefines := new IC_NML_Functions.SpecDefineSets 160 | return this 161 | } 162 | } 163 | 164 | class SpecDefine 165 | { 166 | __new(upgradeID, requiredLvl, requiredUpgradeID, specName) 167 | { 168 | this.UpgradeID := upgradeID 169 | this.RequiredLvl := requiredLvl 170 | this.RequiredUpgradeID := requiredUpgradeID 171 | this.SpecName := specName 172 | return this 173 | } 174 | } 175 | 176 | class SpecDefineSets 177 | { 178 | ;each item is an array of spec upgrades associated with a given level and required upgrade. 179 | specList := {} 180 | specListSize := 0 181 | ;an array that mimics specList, but consists of strings for drop down list gui elements. 182 | ddlList := {} 183 | ;each item is an object of data to know which items from specList to use based on level and required upgrade data. 184 | setList := {} 185 | setListSize := 0 186 | 187 | AddSpec(upgID, reqLvl, reqUpgID, specName) 188 | { 189 | isNewSet := true 190 | for k, v in this.setList 191 | { 192 | if (reqLvl == v.reqLvl) 193 | { 194 | isNewSet := false 195 | ;this handles spec sets like Morg and Selise that change based on previous choices 196 | if !v.listIndex.HasKey(reqUpgID) 197 | { 198 | index := this.createNewSpecListEntry() 199 | v.AddNewReqUpgID(index, reqUpgID) 200 | } 201 | else 202 | index := v.listIndex[reqUpgID] 203 | ;following should not be possible, but leaving here just in case 204 | ;if !IsObject(this.specList[index]) 205 | ; this.createNewSpecListEntry(index) 206 | this.pushSpec(index, upgID, reqLvl, reqUpgID, specName, k) 207 | break 208 | } 209 | } 210 | if isNewSet 211 | { 212 | index := this.createNewSpecListEntry() 213 | this.setList.Push(new IC_NML_Functions.SetData(index, reqLvl, reqUpgID)) 214 | this.setListSize := this.setList.Count() 215 | this.pushSpec(index, upgID, reqLvl, reqUpgID, specName, k) 216 | } 217 | } 218 | 219 | pushSpec(index, upgID, reqLvl, reqUpgID, specName, k) 220 | { 221 | this.specList[index].Push(new IC_NML_Functions.SpecDefine(upgID, reqLvl, reqUpgID, specName)) 222 | } 223 | 224 | createNewSpecListEntry() 225 | { 226 | this.specListSize += 1 227 | this.specList[this.specListSize] := {} 228 | this.ddlList[this.specListSize] := "" 229 | return this.specListSize 230 | } 231 | 232 | SortSpecList() 233 | { 234 | for k, v in this.specList 235 | { 236 | ;insertion sort 237 | i := 1 238 | while (i <= v.Count()) 239 | { 240 | j := i 241 | while (j > 1 AND v[j-1].UpgradeID > v[j].UpgradeID) 242 | { 243 | temp := v[j].Clone() 244 | v[j] := v[j-1].Clone() 245 | v[j-1] := temp.Clone() 246 | --j 247 | } 248 | ++i 249 | } 250 | } 251 | } 252 | 253 | SpecDefineList[reqLvl, reqUpgID] 254 | { 255 | get 256 | { 257 | index := this.getIndex(reqLvl, reqUpgID) 258 | if (index == -1) 259 | return "" 260 | else 261 | return this.specList[index] 262 | } 263 | } 264 | 265 | DDL[reqLvl, reqUpgID] 266 | { 267 | get 268 | { 269 | index := this.getIndex(reqLvl, reqUpgID) 270 | if (index == -1) 271 | return "" 272 | else 273 | { 274 | string := "" 275 | for k, v in this.specList[index] 276 | { 277 | string .= v.SpecName . "|" 278 | } 279 | return string 280 | } 281 | } 282 | } 283 | 284 | getIndex(reqLvl, reqUpgID) 285 | { 286 | for k, v in this.setList 287 | { 288 | if (reqLvl == v.reqLvl) 289 | { 290 | if v.listIndex.HasKey(0) 291 | return v.listIndex[0] 292 | else 293 | return v.listIndex[reqUpgID] 294 | } 295 | } 296 | return -1 297 | } 298 | } 299 | 300 | ;an object for all the spec upgrades associated with a particular level. 301 | class SetData 302 | { 303 | listIndex := {} 304 | listCount := 0 305 | 306 | __new(index, reqLvl, reqUpgID) 307 | { 308 | this.reqLvl := reqLvl 309 | this.AddNewReqUpgID(index, reqUpgID) 310 | return this 311 | } 312 | 313 | AddNewReqUpgID(index, reqUpgID) 314 | { 315 | this.listIndex[reqUpgID] := index 316 | this.listCount += 1 317 | } 318 | } 319 | 320 | LevelAndSpec(champID, targetLvl, maxLvlData, specSettings) 321 | { 322 | seat := g_SF.Memory.ReadChampSeatByID(champID) 323 | inputKey := "{F" . seat . "}" 324 | if !targetLvl 325 | targetLvl := maxLvlData[champID] 326 | while (targetLvl > g_SF.Memory.ReadChampLvlByID(champID) AND !(this.endScript)) 327 | { 328 | g_SF.DirectedInput(,, inputKey) 329 | for k, v in specSettings[champID] 330 | { 331 | if (v.RequiredLvl == g_SF.Memory.ReadChampLvlByID(champID)) 332 | this.PickSpec(v.Choice, v.Choices, v.UpgradeID) 333 | } 334 | } 335 | return 336 | } 337 | 338 | IsSpec(champID, champLvl, specSettings) 339 | { 340 | for k, v in specSettings[champID] 341 | { 342 | if (v.RequiredLvl == champLvl) 343 | return true 344 | } 345 | return false 346 | } 347 | 348 | PickSpec(champID, champLvl, specSettings) 349 | { 350 | static lastUpgrade := 0 351 | static clickCount := 0 352 | for k, v in specSettings[champID] 353 | { 354 | if (v.RequiredLvl == champLvl) 355 | { 356 | choice := v.Choice 357 | choices := v.Choices 358 | upgradeID := v.UpgradeID 359 | } 360 | } 361 | ScreenCenterX := (g_SF.Memory.ReadScreenWidth(1) / 2) 362 | ScreenCenterY := (g_SF.Memory.ReadScreenHeight(1) / 2) 363 | yClick := ScreenCenterY + 245 364 | ButtonWidth := 70 365 | ButtonSpacing := 180 366 | TotalWidth := (ButtonWidth * Choices) + (ButtonSpacing * (Choices - 1)) 367 | xFirstButton := ScreenCenterX - (TotalWidth / 2) 368 | xClick := xFirstButton + 35 + (250 * (Choice - 1)) 369 | StartTime := A_TickCount 370 | ElapsedTime := 0 371 | loop, 1 372 | { 373 | WinActivate, ahk_exe IdleDragons.exe 374 | MouseClick, Left, xClick, yClick, 1 375 | Sleep, 10 376 | } 377 | if (lastUpgrade == upgradeID) 378 | ++clickCount 379 | else 380 | { 381 | lastUpgrade := upgradeID 382 | clickCount := 0 383 | } 384 | if (clickCount > 5) 385 | { 386 | msgbox, 4,, The script has failed specializing in %clicCount% consecutive attempts. Continue? 387 | IfMsgBox No 388 | this.endScript := true 389 | } 390 | return 391 | } 392 | 393 | ;favorite: 1 = save slot 1 (Q), 2 = save slot 2 (W), 3 = save slot 3 (E) 394 | LevelAndSpecFavoriteFormation(favorite, maxLvlData, specSettings) 395 | { 396 | this.endScript := false 397 | if (favorite == 1) 398 | inputKey := "q" 399 | else if (favorite == 2) 400 | inputKey := "w" 401 | else if (favorite == 3) 402 | inputKey := "e" 403 | loop 3 404 | g_SF.DirectedInput(,, inputKey) 405 | champArray := g_SF.Memory.GetFormationByFavorite(favorite) 406 | for k, v in champArray 407 | { 408 | if (v == -1) 409 | continue 410 | g_SF.DirectedInput(,, inputKey) 411 | this.LevelAndSpec(v, 0, maxLvlData, specSettings) 412 | if this.endScript 413 | return 414 | } 415 | } 416 | } -------------------------------------------------------------------------------- /IC_NoModronLvling_Extra/README.md: -------------------------------------------------------------------------------- 1 | # No Modron Leveling 2 | ## Description: 3 | An add on that will level and specialize champions without Modron Automation. 4 | # 5 | ## Instructions: 6 | Instructions: 7 | 1. If it is your first time using, press the 'Select/Create Spec. Settings' button and select the desired specializations for each champion. 8 | 2. If it is your first time using, press the 'Load Max. Lvl Data' button. 9 | 3. In game, load the desires formations to formation favorites 1/Q, 2/W, and/or 3/E. 10 | 4. Check the appropriate boxes on the script for the formation favoriates you want leveled and specialized. 11 | 5. Press the 'Level and Specialize' Button. 12 | 6. A message box should notify you when complete. 13 | 14 | Notes: 15 | 1. When a new champion is added you will need to repeat Instruction steps 1 and 2. 16 | 2. When a soft cap increase is released you will need to repeat Instruction step 2. 17 | 3. If a champion rework or rebalance results in different or new upgrades you may need to repeat Instruction steps 1 and 2. 18 | 19 | Known Issues: 20 | 1. Occasionally, the upgrade lists are not read correctly from memory. You will know this is the case when the Select Specialization window opens and champions you own are not present or the drop down lists to select specializations are blank. If this occurs, please make sure the game is running and reload the script. 21 | 2. The script can click before the specialization window appears or after it is gone, resulting in a champion formation dialogue opening. This should not interfere with the script functionality. 22 | 23 | ## ChangeLog: 24 | v0.0.2, 5/21/22 25 | 26 | Update to Auto Offsets v2 Script Hub. Maybe. 27 | 28 | v0.0.1 March 12, 2022 29 | 30 | Update for changed specialization dialogs. 31 | 32 | v0.0.0 February 19, 2022 33 | 34 | Beta release. 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repo is no longer being maintained. 2 | 3 | # IC_Addons 4 | Addons for IC Script Hub - NERDs and No Modron Leveling are still to be updated for Auto Offset revisions. Azaka is in need of testing. 5 | 6 | ## IC_Azaka_Extra 7 | This AddOn will spam Azaka and other champion's ults at a set Omin number of contracts fulfilled value. 8 | 9 | ## IC_NERDs_Extra 10 | This AddOn will launch a seaparte script that will spam NERDs ultimate until you get the desired set of three NERDs. 11 | 12 | ## IC_NoModronLvling_Extra 13 | An add on that will level and specialize champions without Modron Automation. 14 | --------------------------------------------------------------------------------