From f965f48518a66b56540a49ef9f2b36d7fd5e8ffc Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Mon, 15 Feb 2021 00:24:43 -0600 Subject: [PATCH 01/28] Daemon triggers in Abyss should now work --- u4_decompile/SRC/U4_COMBB.C | 43 ++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/u4_decompile/SRC/U4_COMBB.C b/u4_decompile/SRC/U4_COMBB.C index 77f7b80..e949719 100644 --- a/u4_decompile/SRC/U4_COMBB.C +++ b/u4_decompile/SRC/U4_COMBB.C @@ -137,7 +137,7 @@ unsigned char bp06; unsigned char bp04; { register int /*si*/loc_A; - int loc_B, loc_C/*bp_04, bp_06*/; + int loc_B, loc_C, loc_D, loc_E/*bp_04, bp_06*/; for(loc_A = 3; loc_A >= 0; loc_A --) { if(D_95B2[(loc_A << 2)]) { @@ -149,12 +149,49 @@ unsigned char bp04; if( loc_B | (loc_C = (*(unsigned *)(D_95B2+(loc_A << 2)+2) >> 4) & 0xf) - ) Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)]; + ) + { + if( D_95B2[(loc_A << 2)] < TIL_80 ) { + Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)]; + } + else { + for(loc_D = 15; loc_D >= 0 && Fighters._tile[loc_D]; loc_D--) { + } + if(loc_D != -1) { + Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[(loc_A << 2)]; + loc_E = D_23D2[C_7C25(D_95B2[(loc_A << 2)])]; + Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E); + + Combat._npcX[loc_D] = loc_C; + Combat._npcY[loc_D] = loc_B; + } + } + + } + loc_B = (*(unsigned *)(D_95B2+(loc_A << 2)+2) >> 8) & 0xf; if( loc_B | (loc_C = (*(unsigned *)(D_95B2+(loc_A << 2)+2) >> 12) & 0xf) - ) Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)] & 0xff; + ) + { + if( D_95B2[(loc_A << 2)] < TIL_80 ) { + Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)]; + } + else { + for(loc_D = 15; loc_D >= 0 && Fighters._tile[loc_D]; loc_D--) { + } + if(loc_D != -1) { + Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[(loc_A << 2)]; + loc_E = D_23D2[C_7C25(D_95B2[(loc_A << 2)])]; + Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E); + + Combat._npcX[loc_D] = loc_C; + Combat._npcY[loc_D] = loc_B; + } + } + + } } } }/* while(--loc_A >= 0);*/ From fe12cd5d5deda2bf129ca2e5987ff6a3ddf1a478 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Mon, 15 Feb 2021 16:02:56 -0600 Subject: [PATCH 02/28] Save 143 bytes over the original --- u4_decompile/SRC/U4_COMBB.C | 83 +++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/u4_decompile/SRC/U4_COMBB.C b/u4_decompile/SRC/U4_COMBB.C index e949719..ca6d12f 100644 --- a/u4_decompile/SRC/U4_COMBB.C +++ b/u4_decompile/SRC/U4_COMBB.C @@ -137,60 +137,51 @@ unsigned char bp06; unsigned char bp04; { register int /*si*/loc_A; - int loc_B, loc_C, loc_D, loc_E/*bp_04, bp_06*/; - - for(loc_A = 3; loc_A >= 0; loc_A --) { - if(D_95B2[(loc_A << 2)]) { + int loc_B, loc_C, loc_D, loc_E, loc_AShift/*bp_04, bp_06*/; + + for(loc_A = 12; loc_A >= 0; loc_A=loc_A-4) { + if(D_95B2[loc_A]) { + + /*itoa(loc_A, Party.chara[7]._name, 16); + u4_puts(Party.chara[7]._name); + u4_puts("\n"); + itoa(loc_A << 2, Party.chara[7]._name, 16); + u4_puts(Party.chara[7]._name); + u4_puts("\n");*/ + if( - (bp06 << 12) == (*(unsigned *)(D_95B2+(loc_A << 2)) & 0xf000) && - (bp04 << 8) == (*(unsigned *)(D_95B2+(loc_A << 2)) & 0x0f00) + (bp06 << 12) == (*(unsigned *)(D_95B2+loc_A) & 0xf000) && + (bp04 << 8) == (*(unsigned *)(D_95B2+loc_A) & 0x0f00) ) { - loc_B = *(unsigned *)(D_95B2+(loc_A << 2)+2) & 0xf; - if( - loc_B | - (loc_C = (*(unsigned *)(D_95B2+(loc_A << 2)+2) >> 4) & 0xf) - ) - { - if( D_95B2[(loc_A << 2)] < TIL_80 ) { - Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)]; - } - else { - for(loc_D = 15; loc_D >= 0 && Fighters._tile[loc_D]; loc_D--) { + loc_AShift = 0; + while(loc_AShift <= 8) { + + loc_B = (*(unsigned *)(D_95B2+loc_A+2) >> loc_AShift) & 0xf; + if( + loc_B | + (loc_C = (*(unsigned *)(D_95B2+loc_A+2) >> (loc_AShift+4)) & 0xf) + ) + { + if( D_95B2[loc_A] < TIL_80 ) { + Combat_MAP(loc_B, loc_C) = D_95B2[loc_A]; } - if(loc_D != -1) { - Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[(loc_A << 2)]; - loc_E = D_23D2[C_7C25(D_95B2[(loc_A << 2)])]; - Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E); - - Combat._npcX[loc_D] = loc_C; + else { + loc_D = 15; + while(loc_D >= 0 && Fighters._tile[loc_D]) { + loc_D--; + } + if(loc_D != -1) { + Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[loc_A]; + loc_E = D_23D2[C_7C25(D_95B2[loc_A])]; + Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E); + + Combat._npcX[loc_D] = loc_C; Combat._npcY[loc_D] = loc_B; } - } - - } - - loc_B = (*(unsigned *)(D_95B2+(loc_A << 2)+2) >> 8) & 0xf; - if( - loc_B | - (loc_C = (*(unsigned *)(D_95B2+(loc_A << 2)+2) >> 12) & 0xf) - ) - { - if( D_95B2[(loc_A << 2)] < TIL_80 ) { - Combat_MAP(loc_B, loc_C) = D_95B2[(loc_A << 2)]; - } - else { - for(loc_D = 15; loc_D >= 0 && Fighters._tile[loc_D]; loc_D--) { } - if(loc_D != -1) { - Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[(loc_A << 2)]; - loc_E = D_23D2[C_7C25(D_95B2[(loc_A << 2)])]; - Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E); - Combat._npcX[loc_D] = loc_C; - Combat._npcY[loc_D] = loc_B; - } } - + loc_AShift=loc_AShift+8; } } } From 5c12d513d62c787750211ea1a6d79c53529427f7 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Mon, 15 Feb 2021 21:43:41 -0600 Subject: [PATCH 03/28] Move a few lines into a function Netted a few more bytes freed up but not below where we started yet --- u4_decompile/SRC/U4.H | 1 + u4_decompile/SRC/U4_COMBB.C | 17 ++++++----------- u4_decompile/SRC/U4_COMBC.C | 22 ++++++++++++++++------ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/u4_decompile/SRC/U4.H b/u4_decompile/SRC/U4.H index 3423a0a..5c2bb40 100644 --- a/u4_decompile/SRC/U4.H +++ b/u4_decompile/SRC/U4.H @@ -305,6 +305,7 @@ extern C_7D50(); extern C_7D92(); extern C_7DBC(); extern C_7DFE(int); +extern PrepFighters(int,unsigned); extern C_7FD7(); extern C_7FFD(); extern C_837A(); diff --git a/u4_decompile/SRC/U4_COMBB.C b/u4_decompile/SRC/U4_COMBB.C index ca6d12f..6fc917b 100644 --- a/u4_decompile/SRC/U4_COMBB.C +++ b/u4_decompile/SRC/U4_COMBB.C @@ -142,13 +142,6 @@ unsigned char bp04; for(loc_A = 12; loc_A >= 0; loc_A=loc_A-4) { if(D_95B2[loc_A]) { - /*itoa(loc_A, Party.chara[7]._name, 16); - u4_puts(Party.chara[7]._name); - u4_puts("\n"); - itoa(loc_A << 2, Party.chara[7]._name, 16); - u4_puts(Party.chara[7]._name); - u4_puts("\n");*/ - if( (bp06 << 12) == (*(unsigned *)(D_95B2+loc_A) & 0xf000) && (bp04 << 8) == (*(unsigned *)(D_95B2+loc_A) & 0x0f00) @@ -171,13 +164,15 @@ unsigned char bp04; loc_D--; } if(loc_D != -1) { - Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[loc_A]; + + PrepFighters(loc_D,D_95B2[loc_A]); + /*Fighters._tile[loc_D] = Fighters._gtile[loc_D] = D_95B2[loc_A]; loc_E = D_23D2[C_7C25(D_95B2[loc_A])]; - Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E); + Fighters._HP[loc_D] = (loc_E >> 1) | U4_RND4(loc_E);*/ Combat._npcX[loc_D] = loc_C; - Combat._npcY[loc_D] = loc_B; - } + Combat._npcY[loc_D] = loc_B; + } } } diff --git a/u4_decompile/SRC/U4_COMBC.C b/u4_decompile/SRC/U4_COMBC.C index 3c612b9..ee639e7 100644 --- a/u4_decompile/SRC/U4_COMBC.C +++ b/u4_decompile/SRC/U4_COMBC.C @@ -194,7 +194,7 @@ register unsigned si; C_7E7E() { register int loc_A, loc_D; - int loc_B, loc_C; + int loc_B; unsigned loc_E; for(loc_D = 15; loc_D >= 0; loc_D --) @@ -221,9 +221,7 @@ C_7E7E() loc_E = D_2406[C_7C25(D_9452)]; } } - Fighters._tile[loc_D] = Fighters._gtile[loc_D] = loc_E; - loc_C = D_23D2[C_7C25(loc_E)]; - Fighters._HP[loc_D] = (loc_C >> 1) | U4_RND4(loc_C); + PrepFighters(loc_D,loc_E); } for(loc_D = Party.f_1d8 - 1; loc_D >= 0; loc_D --) { if(!isCharaAlive(loc_D)) @@ -233,6 +231,17 @@ C_7E7E() } } +PrepFighters(loc_A, loc_D) +register int loc_A; +unsigned loc_D; +{ + int loc_B; + + Fighters._tile[loc_A] = Fighters._gtile[loc_A] = loc_D; + loc_B = D_23D2[C_7C25(loc_D)]; + Fighters._HP[loc_A] = (loc_B >> 1) | U4_RND4(loc_B); +} + C_7FD7() { if(CurMode != MOD_COM_CAMP) { @@ -324,9 +333,10 @@ C_7FFD() /*shouldn't be "if(loc_A._010[loc_B]) {" ?*/ Combat._npcX[loc_B] = loc_A._020[loc_B]; Combat._npcY[loc_B] = loc_A._030[loc_B]; - Fighters._tile[loc_B] = Fighters._gtile[loc_B] = loc_A._010[loc_B]; + PrepFighters(loc_B, loc_A._010[loc_B]); + /*Fighters._tile[loc_B] = Fighters._gtile[loc_B] = loc_A._010[loc_B]; loc_C = D_23D2[C_7C25(loc_A._010[loc_B])]; - Fighters._HP[loc_B] = (loc_C >> 1) | U4_RND4(loc_C); + Fighters._HP[loc_B] = (loc_C >> 1) | U4_RND4(loc_C);*/ if(Fighters._tile[loc_B] == (char)TIL_AC) Fighters._gtile[loc_B] = TIL_3C; } From 51320f736fabb5cc00a98ffb295c5ccdbf8571f7 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Fri, 7 May 2021 00:56:10 -0500 Subject: [PATCH 04/28] Town saving and loading Needs to have a pre-existing TOWNMAP.SAV file or it crashes when saving. BUG: If it saves when a door is open then the door is gone on load (going to work on fix but need sleep) --- u4_decompile/SRC/U4_MAIN.C | 5 +++++ u4_decompile/SRC/U4_Q_N_V.C | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/u4_decompile/SRC/U4_MAIN.C b/u4_decompile/SRC/U4_MAIN.C index e9e1f47..3c87340 100644 --- a/u4_decompile/SRC/U4_MAIN.C +++ b/u4_decompile/SRC/U4_MAIN.C @@ -24,6 +24,11 @@ void cdecl /*C_191E*/main() File_DNG = dopen(D_0894[Party._loc - 0x11], 0); if(setjmp(D_9458) == 0) DNG_main(); + } else if (Party._loc != 0 && Party._loc < 0x11) { + CurMode = MOD_BUILDING; + C_3E30(Party._loc); + if(Load("TOWNMAP.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); } else { Party._loc = 0; } diff --git a/u4_decompile/SRC/U4_Q_N_V.C b/u4_decompile/SRC/U4_Q_N_V.C index e209626..cda65c6 100644 --- a/u4_decompile/SRC/U4_Q_N_V.C +++ b/u4_decompile/SRC/U4_Q_N_V.C @@ -15,7 +15,7 @@ u4_putl(Party._moves, 1, '0'); u4_puts(/*D_21B2*/" moves\n"); if(Party._loc) { - if(Party._loc < 0x11 || Party._loc > 0x18) { + if(Party._loc > 0x18) { u4_puts(/*D_21BA*/"Not Here!\n"); return; } @@ -26,7 +26,13 @@ if(Save(/*D_21CF*/"MONSTERS.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) exit(3); } - if(Party._loc < 0x11 || Party._loc > 0x18) + if (Party._loc != 0 && Party._loc < 0x11) + { + if(Save("TOWNMAP.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + return; + } + if(Party._loc == 0 || Party._loc > 0x18) return; if(Save(/*D_21DC*/"MONSTERS.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) exit(3); From 7ffcd5a0846b1e0a94c1e7b5a137a0103bd949ac Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Fri, 7 May 2021 09:12:51 -0500 Subject: [PATCH 05/28] Force doors to close before saving --- u4_decompile/SRC/U4_Q_N_V.C | 2 ++ 1 file changed, 2 insertions(+) diff --git a/u4_decompile/SRC/U4_Q_N_V.C b/u4_decompile/SRC/U4_Q_N_V.C index cda65c6..ca9d729 100644 --- a/u4_decompile/SRC/U4_Q_N_V.C +++ b/u4_decompile/SRC/U4_Q_N_V.C @@ -28,6 +28,8 @@ } if (Party._loc != 0 && Party._loc < 0x11) { + /*Force doors to close before saving*/ + C_431D(); C_431D(); C_431D(); C_431D(); C_431D(); if(Save("TOWNMAP.SAV", sizeof(struct t_500), &D_8742) == -1) exit(3); return; From a697f5cddd8b2d7c1cba984580c4656c3bf692e9 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Mon, 10 May 2021 00:02:32 -0500 Subject: [PATCH 06/28] Brute force but this will save the horse location when in LCB --- u4_decompile/SRC/U4_EXPLO.C | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/u4_decompile/SRC/U4_EXPLO.C b/u4_decompile/SRC/U4_EXPLO.C index 3277625..67ed480 100644 --- a/u4_decompile/SRC/U4_EXPLO.C +++ b/u4_decompile/SRC/U4_EXPLO.C @@ -36,6 +36,12 @@ unsigned bp04; { if(Save(/*D_172B*/"OUTMONST.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) exit(3); + if(bp04 == 1) { + if(Load("LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) + exit(3); + if(SAVE("LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + } if(Load(D_0824[bp04 - 0x01], sizeof(struct t_500), &D_8742) == -1) exit(3); File_TLK = dopen(D_1738[Party._loc - 1], 0); @@ -383,7 +389,9 @@ C_431D() return; } u4_puts(/*D_184B*/"to second floor!\n"); - if(Load(/*D_185D*/"LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) + if(Save(/*D_185D*/"LCB_1.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + if(Load(/*D_185D*/"LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) exit(3); } else { w_What(); @@ -432,6 +440,8 @@ C_431D() return; } u4_puts(/*D_18AA*/"to first floor!\n"); - if(Load(/*D_18BB*/"LCB_1.ULT", sizeof(struct t_500), &D_8742) == -1) + if(Save(/*D_185D*/"LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + if(Load(/*D_18BB*/"LCB_1.SAV", sizeof(struct t_500), &D_8742) == -1) exit(3); } From 7f7d7045745fa5b5308722833d5526e24a78f1e0 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Wed, 23 Jun 2021 23:27:54 -0500 Subject: [PATCH 07/28] Fix disappearing monsters Monsters when crossing the border of the map can disappear --- u4_decompile/SRC/U4_NPC.C | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/u4_decompile/SRC/U4_NPC.C b/u4_decompile/SRC/U4_NPC.C index b970a65..76b1b6f 100644 --- a/u4_decompile/SRC/U4_NPC.C +++ b/u4_decompile/SRC/U4_NPC.C @@ -345,10 +345,16 @@ int bp04; C_56D3(bp04) int bp04; { - return - (D_8742._npc._x[bp04] - D_95A5.x*16) >= 32 || - (D_8742._npc._y[bp04] - D_95A5.y*16) >= 32 - ; + return !Between(D_8742._npc._x[bp04], D_95A5.x*16, D_95A5.x*16+31) || + !Between(D_8742._npc._y[bp04], D_95A5.y*16, D_95A5.y*16+31); +} + +Between(point, lowerbound, upperbound) +unsigned char point; +unsigned char lowerbound; +unsigned char upperbound; +{ + return (lowerbound <= upperbound && point >= lowerbound && point <= upperbound) || (lowerbound > upperbound && (point >= lowerbound || point <= upperbound)); } /*move outside NPC*/ From 4d02465f5a0ddba624bd6ba470b1904809cc184c Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Sat, 26 Jun 2021 22:56:28 -0500 Subject: [PATCH 08/28] Fix pirate ships not cross map edge and wrong combat map being used --- u4_decompile/SRC/U4.H | 1 + u4_decompile/SRC/U4_COMBC.C | 2 +- u4_decompile/SRC/U4_NPC.C | 2 +- u4_decompile/SRC/U4_UTIL.C | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/u4_decompile/SRC/U4.H b/u4_decompile/SRC/U4.H index 3423a0a..cf32173 100644 --- a/u4_decompile/SRC/U4.H +++ b/u4_decompile/SRC/U4.H @@ -205,6 +205,7 @@ extern /*C_162F*/AskY_N(); extern long /*C_169C*/AskInt(int); /*u4_util2*/ extern void cdecl /*C_16CD*/u_delay(int, int); +extern unsigned char u4_wrap(int); extern unsigned char u_rand_a(); #define U4_RND1(a) (u_rand_a()&(a)) diff --git a/u4_decompile/SRC/U4_COMBC.C b/u4_decompile/SRC/U4_COMBC.C index 3c612b9..bc73b99 100644 --- a/u4_decompile/SRC/U4_COMBC.C +++ b/u4_decompile/SRC/U4_COMBC.C @@ -180,7 +180,7 @@ register unsigned si; D_9772 = D_8742._npc._x[si]; D_9140 = D_8742._npc._y[si]; if(Party._loc == 0x00) { - D_946C = D_8742._map.x32x32[(D_9140 - (D_95A5.y<<4))][(D_9772 - (D_95A5.x<<4))]; + D_946C = D_8742._map.x32x32[u4_wrap(D_9140 - (D_95A5.y*16))][u4_wrap(D_9772 - (D_95A5.x*16))]; } else { D_946C = D_8742._map.x32x32[D_9140][D_9772]; } diff --git a/u4_decompile/SRC/U4_NPC.C b/u4_decompile/SRC/U4_NPC.C index 76b1b6f..0a50dfa 100644 --- a/u4_decompile/SRC/U4_NPC.C +++ b/u4_decompile/SRC/U4_NPC.C @@ -202,7 +202,7 @@ register int si; unsigned char bp06; unsigned char bp04; { - if(C_4E94(si, bp06, bp04, D_8742._map.x32x32[bp04-D_95A5.y*16][bp06-D_95A5.x*16])) { + if(C_4E94(si, bp06, bp04, D_8742._map.x32x32[u4_wrap(bp04-D_95A5.y*16)][u4_wrap(bp06-D_95A5.x*16)])) { if(C_2A5A(D_8742._npc._gtile[si] & 3)) { D_8742._npc._old_x[si] = D_8742._npc._x[si]; D_8742._npc._x[si] = bp06; diff --git a/u4_decompile/SRC/U4_UTIL.C b/u4_decompile/SRC/U4_UTIL.C index 40b0e87..227f741 100644 --- a/u4_decompile/SRC/U4_UTIL.C +++ b/u4_decompile/SRC/U4_UTIL.C @@ -813,3 +813,9 @@ unsigned char upperbound; else return 0; } + +unsigned char u4_wrap(input) +int input; +{ + return (unsigned char)((input % 256 + 256) % 256); +} \ No newline at end of file From 141af4401b32e9e061c4ec8901cf09d1eb4cb9f0 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Sat, 26 Jun 2021 23:10:03 -0500 Subject: [PATCH 09/28] Swap out disappearing monster solution for the wrap code that solved other stuff --- u4_decompile/SRC/U4_NPC.C | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/u4_decompile/SRC/U4_NPC.C b/u4_decompile/SRC/U4_NPC.C index 0a50dfa..8a9457e 100644 --- a/u4_decompile/SRC/U4_NPC.C +++ b/u4_decompile/SRC/U4_NPC.C @@ -345,16 +345,10 @@ int bp04; C_56D3(bp04) int bp04; { - return !Between(D_8742._npc._x[bp04], D_95A5.x*16, D_95A5.x*16+31) || - !Between(D_8742._npc._y[bp04], D_95A5.y*16, D_95A5.y*16+31); -} - -Between(point, lowerbound, upperbound) -unsigned char point; -unsigned char lowerbound; -unsigned char upperbound; -{ - return (lowerbound <= upperbound && point >= lowerbound && point <= upperbound) || (lowerbound > upperbound && (point >= lowerbound || point <= upperbound)); + return + u4_wrap(D_8742._npc._x[bp04] - D_95A5.x*16) >= 32 || + u4_wrap(D_8742._npc._y[bp04] - D_95A5.y*16) >= 32 + ; } /*move outside NPC*/ From 255b56d688a56286c1ac52e9c81df75fe38bb707 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Thu, 1 Jul 2021 00:44:30 -0500 Subject: [PATCH 10/28] Hopefully ready for integration --- U4DosRandomizer/Avatar.cs | 12 ++++++++++++ U4DosRandomizer/AvatarOffsetsNew.cs | 8 +++++++- U4DosRandomizer/AvatarOffsetsOriginal.cs | 5 +++++ U4DosRandomizer/Flags.cs | 3 +++ U4DosRandomizer/IAvatarOffset.cs | 4 ++++ U4DosRandomizer/Program.cs | 17 +++++++++++++++++ U4DosRandomizer/UltimaData.cs | 3 +++ u4_decompile/SRC/U4_USE.C | 4 +++- 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/U4DosRandomizer/Avatar.cs b/U4DosRandomizer/Avatar.cs index 08bd1c8..427c59b 100644 --- a/U4DosRandomizer/Avatar.cs +++ b/U4DosRandomizer/Avatar.cs @@ -172,6 +172,10 @@ public void Load(string path, UltimaData data, IWorldMap worldMap) textOffset++; } + data.PrincipleItemRequirements.Add(avatarBytes[AvatarOffset.BELL_REQUIREMENT_OFFSET]); + data.PrincipleItemRequirements.Add(avatarBytes[AvatarOffset.BOOK_REQUIREMENT_OFFSET]); + data.PrincipleItemRequirements.Add(avatarBytes[AvatarOffset.CANDLE_REQUIREMENT_OFFSET]); + var wordOfPassageTextBytes = new List(); for (int offSet = 0; offSet < 9; offSet++) @@ -361,6 +365,14 @@ public void Update(UltimaData data, Flags flags) } } + if (data.PrincipleItemRequirements[0] != 13) + { + avatarBytes[AvatarOffset.BELL_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[0]; + avatarBytes[AvatarOffset.BOOK_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[1]; + avatarBytes[AvatarOffset.CANDLE_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[2]; + avatarBytes[AvatarOffset.ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET] = (byte)0x0; + } + var wordOfPassageBytes = Encoding.ASCII.GetBytes(data.WordOfPassage.ToLower()); for (int j = 0; j < wordOfPassageBytes.Length; j++) { diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index 072637a..e3d999f 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -22,7 +22,8 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) PropertyInfo[] properties = this.GetType().GetInterface("IAvatarOffset").GetProperties(); foreach (PropertyInfo pi in properties) { - if(pi.Name.ToLower().Contains("offset") && !pi.Name.ToLower().Contains("blink") && !pi.Name.ToLower().Contains("enable") && !pi.Name.ToLower().Contains("encoded") && !pi.Name.ToLower().Contains("seed") && !pi.Name.ToLower().Contains("pointer")) + if(pi.Name.ToLower().Contains("offset") && !pi.Name.ToLower().Contains("blink") && !pi.Name.ToLower().Contains("enable") && !pi.Name.ToLower().Contains("encoded") && !pi.Name.ToLower().Contains("seed") && !pi.Name.ToLower().Contains("pointer") + && !pi.Name.ToLower().Contains("bell") && !pi.Name.ToLower().Contains("book") && !pi.Name.ToLower().Contains("candle")) { var newValue = avatarBytes[(int)pi.GetValue(this, null)]; var oldValue = originalAvatarBytes[(int)pi.GetValue(originalOffsets, null)]; @@ -58,6 +59,9 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) } } + public int BELL_REQUIREMENT_OFFSET { get; } = 0x4E0; // ??? + public int BOOK_REQUIREMENT_OFFSET { get; } = 0x52A; // ??? + public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x56F; // ??? public int MOONGATE_X_OFFSET { get; } = 0x0fd5e; //0fad1 public int MOONGATE_Y_OFFSET { get; } = 0x0fd66; //fad9 public int AREA_X_OFFSET { get; } = 0x0fd8e; //fb01 // towns, cities, castles, dungeons, shrines @@ -180,6 +184,8 @@ 0x2 1 Y Coordinate of Item public int ENABLE_SACRIFICE_FIX_OFFSET { get; } = 0xA7FB; // New + public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } = 0x4E9; // New + public int ENCODED_FLAGS_OFFSET { get; } = 0xFBA7; // New public int SEED_OFFSET { get; } = 0xFB87; // New diff --git a/U4DosRandomizer/AvatarOffsetsOriginal.cs b/U4DosRandomizer/AvatarOffsetsOriginal.cs index be6310c..0dcdfdf 100644 --- a/U4DosRandomizer/AvatarOffsetsOriginal.cs +++ b/U4DosRandomizer/AvatarOffsetsOriginal.cs @@ -6,6 +6,9 @@ namespace U4DosRandomizer { public class AvatarOffsetsOriginal : IAvatarOffset { + public int BELL_REQUIREMENT_OFFSET { get; } = 0x000; + public int BOOK_REQUIREMENT_OFFSET { get; } = 0x000; + public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x000; // https://wiki.ultimacodex.com/wiki/Ultima_IV_Internal_Formats#AVATAR.EXE // Above doesn't work anymore cuz we have modified AVATAR.EXE public int MOONGATE_X_OFFSET { get; } = 0x0fad1; @@ -134,6 +137,8 @@ 0x2 1 Y Coordinate of Item public int ENABLE_SACRIFICE_FIX_OFFSET => throw new NotImplementedException(); + public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET => throw new NotImplementedException(); + public int ENCODED_FLAGS_OFFSET => throw new NotImplementedException(); public int SEED_OFFSET => throw new NotImplementedException(); diff --git a/U4DosRandomizer/Flags.cs b/U4DosRandomizer/Flags.cs index a4c0742..07ed60a 100644 --- a/U4DosRandomizer/Flags.cs +++ b/U4DosRandomizer/Flags.cs @@ -38,6 +38,7 @@ public Flags(int seed, int version) public bool RandomizeSpells { get; internal set; } public bool Sextant { get; internal set; } public bool ClothMap { get; internal set; } + public bool PrincipleItems { get; internal set; } public List SupportedVersions = new List() { 9 }; @@ -74,6 +75,7 @@ public string GetEncoded() mask = 0; mask = SET_MSK(mask, ClothMap, 0); mask = SET_MSK(mask, StartingWeapons, 1); + mask = SET_MSK(mask, PrincipleItems, 2); encoded.Add((byte)mask); encoded.Add((byte)Overworld); @@ -130,6 +132,7 @@ public void DecodeAndSet(string encodedString) mask = encoded[7]; ClothMap = TST_MSK(mask, 0); StartingWeapons = TST_MSK(mask, 1); + PrincipleItems = TST_MSK(mask, 2); Overworld = encoded[8]; QuestItemPercentage = encoded[9]; diff --git a/U4DosRandomizer/IAvatarOffset.cs b/U4DosRandomizer/IAvatarOffset.cs index 872bf15..8f64d07 100644 --- a/U4DosRandomizer/IAvatarOffset.cs +++ b/U4DosRandomizer/IAvatarOffset.cs @@ -2,6 +2,9 @@ namespace U4DosRandomizer { public interface IAvatarOffset { + int BELL_REQUIREMENT_OFFSET { get; } + int BOOK_REQUIREMENT_OFFSET { get; } + int CANDLE_REQUIREMENT_OFFSET { get; } int MOONGATE_X_OFFSET { get; } int MOONGATE_Y_OFFSET { get; } int AREA_X_OFFSET { get; } @@ -72,6 +75,7 @@ public interface IAvatarOffset int ENABLE_HIT_CHANCE_OFFSET { get; } int ENABLE_DIAGONAL_ATTACK_OFFSET { get; } int ENABLE_SACRIFICE_FIX_OFFSET { get; } + int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET { get; } int BLINK_DESTINATION2_EXCLUSION_X2_OFFSET { get; } int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } diff --git a/U4DosRandomizer/Program.cs b/U4DosRandomizer/Program.cs index 5211ddb..49b00b0 100644 --- a/U4DosRandomizer/Program.cs +++ b/U4DosRandomizer/Program.cs @@ -137,6 +137,10 @@ static void Main(string[] args) "--clothMap", "Cloth map of the world.", CommandOptionType.NoValue); + CommandOption principleItemsArg = commandLineApplication.Option( + "--principleItems", + "Randomize the order of the Principle Items.", + CommandOptionType.NoValue); CommandOption spoilerLogArg = commandLineApplication.Option( "--spoilerLog", @@ -274,6 +278,7 @@ static void Main(string[] args) flags.RandomizeSpells = randomizeSpellsArg.HasValue(); flags.Sextant = sextantArg.HasValue(); flags.ClothMap = clothMapArg.HasValue(); + flags.PrincipleItems = principleItemsArg.HasValue(); Randomize(seed, path, flags, encodedArg.Value()); //Console.WriteLine("Seed: " + seed); //var random = new Random(seed); @@ -450,6 +455,18 @@ private static void Randomize(int seed, string path, Flags flags, string encoded } } + if(flags.PrincipleItems) + { + var values = new List> { new Tuple(0, 0x10), new Tuple(1,0x08), new Tuple(2, 0x04) }; + values.Shuffle(random); + + for(int i = 0; i < values.Count(); i++) + { + ultimaData.PrincipleItemRequirements[values[i].Item1] = values[(i+1) % values.Count()].Item2; + } + ultimaData.PrincipleItemRequirements[values[0].Item1] = (byte)(4 - values[0].Item1); + } + //worldMap.TestAbyssEjection(); diff --git a/U4DosRandomizer/UltimaData.cs b/U4DosRandomizer/UltimaData.cs index 62bca1f..c471454 100644 --- a/U4DosRandomizer/UltimaData.cs +++ b/U4DosRandomizer/UltimaData.cs @@ -107,6 +107,7 @@ public void SetItems(List value) public List StartingPositions { get; set; } public List LBText { get; internal set; } public List Mantras { get; internal set; } + public List PrincipleItemRequirements { get; internal set; } public string WordOfPassage { get; internal set; } public List StartingCharacters { get; internal set; } public byte DaemonSpawnX1 { get; internal set; } @@ -166,6 +167,7 @@ public UltimaData() StartingPositions = new List(); LBText = new List(); Mantras = new List(); + PrincipleItemRequirements = new List(); PirateCove = new List(); AbyssEjectionLocations = new List(); ShopLocations = new List>(); @@ -289,6 +291,7 @@ public ICoordinate GetLocation(int i) public static int ITEM_RUNE_HONOR { get; } = 20; public static int ITEM_RUNE_SPIRITUALITY { get; } = 21; public static int ITEM_RUNE_HUMILITY { get; } = 22; + /* * https://github.com/ergonomy-joe/u4-decompiled/blob/master/SRC/U4_SRCH.C#L246 * 0 - Mandrake diff --git a/u4_decompile/SRC/U4_USE.C b/u4_decompile/SRC/U4_USE.C index e7d28e2..ece2f11 100644 --- a/u4_decompile/SRC/U4_USE.C +++ b/u4_decompile/SRC/U4_USE.C @@ -163,7 +163,9 @@ C_0487() { u4_puts(D_0100); return; } - if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9) { + if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9 || + (!TST_MSK(Party.mItems, 13) && U4_RND1(7) >= 8) + ) { u4_puts(D_00EE); return; } From 4c97051fa06f613ed86a35e795081387bfb0f8a2 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Sat, 10 Jul 2021 22:05:30 -0500 Subject: [PATCH 11/28] Awaken whole party #76 --- u4_decompile/SRC/U4_SPELL.C | 38 +++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/u4_decompile/SRC/U4_SPELL.C b/u4_decompile/SRC/U4_SPELL.C index 40fb094..1d9e2d9 100644 --- a/u4_decompile/SRC/U4_SPELL.C +++ b/u4_decompile/SRC/U4_SPELL.C @@ -147,19 +147,33 @@ int bp04; /*C_6558*/SPL_Awaken() { register int si; + if(U4_RND1(7) < 8) { - si = AskChara(/*D_20E2*/"Who:\x12\x12\b"); - if(si < 0) - return; - if(!C_63B4()) - return; - if(Party.chara[si]._stat != 'S') { - w_Failed(); - return; - } - Party.chara[si]._stat = 'G'; - if(CurMode >= MOD_COMBAT) { - D_944A[si] = Fighters._chtile[si] = C_0ACF(si); + si = AskChara(/*D_20E2*/"Who:\x12\x12\b"); + if(si < 0) + return; + if(!C_63B4()) + return; + if(Party.chara[si]._stat != 'S') { + w_Failed(); + return; + } + Party.chara[si]._stat = 'G'; + if(CurMode >= MOD_COMBAT) { + D_944A[si] = Fighters._chtile[si] = C_0ACF(si); + } + } else { + if(!C_63B4()) + return; + for(si = Party.f_1d8-1; si >= 0; si--) + { + if(Party.chara[si]._stat == 'S') { + Party.chara[si]._stat = 'G'; + if(CurMode >= MOD_COMBAT) { + D_944A[si] = Fighters._chtile[si] = C_0ACF(si); + } + } + } } } From 714a2b21e09e361d31e10fe15f3bd382ac3c617d Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Sat, 10 Jul 2021 23:08:51 -0500 Subject: [PATCH 12/28] Revert "Revert "Fix weapon overflow exploit"" This reverts commit 300716f1cb16fa53dea8ee8b5e12edae2b17052a. --- u4_decompile/SRC/U4_SHOPS.C | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/u4_decompile/SRC/U4_SHOPS.C b/u4_decompile/SRC/U4_SHOPS.C index 983b136..5c782ba 100644 --- a/u4_decompile/SRC/U4_SHOPS.C +++ b/u4_decompile/SRC/U4_SHOPS.C @@ -316,9 +316,21 @@ C_CD1D(bp06, bp04) int bp06; int bp04; { - if(D_46D2[bp06] * bp04 > Party._gold) { - u4_puts(/*D_4652*/"I fear you have not the funds, perhaps something else.\n"); - return; + register int si; + + if(U4_RND1(7) < 8) { + if(D_46D2[bp06] * bp04 > Party._gold) { + u4_puts(/*D_4652*/"I fear you have not the funds, perhaps something else.\n"); + return; + } + } else { + /*Loop so it can't jump to an overflow and allow purchasing a lot of items for cheap. */ + for(si = 0; si <= bp04; si++) { + if(D_46D2[bp06] * si > Party._gold) { + u4_puts(/*D_4652*/"I fear you have not the funds, perhaps something else.\n"); + return; + } + } } Party._gold -= D_46D2[bp06] * bp04; dspl_Gold(); Party._weapons[bp06] += bp04; From 15751c7bba3d47fc43cefc2fda0d82e55c3f4d0b Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Tue, 13 Jul 2021 22:12:57 -0500 Subject: [PATCH 13/28] "Other" Option in character gen #107 --- u4_decompile/SRC-TITLE/TITLE_1.C | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/u4_decompile/SRC-TITLE/TITLE_1.C b/u4_decompile/SRC-TITLE/TITLE_1.C index 5f61725..1fd6ea4 100644 --- a/u4_decompile/SRC-TITLE/TITLE_1.C +++ b/u4_decompile/SRC-TITLE/TITLE_1.C @@ -801,7 +801,11 @@ C_2E04() Party.chara[0]._str = tmp_str; Party.chara[0]._int = tmp_int; Party.chara[0]._dex = tmp_dex; - Party.chara[0].p_24 = (M_or_F == 'M')?0x0b:0x0c; + switch(M_or_F) { + case 'F': Party.chara[0].p_24 = 0x0c; break; + case 'O': Party.chara[0].p_24 = 'O'; break; + default: Party.chara[0].p_24 = 0x0b; break; + } for(loc_A = 31; loc_A >= 0; loc_A --) { D_6976._npc._000[loc_A] = D_6976._npc._020[loc_A] = @@ -882,10 +886,14 @@ C_3030() return; } Gra_2(); - C_0B1E(17, 4, /*D_31A2*/"Art thou Male or Female? "); + if(U4_RND1(7) < 8) { + C_0B1E(17, 4, /*D_31A2*/"Art thou Male or Female? "); + } else { + C_0B1E(17, 4, /*D_31A2*/"Art thou Male, Female or Other? "); + } M_or_F = u_kbread() & 0xff; u4_toupper(M_or_F); - while(M_or_F != 'M' && M_or_F != 'F') { + while(M_or_F != 'M' && M_or_F != 'F' && M_or_F != 'O') { sound_1(); M_or_F = u_kbread() & 0xff; if(M_or_F == 0x1b || M_or_F == KBD_ENTER || M_or_F == KBD_SPACE) { From 1133807123fd9ef0adc5cb65c8bbe182852a2d37 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Tue, 13 Jul 2021 23:05:38 -0500 Subject: [PATCH 14/28] Town save turn off --- u4_decompile/SRC/U4_EXPLO.C | 28 +++++++++++++++++++--------- u4_decompile/SRC/U4_Q_N_V.C | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/u4_decompile/SRC/U4_EXPLO.C b/u4_decompile/SRC/U4_EXPLO.C index 67ed480..1a9bbd7 100644 --- a/u4_decompile/SRC/U4_EXPLO.C +++ b/u4_decompile/SRC/U4_EXPLO.C @@ -36,7 +36,7 @@ unsigned bp04; { if(Save(/*D_172B*/"OUTMONST.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) exit(3); - if(bp04 == 1) { + if(bp04 == 1 && U4_RND1(7) < 8) { if(Load("LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) exit(3); if(SAVE("LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) @@ -389,10 +389,15 @@ C_431D() return; } u4_puts(/*D_184B*/"to second floor!\n"); - if(Save(/*D_185D*/"LCB_1.SAV", sizeof(struct t_500), &D_8742) == -1) - exit(3); - if(Load(/*D_185D*/"LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) - exit(3); + if(U4_RND1(7) < 8) { + if(Load(/*D_185D*/"LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) + exit(3); + } else { + if(Save(/*D_185D*/"LCB_1.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + if(Load(/*D_185D*/"LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + } } else { w_What(); } @@ -440,8 +445,13 @@ C_431D() return; } u4_puts(/*D_18AA*/"to first floor!\n"); - if(Save(/*D_185D*/"LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) - exit(3); - if(Load(/*D_18BB*/"LCB_1.SAV", sizeof(struct t_500), &D_8742) == -1) - exit(3); + if(U4_RND1(7) < 8) { + if(Load(/*D_18BB*/"LCB_1.ULT", sizeof(struct t_500), &D_8742) == -1) + exit(3); + } else { + if(Save(/*D_185D*/"LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + if(Load(/*D_18BB*/"LCB_1.SAV", sizeof(struct t_500), &D_8742) == -1) + exit(3); + } } diff --git a/u4_decompile/SRC/U4_Q_N_V.C b/u4_decompile/SRC/U4_Q_N_V.C index ca9d729..a3e937c 100644 --- a/u4_decompile/SRC/U4_Q_N_V.C +++ b/u4_decompile/SRC/U4_Q_N_V.C @@ -15,7 +15,7 @@ u4_putl(Party._moves, 1, '0'); u4_puts(/*D_21B2*/" moves\n"); if(Party._loc) { - if(Party._loc > 0x18) { + if((U4_RND1(7) < 8 && Party._loc < 0x11) || Party._loc > 0x18) { u4_puts(/*D_21BA*/"Not Here!\n"); return; } From f3f7d48b746e21de5e0bafbf8f63d8aa45e89803 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Tue, 13 Jul 2021 23:48:55 -0500 Subject: [PATCH 15/28] Turn off daemon triggers --- u4_decompile/SRC/U4_COMBB.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/u4_decompile/SRC/U4_COMBB.C b/u4_decompile/SRC/U4_COMBB.C index 6fc917b..48c41a1 100644 --- a/u4_decompile/SRC/U4_COMBB.C +++ b/u4_decompile/SRC/U4_COMBB.C @@ -155,7 +155,7 @@ unsigned char bp04; (loc_C = (*(unsigned *)(D_95B2+loc_A+2) >> (loc_AShift+4)) & 0xf) ) { - if( D_95B2[loc_A] < TIL_80 ) { + if( U4_RND1(7) < 8 || D_95B2[loc_A] < TIL_80 ) { Combat_MAP(loc_B, loc_C) = D_95B2[loc_A]; } else { From da8db6e6b155c8a3f16629f9daf99d1b6f51bcf5 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Wed, 14 Jul 2021 23:21:52 -0500 Subject: [PATCH 16/28] Turn off disappearing monsters fix --- u4_decompile/SRC/U4_COMBC.C | 6 +++++- u4_decompile/SRC/U4_NPC.C | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/u4_decompile/SRC/U4_COMBC.C b/u4_decompile/SRC/U4_COMBC.C index f81df3e..fb2cc9f 100644 --- a/u4_decompile/SRC/U4_COMBC.C +++ b/u4_decompile/SRC/U4_COMBC.C @@ -180,7 +180,11 @@ register unsigned si; D_9772 = D_8742._npc._x[si]; D_9140 = D_8742._npc._y[si]; if(Party._loc == 0x00) { - D_946C = D_8742._map.x32x32[u4_wrap(D_9140 - (D_95A5.y*16))][u4_wrap(D_9772 - (D_95A5.x*16))]; + if(U4_RND1(7) < 8) { + D_946C = D_8742._map.x32x32[D_9140 - (D_95A5.y<<4)][D_9772 - (D_95A5.x<<4)]; + } else { + D_946C = D_8742._map.x32x32[u4_wrap(D_9140 - (D_95A5.y*16))][u4_wrap(D_9772 - (D_95A5.x*16))]; + } } else { D_946C = D_8742._map.x32x32[D_9140][D_9772]; } diff --git a/u4_decompile/SRC/U4_NPC.C b/u4_decompile/SRC/U4_NPC.C index 8a9457e..860e75a 100644 --- a/u4_decompile/SRC/U4_NPC.C +++ b/u4_decompile/SRC/U4_NPC.C @@ -202,7 +202,11 @@ register int si; unsigned char bp06; unsigned char bp04; { - if(C_4E94(si, bp06, bp04, D_8742._map.x32x32[u4_wrap(bp04-D_95A5.y*16)][u4_wrap(bp06-D_95A5.x*16)])) { + unsigned char temp = D_8742._map.x32x32[u4_wrap(bp04-D_95A5.y*16)][u4_wrap(bp06-D_95A5.x*16)]; + if(U4_RND1(7) < 8) { + temp = D_8742._map.x32x32[bp04-D_95A5.y*16][bp06-D_95A5.x*16]; + } + if(C_4E94(si, bp06, bp04, temp)) { if(C_2A5A(D_8742._npc._gtile[si] & 3)) { D_8742._npc._old_x[si] = D_8742._npc._x[si]; D_8742._npc._x[si] = bp06; @@ -345,10 +349,17 @@ int bp04; C_56D3(bp04) int bp04; { - return - u4_wrap(D_8742._npc._x[bp04] - D_95A5.x*16) >= 32 || - u4_wrap(D_8742._npc._y[bp04] - D_95A5.y*16) >= 32 - ; + if (U4_RND1(7) < 8) { + return + (D_8742._npc._x[bp04] - D_95A5.x*16) >= 32 || + (D_8742._npc._y[bp04] - D_95A5.y*16) >= 32 + ; + } else { + return + u4_wrap(D_8742._npc._x[bp04] - D_95A5.x*16) >= 32 || + u4_wrap(D_8742._npc._y[bp04] - D_95A5.y*16) >= 32 + ; + } } /*move outside NPC*/ From 1c68af1f6af2e7cc09f015b44a5d71301aca0d0a Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Thu, 15 Jul 2021 21:53:09 -0500 Subject: [PATCH 17/28] Offsets round 1 --- U4DosRandomizer/AvatarOffsetsNew.cs | 145 ++++++++++++----------- U4DosRandomizer/AvatarOffsetsOriginal.cs | 6 +- 2 files changed, 80 insertions(+), 71 deletions(-) diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index c7bf94e..720d1e0 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -23,7 +23,7 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) foreach (PropertyInfo pi in properties) { if(pi.Name.ToLower().Contains("offset") && !pi.Name.ToLower().Contains("blink") && !pi.Name.ToLower().Contains("enable") && !pi.Name.ToLower().Contains("encoded") && !pi.Name.ToLower().Contains("seed") && !pi.Name.ToLower().Contains("pointer") - && !pi.Name.ToLower().Contains("bell") && !pi.Name.ToLower().Contains("book") && !pi.Name.ToLower().Contains("candle")) + && !pi.Name.ToLower().Contains("bell")) { var newValue = avatarBytes[(int)pi.GetValue(this, null)]; var oldValue = originalAvatarBytes[(int)pi.GetValue(originalOffsets, null)]; @@ -56,42 +56,50 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) throw new Exception($"Offset {pi.Name} appears to be wrong."); } } + else if (pi.Name.Contains("bell")) + { + var newValue = avatarBytes[(int)pi.GetValue(this, null)]; + if (newValue != 0x10) + { + throw new Exception($"Offset {pi.Name} appears to be wrong."); + } + } } } - public int ABYSS_PARTY_COMPARISON { get; } = 0x3452; // 0x34AB - public int LB_PARTY_COMPARISON { get; } = 0xE641; // 0xE449 - public int BELL_REQUIREMENT_OFFSET { get; } = 0x4E0; // ??? - public int BOOK_REQUIREMENT_OFFSET { get; } = 0x52A; // ??? - public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x56F; // ??? - public int MOONGATE_X_OFFSET { get; } = 0x0fd5e; //0fad1 - public int MOONGATE_Y_OFFSET { get; } = 0x0fd66; //fad9 - public int AREA_X_OFFSET { get; } = 0x0fd8e; //fb01 // towns, cities, castles, dungeons, shrines - public int AREA_Y_OFFSET { get; } = 0x0fdae; //fb21 - - public int DEATH_EXIT_X_OFFSET { get; } = 0x0fea; //11ac - public int DEATH_EXIT_Y_OFFSET { get; } = 0x0fef; //11b1 - - public int PIRATE_COVE_X_OFFSET { get; } = 0x0fe36; //fba9 // length 8 - public int PIRATE_COVE_Y_OFFSET { get; } = 0x0fe3e; //fbb1 // length 8 - public int PIRATE_COVE_SHIP_TILES { get; } = 0x0fe46; //fbb9 // length 8 (Direction pirates are facing) - public int PIRATE_COVE_SPAWN_TRIGGER_Y_OFFSET1 { get; } = 0x0302b; //3084 - public int PIRATE_COVE_SPAWN_TRIGGER_X_OFFSET1 { get; } = 0x03032; //308B - public int PIRATE_COVE_SPAWN_TRIGGER_Y_OFFSET2 { get; } = 0x030CA; //3123 - public int PIRATE_COVE_SPAWN_TRIGGER_X_OFFSET2 { get; } = 0x030d1; //312A - public int WORD_OF_PASSAGE { get; } = 0x1077D; // 104F0 - public int MONSTER_HP_OFFSET { get; } = 0x11938; //11685 // length 52 - public int MONSTER_LEADER_TYPES_OFFSET { get; } = 0x1196C; //116b9 // length 36 - public int MONSTER_ENCOUNTER_SIZE_OFFSET { get; } = 0x11990; //116dd // length 36 - public int ALTAR_EXIT_DESTINATION { get; } = 0x11B80; //118c5 // length 12 : altar room exit destinations + public int ABYSS_PARTY_COMPARISON { get; } = 0x34BB; // 34AB + public int LB_PARTY_COMPARISON { get; } = 0xE8D1; // E449 + public int BELL_REQUIREMENT_OFFSET { get; } = 0x4E0; // New + public int BOOK_REQUIREMENT_OFFSET { get; } = 0x52A; // 6DB + public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x56F; // 720 + public int MOONGATE_X_OFFSET { get; } = 0x0fffa; //0fad1 + public int MOONGATE_Y_OFFSET { get; } = 0x10002; //fad9 + public int AREA_X_OFFSET { get; } = 0x1002a; //fb01 // towns, cities, castles, dungeons, shrines + public int AREA_Y_OFFSET { get; } = 0x1004a; //fb21 + + public int DEATH_EXIT_X_OFFSET { get; } = 0x0ffb; //11ac + public int DEATH_EXIT_Y_OFFSET { get; } = 0x1000; //11b1 + + public int PIRATE_COVE_X_OFFSET { get; } = 0x100d2; //fba9 // length 8 + public int PIRATE_COVE_Y_OFFSET { get; } = 0x100da; //fbb1 // length 8 + public int PIRATE_COVE_SHIP_TILES { get; } = 0x100e2; //fbb9 // length 8 (Direction pirates are facing) + public int PIRATE_COVE_SPAWN_TRIGGER_Y_OFFSET1 { get; } = 0x03094; //3084 + public int PIRATE_COVE_SPAWN_TRIGGER_X_OFFSET1 { get; } = 0x0309B; //308B + public int PIRATE_COVE_SPAWN_TRIGGER_Y_OFFSET2 { get; } = 0x03133; //3123 + public int PIRATE_COVE_SPAWN_TRIGGER_X_OFFSET2 { get; } = 0x0313A; //312A + public int WORD_OF_PASSAGE { get; } = 0x10A19; // 104F0 + public int MONSTER_HP_OFFSET { get; } = 0x11C1C; //11685 // length 52 + public int MONSTER_LEADER_TYPES_OFFSET { get; } = 0x11C50; //116b9 // length 36 + public int MONSTER_ENCOUNTER_SIZE_OFFSET { get; } = 0x11C74; //116dd // length 36 + public int ALTAR_EXIT_DESTINATION { get; } = 0x11E64; //118c5 // length 12 : altar room exit destinations /* * 0-3 { get; } = truth (north, east, south, west) * 4-7 { get; } = love * 8-11 { get; } = courage */ - public int AMBUSH_MONSTER_TYPES { get; } = 0x11c1e; //11963 //length 8 : ambush monster types - public int CITY_RUNE_MASK_PAIRS_OFFSET { get; } = 0x11e78; //11baf // length 16 : city/runemask pairs (city id, corresponding rune bitmask) - public int ITEM_LOCATIONS_OFFSET { get; } = 0x11e94; //11bcb // length 120 : 24 five-byte item location records (see below) + public int AMBUSH_MONSTER_TYPES { get; } = 0x11F02; //11963 //length 8 : ambush monster types + public int CITY_RUNE_MASK_PAIRS_OFFSET { get; } = 0x1215C; //11baf // length 16 : city/runemask pairs (city id, corresponding rune bitmask) + public int ITEM_LOCATIONS_OFFSET { get; } = 0x12178; //11bcb // length 120 : 24 five-byte item location records (see below) /* * Each item location record has the following structure: @@ -102,59 +110,59 @@ 0x2 1 Y Coordinate of Item 0x3 2 ??? (a pointer?) */ - public int MONSTER_DAMAGE_BITSHIFT_OFFSET { get; } = 0x9AA1; // 0x98E6 - public int WEAPON_DAMAGE_OFFSET { get; } = 0x119B6; // 0x11703 - public int MONSTER_SPAWN_TIER_ONE { get; } = 0x5B12; // 0x5B68 - public int MONSTER_SPAWN_TIER_TWO { get; } = 0x5B2A; // 0x5B83 - public int MONSTER_SPAWN_TIER_THREE { get; } = 0x5B62; // 0x5BBB + public int MONSTER_DAMAGE_BITSHIFT_OFFSET { get; } = 0x9D03; // 98E6 + public int WEAPON_DAMAGE_OFFSET { get; } = 0x11C9A; // 11703 + public int MONSTER_SPAWN_TIER_ONE { get; } = 0x5CAE; // 5B68 + public int MONSTER_SPAWN_TIER_TWO { get; } = 0x5CC9; // 5B83 + public int MONSTER_SPAWN_TIER_THREE { get; } = 0x5D01; // 5BBB //https://github.com/ergonomy-joe/u4-decompiled/blob/1964651295232b0ca39afafef254541a406eb66b/SRC/U4_COMBC.C#L210 - public int MONSTER_QTY_ONE { get; } = 0x8261; // 0x80EF - public int MONSTER_QTY_TWO { get; } = 0x8272; // 0x8100 - public int LB_TEXT_OFFSET { get; } = 0x159CB; // 0x156ca - public int LB_HELP_TEXT_OFFSET { get; } = 0x165D6; // 0x162D4 - public int MANTRA_OFFSET { get; } = 0x170D6; //16DD4 - public int MANTRA_POINTERS_OFFSET { get; } = 0x17896; // 17594 - public int SHRINE_TEXT_OFFSET { get; } = 0x170F4; //16df2 + public int MONSTER_QTY_ONE { get; } = 0x84D8; // 80EF + public int MONSTER_QTY_TWO { get; } = 0x84E9; // 8100 + public int LB_TEXT_OFFSET { get; } = 0x15CE7; // 156ca + public int LB_HELP_TEXT_OFFSET { get; } = 0x168F2; // 162D4 + public int MANTRA_OFFSET { get; } = 0x173F2; //16DD4 + public int MANTRA_POINTERS_OFFSET { get; } = 0x17BB2; // 17594 + public int SHRINE_TEXT_OFFSET { get; } = 0x17410; //16df2 - public int WHITE_STONE_LOCATION_TEXT { get; } = 0x17736; //17434 - public int BLACK_STONE_LOCATION_TEXT { get; } = 0x177FB; //174F9 + public int WHITE_STONE_LOCATION_TEXT { get; } = 0x17A52; //17434 + public int BLACK_STONE_LOCATION_TEXT { get; } = 0x17B17; //174F9 - public int SHOP_LOCATION_OFFSET { get; } = 0x12248; //11F7F + public int SHOP_LOCATION_OFFSET { get; } = 0x1252C; //11F7F - public int DEMON_SPAWN_TRIGGER_X1_OFFSET { get; } = 0x2EB3; //2F17 !!! e5 - public int DEMON_SPAWN_TRIGGER_X2_OFFSET { get; } = 0x2EB7; //2F1E !!! ea - public int DEMON_SPAWN_TRIGGER_Y1_OFFSET { get; } = 0x2EC8; //2F25 !!! d4 - public int DEMON_SPAWN_TRIGGER_Y2_OFFSET { get; } = 0x2ECC; //2F2C !!! d9 - public int DEMON_SPAWN_LOCATION_X_OFFSET { get; } = 0x2983; //29EA + public int DEMON_SPAWN_TRIGGER_X1_OFFSET { get; } = 0x2F1C; //2F17 !!! e5 + public int DEMON_SPAWN_TRIGGER_X2_OFFSET { get; } = 0x2F20; //2F1E !!! ea + public int DEMON_SPAWN_TRIGGER_Y1_OFFSET { get; } = 0x2F31; //2F25 !!! d4 + public int DEMON_SPAWN_TRIGGER_Y2_OFFSET { get; } = 0x2F35; //2F2C !!! d9 + public int DEMON_SPAWN_LOCATION_X_OFFSET { get; } = 0x29EC; //29EA - public int BALLOON_SPAWN_TRIGGER_X_OFFSET { get; } = 0x2941; //29A8 - public int BALLOON_SPAWN_TRIGGER_Y_OFFSET { get; } = 0x2948; //29AF + public int BALLOON_SPAWN_TRIGGER_X_OFFSET { get; } = 0x29AA; //29A8 + public int BALLOON_SPAWN_TRIGGER_Y_OFFSET { get; } = 0x29B1; //29AF - public int BALLOON_SPAWN_LOCATION_X_OFFSET { get; } = 0x2957; //29BE - public int BALLOON_SPAWN_LOCATION_Y_OFFSET { get; } = 0x295C; //29C3 + public int BALLOON_SPAWN_LOCATION_X_OFFSET { get; } = 0x29C0; //29BE + public int BALLOON_SPAWN_LOCATION_Y_OFFSET { get; } = 0x29C5; //29C3 - public int LBC_DUNGEON_EXIT_X_OFFSET { get; } = 0x470D; //4766 - public int LBC_DUNGEON_EXIT_Y_OFFSET { get; } = 0x4712; //476B + public int LBC_DUNGEON_EXIT_X_OFFSET { get; } = 0x47EF; //4766 + public int LBC_DUNGEON_EXIT_Y_OFFSET { get; } = 0x47F4; //476B public int ITEM_USE_TRIGGER_BELL_X_OFFSET { get; } = 0x04D1; //693 public int ITEM_USE_TRIGGER_BELL_Y_OFFSET { get; } = 0x04D8; //69A - public int ITEM_USE_TRIGGER_BOOK_X_OFFSET { get; } = 0x050A; //6CC - public int ITEM_USE_TRIGGER_BOOK_Y_OFFSET { get; } = 0x0511; //6D3 - public int ITEM_USE_TRIGGER_CANDLE_X_OFFSET { get; } = 0x054F; //711 - public int ITEM_USE_TRIGGER_CANDLE_Y_OFFSET { get; } = 0x0556; //718 - public int ITEM_USE_TRIGGER_SKULL_X_OFFSET { get; } = 0x0621; //7E3 - public int ITEM_USE_TRIGGER_SKULL_Y_OFFSET { get; } = 0x0628; //7EA + public int ITEM_USE_TRIGGER_BOOK_X_OFFSET { get; } = 0x051B; //6CC + public int ITEM_USE_TRIGGER_BOOK_Y_OFFSET { get; } = 0x0522; //6D3 + public int ITEM_USE_TRIGGER_CANDLE_X_OFFSET { get; } = 0x0560; //711 + public int ITEM_USE_TRIGGER_CANDLE_Y_OFFSET { get; } = 0x0567; //718 + public int ITEM_USE_TRIGGER_SKULL_X_OFFSET { get; } = 0x0632; //7E3 + public int ITEM_USE_TRIGGER_SKULL_Y_OFFSET { get; } = 0x0639; //7EA - public int WHIRLPOOL_EXIT_X_OFFSET { get; } = 0x7C04; //7A92 - public int WHIRLPOOL_EXIT_Y_OFFSET { get; } = 0x7C09; //7A97 + public int WHIRLPOOL_EXIT_X_OFFSET { get; } = 0x7E15; //7A92 + public int WHIRLPOOL_EXIT_Y_OFFSET { get; } = 0x7E1A; //7A97 - public int ABYSS_EJECTION_LOCATIONS_X { get; } = 0x1013A; //FEAD // Length 13 - Exit coords for when you fail tests in the Abyss https://github.com/ergonomy-joe/u4-decompiled/blob/c2c2108fa3bb346bcd1d8c207c526f33a4c8f5ef/SRC/U4_END.C#L37 - public int ABYSS_EJECTION_LOCATIONS_Y { get; } = 0x10148; //FEBB + public int ABYSS_EJECTION_LOCATIONS_X { get; } = 0x103D6; //FEAD // Length 13 - Exit coords for when you fail tests in the Abyss https://github.com/ergonomy-joe/u4-decompiled/blob/c2c2108fa3bb346bcd1d8c207c526f33a4c8f5ef/SRC/U4_END.C#L37 + public int ABYSS_EJECTION_LOCATIONS_Y { get; } = 0x103E4; //FEBB - public int SPELL_RECIPE_OFFSET { get; } = 0x11CF2; //11A29 + public int SPELL_RECIPE_OFFSET { get; } = 0x11FD6; //11A29 - public static int RUNE_IMAGE_INDEX2 { get; } = 0xFE12; // FB85 - public static int RUNE_IMAGE_INDEX { get; } = 0x17853; // 17551 + public static int RUNE_IMAGE_INDEX2 { get; } = 0x100AE; // FB85 + public static int RUNE_IMAGE_INDEX { get; } = 0x17B6F; // 17551 public int BLINK_CAST_EXCLUSION_X1_OFFSET { get; } = 0x68BB; // New @@ -181,6 +189,7 @@ 0x2 1 Y Coordinate of Item public int BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET + 4; } } // New + public int ENABLE_BELL_REQUIREMENT { get; } = 0x0; // New public int ENABLE_MIX_QUANTITY_OFFSET { get; } = 0x8FC7; // New public int ENABLE_SLEEP_BACKOFF_OFFSET { get; } = 0xA12A; // New diff --git a/U4DosRandomizer/AvatarOffsetsOriginal.cs b/U4DosRandomizer/AvatarOffsetsOriginal.cs index 7208f5c..dc7f10c 100644 --- a/U4DosRandomizer/AvatarOffsetsOriginal.cs +++ b/U4DosRandomizer/AvatarOffsetsOriginal.cs @@ -6,9 +6,9 @@ namespace U4DosRandomizer { public class AvatarOffsetsOriginal : IAvatarOffset { - public int BELL_REQUIREMENT_OFFSET { get; } = 0x000; - public int BOOK_REQUIREMENT_OFFSET { get; } = 0x000; - public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x000; + public int BELL_REQUIREMENT_OFFSET => throw new NotImplementedException(); + public int BOOK_REQUIREMENT_OFFSET { get; } = 0x6DB; + public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x720; // https://wiki.ultimacodex.com/wiki/Ultima_IV_Internal_Formats#AVATAR.EXE // Above doesn't work anymore cuz we have modified AVATAR.EXE public int ABYSS_PARTY_COMPARISON { get; } = 0x34AB; From d81bb0b33165bd7b740dbe013c5189df497f08aa Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Thu, 15 Jul 2021 23:25:44 -0500 Subject: [PATCH 18/28] Off set round 2 - New values and octodiffs --- U4DosRandomizer/AvatarOffsetsNew.cs | 42 ++++++++++++-------- U4DosRandomizer/Title.cs | 1 + U4DosRandomizer/patches/AVATAR.EXE.octodiff | Bin 93595 -> 94379 bytes U4DosRandomizer/patches/TITLE.EXE.octodiff | Bin 22972 -> 23052 bytes u4_decompile/SRC-TITLE/TITLE_1.C | 1 + u4_decompile/SRC/U4_COMBB.C | 1 + u4_decompile/SRC/U4_COMBC.C | 1 + u4_decompile/SRC/U4_EXPLO.C | 3 ++ u4_decompile/SRC/U4_NPC.C | 2 + u4_decompile/SRC/U4_Q_N_V.C | 1 + u4_decompile/SRC/U4_SHOPS.C | 2 +- u4_decompile/SRC/U4_SPELL.C | 1 + u4_decompile/SRC/U4_USE.C | 1 + 13 files changed, 39 insertions(+), 17 deletions(-) diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index 720d1e0..ed47d33 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -164,49 +164,59 @@ 0x2 1 Y Coordinate of Item public static int RUNE_IMAGE_INDEX2 { get; } = 0x100AE; // FB85 public static int RUNE_IMAGE_INDEX { get; } = 0x17B6F; // 17551 - public int BLINK_CAST_EXCLUSION_X1_OFFSET { get; } = 0x68BB; // New + public int BLINK_CAST_EXCLUSION_X1_OFFSET { get; } = 0x6A9D; // New : C0 public int BLINK_CAST_EXCLUSION_X2_OFFSET { get { return BLINK_CAST_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_CAST_EXCLUSION_Y1_OFFSET { get; } = 0x68D0; // New + public int BLINK_CAST_EXCLUSION_Y1_OFFSET { get; } = 0x6AB2; // New : C0 public int BLINK_CAST_EXCLUSION_Y2_OFFSET { get { return BLINK_CAST_EXCLUSION_Y1_OFFSET + 4; } } // New - public int BLINK_DESTINATION_EXCLUSION_X1_OFFSET { get; } = 0x6955; // New + public int BLINK_DESTINATION_EXCLUSION_X1_OFFSET { get; } = 0x6B37; // New : 01 public int BLINK_DESTINATION_EXCLUSION_X2_OFFSET { get { return BLINK_DESTINATION_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_DESTINATION_EXCLUSION_Y1_OFFSET { get; } = 0x6974; // New + public int BLINK_DESTINATION_EXCLUSION_Y1_OFFSET { get; } = 0x6B56; // New : 01 public int BLINK_DESTINATION_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION_EXCLUSION_Y1_OFFSET + 4; } } // New - public int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET { get; } = 0x6997; // New + public int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET { get; } = 0x6B79; // New : 01 public int BLINK_DESTINATION2_EXCLUSION_X2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } = 0x69BA; // New + public int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } = 0x699C; // New : 01 public int BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET + 4; } } // New - public int ENABLE_BELL_REQUIREMENT { get; } = 0x0; // New - public int ENABLE_MIX_QUANTITY_OFFSET { get; } = 0x8FC7; // New + public int ENABLE_BELL_REQUIREMENT { get; } = 0x04E9; // New : 08 + public int ENABLE_TOWN_SAVE1 { get; } = 0x405E; // New : 08 + public int ENABLE_TOWN_SAVE2 { get; } = 0x471B; // New : 08 + public int ENABLE_TOWN_SAVE3 { get; } = 0x4815; // New : 08 + public int ENABLE_TOWN_SAVE4 { get; } = 0x44A0; // New : 08 + public int ENABLE_MIX_QUANTITY_OFFSET { get; } = 0x9229; // New : 08 - public int ENABLE_SLEEP_BACKOFF_OFFSET { get; } = 0xA12A; // New + public int ENABLE_SLEEP_BACKOFF_OFFSET { get; } = 0xA38C; // New : 08 + public int ENABLE_DAEMON_TRIGGER_FIX { get; } = 0x8006; // New : 08 + public int ENABLE_MAP_EDGE_FIX1 { get; } = 0x56AE; // New : 08 + public int ENABLE_MAP_EDGE_FIX2 { get; } = 0x59D1; // New : 08 + public int ENABLE_MAP_EDGE_FIX3 { get; } = 0x83C0; // New : 08 + public int ENABLE_AWAKEN_ALL { get; } = 0x69C5; // New : 08 - public int ENABLE_ACTIVE_PLAYER_1_OFFSET { get; } = 0x5DD3; // New + public int ENABLE_ACTIVE_PLAYER_1_OFFSET { get; } = 0x5F72; // New : 08 - public int ENABLE_HIT_CHANCE_OFFSET { get; } = 0x62DD; // New + public int ENABLE_HIT_CHANCE_OFFSET { get; } = 0x647C; // New : 08 - public int ENABLE_DIAGONAL_ATTACK_OFFSET { get; } = 0x6491; // New + public int ENABLE_DIAGONAL_ATTACK_OFFSET { get; } = 0x6630; // New : 08 - public int ENABLE_SACRIFICE_FIX_OFFSET { get; } = 0xA7FB; // New + public int ENABLE_SACRIFICE_FIX_OFFSET { get; } = 0xAA5D; // New : 08 - public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } = 0x4E9; // New + public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } = 0x4FA; // New : E8 - public int ENCODED_FLAGS_OFFSET { get; } = 0xFBA7; // New + public int ENABLE_WEAPON_OVERFLOW_FIX { get; } = 0xD377; // New 08 + public int ENCODED_FLAGS_OFFSET { get; } = 0xFE43; // New : 20 - public int SEED_OFFSET { get; } = 0xFB87; // New + public int SEED_OFFSET { get; } = 0xFE23; // New : 20 public const byte Reagent_ash = (0x80 >> 0); public const byte Reagent_ginseng = (0x80 >> 1); diff --git a/U4DosRandomizer/Title.cs b/U4DosRandomizer/Title.cs index e836f9d..4db60c4 100644 --- a/U4DosRandomizer/Title.cs +++ b/U4DosRandomizer/Title.cs @@ -133,6 +133,7 @@ public void Save(string path) } } + public static int ENABLE_OTHER = 0x311E; public static int FLAG_ENCODE_OFFSET = 0x41D1; // N/A public static int START_X_OFFSET = 0x7140; //0x70dc; public static int START_Y_OFFSET = 0x7148; //0x70e4; diff --git a/U4DosRandomizer/patches/AVATAR.EXE.octodiff b/U4DosRandomizer/patches/AVATAR.EXE.octodiff index 3a12aa5a4dc08349125e02a05c8cb6116e27c791..0a8edf1c0ac93167554812763f1526738ddebe6e 100644 GIT binary patch delta 50770 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

YO(`m;-Qk0a3o*!$v|!8 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 delta 50107 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 +AaTrQgUiMzX?aBB^a8fT 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 SX?l}guJm==`qr7!zW)yhM2EZp diff --git a/U4DosRandomizer/patches/TITLE.EXE.octodiff b/U4DosRandomizer/patches/TITLE.EXE.octodiff index 211ee1d27c1d9a4e6358e834e44325c725df676c..443551bb1bb9460100c397afd06ad4a55fc09b4e 100644 GIT binary patch delta 7880 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 kUn&wsWF>EeC>fr=V2> (loc_AShift+4)) & 0xf) ) { + /*ENABLE_DAEMON_TRIGGER_FIX*/ if( U4_RND1(7) < 8 || D_95B2[loc_A] < TIL_80 ) { Combat_MAP(loc_B, loc_C) = D_95B2[loc_A]; } diff --git a/u4_decompile/SRC/U4_COMBC.C b/u4_decompile/SRC/U4_COMBC.C index fb2cc9f..ffa4ba3 100644 --- a/u4_decompile/SRC/U4_COMBC.C +++ b/u4_decompile/SRC/U4_COMBC.C @@ -180,6 +180,7 @@ register unsigned si; D_9772 = D_8742._npc._x[si]; D_9140 = D_8742._npc._y[si]; if(Party._loc == 0x00) { + /*ENABLE_MAP_EDGE_FIX2*/ if(U4_RND1(7) < 8) { D_946C = D_8742._map.x32x32[D_9140 - (D_95A5.y<<4)][D_9772 - (D_95A5.x<<4)]; } else { diff --git a/u4_decompile/SRC/U4_EXPLO.C b/u4_decompile/SRC/U4_EXPLO.C index 1a9bbd7..1aa3f7d 100644 --- a/u4_decompile/SRC/U4_EXPLO.C +++ b/u4_decompile/SRC/U4_EXPLO.C @@ -36,6 +36,7 @@ unsigned bp04; { if(Save(/*D_172B*/"OUTMONST.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) exit(3); + /*ENABLE_TOWN_SAVE1*/ if(bp04 == 1 && U4_RND1(7) < 8) { if(Load("LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) exit(3); @@ -389,6 +390,7 @@ C_431D() return; } u4_puts(/*D_184B*/"to second floor!\n"); + /*ENABLE_TOWN_SAVE2*/ if(U4_RND1(7) < 8) { if(Load(/*D_185D*/"LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) exit(3); @@ -445,6 +447,7 @@ C_431D() return; } u4_puts(/*D_18AA*/"to first floor!\n"); + /*ENABLE_TOWN_SAVE3*/ if(U4_RND1(7) < 8) { if(Load(/*D_18BB*/"LCB_1.ULT", sizeof(struct t_500), &D_8742) == -1) exit(3); diff --git a/u4_decompile/SRC/U4_NPC.C b/u4_decompile/SRC/U4_NPC.C index 860e75a..6093607 100644 --- a/u4_decompile/SRC/U4_NPC.C +++ b/u4_decompile/SRC/U4_NPC.C @@ -203,6 +203,7 @@ unsigned char bp06; unsigned char bp04; { unsigned char temp = D_8742._map.x32x32[u4_wrap(bp04-D_95A5.y*16)][u4_wrap(bp06-D_95A5.x*16)]; + /*ENABLE_MAP_EDGE_FIX1*/ if(U4_RND1(7) < 8) { temp = D_8742._map.x32x32[bp04-D_95A5.y*16][bp06-D_95A5.x*16]; } @@ -349,6 +350,7 @@ int bp04; C_56D3(bp04) int bp04; { + /*ENABLE_MAP_EDGE_FIX3*/ if (U4_RND1(7) < 8) { return (D_8742._npc._x[bp04] - D_95A5.x*16) >= 32 || diff --git a/u4_decompile/SRC/U4_Q_N_V.C b/u4_decompile/SRC/U4_Q_N_V.C index a3e937c..c033c6b 100644 --- a/u4_decompile/SRC/U4_Q_N_V.C +++ b/u4_decompile/SRC/U4_Q_N_V.C @@ -15,6 +15,7 @@ u4_putl(Party._moves, 1, '0'); u4_puts(/*D_21B2*/" moves\n"); if(Party._loc) { + /*ENABLE_TOWN_SAVE4*/ if((U4_RND1(7) < 8 && Party._loc < 0x11) || Party._loc > 0x18) { u4_puts(/*D_21BA*/"Not Here!\n"); return; diff --git a/u4_decompile/SRC/U4_SHOPS.C b/u4_decompile/SRC/U4_SHOPS.C index 5c782ba..403a77f 100644 --- a/u4_decompile/SRC/U4_SHOPS.C +++ b/u4_decompile/SRC/U4_SHOPS.C @@ -317,7 +317,7 @@ int bp06; int bp04; { register int si; - + /*ENABLE_WEAPON_OVERFLOW_FIX*/ if(U4_RND1(7) < 8) { if(D_46D2[bp06] * bp04 > Party._gold) { u4_puts(/*D_4652*/"I fear you have not the funds, perhaps something else.\n"); diff --git a/u4_decompile/SRC/U4_SPELL.C b/u4_decompile/SRC/U4_SPELL.C index 1d9e2d9..cd18127 100644 --- a/u4_decompile/SRC/U4_SPELL.C +++ b/u4_decompile/SRC/U4_SPELL.C @@ -147,6 +147,7 @@ int bp04; /*C_6558*/SPL_Awaken() { register int si; + /*ENABLE_AWAKEN_ALL*/ if(U4_RND1(7) < 8) { si = AskChara(/*D_20E2*/"Who:\x12\x12\b"); diff --git a/u4_decompile/SRC/U4_USE.C b/u4_decompile/SRC/U4_USE.C index ece2f11..8e40a8a 100644 --- a/u4_decompile/SRC/U4_USE.C +++ b/u4_decompile/SRC/U4_USE.C @@ -163,6 +163,7 @@ C_0487() { u4_puts(D_0100); return; } + /*ENABLE_BELL_REQUIREMENT*/ if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9 || (!TST_MSK(Party.mItems, 13) && U4_RND1(7) >= 8) ) { From c3c10ebfc9eb21d065519beec05943621f73848e Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Fri, 16 Jul 2021 00:16:43 -0500 Subject: [PATCH 19/28] Offsets Title round --- U4DosRandomizer/AvatarOffsetsNew.cs | 2 +- U4DosRandomizer/Title.cs | 17 +++++++++++------ U4DosRandomizer/patches/TITLE.EXE.octodiff | Bin 23052 -> 23052 bytes 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index ed47d33..d9d2d19 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -185,7 +185,7 @@ 0x2 1 Y Coordinate of Item public int BLINK_DESTINATION2_EXCLUSION_X2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } = 0x699C; // New : 01 + public int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } = 0x6B9C; // New : 01 public int BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET + 4; } } // New diff --git a/U4DosRandomizer/Title.cs b/U4DosRandomizer/Title.cs index 4db60c4..01a6560 100644 --- a/U4DosRandomizer/Title.cs +++ b/U4DosRandomizer/Title.cs @@ -41,6 +41,11 @@ public void Load(string path, UltimaData data) titleBytes = titleStream.ReadAllBytes(); } + if (titleBytes[ENABLE_OTHER] != 0x08) + { + throw new Exception($"Offset ENABLE_OTHER appears to be wrong."); + } + if (titleBytes[START_X_OFFSET] != 0xE7) { throw new Exception($"Offset START_X_OFFSET appears to be wrong."); @@ -51,12 +56,12 @@ public void Load(string path, UltimaData data) throw new Exception($"Offset START_Y_OFFSET appears to be wrong."); } - if (titleBytes[FLAG_ENCODE_OFFSET] != 0x43) + if (titleBytes[FLAG_ENCODE_OFFSET] != 0x20) { throw new Exception($"Offset FLAG_ENCODE_OFFSET appears to be wrong."); } - if (titleBytes[ENABLE_KARMA_OVERRIDE_OFFSET] != 0x09) + if (titleBytes[ENABLE_KARMA_OVERRIDE_OFFSET] != 0x08) { throw new Exception($"Offset ENABLE_KARMA_OVERRIDE_OFFSET appears to be wrong."); } @@ -134,12 +139,12 @@ public void Save(string path) } public static int ENABLE_OTHER = 0x311E; - public static int FLAG_ENCODE_OFFSET = 0x41D1; // N/A - public static int START_X_OFFSET = 0x7140; //0x70dc; - public static int START_Y_OFFSET = 0x7148; //0x70e4; + public static int FLAG_ENCODE_OFFSET = 0x4201; // N/A + public static int START_X_OFFSET = 0x7170; //0x70dc; + public static int START_Y_OFFSET = 0x7178; //0x70e4; public static int ENABLE_KARMA_OVERRIDE_OFFSET = 0x2EA8; - public static int KARMA_OVERRIDE_VALUES_OFFSET = 0x7150; + public static int KARMA_OVERRIDE_VALUES_OFFSET = 0x7180; private SpoilerLog spoilerLog; public Title(SpoilerLog spoilerLog) diff --git a/U4DosRandomizer/patches/TITLE.EXE.octodiff b/U4DosRandomizer/patches/TITLE.EXE.octodiff index 443551bb1bb9460100c397afd06ad4a55fc09b4e..0ae1c76400fa8fd930ea34a22f2f597f58d19f6b 100644 GIT binary patch delta 57 zcmV-90LK4}v;mB?0VhvGR8K@jOjJPu1XD;sF%$p*0Cc2yTK9;x0puO1KZW Date: Fri, 16 Jul 2021 00:17:04 -0500 Subject: [PATCH 20/28] Fix runes and mantras Talk to work with non-randomized overworld --- U4DosRandomizer/Talk.cs | 234 ++++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/U4DosRandomizer/Talk.cs b/U4DosRandomizer/Talk.cs index 0b5eb9a..39f203f 100644 --- a/U4DosRandomizer/Talk.cs +++ b/U4DosRandomizer/Talk.cs @@ -62,9 +62,9 @@ public void Load(string path) public void Update(UltimaData ultimaData, Avatar avatar, Flags flags, IWorldMap worldMap) { + Person person = null; if (flags.Overworld == 5) { - Person person = null; // --- Items --- if (ultimaData.Items[ultimaData.ITEM_BELL].Changed) { @@ -248,120 +248,6 @@ public void Update(UltimaData ultimaData, Avatar avatar, Flags flags, IWorldMap // --- End Shrines --- - // --- Runes --- - if (flags.Runes) - { - for (int i = 0; i < 8; i++) - { - var itemOption = ultimaData.ItemOptions[UltimaData.ITEM_RUNE_HONESTY + i]; - foreach(var newPerson in itemOption.People) - { - person = FindPerson(newPerson.Name, newPerson.Town); - if(newPerson.Health != null) - { - person.Health = newPerson.Health; - } - if (newPerson.Job != null) - { - person.Job = newPerson.Job; - } - if (newPerson.Keyword1 != null) - { - person.Keyword1 = newPerson.Keyword1; - } - if (newPerson.Keyword2 != null) - { - person.Keyword2 = newPerson.Keyword2; - } - if (newPerson.Yes != null) - { - person.Yes = newPerson.Yes; - } - if (newPerson.No != null) - { - person.No = newPerson.No; - } - if (newPerson.Question != null) - { - person.Question = newPerson.Question; - } - if (newPerson.KeywordResponse1 != null) - { - person.KeywordResponse1 = newPerson.KeywordResponse1; - } - if (newPerson.KeywordResponse2 != null) - { - person.KeywordResponse2 = newPerson.KeywordResponse2; - } - } - } - } - - // --- End Runes --- - - if (flags.Mantras) - { - person = FindPerson("Cromwell"); - person.KeywordResponse2 = $"The mantra of the shrine of honesty is {Mantras[0].Text.ToUpper()}."; - - person = FindPerson("Cricket"); - person.KeywordResponse2 = $"The mantra of the shrine of compassion is {Mantras[1].Text.ToUpper()}!"; - - person = FindPerson("Aesop"); - person.KeywordResponse2 = $"The mantra of valor is '{Mantras[2].Text.ToUpper()}'. Use it in the shrine on the next isle!"; - - person = FindPerson("Silent"); - person.Job = $"{Mantras[3].Text}... {Mantras[3].Text}..."; - person.Health = $"{Mantras[3].Text}... {Mantras[3].Text}..."; - person.Keyword1 = $"{Mantras[3].Text.ToUpper()}..."; - person.KeywordResponse1 = $"{Mantras[3].Text}... {Mantras[3].Text}..."; - person.Keyword2 = $"{Mantras[3].Text.ToUpper()}"; - person.KeywordResponse2 = $"{Mantras[3].Text}... {Mantras[3].Text}..."; - - person = FindPerson("Singsong"); - person.KeywordResponse2 = Mantras[4].Limerick; - - person = FindPerson("Kline"); - person.KeywordResponse1 = $"The mantra is '{Mantras[5].Text}'."; - - person = FindPerson("Barren", "Skara"); - person.KeywordResponse1 = $"I know it well, it is '{Mantras[6].Text.ToUpper()}'."; - - person = FindPerson("the Ankh of\nSpirituality"); - person.Keyword2 = Mantras[6].Text.ToUpper(); - - person = FindPerson("Faultless"); - person.KeywordResponse2 = $"The mantra for pride, being the antithesis of humility, is '{new string(Mantras[7].Text.ToString().ToUpper().Reverse().ToArray())}'."; - } - - if(flags.WordOfPassage) - { - person = FindPerson("Robert Frasier"); - person.Yes = $"It is '{ultimaData.WordTruth.ToLower()}'! Seek ye now the other parts!"; - - person = FindPerson("Lord Robert", "Empath"); - person.Yes = $"It is '{ultimaData.WordLove.ToLower()}'! Seek ye now the other parts!"; - - person = FindPerson("Sentri"); - person.KeywordResponse2 = $"I know but one of three syllables - '{ultimaData.WordCourage.ToLower()}'."; - } - - if(flags.RandomizeSpells) - { - person = FindPerson("Nigel, at thy\nservice."); - person.KeywordResponse2 = $"Yes, resurrection it takes: {GetRecipeText(ultimaData.SpellsRecipes['r' - 'a'].Byte)}!"; - - person = FindPerson("Mentorian"); - if (ultimaData.SpellsRecipes['g' - 'a'].Byte == 0xFF) - { - person.KeywordResponse2 = $"As thou dost bear the ankh I shall tell thee. A gate spell needs { GetRecipeText(ultimaData.SpellsRecipes['g' - 'a'].Byte)}!"; - } - else - { - person.KeywordResponse2 = $"Since thou dost bear the ankh I shall tell thee. A gate spell requires { GetRecipeText(ultimaData.SpellsRecipes['g' - 'a'].Byte)}!"; - } - } - // --- Towns and Castles --- // TODO make response descriptive if (ultimaData.Castles[0].IsDirty()) @@ -432,7 +318,7 @@ public void Update(UltimaData ultimaData, Avatar avatar, Flags flags, IWorldMap var item = ultimaData.Items[ultimaData.ITEM_BELL]; var talkString = talkToLocation[new Tuple(item.Location, item.X, item.Y)].Item1; talkString = talkString.Replace("", "the bell of courage").CapitalizeFirstLetter(); - var person = FindPerson("Garam"); + person = FindPerson("Garam"); person.KeywordResponse2 = talkString; item = ultimaData.Items[ultimaData.ITEM_SKULL]; @@ -484,10 +370,124 @@ public void Update(UltimaData ultimaData, Avatar avatar, Flags flags, IWorldMap ultimaData.LBHelpText[18] = "Thou dost now seem ready to make the final journey into the dark Abyss!\n"; } + // --- Runes --- + if (flags.Runes) + { + for (int i = 0; i < 8; i++) + { + var itemOption = ultimaData.ItemOptions[UltimaData.ITEM_RUNE_HONESTY + i]; + foreach (var newPerson in itemOption.People) + { + person = FindPerson(newPerson.Name, newPerson.Town); + if (newPerson.Health != null) + { + person.Health = newPerson.Health; + } + if (newPerson.Job != null) + { + person.Job = newPerson.Job; + } + if (newPerson.Keyword1 != null) + { + person.Keyword1 = newPerson.Keyword1; + } + if (newPerson.Keyword2 != null) + { + person.Keyword2 = newPerson.Keyword2; + } + if (newPerson.Yes != null) + { + person.Yes = newPerson.Yes; + } + if (newPerson.No != null) + { + person.No = newPerson.No; + } + if (newPerson.Question != null) + { + person.Question = newPerson.Question; + } + if (newPerson.KeywordResponse1 != null) + { + person.KeywordResponse1 = newPerson.KeywordResponse1; + } + if (newPerson.KeywordResponse2 != null) + { + person.KeywordResponse2 = newPerson.KeywordResponse2; + } + } + } + } + + // --- End Runes --- + + if (flags.Mantras) + { + person = FindPerson("Cromwell"); + person.KeywordResponse2 = $"The mantra of the shrine of honesty is {Mantras[0].Text.ToUpper()}."; + + person = FindPerson("Cricket"); + person.KeywordResponse2 = $"The mantra of the shrine of compassion is {Mantras[1].Text.ToUpper()}!"; + + person = FindPerson("Aesop"); + person.KeywordResponse2 = $"The mantra of valor is '{Mantras[2].Text.ToUpper()}'. Use it in the shrine on the next isle!"; + + person = FindPerson("Silent"); + person.Job = $"{Mantras[3].Text}... {Mantras[3].Text}..."; + person.Health = $"{Mantras[3].Text}... {Mantras[3].Text}..."; + person.Keyword1 = $"{Mantras[3].Text.ToUpper()}..."; + person.KeywordResponse1 = $"{Mantras[3].Text}... {Mantras[3].Text}..."; + person.Keyword2 = $"{Mantras[3].Text.ToUpper()}"; + person.KeywordResponse2 = $"{Mantras[3].Text}... {Mantras[3].Text}..."; + + person = FindPerson("Singsong"); + person.KeywordResponse2 = Mantras[4].Limerick; + + person = FindPerson("Kline"); + person.KeywordResponse1 = $"The mantra is '{Mantras[5].Text}'."; + + person = FindPerson("Barren", "Skara"); + person.KeywordResponse1 = $"I know it well, it is '{Mantras[6].Text.ToUpper()}'."; + + person = FindPerson("the Ankh of\nSpirituality"); + person.Keyword2 = Mantras[6].Text.ToUpper(); + + person = FindPerson("Faultless"); + person.KeywordResponse2 = $"The mantra for pride, being the antithesis of humility, is '{new string(Mantras[7].Text.ToString().ToUpper().Reverse().ToArray())}'."; + } + + if (flags.WordOfPassage) + { + person = FindPerson("Robert Frasier"); + person.Yes = $"It is '{ultimaData.WordTruth.ToLower()}'! Seek ye now the other parts!"; + + person = FindPerson("Lord Robert", "Empath"); + person.Yes = $"It is '{ultimaData.WordLove.ToLower()}'! Seek ye now the other parts!"; + + person = FindPerson("Sentri"); + person.KeywordResponse2 = $"I know but one of three syllables - '{ultimaData.WordCourage.ToLower()}'."; + } + + if (flags.RandomizeSpells) + { + person = FindPerson("Nigel, at thy\nservice."); + person.KeywordResponse2 = $"Yes, resurrection it takes: {GetRecipeText(ultimaData.SpellsRecipes['r' - 'a'].Byte)}!"; + + person = FindPerson("Mentorian"); + if (ultimaData.SpellsRecipes['g' - 'a'].Byte == 0xFF) + { + person.KeywordResponse2 = $"As thou dost bear the ankh I shall tell thee. A gate spell needs { GetRecipeText(ultimaData.SpellsRecipes['g' - 'a'].Byte)}!"; + } + else + { + person.KeywordResponse2 = $"Since thou dost bear the ankh I shall tell thee. A gate spell requires { GetRecipeText(ultimaData.SpellsRecipes['g' - 'a'].Byte)}!"; + } + } + // --- Fixes --- if (flags.Fixes) { - var person = FindPerson("Water"); + person = FindPerson("Water"); person.QuestionFlag = 6; SpoilerLog.Add(SpoilerCategory.Fix, $"Water asks question"); From 9fba6c33720ef3f9799e750c7d3dc16f9d7146f6 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Fri, 16 Jul 2021 22:27:45 -0500 Subject: [PATCH 21/28] Flag all the new stuff --- U4DosRandomizer/Avatar.cs | 30 +++++++++++++++++++++ U4DosRandomizer/AvatarOffsetsNew.cs | 1 - U4DosRandomizer/AvatarOffsetsOriginal.cs | 10 +++++++ U4DosRandomizer/Flags.cs | 34 +++++++++++++++++++----- U4DosRandomizer/IAvatarOffset.cs | 10 +++++++ U4DosRandomizer/Program.cs | 34 ++++++++++++++++++++---- 6 files changed, 106 insertions(+), 13 deletions(-) diff --git a/U4DosRandomizer/Avatar.cs b/U4DosRandomizer/Avatar.cs index d69aff6..526a172 100644 --- a/U4DosRandomizer/Avatar.cs +++ b/U4DosRandomizer/Avatar.cs @@ -637,6 +637,36 @@ public void Update(UltimaData data, Flags flags) avatarBytes[AvatarOffset.LB_PARTY_COMPARISON] = 0x00; } + if (flags.TownSaves) + { + avatarBytes[AvatarOffset.ENABLE_TOWN_SAVE1] = (byte)0x0; + avatarBytes[AvatarOffset.ENABLE_TOWN_SAVE2] = (byte)0x0; + avatarBytes[AvatarOffset.ENABLE_TOWN_SAVE3] = (byte)0x0; + avatarBytes[AvatarOffset.ENABLE_TOWN_SAVE4] = (byte)0x0; + } + + if (flags.DaemonTrigger) + { + avatarBytes[AvatarOffset.ENABLE_DAEMON_TRIGGER_FIX] = (byte)0x0; + } + + if (flags.Fixes) + { + avatarBytes[AvatarOffset.ENABLE_MAP_EDGE_FIX1] = (byte)0x0; + avatarBytes[AvatarOffset.ENABLE_MAP_EDGE_FIX2] = (byte)0x0; + avatarBytes[AvatarOffset.ENABLE_MAP_EDGE_FIX3] = (byte)0x0; + } + + if (flags.AwakenUpgrade) + { + avatarBytes[AvatarOffset.ENABLE_AWAKEN_ALL] = (byte)0x0; + } + + if (flags.ShopOverflowFix) + { + avatarBytes[AvatarOffset.ENABLE_WEAPON_OVERFLOW_FIX] = (byte)0x0; + } + if (flags.VGAPatch) { ApplyVGAPatch(); diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index d9d2d19..58f9f52 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -189,7 +189,6 @@ 0x2 1 Y Coordinate of Item public int BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET + 4; } } // New - public int ENABLE_BELL_REQUIREMENT { get; } = 0x04E9; // New : 08 public int ENABLE_TOWN_SAVE1 { get; } = 0x405E; // New : 08 public int ENABLE_TOWN_SAVE2 { get; } = 0x471B; // New : 08 public int ENABLE_TOWN_SAVE3 { get; } = 0x4815; // New : 08 diff --git a/U4DosRandomizer/AvatarOffsetsOriginal.cs b/U4DosRandomizer/AvatarOffsetsOriginal.cs index dc7f10c..fe3ba2c 100644 --- a/U4DosRandomizer/AvatarOffsetsOriginal.cs +++ b/U4DosRandomizer/AvatarOffsetsOriginal.cs @@ -125,6 +125,10 @@ 0x2 1 Y Coordinate of Item public int BLINK_DESTINATION_EXCLUSION_Y2_OFFSET => throw new NotImplementedException(); + public int ENABLE_TOWN_SAVE1 => throw new NotImplementedException(); + public int ENABLE_TOWN_SAVE2 => throw new NotImplementedException(); + public int ENABLE_TOWN_SAVE3 => throw new NotImplementedException(); + public int ENABLE_TOWN_SAVE4 => throw new NotImplementedException(); public int ENABLE_MIX_QUANTITY_OFFSET => throw new NotImplementedException(); public int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET => throw new NotImplementedException(); @@ -136,6 +140,11 @@ 0x2 1 Y Coordinate of Item public int BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET => throw new NotImplementedException(); public int ENABLE_SLEEP_BACKOFF_OFFSET => throw new NotImplementedException(); + public int ENABLE_DAEMON_TRIGGER_FIX => throw new NotImplementedException(); + public int ENABLE_MAP_EDGE_FIX1 => throw new NotImplementedException(); + public int ENABLE_MAP_EDGE_FIX2 => throw new NotImplementedException(); + public int ENABLE_MAP_EDGE_FIX3 => throw new NotImplementedException(); + public int ENABLE_AWAKEN_ALL => throw new NotImplementedException(); public int ENABLE_ACTIVE_PLAYER_1_OFFSET => throw new NotImplementedException(); @@ -146,6 +155,7 @@ 0x2 1 Y Coordinate of Item public int ENABLE_SACRIFICE_FIX_OFFSET => throw new NotImplementedException(); public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET => throw new NotImplementedException(); + public int ENABLE_WEAPON_OVERFLOW_FIX => throw new NotImplementedException(); public int ENCODED_FLAGS_OFFSET => throw new NotImplementedException(); diff --git a/U4DosRandomizer/Flags.cs b/U4DosRandomizer/Flags.cs index c5ff40a..8abff00 100644 --- a/U4DosRandomizer/Flags.cs +++ b/U4DosRandomizer/Flags.cs @@ -43,6 +43,10 @@ public Flags(int seed, int version) public bool PrincipleItems { get; internal set; } public bool SpoilerLog { get; internal set; } public bool VGAPatch { get; internal set; } + public bool TownSaves { get; internal set; } + public bool DaemonTrigger { get; internal set; } + public bool AwakenUpgrade { get; internal set; } + public bool ShopOverflowFix { get; internal set; } public List SupportedVersions = new List() { 9 }; @@ -83,6 +87,15 @@ public string GetEncoded() mask = SET_MSK(mask, NoRequireFullParty, 3); mask = SET_MSK(mask, SpoilerLog, 4); mask = SET_MSK(mask, PrincipleItems, 5); + mask = SET_MSK(mask, VGAPatch, 6); + mask = SET_MSK(mask, TownSaves, 7); + encoded.Add((byte)mask); + + // Add another one just for a bit of future proofing + mask = 0; + mask = SET_MSK(mask, DaemonTrigger, 0); + mask = SET_MSK(mask, AwakenUpgrade, 1); + mask = SET_MSK(mask, ShopOverflowFix, 2); encoded.Add((byte)mask); // Add another one just for a bit of future proofing @@ -147,13 +160,20 @@ public void DecodeAndSet(string encodedString) NoRequireFullParty = TST_MSK(mask, 3); SpoilerLog = TST_MSK(mask, 4); PrincipleItems = TST_MSK(mask, 5); + VGAPatch = TST_MSK(mask, 6); + TownSaves = TST_MSK(mask, 7); mask = encoded[8]; + DaemonTrigger = TST_MSK(mask, 0); + AwakenUpgrade = TST_MSK(mask, 1); + ShopOverflowFix = TST_MSK(mask, 2); + + mask = encoded[9]; - Overworld = encoded[9]; - QuestItemPercentage = encoded[10]; - KarmaSetPercentage = encoded[11]; - KarmaValue = encoded[12]; + Overworld = encoded[10]; + QuestItemPercentage = encoded[11]; + KarmaSetPercentage = encoded[12]; + KarmaValue = encoded[13]; if (KarmaValue == 0) { KarmaValue = null; @@ -162,10 +182,10 @@ public void DecodeAndSet(string encodedString) { KarmaValue--; } - MonsterDamage = encoded[13]; - WeaponDamage = encoded[14]; + MonsterDamage = encoded[14]; + WeaponDamage = encoded[15]; - var spellRemoveMask = BitConverter.ToInt32(encoded, 15); + var spellRemoveMask = BitConverter.ToInt32(encoded, 16); SpellRemove = ""; for (int offset = 0; offset < 26; offset++) { diff --git a/U4DosRandomizer/IAvatarOffset.cs b/U4DosRandomizer/IAvatarOffset.cs index b570cac..c09390b 100644 --- a/U4DosRandomizer/IAvatarOffset.cs +++ b/U4DosRandomizer/IAvatarOffset.cs @@ -74,13 +74,23 @@ public interface IAvatarOffset int BLINK_DESTINATION_EXCLUSION_X2_OFFSET { get; } int BLINK_DESTINATION_EXCLUSION_Y1_OFFSET { get; } int BLINK_DESTINATION_EXCLUSION_Y2_OFFSET { get; } + int ENABLE_TOWN_SAVE1 { get; } + int ENABLE_TOWN_SAVE2 { get; } + int ENABLE_TOWN_SAVE3 { get; } + int ENABLE_TOWN_SAVE4 { get; } int ENABLE_MIX_QUANTITY_OFFSET { get; } int ENABLE_SLEEP_BACKOFF_OFFSET { get; } + int ENABLE_DAEMON_TRIGGER_FIX { get; } + int ENABLE_MAP_EDGE_FIX1 { get; } + int ENABLE_MAP_EDGE_FIX2 { get; } + int ENABLE_MAP_EDGE_FIX3 { get; } + int ENABLE_AWAKEN_ALL { get; } int ENABLE_ACTIVE_PLAYER_1_OFFSET { get; } int ENABLE_HIT_CHANCE_OFFSET { get; } int ENABLE_DIAGONAL_ATTACK_OFFSET { get; } int ENABLE_SACRIFICE_FIX_OFFSET { get; } int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } + int ENABLE_WEAPON_OVERFLOW_FIX { get; } int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET { get; } int BLINK_DESTINATION2_EXCLUSION_X2_OFFSET { get; } int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } diff --git a/U4DosRandomizer/Program.cs b/U4DosRandomizer/Program.cs index 5322d0e..325e6a1 100644 --- a/U4DosRandomizer/Program.cs +++ b/U4DosRandomizer/Program.cs @@ -149,6 +149,22 @@ static void Main(string[] args) "--principleItems", "Randomize the order of the Principle Items.", CommandOptionType.NoValue); + CommandOption townSavesArg = commandLineApplication.Option( + "--townSaves", + "Enable saving in towns.", + CommandOptionType.NoValue); + CommandOption daemonTriggerArg = commandLineApplication.Option( + "--daemonTrigger", + "Fix daemon spawn in Abyss", + CommandOptionType.NoValue); + CommandOption awakenUpgradeArg = commandLineApplication.Option( + "--awakenUpgrade", + "Awaken spell awakens all characters.", + CommandOptionType.NoValue); + CommandOption shopOverflowArg = commandLineApplication.Option( + "--shopOverflow", + "Don't allow overflow exploit in shops.", + CommandOptionType.NoValue); CommandOption vgaPatchArg = commandLineApplication.Option( "--vgaPatch", "VGA patch compatibility.", @@ -293,8 +309,13 @@ static void Main(string[] args) flags.Sextant = sextantArg.HasValue(); flags.ClothMap = clothMapArg.HasValue(); flags.PrincipleItems = principleItemsArg.HasValue(); + flags.TownSaves = townSavesArg.HasValue(); + flags.DaemonTrigger = daemonTriggerArg.HasValue(); + flags.AwakenUpgrade = awakenUpgradeArg.HasValue(); + flags.ShopOverflowFix = shopOverflowArg.HasValue(); flags.SpoilerLog = spoilerLogArg.HasValue(); flags.VGAPatch = vgaPatchArg.HasValue(); + Randomize(seed, path, flags, encodedArg.Value()); //Console.WriteLine("Seed: " + seed); //var random = new Random(seed); @@ -402,13 +423,16 @@ private static void Randomize(int seed, string path, Flags flags, string encoded { var clothMap = worldMap.ToClothMap(ultimaData, new Random(randomValues[5])); clothMap.SaveAsPng($"clothMap-{seed}.png"); - new Process + if (flags.Overworld == 5) { - StartInfo = new ProcessStartInfo($"clothMap-{seed}.png") + new Process { - UseShellExecute = true - } - }.Start(); + StartInfo = new ProcessStartInfo($"clothMap-{seed}.png") + { + UseShellExecute = true + } + }.Start(); + } } if(flags.RandomizeSpells) From e89e0c30a2dedf6b81d6aa30f76242faa7ccb6ef Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Fri, 16 Jul 2021 22:30:16 -0500 Subject: [PATCH 22/28] Fix town save enable for LCB --- U4DosRandomizer/patches/AVATAR.EXE.octodiff | Bin 94379 -> 94379 bytes u4_decompile/SRC/U4_EXPLO.C | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/U4DosRandomizer/patches/AVATAR.EXE.octodiff b/U4DosRandomizer/patches/AVATAR.EXE.octodiff index 0a8edf1c0ac93167554812763f1526738ddebe6e..456d013608530a80a20f2fe4ca444fe3a206afc6 100644 GIT binary patch delta 68 zcmV-K0K5OI;RUPV1t(8KR8K@jOjJPu1XD;sF%$p*07hp^1sV;Mv2`F_VK~hcpgiT` aRk0`a1OW)M9R+ne0dj+rK(~`X0T?jqO%>Mw delta 68 zcmV-K0K5OI;RUPV1t(8KR8K@jOjJPu1XD;sF%$p*0EaWJotS=QD^k7cyRE(2)d|o2 aiLod31OW%L9R+ne0ds?sK(~`X0T?iFU>V;4 diff --git a/u4_decompile/SRC/U4_EXPLO.C b/u4_decompile/SRC/U4_EXPLO.C index 1aa3f7d..386b937 100644 --- a/u4_decompile/SRC/U4_EXPLO.C +++ b/u4_decompile/SRC/U4_EXPLO.C @@ -37,7 +37,7 @@ unsigned bp04; if(Save(/*D_172B*/"OUTMONST.SAV", sizeof(struct tNPC), &(D_8742._npc)) == -1) exit(3); /*ENABLE_TOWN_SAVE1*/ - if(bp04 == 1 && U4_RND1(7) < 8) { + if(bp04 == 1 && U4_RND1(7) >= 8) { if(Load("LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) exit(3); if(SAVE("LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) From 7c35af38ab3b536d193833fc222aa87b40eb19f9 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Sun, 18 Jul 2021 00:29:42 -0500 Subject: [PATCH 23/28] Save crash fix with updated offsets --- U4DosRandomizer/AvatarOffsetsNew.cs | 97 ++++++++++++-------- U4DosRandomizer/patches/AVATAR.EXE.octodiff | Bin 94379 -> 94379 bytes u4_decompile/SRC/U4_EXPLO.C | 2 +- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index 58f9f52..1853518 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -22,8 +22,7 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) PropertyInfo[] properties = this.GetType().GetInterface("IAvatarOffset").GetProperties(); foreach (PropertyInfo pi in properties) { - if(pi.Name.ToLower().Contains("offset") && !pi.Name.ToLower().Contains("blink") && !pi.Name.ToLower().Contains("enable") && !pi.Name.ToLower().Contains("encoded") && !pi.Name.ToLower().Contains("seed") && !pi.Name.ToLower().Contains("pointer") - && !pi.Name.ToLower().Contains("bell")) + if(!pi.Name.ToLower().Contains("blink") && !pi.Name.ToLower().Contains("enable") && !pi.Name.ToLower().Contains("encoded") && !pi.Name.ToLower().Contains("seed") && !pi.Name.ToLower().Contains("pointers") && !pi.Name.Contains("BELL_REQUIREMENT_OFFSET")) { var newValue = avatarBytes[(int)pi.GetValue(this, null)]; var oldValue = originalAvatarBytes[(int)pi.GetValue(originalOffsets, null)]; @@ -48,27 +47,47 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) throw new Exception($"Offset {pi.Name} appears to be wrong."); } } - else if (pi.Name.Contains("enable")) + else if (pi.Name.ToLower().Contains("enable")) { var newValue = avatarBytes[(int)pi.GetValue(this, null)]; - if (newValue != 0x08) + if (newValue != 0x08 && newValue != 0x09) { throw new Exception($"Offset {pi.Name} appears to be wrong."); } } - else if (pi.Name.Contains("bell")) + else if (pi.Name.Contains("BELL_REQUIREMENT_OFFSET")) { var newValue = avatarBytes[(int)pi.GetValue(this, null)]; - if (newValue != 0x10) + if (newValue != 0x20) { throw new Exception($"Offset {pi.Name} appears to be wrong."); } } + else if(pi.Name.Contains("MANTRA_POINTERS_OFFSET")) + { + var newValue = avatarBytes[(int)pi.GetValue(this, null)-1]; + if (newValue != 0x00) + { + throw new Exception($"Offset {pi.Name} appears to be wrong."); + } + } + else if (pi.Name.Contains("ENCODED_FLAGS_OFFSET") || pi.Name.Contains("SEED_OFFSET")) + { + var newValue = avatarBytes[(int)pi.GetValue(this, null)]; + if (newValue != 0x20) + { + throw new Exception($"Offset {pi.Name} appears to be wrong."); + } + } + else + { + throw new NotImplementedException($"Offset {pi.Name} not being tested."); + } } } public int ABYSS_PARTY_COMPARISON { get; } = 0x34BB; // 34AB - public int LB_PARTY_COMPARISON { get; } = 0xE8D1; // E449 + public int LB_PARTY_COMPARISON { get; } = 0xE8D2; // E449 public int BELL_REQUIREMENT_OFFSET { get; } = 0x4E0; // New public int BOOK_REQUIREMENT_OFFSET { get; } = 0x52A; // 6DB public int CANDLE_REQUIREMENT_OFFSET { get; } = 0x56F; // 720 @@ -110,14 +129,14 @@ 0x2 1 Y Coordinate of Item 0x3 2 ??? (a pointer?) */ - public int MONSTER_DAMAGE_BITSHIFT_OFFSET { get; } = 0x9D03; // 98E6 + public int MONSTER_DAMAGE_BITSHIFT_OFFSET { get; } = 0x9D04; // 98E6 public int WEAPON_DAMAGE_OFFSET { get; } = 0x11C9A; // 11703 - public int MONSTER_SPAWN_TIER_ONE { get; } = 0x5CAE; // 5B68 - public int MONSTER_SPAWN_TIER_TWO { get; } = 0x5CC9; // 5B83 - public int MONSTER_SPAWN_TIER_THREE { get; } = 0x5D01; // 5BBB + public int MONSTER_SPAWN_TIER_ONE { get; } = 0x5CAF; // 5B68 + public int MONSTER_SPAWN_TIER_TWO { get; } = 0x5CCA; // 5B83 + public int MONSTER_SPAWN_TIER_THREE { get; } = 0x5D02; // 5BBB //https://github.com/ergonomy-joe/u4-decompiled/blob/1964651295232b0ca39afafef254541a406eb66b/SRC/U4_COMBC.C#L210 - public int MONSTER_QTY_ONE { get; } = 0x84D8; // 80EF - public int MONSTER_QTY_TWO { get; } = 0x84E9; // 8100 + public int MONSTER_QTY_ONE { get; } = 0x84D9; // 80EF + public int MONSTER_QTY_TWO { get; } = 0x84EA; // 8100 public int LB_TEXT_OFFSET { get; } = 0x15CE7; // 156ca public int LB_HELP_TEXT_OFFSET { get; } = 0x168F2; // 162D4 public int MANTRA_OFFSET { get; } = 0x173F2; //16DD4 @@ -141,8 +160,8 @@ 0x2 1 Y Coordinate of Item public int BALLOON_SPAWN_LOCATION_X_OFFSET { get; } = 0x29C0; //29BE public int BALLOON_SPAWN_LOCATION_Y_OFFSET { get; } = 0x29C5; //29C3 - public int LBC_DUNGEON_EXIT_X_OFFSET { get; } = 0x47EF; //4766 - public int LBC_DUNGEON_EXIT_Y_OFFSET { get; } = 0x47F4; //476B + public int LBC_DUNGEON_EXIT_X_OFFSET { get; } = 0x47F0; //4766 + public int LBC_DUNGEON_EXIT_Y_OFFSET { get; } = 0x47F5; //476B public int ITEM_USE_TRIGGER_BELL_X_OFFSET { get; } = 0x04D1; //693 public int ITEM_USE_TRIGGER_BELL_Y_OFFSET { get; } = 0x04D8; //69A @@ -153,8 +172,8 @@ 0x2 1 Y Coordinate of Item public int ITEM_USE_TRIGGER_SKULL_X_OFFSET { get; } = 0x0632; //7E3 public int ITEM_USE_TRIGGER_SKULL_Y_OFFSET { get; } = 0x0639; //7EA - public int WHIRLPOOL_EXIT_X_OFFSET { get; } = 0x7E15; //7A92 - public int WHIRLPOOL_EXIT_Y_OFFSET { get; } = 0x7E1A; //7A97 + public int WHIRLPOOL_EXIT_X_OFFSET { get; } = 0x7E16; //7A92 + public int WHIRLPOOL_EXIT_Y_OFFSET { get; } = 0x7E1B; //7A97 public int ABYSS_EJECTION_LOCATIONS_X { get; } = 0x103D6; //FEAD // Length 13 - Exit coords for when you fail tests in the Abyss https://github.com/ergonomy-joe/u4-decompiled/blob/c2c2108fa3bb346bcd1d8c207c526f33a4c8f5ef/SRC/U4_END.C#L37 public int ABYSS_EJECTION_LOCATIONS_Y { get; } = 0x103E4; //FEBB @@ -164,55 +183,55 @@ 0x2 1 Y Coordinate of Item public static int RUNE_IMAGE_INDEX2 { get; } = 0x100AE; // FB85 public static int RUNE_IMAGE_INDEX { get; } = 0x17B6F; // 17551 - public int BLINK_CAST_EXCLUSION_X1_OFFSET { get; } = 0x6A9D; // New : C0 + public int BLINK_CAST_EXCLUSION_X1_OFFSET { get; } = 0x6A9E; // New : C0 public int BLINK_CAST_EXCLUSION_X2_OFFSET { get { return BLINK_CAST_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_CAST_EXCLUSION_Y1_OFFSET { get; } = 0x6AB2; // New : C0 + public int BLINK_CAST_EXCLUSION_Y1_OFFSET { get; } = 0x6AB3; // New : C0 public int BLINK_CAST_EXCLUSION_Y2_OFFSET { get { return BLINK_CAST_EXCLUSION_Y1_OFFSET + 4; } } // New - public int BLINK_DESTINATION_EXCLUSION_X1_OFFSET { get; } = 0x6B37; // New : 01 + public int BLINK_DESTINATION_EXCLUSION_X1_OFFSET { get; } = 0x6B38; // New : 01 public int BLINK_DESTINATION_EXCLUSION_X2_OFFSET { get { return BLINK_DESTINATION_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_DESTINATION_EXCLUSION_Y1_OFFSET { get; } = 0x6B56; // New : 01 + public int BLINK_DESTINATION_EXCLUSION_Y1_OFFSET { get; } = 0x6B57; // New : 01 public int BLINK_DESTINATION_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION_EXCLUSION_Y1_OFFSET + 4; } } // New - public int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET { get; } = 0x6B79; // New : 01 + public int BLINK_DESTINATION2_EXCLUSION_X1_OFFSET { get; } = 0x6B7A; // New : 01 public int BLINK_DESTINATION2_EXCLUSION_X2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_X1_OFFSET + 4; } } // New - public int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } = 0x6B9C; // New : 01 + public int BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET { get; } = 0x6B9D; // New : 01 public int BLINK_DESTINATION2_EXCLUSION_Y2_OFFSET { get { return BLINK_DESTINATION2_EXCLUSION_Y1_OFFSET + 4; } } // New public int ENABLE_TOWN_SAVE1 { get; } = 0x405E; // New : 08 - public int ENABLE_TOWN_SAVE2 { get; } = 0x471B; // New : 08 - public int ENABLE_TOWN_SAVE3 { get; } = 0x4815; // New : 08 - public int ENABLE_TOWN_SAVE4 { get; } = 0x44A0; // New : 08 - public int ENABLE_MIX_QUANTITY_OFFSET { get; } = 0x9229; // New : 08 + public int ENABLE_TOWN_SAVE2 { get; } = 0x471C; // New : 08 + public int ENABLE_TOWN_SAVE3 { get; } = 0x4816; // New : 08 + public int ENABLE_TOWN_SAVE4 { get; } = 0x74A1; // New : 08 + public int ENABLE_MIX_QUANTITY_OFFSET { get; } = 0x922A; // New : 08 - public int ENABLE_SLEEP_BACKOFF_OFFSET { get; } = 0xA38C; // New : 08 - public int ENABLE_DAEMON_TRIGGER_FIX { get; } = 0x8006; // New : 08 - public int ENABLE_MAP_EDGE_FIX1 { get; } = 0x56AE; // New : 08 - public int ENABLE_MAP_EDGE_FIX2 { get; } = 0x59D1; // New : 08 - public int ENABLE_MAP_EDGE_FIX3 { get; } = 0x83C0; // New : 08 - public int ENABLE_AWAKEN_ALL { get; } = 0x69C5; // New : 08 + public int ENABLE_SLEEP_BACKOFF_OFFSET { get; } = 0xA38D; // New : 08 + public int ENABLE_DAEMON_TRIGGER_FIX { get; } = 0x8007; // New : 08 + public int ENABLE_MAP_EDGE_FIX1 { get; } = 0x56AF; // New : 08 + public int ENABLE_MAP_EDGE_FIX2 { get; } = 0x59D2; // New : 08 + public int ENABLE_MAP_EDGE_FIX3 { get; } = 0x83C1; // New : 08 + public int ENABLE_AWAKEN_ALL { get; } = 0x69C6; // New : 08 - public int ENABLE_ACTIVE_PLAYER_1_OFFSET { get; } = 0x5F72; // New : 08 + public int ENABLE_ACTIVE_PLAYER_1_OFFSET { get; } = 0x5F73; // New : 08 - public int ENABLE_HIT_CHANCE_OFFSET { get; } = 0x647C; // New : 08 + public int ENABLE_HIT_CHANCE_OFFSET { get; } = 0x647D; // New : 08 - public int ENABLE_DIAGONAL_ATTACK_OFFSET { get; } = 0x6630; // New : 08 + public int ENABLE_DIAGONAL_ATTACK_OFFSET { get; } = 0x6631; // New : 08 - public int ENABLE_SACRIFICE_FIX_OFFSET { get; } = 0xAA5D; // New : 08 + public int ENABLE_SACRIFICE_FIX_OFFSET { get; } = 0xAA5E; // New : 08 - public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } = 0x4FA; // New : E8 + public int ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET { get; } = 0x4E9; // New : E8 - public int ENABLE_WEAPON_OVERFLOW_FIX { get; } = 0xD377; // New 08 + public int ENABLE_WEAPON_OVERFLOW_FIX { get; } = 0xD378; // New 08 public int ENCODED_FLAGS_OFFSET { get; } = 0xFE43; // New : 20 public int SEED_OFFSET { get; } = 0xFE23; // New : 20 diff --git a/U4DosRandomizer/patches/AVATAR.EXE.octodiff b/U4DosRandomizer/patches/AVATAR.EXE.octodiff index 456d013608530a80a20f2fe4ca444fe3a206afc6..2bc58750a219944473347e06d135eebae7b3047f 100644 GIT binary patch delta 16752 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 delta 16844 zcmZ{M2V9g#)A+M+6hW~BMG)y7L_j)-D0reEo(-&E!QO!bHAo36aEFaW#ExJLwur&9 z8Wn6{EHS7_OtWj|JXDex+l$ zWGDS-(T_M#_deFf=YK+G<68Mpkkj#f{K-XH*vH&xHiv@D0k+d4eU4{+J3@7dK$45< z9D&jCDn`K8UG)tCGbhy{0xzbh_7O0eqADX`o~qhLARs|iOyCz+)p`PB+*J7l5)xEj z5Ev_0We{+gs7fQy%T=|M!0(4u^YJrYl|-ORqAG#Fft9KW1h#EdjUf=JR>crl)_bB# zN}wrG6;5EJvnrUt5*L*(0lVt|ScdBujQm~wkAI>LnNmGANMaz_nE^fM z&NAUfl+^{f(b*gc_{se^}z*j%0 zU8+cVkfJqjoRu6VIX!s6RJc2a(aBwfOh`t-F7~uLHd}vX3YUR(k zseC&1;&^3aZlg|o9P8R!28Q3|hM{b^0q?1|Tpxzf<3pB(thv&r+iV+Heg%fNsP+iV z78w>?f!r2VvB2E0k`qW>kaki*TX_lNo}ApIag38329?vPmtwn+9EY0CA8NtN2fl20J)|f$Noil z(j|D`z3S*AuGSIoi4IoMF#t6RZiJ$o- zpLSLCosb(Aj)Q8%1|ZQN^yV;Yud^4y=&EWnVz@`?!{Do`e1VNbe8ojB#8Q4gJ1j_{ zBX?kN2wYFCqU^2bUj)q$qGoz*g}K^><#tr>DV-K&Nn+@#C_B=bmPO6^%=l6qlwHUT zgF^Hu)*W?vPc4RfkTN=K_-L|{ZXNEJHSS`){`Eq0p9rs(Ol7zQ^>2YiiQ9^G~f<$0dNK>knpx-WGOq+z`h+QdS zeVGKsXK@LBB33IwPhh8zCSEJSuw6p;HVNkt8>GeRh$6Uzf6j9awG#9Nb^&R6YH5tx zCEOHg@Ga^Q`?gkmM@dw>h@*&xLIZpaE{I)2qT98~Dc$&raLgL&YdPAm4gEc$k0H7T zN8hoAN-Bx=CTY|^+Q#;b*z@sQ1!C9zP(73LjDJ;}*BpOh4SqB|x*svXPaAqU+MiU> z=4czYH=;(zFMQ&Psuj8ZsMQ?D9+uRo4VVo|xk05d(S}cJn4yIXKBHS>`WRlQVcoIO zM9*MjcMUVc#tnKu#=$V9hV{k99%?)?BxKe(_c!R8%I|MKP?!WO++M6XpV~>WdZ9(B z4616Rxh;kn4>b6e*s<~(hZ$%7Ao9>l2}LgH6kh-*~TI4-Z@SYj;$DM{UEk%uoZ!=3v_gBZ=WG& zxhijwO3+E|-l|I?_TefbI6F!0(h8r2@a}YbY^YnvIX zeWh+{PL3v9SY?cXh}#ofMrp4x@nJoWT&yH=T~(nF2YWfj7%|)F{_!)+ z|5C97HZs_HT(R1Ma@py%GEg3e0n{N*L2lC{apt{Fombp-(;U^i{a82QgCg(r`g~~% zF3$JjVn`fyk9Q(}(=qXb$T!tR@%Dr;dSZgF#lxco(&q3~H>Qsxm{uq5&&`Ib3?Q6J zCdx=99X~P5YTmOdz4AMS)$FIB|!Xrn0l5!<8~TDk4_v#A}E-QFCP+Y5Z9S>wIZ5jHGWTM;nr}l?JK0 zs^94DDYiQBGhH-gn?dNA0_kh;rzTUEks&mD>NN6(KAbv&T%{ff_Go!of)n`TZi`(D$uj}<23v~pzaG&oH%p8sN{i)nb z5~w|m3hM#T`w8Q^KRzJ3PQc}Q{W3$12ApYR;=pNTmFg<^zL)wS6#b>%2kX93@5#w* z7Chv7aPXXZGnAjgy`fX`cx6k@pIwEZuuw(v@O48q73T_B4eEw`^ipovxk4eMv#8~{ zLcQ#KwJy7f$nOvGKqb+xN99321z=_kj-aT-)asto7L%;x!>FGw)cT7+FKo$;l~$(< z>+-4!1@$Bm8p~-+v%{_wj+S?U^(QMys=mhLbfJ1kyH&Dlit@+G-C^0uN(0>6+Kg3~ zSCl_Ylo7w5OU*~A`FZn|u=Jp~ml}msx9zu$M)7gVG(*Me>_YCoD~`!v-F|Uld~qQA zOm<;HYCO&;m(@!PQ)1a8e6=NX;0(t;>%U@ZYz*12tjBO)G(KNUKkmnAv}(pEqM$cs z*chIxWHz=kI7$DVv6M`rvu9@DC_kR**nQTwXb-KUGB>24)I3Q_TQI0fhc$jlOTL`(5(p&vq?kYoj- zS%A|k`WJELxYD7s;z$GCF{?j$K(EiTBU$v-EPGsfKbsvxp3rHtO?xN~tGlvT+fM<~ zCAxO@D3j`+TlK?z6_oVx>`A>A?}ba3RL2E2r33X_I(Cjd$*1XaY=|i>ofF_xUV-Cg z%MKODm>%*TDrZ%#k9*45vDU{D`tO`UCg~Neofsma2OTokrH}4O?!Rxp-4j`?Hw}Hd z6JlPS;IPMZ&0HrPp@JTs+m}3~*XCN03-tM1PYmwO=M5rWbmBZaTuU`#O=w^ z@Hc-cE};qE<=pHhsNG>J0x{BffRTpsL(WYbL2ZV?d(AvQlTk;+Fer-sfMfBV>df~i zMl@)?FZq!!o<9_Wx?}Sld!=%B>|GY5K&!J_)J%h#CDK>(XAN3Vi>QlbfrwI=oGEmB z;eKAXPU{ui`+q%zXls#EVRBZBuK$GomeK`wq?De(PdWW%L4S)oXD}@7+nkWt?xi|$ z>>ld&3$#HyN&w_72sui-YI8aQ5jz%sX|@I7r-&mNVB{PA?jj?_d39 ziG=6~<+OR}bn=WQEOWCPUdo4UlyI)Az~_jN8j*cwX<=HnqX(AtF}!$P zbizIK#(Qfy)w&O~PD^!@+HQfJ|ERlYahfet?BM&- zHmk9X$R}*k_|MPR_|MH3CpwQ1*%nrYm}ezof|Y6usq}|b3)Ax@sv`ocwv(|pn7k$B zWAZkPwxrq2*-N#gC#aRFeDkxQg*%!wryrFv46T*?aM5X{+AsEQXI|nNm|_Z)&u_{Pt41!Wz&ldkHt0G_m0x?}gH#cVz@%`3)i zU6X1D?`TZAqhW9{)2cbW2)7TY%PjzDq=Xt0#+MlKA!@^RPA7S4hsz(v~)*jc_5BT?vN6-6LINJZQN!%Gr zzeGn+HHw*Aw^Wh2hy0#cXj(=8S}}rbq@gR_`xT#ST_|}x^nNe$8L_VHj7dJ_88CK2q|RS=<9H!%|j8BEzIu66Ci)mq|1n?!IM@y<=m z4n>q~f}bl}t;H;n+lsFL+-$!7MrMNz%?2Dw0YmlaNIG#7Y^ziz=(h$sk2ip_Qrxh& zS8!+3*E$>S*xD)Hg-KDu*$qkzlhtNyJT|H}uvz%^u7nRCE*Mt?SWUZT^z{udQNDxe zmGI&^4A|6hh482})*xY?ko#(IYB%M5zC7F#ZKI*nGM0M$wjOf7YM(E;JYHbSv5SlA z*&6&ZZtLl)09$A?_B3`g_LTY+2-iU>j)A0gEgJNd*i%8ro-T+z^`IkHB}*FDK{36! zYLLN)^L)C^qMb5b1FxR%7~>WSz)sic2P(4a^n(50Wt zzZ@45OA~S&i3?qgpE~qFjx+hS`c{rVA+@wqZV*{ZBXav=8jzA}OU&rz+(~2{ZOVCw1ukSjXo+gV(mI%Ajk*8Tx`hVpvy<)T}7UQBUi_t zzFOVeK9nQ&gen>yU{beM*`#by)-}8f(GOLmJTAy=Rwn>vE^BPe-_uHKdH1qpC1)*d z=3)d#wGlj|GuL=`>sNs9YEZX^ho_z6VK?2oCdgfl4<-|A(+yYYr}m1S)CmgsL+*nW%W)nc)Ge?KS4nMJc4c;xPX99bP@H+aeV7~L@oDSu{*c?&qMWyHv_4kZKsx==>bl@mP2WT?M{ z?C0t-5dKnche4OsB@nz;B+sQtuFey47u+kRYaqJfqmmFT$Q8O64%;EV&tB@e?qrrS zw`O6!`x|vY_9~~bm{Y_mF>TPV8|pMnZG#}0+#*gCxji=yrj>}n%lJ(wJr2f{0lFw`WLly7~zEWxw^L3WN;#DXV_lgWON~)n&Mtp7?`JYN8S4-l+s!K`iiua;e z%|;a427j{|!El^@u|Bxls|+}p2`gIAT&C(y@Fl&zew>*yqihOyOROruF%6>h;KUBK z6*VJelQ_k4bC!#U1E24SQ|Ni)a2c$EsA3!r$Z2K7c#^F{lDyB$l9Ucj zp*E?KP%pWKMn6u$N)W!Jo%MPKbm6RrJFwy+x(|s)e2zOtdC7X*WXh-I!|i+pP1)#y znv`ucvwpo&yMuMn##s6=K1bD`w3RsL)1NllVruhlqityADzv+#Dp0NCR-3;XbG_B` zm9Z=SgrE%eJNA;Ya*sk;(S%h3g;GyIBjO>A3`Xa12Yf}xZ;Hm#gFTxp`se4NBc~&3 z+VVIy6Tc@c=i$^#<=y(c<@qy(*cG)9pUYmO$jd7rhd$rrM82Tii+Yd#Vg)mGkulsj z*(Bui%`T8Oi2-W}$z9wuSeekow=`cHn79H+5vbRSDc)zy&P4{&6{62ot-*?iS`X(A z5x|_TED9sX=&2$<`?JecxdMwt%If9y(!X)!5}Fj!#=yL_E^-^T2;tjlcj`m>&`25@ z(qj|sIu1`(wC`A~3@LgpZ%@3grtO)V@7N?%#3))v67ye4!!szL-%@MChIG++3h5*2 z(q&J&x;w1Wu`vQ)K(qd=m#sZ<(>8nQ5fq-Dq2O)6&Vo$gId@aWQ-RX zuizLKbz}^0r4MYS4~MQTED7nIIeix63^P74@Oq~9Wer<3GlcseSsF6DmAC2c(~(}% zN`F_bwWb7)d}IowuWzTJvW@mHaUsj-gpxtd zrgF7Kz5Wjch5|fqX1^kjPP@2)DXoUt(?pk)xb(f8%4wT8?e=E&9BHdl+f;o?b+?3) zg*1GN#o*DY%6r_IOKm`!$_(9PFi50JLJd|Xx8+S@wrPn-yHq}jb<#VFhZYzd%%|J8 zcw=^YV~e$Qr*xdR79h*P81}Q)sm5zJW8+|GGVVCWrA`BT1uF zUGaOnck_OD2So18&pFKGZtyT08SGgZb{<9-mu@$SSOy8Hs#}7X5Zss&N%fE0x)F?Co^225WVcG2#$rgZ!;cqOcF6JE_op3R77OwqYY#I(D^2}E+~34F zZQ&kppf)@E;+b05PRB%(JWZND4=6%Yag{fKw@ch>)h=RAr;pV&^tZ+A7QUFxVlgb^ zo9>Sbp>-> z0E^RA>A3t3!dIGC3o2T+C$#VS1!7{SSk>yPe6(RqI(mx-MAP?stPIC$DMnH2a)+Ry zJH&#MJr}C&gclEGXvb%1Sim-e`)SH6qA?}BpqiN2EE~58Ue;1z5kLZ&^m&Cn!K(0HOA=1q_s%0nsyFX7C4IN0ppTKm z+}$?t$2W)2-88Yys_$ChBCY$<7TprQbRYq=%RYPi;5q78F%8Tv{9PUik`$Z;1L0#b zdb#nNzw&3lgTLt5eevk02lrK(^jO}(@W0V{Us+k5S%&O^c}okE&(-CX6%sK{X-G#p z^yVNuFvF0s{GIkep>|d=*zEM2yPUWu4DuqTFd!1D3-#OlMb-J%74ti@;vvQ|5GW7luV>ZsXd_<$Ed%@XAM8 zC#Ks^2Gggj=U{Qw73&mWI#c5xRSdDynH^$=(OCx^B##oY#=Gu-8L6jV9;h<4K%?n1 z8>|5RU1)`AfW>-nr1K62Pd1#!6MK#Sh+=ry3`L8uxX}l8Ef)ngCbGFG@M)s>*7p)& zE$;R$g23bmy_vX9`cfvQd-vwS!sXeSF9i&zbx7H3jQ23#l+u=iF&5Jk*?Od&l!zW% zm$#B?RAsp8p|(*p>5v~eOSc^w)4e7EO9!0$K?}Qs)JN#YLy2S*oqE`=uSbG*nbwET zGgbEmmgXs*nTutMuj!7%?&xe+4qM`TK0PeO;~kH$3rGe%@$~|%DBB&0CsuUjkqGiD zJ$GaPUZMH>h&@?AdsW$>Hw08!6E_-PWl!|!=lJ=E?ymC2v&x1ld&9!y+)GA^)wQ&5 zl{sfPYE7c4|51D5Oef)|F3mi;kW8#rAJrjb5PkVg6rP&|R1d+UqLtNy@bu+$wG6XO z<6}$kg2(5_8VNC{b58_diMZ^9H91dfPgs$1dLN&^pc?#~L9I_(;{nVd{IsKqCqv0o zy5nR(*5L)B8h1S1o`fsk@sU!jK7$QeJWCX0@vu&dzl)&%4ZZjiI_iJJ$7=D=&K|E= z&1K2(`;I5NlBbrS@&6()(c+u_FZ|2-sDDBtUHr8ftz!1%IlaRMl0*3E(>a%Sq{#aM z`&mq7r-ouiUUDiNcb%V4#TaZu#%{=%c-qaV)Dy{yk!%`GIPFW^tLf=+I#^PMGdF!s z&ldNSBhztB5TCwmf7;HUa7TfX+4#xuG=H&#=dh}?fxQ$XnR|b%LW~oq7S>u0;Brwz z1I|sxfuiRe$ZN{ZIr!d;`LE#N1hSloVb}3X($2|{^RH33H5#$s5V3=Hs|h6-ht^Cd zAL)^rP+4uXdQcTnm`qS)tGeHMV2D8<8{#E{%ILNg;+-LEk7lD0Rvg_P6b~Q4LmeK) zT^ioHFtJHUvW$k*dZMe$ueBgR*VKj$m)9%PT8`@6ex}U)aQn}7Lv69{$|Gh?+Pig; zHfY_MIQQ2LwJ(tJvvCB!Sr>_g`*;p+r^Cvvly*MvOS;p+=le|kcLwK)w8NyKl|+-) z1oyR2l=M;yeXU7*3Ey#Od;1NX`qX}>N&6f2e`+Ir6KtiY&U>59(aJ()U-M-SmDQxZ zhS8K<=s7Y(i^G1J+HpGVAMXiyx3H(GTca)b}C|arsthG>-+o*+N(AET<{!3yL zyier%ayvY4m-rkWb12ib;O0VM&*8Qfz}qP1IYtK?E=3H?(lUQiT{OWw5y}U)<1mc< zBmqtN8X{=d%RLwM`vk>dc@2HFyq|^zdw&N8pQy0?8r~*|N~0NCUk!O1;UR}=Ujp@L zgoaOT?6DEf(@mG{f_G_ov4=ODcHK}Le5W^%*G7z9B?8hu0qjJ;Ec)WI??5jtyXfa_ ze)AeEL?|DDj;}0f6M>G))qYJA>iU@7o!VycR^{=P8u1Rv#=4%kl+ID$t-K{$NdKqo1_s7k6zTU^d$ z_~eKiFSdKzV_U)nYcOkhBg0ixS2aQdedwVp4tQ+RaAgLmroP{uAk9?$U5;e_D2S&^ zulkwl56%rcBi5;7hN(@My*FNvqNlDp;-S|4tL|QV!uib_esiXWz&sGSu^nJ6FfRmT zg~QxfjGN!X##px}w86}j#$L0w`yv+7upJ_8k>hPy39LpMOasw`@N_J0C(wy*xORn% zp%bo;#)S63bxSM`*I$oCEqmQ?>RuSqc9_=5fm3gzBX4+5y*3VGYWLcTuhv(5xt`6& z-s8u^`WUROuoq1-cBxRtQk8gG6OVSt4V$FYk?X?oc&Lft4I-Cl^vl+RY5XOt<$_ao z&1zwA@>20zmOd9c)8B45TMzrM9u|A6R%lq7w<<-$vaz>W)b@KTjBCQbcgRW#Zqx9g z9ctLt-O4!j(!0Y6;lOsX(^|4nJe`~lesQ0!h;Bt`C=YXNkxXO9OAZNXR%G@uZu6Sq%drd}3SV-e?+!Ng95yHRa3H!xhlQzm&SA5NHh9Z*o{$XBcw-8mb2Gbz*RlI()?uW$zlgBC(nj0STeOYq*nWoA# z9Cil7(6JciO0XdOdkZTXgvnMgd=mw`qg2;h*d=VQq&^Lm;Fo0)thAaTUa!d? z0$qaPuQBkS4EAR@9{sjsHV%P*g4ipBH3q?pq50Aep%YR1e!{v9mciX1W{F=7L2T(@ zZ5>dGO6P{7-{mfD9=t+Vl}*?eNO2@cR915mFOO9Ou`LL~DCU;Eb3`!PiH&7Je8R(T zL&abzOIOvEuo{F<48jBi&rfOhTjqV?f_>|y6Mh!`ZxH(hDeQwpe^^I1-ZCZM(Jya} z7`Z)wr>A_~*%ZKI9dRiQ5L26XX?pC%VD(6Lp!HxtCen(X4;6{U$KU{^^qrXZNNMP8 zN9l+_<~l?M5rGgHDVhM+kc1Yn7!CX6+%P}lwP&p*(O!K6SqKvM3hY>}iI3wK&u)*( zQU)uf60+u2LGIaG1vAt1>+x}>03Xvp+AiefFjybJt`5U8bATvBTi@XKbiqc(5~48R z3Sf)yYfgZ8>Y(kNJ43S~`@=A|C*rZ?(LnLe-hse2w4(Hb=P)-->p7!G082qT76!tN zQ5qbu%w|c(NtPZZV?!`gABCuE18LJ;M|$OsDcMB-xZ|278>LM6z}ds2V5>h29>tEJ z5*z$QqrD%Z9XxZK7@gP+M5Otvdx{HN{}DLx)R^yn;B#|S3%iTh3H~r~NGT@w11Ivl z?6(&9EA~??j8~G?NHoA7Ur?jrYl4|T*ZlaI@tx3C?}B5r;zzH5yMC>%h4)LZ`!VTo zEK~c53iWSQs1GV+#AYGlke|wph#DnPqn~(Yz$TICV&-K07d6rVeFQ z!`1IF6(s^YhR8r|FUq_gQCk~6G~Dgrh~URABSo(cdKme!TL{wi0|`C!QI((AXD*1&iI3=<$tmzJW)fNte-{G-2e4ma z@St%3AFejv!~>wHkutCyz~b@CV!;3Jn39o3wW)5c&NOpsl;`p);aN_ z?r%Pj8{OuWry)I>%^az9%wg!5ne^4&U=m5)esRsxjc)bH;E@pH1FuK0o!I{nAJGL4 zg=u}V6Z;l{{e0SeaAOOrLr5PVunha;gX)(5a=>4Z;=OkV2W-74`?OV+C{)FGTVR_% zuB3nb;w9bX-Rh6{7De97JQnYfd5g;YJ5Z~P5eq~hZk~OKb_tiZ1m#^QNYP^vvFc|m z36T@&*k2tDTfA8^HauwdulyGjJAbvXs_|x<5%j|AQzs9-SUG}z^@88%kH02mMGb)B zrK}D?bG@=NKTO2AwV(wbV)0={hZod={=;GZQmq@hk8E|rUy#qst8K7f#(=#SQz6W< z9fl6j)r&PE%+L#L!th#a=|CGHbx@XcpplRoNH_d!Ckgb174+V3W;)ZO==VQcXT?Wo z-Ei$k5EjAWD2VU|kEpg@P-1F-W0~w_<)Q$>+3q%l>VDR*neA{@~Qg)(P3@=HDF*uXwW{8Q$Qe=YO}&su~6> zm#~u2xD$J}sqtY9eB;TkBJ5yC*e*|Y6JcB0VQ;AmimWtO?W$pq63*lCP;PW5CywjTwV}>It5$ zV!MaN;&xjmu$c(&>8UEgb1#D*Z^Rw_V`SFhevs`2lNZA%X$L*F z^kWCcsEjoA(hp|})ZgIOxdQb;{HiTb?}cenXq*o|{h?1so|*mFIqYyszfbc)hbhP7 z(Pck8R75w{9x7H{DNk0GTds#EdvTwptM2vk=p2lpR9ST?{+y@mSSkLlhevEYxcw&x z5qKdX3c1x5d>_!IHTNvLZ}8+-I0D53N`7(j7;U`g9^ny;6IN07!(KrDfyRp3!WbnHiJA_{jKH@DP z16G5LD{jiVPZrQ&!bG&N8yt`I7blgxD=zqApp(`QM@iik_mWst<})N)@8(|1*LU%< z8-zyiWF80oHW*Lyus8H}xbIgPi@`a>FVMl2Y8+LTp*P!LUGa zg7V?j3qUq_8-T;63)X?G3@NaP_0W!NrMDh>8Xa_12Qq_6GAO4;kG$}DYse#aqoJ;9 zKc+xnC|&xf-^3fAOd(-!5d6^vT71PJk-LgVM7*a;XXZBjAJs0LDK`FkD))O!K zp$cl#?9Ap^xk)>DsWXnun@3jTx45(!|Lz1(xPZ^#wlG1f3C6gvrpek_AA!0^=)A{vCfC9{NWveTJhsd_?h3m)LZ3M^>nWJCIJXbBB#u=k zV*23R#ye#i)H<`%2s_mZQ|8T`)^^E|hsFzC*msED<}7YI5?}4MV~Q(|kvJ72LUM3pgvK%^jtmc4jsR2PdQ^c!iAz zkwaXVCw_&vK*k{V+D{JGJ2&h^sjj>)%o^0DzHAyCc4F&M!agUiLyQB_=$|NM=Mb{l zNz_>5qt&<@YW#<&aTxV_>SXEeiql^gm(54G9!|&5$Z4JQxi(Q6N0XlpGW+1DS|?~? zKd8^LgNVn=jXbLuPp>?6=w9QCNb?^D{GrjY zXZB861J&_3&!nk6@N+Q!M2s(wIe~nKtWn@@ikI7*@VeT^XT2@QJFyeUy1@Z9dTA%D zE>F3CLfGfj`%i0+$qsED*Cj!$1DiS%x5swa4@nU0z@{N=fCFA_%lOkGv}Y?)nRh0s z<%3}@Ovcp$_Ew#ywpfOj-75C+=f z{Km~UNZOpDtBTMtE0i+Nx@|mi8++u2Md8c)*Xu_qFy#qG^ayKS*2sbgYvzFtT4BTH zA=J+r`Zu$E_~dTQ&U}vBjkPKpO;?m3DG#aB$6ug`#Sjx~b_jzfLSf#K_Rc0RJq{&2lE#)>mgR^MwWu)L83I0rd_Futl4e^I?((VgF1id zk9z{1^)=#IBfb5?)8;^59@r4PPs)Fsthz_oht)E+0$GMtgtAVoB5$z z#$&kW#w2U;tt{Jxf9r%=UwxGcAXbI&y5}?9rUtAGEnN-0E!8rXiQ>Cjwnm$Hkww=M&iL}*bBM?CC&hVq z&=T_h;GQcippCD}@oaHJQzY@K zzSDG4zgqG3%N~6+QUCp~a>U~3kI~gJ17q3A5k};Q!GOGZmh+D;Xj)LZ=*8myERI`J zx@6yynk6@u{Ix{0r1#R8rL&f1F1@tWWLe&_E6aXa7MMIX`R9`!J;)A&tO6<|eTg5Q zn`@|W!vjC6e)yLP{SG@83)6m%D;6&Qn^!D6SW{mtgv*4@I{Nxvo4fTQ(>Ck$(%raO zx0gh}L}J)=e2Jc+{@xOObF#O@z{+ZGiD4IPcCy4LBb~l`OGtOay(L}x;uHQC3W8uX zBza!aoLM&GlD7=AAg}vQuN>u`T{+HuYvly@gO!3X6#vFnCc2-kOmZ(jIiU~Pqx0F# fpWgj?>)HFKJsP$=a=t(J_Xod)o$PEyc8~dgFZi@R diff --git a/u4_decompile/SRC/U4_EXPLO.C b/u4_decompile/SRC/U4_EXPLO.C index 386b937..d9af14d 100644 --- a/u4_decompile/SRC/U4_EXPLO.C +++ b/u4_decompile/SRC/U4_EXPLO.C @@ -40,7 +40,7 @@ unsigned bp04; if(bp04 == 1 && U4_RND1(7) >= 8) { if(Load("LCB_2.ULT", sizeof(struct t_500), &D_8742) == -1) exit(3); - if(SAVE("LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) + if(Save("LCB_2.SAV", sizeof(struct t_500), &D_8742) == -1) exit(3); } if(Load(D_0824[bp04 - 0x01], sizeof(struct t_500), &D_8742) == -1) From 39a64a9f3c7da5744d5281be11e9660f9c1d6c48 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Sun, 18 Jul 2021 23:37:51 -0500 Subject: [PATCH 24/28] Fix Bell so it is usable --- U4DosRandomizer/Avatar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/U4DosRandomizer/Avatar.cs b/U4DosRandomizer/Avatar.cs index 526a172..20f6bbb 100644 --- a/U4DosRandomizer/Avatar.cs +++ b/U4DosRandomizer/Avatar.cs @@ -437,7 +437,7 @@ public void Update(UltimaData data, Flags flags) } } - if (data.PrincipleItemRequirements[0] != 13) + if (data.PrincipleItemRequirements[0] != 32) { avatarBytes[AvatarOffset.BELL_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[0]; avatarBytes[AvatarOffset.BOOK_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[1]; From 935b40c642060e09435334916df540357b56b57b Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Mon, 19 Jul 2021 23:51:18 -0500 Subject: [PATCH 25/28] Fix PrincipleItems (stop trying to use bytes and just use the ushort) --- U4DosRandomizer/Avatar.cs | 14 +++++++------- U4DosRandomizer/AvatarOffsetsNew.cs | 2 +- U4DosRandomizer/Program.cs | 6 ++++-- U4DosRandomizer/UltimaData.cs | 4 ++-- U4DosRandomizer/patches/AVATAR.EXE.octodiff | Bin 94379 -> 94379 bytes u4_decompile/SRC/U4_USE.C | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/U4DosRandomizer/Avatar.cs b/U4DosRandomizer/Avatar.cs index 20f6bbb..e9fb187 100644 --- a/U4DosRandomizer/Avatar.cs +++ b/U4DosRandomizer/Avatar.cs @@ -200,9 +200,9 @@ public void Load(string path, UltimaData data, IWorldMap worldMap, Flags flags) textOffset++; } - data.PrincipleItemRequirements.Add(avatarBytes[AvatarOffset.BELL_REQUIREMENT_OFFSET]); - data.PrincipleItemRequirements.Add(avatarBytes[AvatarOffset.BOOK_REQUIREMENT_OFFSET]); - data.PrincipleItemRequirements.Add(avatarBytes[AvatarOffset.CANDLE_REQUIREMENT_OFFSET]); + data.PrincipleItemRequirements.Add(BitConverter.ToUInt16(avatarBytes, AvatarOffset.BELL_REQUIREMENT_OFFSET-1)); + data.PrincipleItemRequirements.Add(BitConverter.ToUInt16(avatarBytes, AvatarOffset.BOOK_REQUIREMENT_OFFSET-1)); + data.PrincipleItemRequirements.Add(BitConverter.ToUInt16(avatarBytes, AvatarOffset.CANDLE_REQUIREMENT_OFFSET-1)); var wordOfPassageTextBytes = new List(); @@ -437,11 +437,11 @@ public void Update(UltimaData data, Flags flags) } } - if (data.PrincipleItemRequirements[0] != 32) + if (data.PrincipleItemRequirements[0] != 1024) { - avatarBytes[AvatarOffset.BELL_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[0]; - avatarBytes[AvatarOffset.BOOK_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[1]; - avatarBytes[AvatarOffset.CANDLE_REQUIREMENT_OFFSET] = data.PrincipleItemRequirements[2]; + avatarBytes.OverwriteBytes((ushort)data.PrincipleItemRequirements[0], AvatarOffset.BELL_REQUIREMENT_OFFSET-1); + avatarBytes.OverwriteBytes((ushort)data.PrincipleItemRequirements[1], AvatarOffset.BOOK_REQUIREMENT_OFFSET-1); + avatarBytes.OverwriteBytes((ushort)data.PrincipleItemRequirements[2], AvatarOffset.CANDLE_REQUIREMENT_OFFSET-1); avatarBytes[AvatarOffset.ENABLE_PRINCIPLE_ITEM_REORDER_OFFSET] = (byte)0x0; } diff --git a/U4DosRandomizer/AvatarOffsetsNew.cs b/U4DosRandomizer/AvatarOffsetsNew.cs index 1853518..886b813 100644 --- a/U4DosRandomizer/AvatarOffsetsNew.cs +++ b/U4DosRandomizer/AvatarOffsetsNew.cs @@ -58,7 +58,7 @@ public AvatarOffsetsNew(byte[] avatarBytes, string originalFile) else if (pi.Name.Contains("BELL_REQUIREMENT_OFFSET")) { var newValue = avatarBytes[(int)pi.GetValue(this, null)]; - if (newValue != 0x20) + if (newValue != 0x04) { throw new Exception($"Offset {pi.Name} appears to be wrong."); } diff --git a/U4DosRandomizer/Program.cs b/U4DosRandomizer/Program.cs index 325e6a1..3f1d4e6 100644 --- a/U4DosRandomizer/Program.cs +++ b/U4DosRandomizer/Program.cs @@ -497,14 +497,16 @@ private static void Randomize(int seed, string path, Flags flags, string encoded if(flags.PrincipleItems) { - var values = new List> { new Tuple(0, 0x10), new Tuple(1,0x08), new Tuple(2, 0x04) }; + //https://www.youtube.com/watch?v=GhnCj7Fvqt0 + var values = new List> { new Tuple(0, ultimaData.PrincipleItemRequirements[1]), new Tuple(1, ultimaData.PrincipleItemRequirements[2]), new Tuple(2, ultimaData.PrincipleItemRequirements[0]) }; values.Shuffle(random); for(int i = 0; i < values.Count(); i++) { ultimaData.PrincipleItemRequirements[values[i].Item1] = values[(i+1) % values.Count()].Item2; } - ultimaData.PrincipleItemRequirements[values[0].Item1] = (byte)(4 - values[0].Item1); + // Make the dependency for the first item be owning itself instead of one of the other items being used so there is an item you can start with + ultimaData.PrincipleItemRequirements[values[0].Item1] = 1 << (4 - values[0].Item1); } diff --git a/U4DosRandomizer/UltimaData.cs b/U4DosRandomizer/UltimaData.cs index 7c71f50..04eb54e 100644 --- a/U4DosRandomizer/UltimaData.cs +++ b/U4DosRandomizer/UltimaData.cs @@ -108,7 +108,7 @@ public void SetItems(List value) public List LBText { get; internal set; } public List LBHelpText { get; internal set; } public List Mantras { get; internal set; } - public List PrincipleItemRequirements { get; internal set; } + public List PrincipleItemRequirements { get; internal set; } public string WordOfPassage { get; internal set; } public List StartingCharacters { get; internal set; } public byte DaemonSpawnX1 { get; internal set; } @@ -169,7 +169,7 @@ public UltimaData() LBText = new List(); LBHelpText = new List(); Mantras = new List(); - PrincipleItemRequirements = new List(); + PrincipleItemRequirements = new List(); PirateCove = new List(); AbyssEjectionLocations = new List(); ShopLocations = new List>(); diff --git a/U4DosRandomizer/patches/AVATAR.EXE.octodiff b/U4DosRandomizer/patches/AVATAR.EXE.octodiff index 2bc58750a219944473347e06d135eebae7b3047f..a236bf62b4af11a50854ca940de1df03dc4912a7 100644 GIT binary patch delta 61 zcmV-D0K)&P;RUPV1t(8KR8K@jOjJPu1XD;sF%$p*0By`3U5mv_O*#L3+6Q2M8 diff --git a/u4_decompile/SRC/U4_USE.C b/u4_decompile/SRC/U4_USE.C index 8e40a8a..ecfe850 100644 --- a/u4_decompile/SRC/U4_USE.C +++ b/u4_decompile/SRC/U4_USE.C @@ -165,7 +165,7 @@ C_0487() { } /*ENABLE_BELL_REQUIREMENT*/ if(Party._loc != 0 || Party._x != 0xe9 || Party._y != 0xe9 || - (!TST_MSK(Party.mItems, 13) && U4_RND1(7) >= 8) + (!TST_MSK(Party.mItems, 10) && U4_RND1(7) >= 8) ) { u4_puts(D_00EE); return; From 0c64fb238d326152608180db2cfb6b29c1ab0455 Mon Sep 17 00:00:00 2001 From: fenyx4 Date: Tue, 20 Jul 2021 21:37:35 -0500 Subject: [PATCH 26/28] Update README.md --- README.md | 61 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index c7681a4..ddecd4a 100644 --- a/README.md +++ b/README.md @@ -11,27 +11,45 @@ Requires Ultima IV which is available for free at https://www.gog.com/game/ultim ``` Options: - -s |--s The seed for the randomizer. Same seed will produce the same map. Defaults to random value. - -p |--p Path to Ultima 4 installation. Leaving blank will assume it is the working directory. - -r |--r Restore original Ultima 4 files. - --miniMap Output a minimap of the overworld. - -o |--overworld Sets randomization level for Overworld map. 1 for no change. 2 for shuffle overworld locations. 5 for randomize the entire map. Defaults to 5. - --spellRemove Put in the letters of the spells you want removed. e.g. "--spellRemove zed" would remove zdown, energy field and dispel. - --mixQuantity Lets you input how much of a spell you want to mix. - --dngStone Randomize the location of stones in the dungeons - --fixes Collection of non-gameplay fixes. - --hythlothFix Fixes an issue with Hythloth dungeon room. - --sleepLockAssist Helps prevent sleeplock in battles. - --activePlayer Allow selecting which characters are active in combat. - --appleHitChance Change hit chance to behave like the original Apple II version. - --diagonalAttack Allow diagonal attacks in combat. - --sacrificeFix Adds a way to gain sacrifice which the shrine says should work. - --questItems Percentage chance to start with a quest item. - --runes Randomize the location of the runes. - --karmaValue Value to override starting karma value for a virtue. Leave blank for random. - --karmaPercentage Percentage chance to override a starting karma value for a virtue. Default 0 (no override). - --spoilerLog Output a spoiler log. - -? | -h | --help Show help information + -s |--s The seed for the randomizer. Same seed will produce the same map. Defaults to random value. + -p |--p Path to Ultima 4 installation. Leaving blank will assume it is the working directory. + -r |--r Restore original Ultima 4 files. + -e |--encoded Encoded flags. Overrides all other flags. + --miniMap Output a minimap of the overworld. + -o |--overworld Sets randomization level for Overworld map. 1 for no change. 2 for shuffle overworld locations. 5 for randomize the entire map. Defaults to 5. + --spellRemove Put in the letters of the spells you want removed. e.g. "--spellRemove zed" would remove zdown, energy field and dispel. + --startingWeaponsArmor Randomize the weapons and armor player and companions start with. + --mixQuantity Lets you input how much of a spell you want to mix. + --dngStone Randomize the location of stones in the dungeons + --fixes Collection of non-gameplay fixes. + --hythlothFix Fixes an issue with Hythloth dungeon room. + --sleepLockAssist Helps prevent sleeplock in battles. + --activePlayer Allow selecting which characters are active in combat. + --appleHitChance Change hit chance to behave like the original Apple II version. + --diagonalAttack Allow diagonal attacks in combat. + --sacrificeFix Adds a way to gain sacrifice which the shrine says should work. + --runes Randomize the location of the runes. + --mantras Randomize the mantras. + --wordOfPassage Randomize the Word of Passage. + --questItems <0-100> Percentage chance to start with a quest item. + --karmaValue Value to override starting karma value for a virtue. Leave blank for random. + --karmaPercentage <0-100> Percentage chance to override a starting karma value for a virtue. Default 0 (no override). + --monsterDamage <0-3> Value to change how much damage monsters do. Allowed values 0-3. 0 is quad damage. 1 is more damge. 2 is default. 3 is less damage. + --weaponDamage <1-3> Value to change how much damage weapons do. Allowed values 1-3. 1 is more damge. 2 is default. 3 is less damage. + --earlierMonsters Make more difficult monsters appear earlier. + --monsterQty More monsters from the start. + --noRequireFullParty Don't require the full party. + --randomizeSpells Randomizes the gate and resurrection spells that you learn in game. + --sextant Start with a sextant. + --clothMap Cloth map of the world. + --principleItems Randomize the order of the Principle Items. + --townSaves Enable saving in towns. + --daemonTrigger Fix daemon spawn in Abyss + --awakenUpgrade Awaken spell awakens all characters. + --shopOverflow Don't allow overflow exploit in shops. + --vgaPatch VGA patch compatibility. + --spoilerLog Output a spoiler log. + -? | -h | --help Show help information ``` All the files the randomizer changes get backed up with the extension ".orig" added. Run with '-r' to restore to the original game. @@ -40,6 +58,7 @@ Example: https://imgur.com/qNRxpSy ## Helping +If you end up making changes to the game's source code you will need to update the diff files. Run U4DosRandomizer.Patcher with the below parameters then copy the diffs into U4DosRandomizer/patches and rebuild. ```-b "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\AVATAR.EXE" -s "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\AVATAR.EXE.sig" -n "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\U4_MAIN.EXE" -d "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\AVATAR.EXE.octodiff"``` ```-b "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE.EXE.orig" -s "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE.EXE.sig" -n "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE_0.EXE" -d "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE.EXE.octodiff"``` From 97240d4e0e292a6d36bc3c14fa86eaebf24bcbde Mon Sep 17 00:00:00 2001 From: Fenyx4 Date: Wed, 28 Jul 2021 22:35:46 -0500 Subject: [PATCH 27/28] Update Program.cs --- U4DosRandomizer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/U4DosRandomizer/Program.cs b/U4DosRandomizer/Program.cs index 3f1d4e6..8e81a74 100644 --- a/U4DosRandomizer/Program.cs +++ b/U4DosRandomizer/Program.cs @@ -167,7 +167,7 @@ static void Main(string[] args) CommandOptionType.NoValue); CommandOption vgaPatchArg = commandLineApplication.Option( "--vgaPatch", - "VGA patch compatibility.", + "VGA patch compatibility. Run randomizer after applying VGA patch.", CommandOptionType.NoValue); CommandOption spoilerLogArg = commandLineApplication.Option( From 56d459a714ad3aa7040a2cc6d6849551b7dd96aa Mon Sep 17 00:00:00 2001 From: Fenyx4 Date: Wed, 28 Jul 2021 22:36:01 -0500 Subject: [PATCH 28/28] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ddecd4a..1592a6d 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Options: --daemonTrigger Fix daemon spawn in Abyss --awakenUpgrade Awaken spell awakens all characters. --shopOverflow Don't allow overflow exploit in shops. - --vgaPatch VGA patch compatibility. + --vgaPatch VGA patch compatibility. Run randomizer after applying VGA patch. --spoilerLog Output a spoiler log. -? | -h | --help Show help information ``` @@ -62,4 +62,4 @@ If you end up making changes to the game's source code you will need to update t ```-b "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\AVATAR.EXE" -s "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\AVATAR.EXE.sig" -n "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\U4_MAIN.EXE" -d "E:\Projects\U4DosRandomizer\u4_decompile\SRC\ORIGINAL\AVATAR.EXE.octodiff"``` ```-b "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE.EXE.orig" -s "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE.EXE.sig" -n "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE_0.EXE" -d "E:\Projects\U4DosRandomizer\u4_decompile\SRC-TITLE\ORIGINAL\TITLE.EXE.octodiff"``` -"The generation of random numbers is too important to be left to chance." - Robert R. Coveyou \ No newline at end of file +"The generation of random numbers is too important to be left to chance." - Robert R. Coveyou