-
Notifications
You must be signed in to change notification settings - Fork 2
/
Bizhawk_Golden_Sun_Utility_Script_v1.3.2.lua
1897 lines (1706 loc) · 67.6 KB
/
Bizhawk_Golden_Sun_Utility_Script_v1.3.2.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
function unpack_decorator(f) -- redefine unpack to include 0th key in arrays
local function inner(array)
if array == nil then return end
if array[0] ~= nil then
return array[0], f(array)
else
return f(array)
end
end
return inner
end
table.unpack = unpack_decorator(table.unpack)
local version = (memory.read_u8(0x080000A0) == 0x4F) and "J" or "U" -- check version and set global
JPN = nil
if version == "J" then JPN = 1 else JPN = 0
end
local AD1 = 0x0200053a -- Isaac PP
local AD3 = 0x02000479 -- Next Encounter
local AD4 = 0x020023A8 -- Battle RN
local AD5 = 0x03001CB4 -- General RN
local AD6 = (0x020301A8) -- Encounter Step Counter
local EncounterRate = memory.read_u32_le(0x02000478)
local gcount = 0
local bcounter = 0
local store = memory.read_u32_le(0x03001CB4)
local bstore = memory.read_u32_le(0x020023A8)
local brncount=0
local fleestore = 0
local fleepercent = 0
local mem = 0x2010000
local memcount = 0
local keypress = {}
local state = false
local brnadvancecounter = 0
local brnreducecounter = 0
local grnadvancecounter = 0
local grnreducecounter = 0
local timerstate = false
local timeron = false
local fighttimer = 0
local infight = false
local fighttimertext = 0
local fightlength = 0
local pplock = false
local ppstate = false
local encounterlock = false
local encounterstate = false
local minorhudlock = true
local minorhudstate = false
local overlaystate = false
local overlay = false
local randomisercounter = 0
local randomiserstate = false
local grnrandomisercounter = 0
local grnrandomiserstate = false
local nosq = false
local nosqstate = false
local debugmode = false
local debugmodestate = false
local DialID
local BRN_temp = 0
local BRN_temps = 0
local BRN_tempss = 0
local BRN_tempsss = 0
local BRN_tempssss = 0
local RatePredictionRNGStore = 0
local RatePredictionVectorStore = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}
local tableVariableStore = 0
local globaltimerstate = false
local globaltimeron = false
local globaltimerpause = false
local globaltimer = 0
local globaltimertext = 0
local globallength = 0
local globaltimerstore = {0,0,0}
local globaltimerstoretimer = 0
local BaseHP = 0x02000510
local BasePP = 0x02000512
local BaseAtk = 0x02000518
local BaseDef = 0x0200051A
local BaseAgi = 0x0200051C
local BaseLuc = 0x0200051E -- read_u8 for this entry
local Cursor = (0x050003CA) -- alternatively, 0x03007DE4 which gives slot in part, not character
--local CursorGaret = (0x020333F0) -- as above
--local CursorIvan = (0x02033428)
--local CursorMia = (0x02033460)
local CharMemDiff = 0x14C -- gap between character memory values
local CurrentChar = 0
local CurrentName = ""
local CharEXP = 0
local IsaacLevels = {0,24,67,144,283,519,873,1369,2039,2910,3999,5306,6861,8696,10843,13334,16224,19548,23371,27767,32778,38491,45004,52429,60893,70457}--26 levels
local GaretLevels = {0,30,84,176,332,582,957,1482,2191,3113,4265,5647,7292,9233,11504,14138,17193,20706,24746,29271,34339,40015,46372,53492,61894,71808}
local IvanLevels = {0,32,90,194,350,568,895,1418,2150,3102,4292,5720,7419,9424,11770,14491,17647,21276,25449,30248,35719,41956,49066,57171,66411,76852}
local MiaLevels = {0,31,87,188,350,609,997,1540,2273,3226,4341,5657,7197,8999,11107,13594,16529,19992,24078,28899,34395,40660,47802,55944,65226,75715}
local levelstore = 1
local statstate = false
local StatColor = {0xFF00FF00,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
local SelectedStat = 0
local StatToChange = 0
local IsaacGoals = {{30,182},{20,80},{13,86},{6,38},{8,86}}
local GaretGoals = {{33,191},{18,76},{11,83},{8,41},{6,76}}
local IvanGoals = {{28,166},{24,92},{8,76},{4,35},{11,91}}
local MiaGoals = {{29,173},{23,90},{9,79},{5,37},{7,80}}
local CurrentGoals = {{0,0},{0,0},{0,0},{0,0},{0,0}}
local StatusMenuOpen = false
local RNmultipliers = {0x41C64E6D}
local RNintervals = {0x3039}
function multMod (A,B,C) -- Multiplies big numbers, and takes mod 2^32
return (A*B+C) & 0xFFFFFFFF
end
for i=1,31 do -- Constructs the effective multipliers and increments for each power of 2
RNmultipliers[i+1] = multMod(RNmultipliers[i],RNmultipliers[i],0)
RNintervals[i+1] = multMod(RNintervals[i],RNmultipliers[i],RNintervals[i])
end
function PluginDetect(arg) -- detect which plugin scripts are installed
local out = {}
for i=1,#arg do
local FileName = arg[i]
if string.find(FileName, "%.%a+$") == nil then FileName = FileName + ".lua"
end
local File = io.open(arg[i], "r")
if File ~= nil then io.close(File); table.insert(out, true)
else table.insert(out, false)
end
end
return table.unpack(out)
end
function gui.scaledtext (x, y, ...) -- scales gui elements to emulator screen ratio
local borderX = client.borderwidth()
local borderY = client.borderheight()
local width = client.screenwidth() - 2*borderX
local height = client.screenheight() - 2*borderY
gui.text(x/240 * width + borderX, y/160 * height + borderY, ...)
end
function LevelCalculator(CurrentCharacter)
CharEXP = memory.read_u32_le(0x02000624+CharMemDiff*CurrentCharacter)
levelstore = 1
if CurrentCharacter == 0 then
CharLevels = IsaacLevels
elseif CurrentCharacter == 1 then
CharLevels = GaretLevels
elseif CurrentCharacter == 2 then
CharLevels = IvanLevels
elseif CurrentCharacter == 3 then
CharLevels = MiaLevels
end
while CharEXP - CharLevels[levelstore+1] > 0 do
levelstore = levelstore + 1
end
return levelstore
end
function WhichStat(S,C) -- SelectedStat, CurrentChar
if S == 0 then
return BaseHP+CharMemDiff*C
elseif S == 1 then
return BasePP+CharMemDiff*C
elseif S == 2 then
return BaseAtk+CharMemDiff*C
elseif S == 3 then
return BaseDef+CharMemDiff*C
elseif S == 4 then
return BaseAgi+CharMemDiff*C
end
end
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-- New things from TLA Utility Script 2.2
-- Good Rate analysis
local GoodRateThreshold = 0xC00 -- Hex value between 0x100 and 0x16000
local CurrentRate = 0
local encounteranalysisstate = false
local encounteranalysis = false
local encounterColor = {0,0,0}
local encounterValue = memory.read_u32_le(0x02000478)
local encounterPreviousvalue = memory.read_u32_le(0x02000478)
-- Exploratory Rate analysis
local OldRate = 0
local NewRate = 0
local RateRate = 0
local WorldMapOffset = 0
local StepGRNOffset = 0
local moveList = {"Base", "Move", "Frost", "Growth", "Douse / Halt", "Lift / Carry", "Mind Read"}
local grnAdvanceList = {0, 295, 96, 63, 80, 72, 0}
local tableVariable = 1
local tableVairabletemp = 1
local tableState = false
function NormalisedRate(IN) -- takes the encounter rate value returns a number between 0-100, 0 being low enc and 100 being high enc
NormRate = memory.read_u32_le(IN)
--IsNegative = 0
if NormRate == 0 then
NormRate = ""
return NormRate
else
if NormRate >= 0xFFFF0000 then
NormRate = NormRate - 0xFFFFFFFF
--IsNegative = 1
end
NormRate = math.floor((0xFFFF - NormRate)/0xFF0)
return NormRate
end
end
function NormalisedRate2(IN) -- takes the encounter rate value returns a number between 0-100, 0 being low enc and 100 being high enc
NormRate = IN
--IsNegative = 0
if NormRate == 0 then
NormRate = ""
return NormRate
else
NormRate = math.floor((0xFFFF - NormRate)/0xFF0)
return NormRate
end
end
function NormalisedRate3(IN) -- takes the encounter rate value returns a number between 0-100, 0 being low enc and 100 being high enc
NormRate = IN
--IsNegative = 0
NormRate = math.floor((0xFFFF - NormRate)/0xFF0)
return NormRate
end
--------------------------------------------------- NEW SHIT STARTS HERE
function RNC(R) -- RN concatenate
return ((R >> 8) & 0xFFFF)
end
function RatePrediction(IN)
RatePred1 = math.floor(RNC(RNA(IN)))
RatePred2 = math.floor(RNC(RNA(RNA(IN))))
RatePred3 = math.floor(RNC(RNA(RNA(RNA(IN)))))
RatePred4 = math.floor(RNC(RNA(RNA(RNA(RNA(IN))))))
RatePred = math.floor(RatePred1 - RatePred2 + RatePred3 - RatePred4)/2
return RatePred
end
function RatePsyCalc(IN,ADV)
R=RNA(IN,ADV)
R=RatePrediction(R)
R=NormalisedRate3(R)
return R
end
function ColorRate(R) -- R = ColorRate1
ColorRateS= 0xFFFF0000
ColorRateShade = math.floor((22-R)/22*255)
if ColorRateShade <= 63 then
ColorRateS = 0xFFFF0000 + 1024*ColorRateShade
elseif ColorRateShade <=191 then
ColorRateS = 0xFF00FF00 + 256*256*(255-255*(ColorRateShade-63)/128-1)
else
ColorRateS = 0xFF00FF00
end
return ColorRateS
end
--function PercentRoll(RNG,Percent) --unused
--RNG = &(>>(RNG,8), 0xFFFF)
--return >>(RNG*Percent,16)
--end
--begin the script proper
print("Welcome to the Golden Sun Utility Script")
print("Currently configured for " .. version .. " version")
print("Commands:")
print("shift+g: advances the GRN by one")
print("shift+b: advances the BRN by one")
print("shift+r: advance BRN/GRN by a random amount")
print("shift+a: toggle minor hud")
print("shift+t: toggle battle timer")
print("shift+y: force display of last fight length (timer must be on)")
print("shift+p: lock Isaac's pp to 5")
print("shift+e: toggle encounters")
print("shift+o: toggle map data overlay")
print("shift+q: toggle global timer")
print("shift+k: toggle no s&q probabilities")
print("In the status menu, use 'I' and 'K' to select a stat to change. 'L' to advance the stat by 1, 'J' to decrease the stat by 1.")
function RNA (R, advances) -- RN Advance Function
if advances == nil then
return multMod(R, RNmultipliers[1], RNintervals[1])
else
advances = (advances & 0xFFFFFFFF)
for i=1,32 do
if (advances & 1)==1 then
R = multMod(R, RNmultipliers[i], RNintervals[i])
end
advances = (advances >> 1)
if advances == 0 then break end
end
return R
end
end
function RNB (R) -- RN Advance and reduce for use in RNG calculations
return ((RNA(R) >> 8) & 0xFFFF)
end
function FindKey(table, value) -- function to help search arrays
for k,v in pairs(table) do
if v == value then return k end
end
end
function FindItemHolder(ItemIndex) -- this lets us find out who's wearing a specific item
for i=0,3 do
for j=0,14 do
if ((2^10-1) & (memory.read_u16_le(0x020005D8 + 2*j + 0x14C*i)))==(0x200 + ItemIndex) then
return i
end
end
end
end
local VenusDjinn = {"Flint","Granite","Quartz","Vine","Sap","Ground","Bane"} -- Array of all TBS Djinn
local MercDjinn = {"Fizz","Sleet","Mist","Spritz","Hail","Tonic","Dew"}
local MarsDjinn = {"Forge","Fever","Corona","Scorch","Ember","Flash","Torch"}
local JupDjinn = {"Gust","Breeze","Zephyr","Smog","Kite","Squall","Luff"}
local DjinnType = {VenusDjinn,MercDjinn,MarsDjinn,JupDjinn} -- Lets us select the element we need
function FindDjinniHolder(DjinnName)
local DjinnIndex, ElementNum
for i=1,4 do
DjinnIndex = FindKey(DjinnType[i], DjinnName)
if DjinnIndex ~= nil then ElementNum = i-1; break; end
end
DjinnIndex = DjinnIndex - 1
local BaseAddress = 0x020005F8 + 4*ElementNum
for i=0,3 do
if (2^DjinnIndex & memory.read_u8(BaseAddress + 0x14C*i)) ~= 0 then
return i
end
end
end
BattleState = nil -- Encounter detection
local MapDataCheck, EncounterDataCheck = PluginDetect({"MapData.lua","EncounterData.lua"}) -- check plugin installations
if MapDataCheck == true then -- if plugin is installed
print("MapData_1.3 plugin detected.\n Shift+D to save data.")
require("MapData_1.3")
end
if EncounterDataCheck == true then
print("EncounterData plugin detected.\n Ctrl+E to display.")
require("EncounterData")
end
while true do
keypress = input.get()
gui.scaledtext(0,0,"Frame:"..(emu.framecount()),nil,"bottomleft")
gui.scaledtext(180,0,"BRN: ".. (memory.read_u32_le(AD4)))
gui.scaledtext(180,10,"GRN: ".. (memory.read_u32_le(AD5)))
--gui.scaledtext(0,80,"Dialogue ID:".. (memory.read_u16_le(0x020301D8)))
if minorhudlock==false then
if mem <= 0x2008000 then
mem = 0x2010000
memcount=0
end
if memory.read_u32_le(mem) ~= 0 then
if memory.read_u32_le(mem+0x4) ~=0 or memory.read_u32_le(mem+0x8)~=0 or memory.read_u32_le(mem+0xB)~=0 or memory.read_u32_le(mem+0xF)~=0 or memory.read_u32_le(mem+0x10)~=0 then
mem = 0x2010000
memcount=0
end
end
while memcount <= 20000 and memory.read_u32_le(mem) == 0 or mem==0x02010000 do
mem = mem-0x4
memcount = memcount+1
end
--show our X,Y coordinates while not in combat or the overworld
if memory.read_u16_le(0x02000400)~=0x1FE and memory.read_u16_le(0x02000400)~=0x02 then
local tile = memory.read_u32_le(0x020301B8)
local tile_value = memory.read_u16_le(tile)
gui.scaledtext(80,20,"Tile Address: 0x".. string.format("%x",tile))
gui.scaledtext(120,0,"X: " .. string.format("%.6f",(memory.read_u32_le(0x02030ec4)/0x0100000)))
gui.scaledtext(120,10,"Y: " .. string.format("%.6f",(memory.read_u32_le(0x02030ecc)/0x100000)))
end
--find nonzero
gui.scaledtext(180,0,"Nonzero Tile: " .. memcount,nil,"bottomleft")
end
-- Attacks First, Caught by Surprise Check
function AF (R) -- Attacks First Check, 0 = nothing, 1 = AF, 2 = CBS
R1=R
R2 = RNB(R1)
R1 = (R1 << 8)
R1 = (R1 >> 16)
if (R1 & 0xF) == 0 then
return 1
else
if (R2 & 0x1F) ==0 then
return 2
else
return 0
end
end
end
-- Cycle-based bossfight calculators follow
-- Determine the starting point for the Saturos battle
function ModRoll(RNG, modvalue) -- for modular cycles
return (RNG >> 8) % modvalue
end
function SaturosCycle(Advances)
return ModRoll(RNA(memory.read_u32_le(AD4),Advances), 8)
end
local SaturosMoveset = {[0] = "HF", "FB", "Atk", "FB", "HF", "Atk", "Erup", "Atk"}
if memory.read_u8(0x020309A0)==0xA1 then -- if we are fighting Sleet, show our starting point for several BRN
gui.scaledtext(170,40,"Saturos:")
for i=0,8 do
local colour = 0xFFFFFFFF
local CycleNum = SaturosCycle(i)
if CycleNum == 7 then colour = 0xFF00FF00 elseif CycleNum == 6 then colour = 0xFF0000FF else colour = 0xFFFF0000 end
gui.scaledtext(170,50 + 10*i, "+" .. tostring(i) .. ": " .. SaturosMoveset[SaturosCycle(i)] .. "-" .. SaturosMoveset[(SaturosCycle(i)+1) % 8], colour)
end
end
--
pc1 = memory.read_u8(0x02000438)
pc2 = memory.read_u8(0x02000439)
pc3 = memory.read_u8(0x0200043A)
pc4 = memory.read_u8(0x0200043B)
-- Missing Agility Scripts
if memory.read_u16_le(0x02000400) ~= 0x1FE and minorhudlock == false and StatusMenuOpen == false then
iagi=memory.read_u8(0x02000500+0x1C+0x14C*0)
ilv=memory.read_u8(0x02000500+0x14C*0+0xF)
iagilv=-iagi+(ilv-1)*4+0xC -- imperfect levels ups discounting randomly rolled stats on new file
gagi=memory.read_u8(0x02000500+0x1C+0x14C*1)
glv=memory.read_u8(0x02000500+0x14C*1+0xF)
gagilv=-gagi+(glv-1)*4+0xA -- imperfect levels ups discounting randomly rolled stats on new file
vagi=memory.read_u8(0x02000500+0x1C+0x14C*2)
vlv=memory.read_u8(0x02000500+0x14C*2+0xF)
vagilv=-vagi+(vlv-4)*4+0x1B -- imperfect levels ups discounting randomly rolled stats on new file
magi=memory.read_u8(0x02000500+0x1C+0x14C*3)
mlv=memory.read_u8(0x02000500+0x14C*3+0xF)
magilv=-magi+(mlv-10)*4+0x2C -- imperfect levels ups discounting randomly rolled stats on new file
gui.scaledtext(60,0,"Missing Agi I:" .. iagilv .. " G:" .. gagilv .. " V:" .. vagilv .. " M:" .. magilv,nil,"bottomleft")
end
-- begin enemy HP/encounter loops
--Agility Battle Scripts
local pcag1=memory.read_u16_le(0x0203033C)
local pcag2=memory.read_u16_le(0x0203033C+0x10)
local pcag3=memory.read_u16_le(0x0203033C+0x20)
local pcag4=memory.read_u16_le(0x0203033C+0x30)
if memory.read_u8(0x02030368)==0xFF and memory.read_u8(0x02030368+0x02)==0 then -- Hacky way of checking if we are in fight menu or battle
if pcag1 >= 1000 then
pcag1 = memory.read_u8(0x02000540+0x14C*pc1)
end
if pcag2 >= 1000 then
pcag2 = memory.read_u8(0x02000540+0x14C*pc2)
end
if pcag3 >= 1000 then
pcag3 = memory.read_u8(0x02000540+0x14C*pc3)
end
if pcag4 >= 1000 then
pcag4 = memory.read_u8(0x02000540+0x14C*pc4)
end
gui.scaledtext(0,40,"PC" .. pc1 .. " Agi: " .. pcag1) -- Displays agility of party member pc1
gui.scaledtext(0,50,"PC" .. pc2 .. " Agi: " .. pcag2)
gui.scaledtext(0,60,"PC" .. pc3 .. " Agi: " .. pcag3)
gui.scaledtext(0,70,"PC" .. pc4 .. " Agi: " .. pcag4)
if memory.read_u8(0x020308B0)>0 then
gui.scaledtext(60,40, "E1 Agi: " .. memory.read_u8(0x020308B0+0x8)) -- If Enemy 1 has nonzero HP display E1 agility
gui.scaledtext(110,40, "HP: " .. memory.read_u16_le(0x020308B0))
else
end
if memory.read_u8(0x020308B0+0x14C)>0 then
gui.scaledtext(60,50, "E2 Agi: " .. memory.read_u8(0x020308B0+0x8+0x14C))
gui.scaledtext(110,50, "HP: " .. memory.read_u16_le(0x020308B0+0x14C))
else
end
if memory.read_u8(0x020308B0+0x14C*2)>0 then
gui.scaledtext(60,60, "E3 Agi: " .. memory.read_u8(0x020308B0+0x8+0x14C*2))
gui.scaledtext(110,60, "HP: " .. memory.read_u16_le(0x020308B0+0x14C*2))
else
end
if memory.read_u8(0x020308B0+0x14C*3)>0 then
gui.scaledtext(60,70, "E4 Agi: " .. memory.read_u8(0x020308B0+0x8+0x14C*3))
gui.scaledtext(110,70, "HP: " .. memory.read_u16_le(0x020308B0+0x14C*3))
else
end
if memory.read_u8(0x020308B0+0x14C*4)>0 then
gui.scaledtext(60,80, "E5 Agi: " .. memory.read_u8(0x020308B0+0x8+0x14C*4))
gui.scaledtext(110,80, "HP: " .. memory.read_u16_le(0x020308B0+0x14C*4))
else
end
elseif memory.read_u16_le(0x02000400)==0x1FE then -- otherwise, we are in a battle and do the following
local j=1
local k=1
local trn={}
while memory.read_u8(0x02030338+0x04+0x10*(j-1)) ~= 0 do --while loop which checks nonzero agilities and therefore count number of actors in the battle
trn[j]= memory.read_u8(0x02030338+0x10*(j-1)) -- add the character index to the trn array in order
if trn[j]==0xFF then -- if user has already acted then do nothing
j=j+1
else
gui.scaledtext(310+20*k,105,trn[j]) -- if user hasn't acted then display user in the turn order queue
j=j+1
k=k+1
end
end
gui.scaledtext(40,40, "Turn Order: ")
end
-- Agility Bonus Calculator
if memory.read_u8(0x0203033C-0x50)>0 then
local l=1
while memory.read_u8(0x02030328-0x50+0x10*l) ~= pc1 and l<15 do
l=l+1
end
if l~=15 then
pcntag1=(memory.read_u8(0x02030328-0x50+0x10*l+0x04)-memory.read_u8(0x02000BDC+0x14C*(pc1-5)))/memory.read_u8(0x02000BDC+0x14C*(pc1-5))*10000
pcntag1= math.floor(pcntag1)/100
gui.scaledtext(0,90,"PC" .. pc1 .. " Bonus: " .. pcntag1 .. "%")
end
local l=1
while memory.read_u8(0x02030328+0x10*l) ~= pc2 and l<15 do
l=l+1
end
if l~=15 then
pcntag2=(memory.read_u8(0x02030328+0x10*l+0x04)-memory.read_u8(0x02000BDC+0x14C*(pc2-5)))/memory.read_u8(0x02000BDC+0x14C*(pc2-5))*10000
pcntag2= math.floor(pcntag2)/100
gui.scaledtext(0,100,"PC" .. pc2 .. " Bonus: " .. pcntag2 .. "%")
end
local l=1
while memory.read_u8(0x02030328+0x10*l) ~= pc3 and l<15 do
l=l+1
end
if l~=15 then
pcntag3=(memory.read_u8(0x02030328+0x10*l+0x04)-memory.read_u8(0x02000BDC+0x14C*(pc3-5)))/memory.read_u8(0x02000BDC+0x14C*(pc3-5))*10000
pcntag3= math.floor(pcntag3)/100
gui.scaledtext(0,110,"PC" .. pc3 .. " Bonus: " .. pcntag3 .. "%")
end
if memory.read_u8(0x0200045B)==0 and memory.read_u8(0x0200045C)==0 then
else
local l=1
while memory.read_u8(0x02030328+0x10*l) ~= pc4 and l<15 do
l=l+1
end
if l~=15 then
pcntag4=(memory.read_u8(0x02030328+0x10*l+0x04)-memory.read_u8(0x02000BDC+0x14C*(pc4-5)))/memory.read_u8(0x02000BDC+0x14C*(pc4-5))*10000
pcntag4= math.floor(pcntag4)/100
gui.scaledtext(0,120,"PC" .. pc4 .. " Bonus: " .. pcntag4 .. "% Roll " .. memory.read_u8(0x02030328+0x10*l+0x04))
end
end
end
-- HP/encounter display
-- Colorrate stuff
-- Encounter Rate Functions
if CurrentRate ~= NormalisedRate(AD6) then
if memory.read_u32_le(AD6) == 0 then
CurrentRate = 0
end
if EncounterRate ~= memory.read_u32_le(0x02000478) and memory.read_u32_le(0x02000478) < 0x100000 then
if store ~= memory.read_u32_le(AD5) then
EncounterRate = memory.read_u32_le(0x02000478)+1
end
ColorRate1 = memory.read_u32_le(0x02000478)-EncounterRate
ColorRateShade = 0
ColorRate2 = 0xFFFFFFFF
if ColorRate1 < 0 then
EncounterRate = memory.read_u32_le(0x02000478)
ColorRate2 = 0xFFFFFFFF
CurrentRate = 0
else
if memory.read_u16_le(0x02000400) ~= 2 then -- world map?
GoodRateThreshold2 = GoodRateThreshold*1.3
if memory.read_u16_le(0x020301B4)==0xCC then -- Is Felix Walking?
GoodRateThreshold2 = GoodRateThreshold2 / 2
end
else
GoodRateThreshold2 = GoodRateThreshold
if memory.read_u16_le(0x020301B4)==0x66 then -- Is Felix Walking?
GoodRateThreshold2 = GoodRateThreshold2 / 2
end
end
if ColorRate1 >= GoodRateThreshold2 then
ColorRate2= 0xFFFF0000
EncounterRate = memory.read_u32_le(0x02000478)
CurrentRate = NormalisedRate(AD6)
if NormalisedRate(AD6) == "" then
ColorRate2= 0xFFFFFFFF
end
else
ColorRateShade = math.floor((GoodRateThreshold2-ColorRate1)/GoodRateThreshold2*255)
if ColorRateShade <= 63 then
ColorRate2 = 0xFFFF0000 + 1024*ColorRateShade
elseif ColorRateShade <=191 then
ColorRate2 = 0xFF00FF00 + 256*256*(255-255*(ColorRateShade-63)/128-1)
else
ColorRate2 = 0xFF00FF00
end
EncounterRate = memory.read_u32_le(0x02000478)
CurrentRate = NormalisedRate(AD6)
end
end
end
end
if memory.read_u8(0x020309a0) >= 1 then
--
else
gui.scaledtext(0,20,"Encounter: ".. (memory.read_u16_le(AD3)))
gui.scaledtext(0,30,"Isaac PP: ".. (memory.read_u8(0x0200053A)))
gui.scaledtext(180,20,"Rate: ".. NormalisedRate(AD6), ColorRate2)
gui.scaledtext(0,40,"PP Regen: ".. (math.floor((memory.read_u8(0x020301B5))/0xF)))
if memory.read_u16_le(0x02000486) > 0 then
gui.scaledtext(0,50,"Avoid Counter: " .. (memory.read_u16_le(0x02000486)))
end
end
-- Encounter Value Increasing if loop
encounterValue = memory.read_u32_le(0x02000478)
if encounterValue == 0 and encounterPreviousvalue ~= 0 then
encounterPreviousvalue = 0
encounterColor = 0xFFFFFFFF
elseif encounterValue ~= encounterPreviousvalue then
encounterColor = 0xFF00FF00
encounterPreviousvalue = memory.read_u32_le(0x02000478)
else
encounterColor = 0xFFFFFFFF
encounterPreviousvalue = memory.read_u32_le(0x02000478)
end
-- begin RNG counters
GRN = memory.read_u32_le(AD5)
BRN = memory.read_u32_le(AD4)
if GRN == 1710661176 then
store = 1710661176
gcount=0
end
gcountbase = 0
while store ~= GRN and gcountbase <= 10000 do
--print(store)
store = RNA(store)
if store <= 0 then
store = 0xFFFFFFFF+store+1
gcount = gcount +1
gcountbase = gcountbase +1
else
gcount = gcount +1
gcountbase = gcountbase +1
end
end
if store == GRN then
gcountbase = 0
else
store = GRN
gcountbase = 0
gcount = 0
end
bcountbase = 0
while bstore ~= BRN and bcountbase <= 1000 do
bstore = RNA(bstore)
if bstore <= 0 then
bstore = 0xFFFFFFFF+bstore+1
brncount = brncount+1
bcountbase = bcountbase+1
else
brncount = brncount+1
bcountbase = bcountbase+1
end
end
if bstore == BRN then
bcountbase = 0
else
bstore = BRN
bcountbase = 0
brncount = 0
end
if BRN == 0 then -- reset BRN counter on loadstate
bstore = BRN
bcount = 0
end
-- Gui display
gui.scaledtext(0,10,"GRN count: " .. gcount)
gui.scaledtext(0,0,"BRN count: " .. brncount)
-- AF/CBS scripts
if minorhudlock == false then
afb=00
cbsb=00
if afbrn ~= BRN then
afb = BRN
afb = RNA(afb)
afc1 = 0
while AF(afb) ~= 1 do
afb = RNA(afb)
afc1 = afc1 + 1
end
afc2 = afc1+1
afb = RNA(afb)
while AF(afb) ~=1 do
afb = RNA(afb)
afc2 = afc2 + 1
end
afc3 = afc2+1
afb = RNA(afb)
while AF(afb) ~= 1 do
afb = RNA(afb)
afc3 = afc3 + 1
end
afbrn=BRN
end
if cbsbrn ~= BRN then
cbsb = BRN
cbsb = RNA(cbsb)
cbsc1 = 0
while AF(cbsb) ~= 2 do
cbsb = RNA(cbsb)
cbsc1 = cbsc1 + 1
if cbsc1 == 100 then break end
end
cbsc2 = cbsc1+1
cbsb = RNA(cbsb)
while AF(cbsb) ~= 2 do
cbsb = RNA(cbsb)
cbsc2 = cbsc2 + 1
if cbsc2 == 102 then break end
end
cbsc3 = cbsc2+1
cbsb = RNA(cbsb)
while AF(cbsb) ~= 2 do
cbsb = RNA(cbsb)
cbsc3 = cbsc3 + 1
if cbsc3 == 104 then break end
end
cbsbrn = BRN
end
gui.scaledtext(70,0,"AF " .. afc1 .. " " .. afc2 .. " " .. afc3)
gui.scaledtext(70,10,"CBS " .. cbsc1 .. " " .. cbsc2 .. " " .. cbsc3)
end
--necessary information for the following scripts
--eel = memory.read_u8(0x0203089E) venus resistance
--eme = memory.read_u8(0x020308A2) merc res
--ema = memory.read_u8(0x020308A6) mars res
--eju = memory.read_u8(0x020308A8) jup res
-- Vulnerability Key
--12 = Drop Def 25%
--13 = Drop def 12%
--16 = res drop 40
--17 = res drop 20
--20 = delusion
--23 = stun
--24 = sleep
--27 = death
--31 = HP steal
--32 = PP steal
--60 = 50% dmg to health
--69 = 10% dmg to PP
-- Begin Flee/Assassinate Scripts
local el1 = memory.read_u8(0x02030887) -- Enemy 1 Level
local el2 = memory.read_u8(0x020309D3) -- etc
local el3 = memory.read_u8(0x02030B1F)
local el4 = memory.read_u8(0x02030C6B)
local Party = memory.read_u8(0x02000040) -- Party member number
local isl= memory.read_u8(0x0200050F) -- Isaac level
local gal= memory.read_u8(0x0200065B) -- etc
local ivl= memory.read_u8(0x020007A7)
local mil= memory.read_u8(0x020008F3)
if (memory.read_u8(0x020309a0)) >= 1 then
function is_alive(F)
return memory.read_u16_le(0x02000538 + 0x14C * F) > 0
end
function get_level(F)
return memory.read_u8(0x0200050F + 0x14C * F)
end
function is_member(F)
local party_flags = memory.read_u8(0x02000040)
return (party_flags & 2^F) > 0
end
function filter(array, callback)
local out = {}
for k,v in pairs(array) do
if callback(v) then table.insert(out, v) end
end
return out
end
function map(array, callback)
local out = {}
for k,v in pairs(array) do
out[k] = callback(v)
end
return out
end
function sum(array)
local out = 0
for i,v in ipairs(array) do
out = out + v
end
return out
end
party = filter({0, 1, 2, 3, 4, 5, 6, 7}, is_member) -- what is our current party
live_party = filter(party, is_alive) -- check living members
levels = map(live_party, get_level) -- check living member levels
if el4 ~= 0 then -- enemy level averages
ela = (el1+el2+el3+el4)/4
elseif el3 ~=0 then
ela = (el1+el2+el3)/3
elseif el2 ~=0 then
ela = (el1+el2)/2
else
ela = el1
end
LevelAve = sum(levels)/#levels - ela
fleeFail = memory.read_u8(0x02030092)
function flee(S) -- Flee Success Calculation
g = S
g = RNB(g)*10000
fl = 5000 + (2000*fleeFail) + (LevelAve * 500)
g = (g >> 16)
if fl > g then
return true
else
return false
end
end
RN= memory.read_u32_le(0x03001CB4)
count = 0
while flee(RN) == false do -- Attack Cancel to Flee Calculation
count = count + 1
if count == 100 then break end
RN= RNA(RN)
end
gui.scaledtext(170,30,"ACs to Run: " .. count)
-- % Chance to Run
if nosq == true then
fleecount = 0
if fleestore ~= memory.read_u32_le(AD5) then
fleeRN = memory.read_u32_le(AD5)
for i=1,1000 do
if flee(fleeRN) == true then
fleecount= fleecount +1
end
fleeRN=RNA(fleeRN)
end
fleepercent = fleecount/10
fleestore = memory.read_u32_le(AD5)
fev = fleepercent/100
EV = (fev*1+ math.floor(fev+.20,1)*(1-fev)*2+ math.floor(fev+.40,1)*(1-math.floor(fev+.20,1))*(1-fev)*3+ math.floor(fev+.60,1)*(1-math.floor(fev+.40,1))*(1-math.floor(fev+.20,1))*(1-fev)*4+ math.floor(fev+.80,1)*(1-math.floor(fev+.60,1))*(1-math.floor(fev+.40,1))*(1-math.floor(fev+.20,1))*(1-fev)*5+ (1-math.floor(fev+.80,1))*(1-math.floor(fev+.60,1))*(1-math.floor(fev+.40,1))*(1-math.floor(fev+.20,1))*(1-fev)*6)
gui.scaledtext(100,30,"Run EV: ".. EV)
gui.scaledtext(160,30,"Run%: " .. fleepercent)
else
gui.scaledtext(100,30,"Run EV: ".. EV )
gui.scaledtext(160,30,"Run%: " .. fleepercent)
end
end
function vuln (S)
e1Ind = S
vuln1 = memory.read_u8((0x08080EC8 - 0xA000*JPN) + ((e1Ind - 8) * 0x54) + 0x48) -- 0x08080EC8 = U ; 0x08076EC8 = J
vuln2 = memory.read_u8((0x08080EC8 - 0xA000*JPN) + ((e1Ind - 8) * 0x54) + 0x49)
vuln3 = memory.read_u8((0x08080EC8 - 0xA000*JPN) + ((e1Ind - 8) * 0x54) + 0x4A)
return vuln1, vuln2, vuln3
end
function enemy (S,Elm) -- Enemy Elemental Data Table
elemInd = memory.read_u8((0x08080EC8 - 0xA000*JPN) + ((S - 8) * 0x54) + 0x34)
enemyelmlevel = memory.read_u8((0x08088E38 - 0xA000*JPN) + (elemInd * 0x18) + 4+Elm)
return enemyelmlevel
end
function bchance (E) -- base chance for status
if E == 16 or E == 17 then
c = 75
elseif E == 23 then
c = 40
elseif E == 24 then
c = 45
elseif E == 27 then
c = 20
end
return c
end
function get_edata(enemyslot) -- Find enemy elemental stats
local addr = 0x02030878 + 0x14C*enemyslot + 0x48
local epow, eres = {}, {}
for i=0,3 do
epow[i] = memory.read_u16_le(addr+4*i)
eres[i] = memory.read_u16_le(addr+4*i+2)
end
return epow, eres
end
function effectproc (S,E,Elm,U) -- Random number, What effect is this, Elemental Affinity 0 = Venus, 1 = Mercury, 2= Mars, 3 = Jupiter,
-- Who is using this 0 = Isaac, 1 = Garet, 2 = Ivan, 3 = Mia
uelm = memory.read_u8(0x0200061C+U*0x14C+Elm) -- Elemental Power of User
eluc = memory.read_u8(0x020308BA) -- Enemy Luck
eind = memory.read_u8(0x020309a0) -- Enemy Index
eelm = enemy(eind,Elm) -- Enemy Elemental Levels
vul1, vul2, vul3 = vuln(eind) -- Enemy Vulnerability
if vul1 == E or vul2 == E or vul3 == E then -- Vulnerability key at top
v=25
else
v=00
end
if memory.read_u8((0x080844EC - 0xA000*JPN) + (U * 0xB4) + 0x92 + Elm) == 54 then
elmaff = 5
else
elmaff = 0
end
proc = (((uelm + elmaff - eelm)-(math.floor(eluc/2)))*3+bchance(E)+v)
g = RNB(S)*100
g = (g >> 16)
if proc >= g then
return true
else
return false
end
end
function unleash (S)