theSLAYER Posted October 22, 2016 Posted October 22, 2016 Great! I'm gonna quote IGN:"Only one random Mirage Spot can be discovered within your own game each day, but up to ten more can be sent over via StreetPass or Passerbys on the Player Search System." I had previously read you coul unlock all spots, seems I was fooled. Don't know why they added two padding bytes, but seems we won't get anything else from streetpass. But seems we almost cracked the spots, only piece remaining would be 0x1600 and TID, since that spot is the only one with hidden items, but maybe hacking in the mirage spot just for the hidden item is quite pointless, as since you are hacking the spot just for the hidden it, you might hack the item yeah with the ability to hack, the items are easily obtainable. Of course, I am a bit curious though. Manipulating the bytes at those addresses, we may be able to find some sort of list, and 1600 probably ends at that list too. Yeah, I thought the padded bytes was weird as hell too, and the weird 16 that appeared infront didn't make sense. Furthermore, when I didn't use padded bytes, nothing appeared.. So if we write those bytes on a save file that didn't receive streetpasses and is zerorized, and it works, then its confirmed!
suloku Posted October 22, 2016 Posted October 22, 2016 I'm pretty sure they go bay map# except crescent isle being the first instead of the last. Back to padding... I think it is padded due to being a "decrypted" version of what lies at 0x1600. Now we know the output for crescent isle is 01 00 00 000 and have these TID/0x1600 combos for it: TID 00000: FF FF FE FF TID 61931: 76 CC C9 91 Edit: also, my tid&0x91C9 = 0x91C9, which seems suspicious but we'd need anither save with crescent isle as dayly spot to see if this is mere coincidence (I don'tthink so...) Of course now endianess and maybe using the low/high bytes might come at play if 0x1600 is an encrypted u32 with the TID (an u16). FF FF FE FF unlocking the isle suggests the value are two u16 (I may be wrong though). Also, for things like this I recall GF using a modulus, here's what they did in swarms for DP (also check the safari formula): https://projectpokemon.org/wiki/Pokémon_DP_Save_File_Structure#Swarm_Pok.C3.A9mon_-_0x72D4 I made some tests, they are in this order: 0x307D4 MapID XYZ Location Mirage Type 02 184 15.5/2/32.5 East of Mossdeep Mirage Forest Tangela Sunkern Glameow Minccino 03 185 16.5/2/32.5 North of Route 124 Mirage Forest Tangela Sunkern Purugly Vulpix 04 186 19.5/2/19.5 West of Route 114 Mirage Forest Tangela Sunkern Purugly Petilil 05 187 19.5/2/32.5 North of Lilycove Mirage Forest Tangela Sunkern Purugly Cherrim 06 188 19.5/2/9.5 South of Route 132 Mirage Forest Sunkern Petilil Audino 07 189 19.5/-88/28.5 West of Route 105 Mirage Forest Forretress Happiny 08 190 19.5/2/8.5 South of Route 109 Mirage Forest Audino Sunkern 09 191 19.5/2/19.5 North of Route 111 Mirage Forest Kricketune Larvesta 0A 192 19.5/2/27.5 West of Rustboro Mirage Cave Tynamo Klink Boldore Graveler 0B 193 18.5/2/33.5 North of Fortree Mirage Cave Klink Tynamo Excadrill Onix 0C 194 19.5/74/15.5 South of Pacifidlog Mirage Cave Tynamo Cofagrigus Slowpoke 0D 195 18.5/20/17.5 South of Route 107 Mirage Cave Unown 0E 196 19.5/74/15.5 North of Route 124 Mirage Cave Klink Cofagrigus Graveler Boldore 0F 197 17.5/20/24.5 North of Route 132 Mirage Cave Ditto Excadrill Tynamo 10 198 20.5/2/31.5 Southeast of Route 129 Mirage Cave Tynamo Onix Graveler Boldore 11 199 20.5/92/32.5 North of Fallarbor Mirage Cave Slowpoke Tynamo 12 200 19.5/29/27.5 West of Route 104 Mirage Island Venomoth Xatu Zebstrika Darmanitan 13 201 14.5/47/12.5 South of Route 134 Mirage Island Venomoth Xatu Zebstrika Maractus 14 202 23.5/-16/28.5 North of Route 124 Mirage Island Venomoth Xatu Zebstrika Persian 15 203 10.5/29/16.5 West of Dewford Town Mirage Island Venomoth Xatu Zebstrika Tangela 16 204 18.5/29/34.5 South of Pacifidlog Mirage Island Audino Xatu 17 205 19.5/29/26.5 South of Route 132 Mirage Island Munna Ditto 18 206 30.5/29/22.5 North of Route 113 Mirage Island Darmanitan Larvesta 19 207 9.5/29/19.5 East of Shoal Cave Mirage Island Purugly Porygon 1A 208 8.5/38/31.5 West of Route 104 Mirage Mountain Forretress Donphan Kricketune Stantler 1B 460 9.5/92/28.5 North of Lilycove Mirage Mountain Forretress Donphan Kricketune Rufflet 1C 461 10.5/2/22.5 Northeast of Route 125 Mirage Mountain Forretress Donphan Kricketune Vullaby 1D 462 18.5/38/8.5 West of Route 131 Mirage Mountain Forretress Donphan Kricketune Girafarig 1E 463 30.5/2/26.5 North of Mossdeep Mirage Mountain Magby Darmanitan 1F 464 31.5/2/9.5 South of Route 129 Mirage Mountain Zebstrika Elekid 20 465 19.5/20/29.5 Southeast of Route 129 Mirage Mountain Porygon Xatu Munna 21 466 18.5/30/12.5 East of Mossdeep Mirage Mountain Audino Happiny Tangela 01 467 24.5/56/34.5 Crescent Isle Cresselia
theSLAYER Posted October 22, 2016 Posted October 22, 2016 (edited) I was assuming TID will have an operation with the Mirage Daily Value, then end off with p % 33 (akin to how Nature was determined against PID) Too bad this scenario only worked with one of the values: (Lower half xor higher half xor TID) -> 0xFFFE xor 0xFFFF xor 0x0000 = 0x0001 (crescent isle). However I was unable to replicate this with the second pair 0x91C9 xor 0x91C9 xor 0xCC76 -> 0xCC76 -> 52342 (in decimal)-> 42 (last 2 digits) -> (minus until it is in scale) 42-33 = 9 incorrect It's also not this: (TID xor Mirage Daily value) % 33 = ( 23999 xor 0 ) % 33 -> 59 % 99 -> 33 incorrect I also tried: [(vMDV + ^MDV) xor TID ] % 33 = [(0x91C9 + 0xCC76) xor 0x91C9] % 33 -> (0x15E3F xor 0x91C9) % 33 -> 0x1CFF6 % 33 -> 118774 % 33 -> 8 incorrect We know at the very least, the relationship with TID isn't divide, 'cos that will cause everything to go to shit. Actually, if we can figure out why TID 0 and MDV 0 goes to map 465 (ID 20), we'll solve the mystery. perhaps we should or 20 somewhere? (edit: apparently your TID is 0xF1EB, why was I using 0x91C9?) Edited October 22, 2016 by theSLAYER
MichiS97 Posted October 22, 2016 Author Posted October 22, 2016 Great! I'm gonna quote IGN:"Only one random Mirage Spot can be discovered within your own game each day, but up to ten more can be sent over via StreetPass or Passerbys on the Player Search System." I had previously read you coul unlock all spots, seems I was fooled. Don't know why they added two padding bytes, but seems we won't get anything else from streetpass. But seems we almost cracked the spots, only piece remaining would be 0x1600 and TID, since that spot is the only one with hidden items, but maybe hacking in the mirage spot just for the hidden item is quite pointless, as since you are hacking the spot just for the hidden it, you might hack the item I'm not really sure if IGN is right on this one. I'm pretty sure you can unlock all islands on a single day with streetpass
theSLAYER Posted October 22, 2016 Posted October 22, 2016 I'm not really sure if IGN is right on this one. I'm pretty sure you can unlock all islands on a single day with streetpass We figured out that one address (which is a raw value that needs to be cracked; its related to TID) that determines own island, and determined 10 other addresses that determined passed islands, and haven't been able to activate more than 10 passed spots at a time. Writing values into the padded areas between the 10 addresses may cause the island to not even activate..
suloku Posted October 22, 2016 Posted October 22, 2016 (edited) Well, you may test by enabling 11 islands (10 hexed + daily), then streetpass with a oras save that has a daily spot that isn't any of the other 11. But if that was the case, there's no reason you couldn't unlock all spots via online pss, just leave the console there and eventually you have the 32 other spots? Makes sense they limited it to 10+1 daily, to keep the luck factor, or getting crescent isle would be too easy EDIT: You are right about deciphering tid and dmv outputing 0x20. For reference, FF FF FF FE also produces 0x20 with tid 0. EDIT 2: I've been thinking, and since we know (or suspect) the output, seeing what 00000000 and TID 1 produces might help. Also, if it works like passed spots, the output can't be 0, so maybe it is adding +1 after the calculus, or it can't output 0 at all. Edited October 22, 2016 by suloku
theSLAYER Posted October 23, 2016 Posted October 23, 2016 Technically final output 0 is 33. 33 - 33 is 0, so it only -33 if result >33. Thing is, I don't see how xor operations against 0 TID Wil result in 0x20 I haven't been able to figure how they determine mirage spot based on raw MDV At least we got streetpassed ones working..
suloku Posted October 23, 2016 Posted October 23, 2016 Maybe it is modulus 32 -> value range 0-32 (33 possible values) + 1. But as you said, being able to edit the passed spots in batches of 10 is great. Maybe we could even make an ntr plugin to eaaily change the first passed island, the values are near the eon ticket "herpesvalue" so it should be easy to find on a memory dump.
Guest Posted October 23, 2016 Posted October 23, 2016 Speaking of NTR plugins, is a plugin that changes the 3DS's clock while in-game something that could be done? Or if NTR can do that, would it still trigger the anti-time-travel mechanisms? Figured that if the game remained powered on while the change occured, that it might not notice the jump. Kinda surprised nobody tried to make a homebrew raw rtc changer though. Kinda lame to be restricted to a dev app that could be hard to find and I'd have thought that demands for anti-time-travel bypass would have been higher.
suloku Posted October 23, 2016 Posted October 23, 2016 Well, the anti timetravel, for what I know, stores the difference between real clock and raw rtc. I guess we could calcuñate the value and search it in a savegame, the the plugin would fix the value in the save bwfore loading, but for what I saw ctrulib doesn't have the functions to tingle rtc (either real or raw). I guess we are stuck to the dev app. The little demand is because only a few game have anti-timetravel. Also, tested TID 1 and 0x1600 zeroed, output was map 197 (0x0f if the output should be the same as streetpass)
suloku Posted October 27, 2016 Posted October 27, 2016 I coded this really quick, should be user friendly enough: https://github.com/suloku/gen6_safari_mirage_tool/releases/tag/0.1 It also has the friend safari unlock for XY By the way, when coding it I realized that the u32 value at 0x1600 (MDV) is the only thing that get's checksummed in the whole block, unless I trusted the wiki too much, because I haven't really tested the tool on my 3DS, I just saw changes were correctly made with an hex editor.
Falo Posted October 31, 2016 Posted October 31, 2016 Block 5 (0x1600) is Savedata::RandomGroup this block is just a 4 byte random value, which is generated by the 3DS AES engine. I didn't fully reverse it, but it calls SVC 0x28 "GetSystemTick(void)" and then uses a Mersenne Twister algo with sha256 and sha1 hash. So it's not encrypted, just a random value. It's like a seed value from the good old RNG days.
suloku Posted October 31, 2016 Posted October 31, 2016 Block 5 (0x1600) is Savedata::RandomGroupthis block is just a 4 byte random value, which is generated by the 3DS AES engine. I didn't fully reverse it, but it calls SVC 0x28 "GetSystemTick(void)" and then uses a Mersenne Twister algo with sha256 and sha1 hash. So it's not encrypted, just a random value. It's like a seed value from the good old RNG days. Thanks for the info about how it is generated! The "problem" we have is that we haven't been able to figure out the algorythm that the game uses to output the Daily Mirage Spot. We know the algorythm uses this random value and TID, but the algorythm isn't simple enough to guess it without reverse engineering (something I don't have a clue how to do).
Falo Posted November 1, 2016 Posted November 1, 2016 Thanks for the info about how it is generated! The "problem" we have is that we haven't been able to figure out the algorythm that the game uses to output the Daily Mirage Spot. We know the algorythm uses this random value and TID, but the algorythm isn't simple enough to guess it without reverse engineering (something I don't have a clue how to do). The code for this can be found in DllSkyTrip.cro and the code.bin, function to generate mirage spot: ".text:004608F4 sub_4608F4" To find the current Mirage Spot, it uses that random value, and some other values, like the current time and generates a new random value. the final result of it is then "rnd % 33 + 1".
suloku Posted November 1, 2016 Posted November 1, 2016 The code for this can be found in DllSkyTrip.cro and the code.bin, function to generate mirage spot: ".text:004608F4 sub_4608F4"To find the current Mirage Spot, it uses that random value, and some other values, like the current time and generates a new random value. the final result of it is then "rnd % 33 + 1". So that's what we were missing! Would it be very difficult to get the full asm for the function? I don't know how to get it, but I can probably get the asm into a friendlier C (well, I suppose if you can get the asm you are most than capable of also translating it to C). Also, is it really the current time? the_SLAYER and me got the same islands just by setting the random seed to certain values with TID being 0, that's why we assumed it only used those two. Did we just get unfortunate coincidence? edit: should I just get the code.bin into IDA and look for the function you posted? Does it work that way? (I really have no clue)
theSLAYER Posted November 1, 2016 Posted November 1, 2016 So that's what we were missing! Would it be very difficult to get the full asm for the function? I don't know how to get it, but I can probably get the asm into a friendlier C (well, I suppose if you can get the asm you are most than capable of also translating it to C).Also, is it really the current time? the_SLAYER and me got the same islands just by setting the random seed to certain values with TID being 0, that's why we assumed it only used those two. Did we just get unfortunate coincidence? edit: should I just get the code.bin into IDA and look for the function you posted? Does it work that way? (I really have no clue) current time was probably used as a seed to generate the value, but I think the list value shifts based on TID.
Falo Posted November 1, 2016 Posted November 1, 2016 current time was probably used as a seed to generate the value,but I think the list value shifts based on TID. Yes but it's still a random value: unsigned int __fastcall sub_4608F4(int a1, int a2){ _DWORD *savePtr; // r4@1 int trainerId; // r6@1 unsigned int rnd; // r0@1 int rnd_ctx; // [sp+0h] [bp-28h]@1 char ctx; // [sp+10h] [bp-18h]@1 savePtr = *(_DWORD **)(sub_14E348() + 28); trainerId = *(_DWORD *)(*savePtr + 0x129A8); init_rnc_ctx((int)&ctx); j_getGameTime(savePtr, (int)&ctx); j_gfl2::math::Random::Initialize((int)&rnd_ctx, *(_DWORD *)(*savePtr + 0x1048) + trainerId); rnd = j_MersenneTwister((int)&rnd_ctx); *(_WORD *)(a1 + 0x51DA) = rnd % 33 + 1; return rnd % 33 + 1;} //*(_DWORD *)(*savePtr + 0x1048) = the random value from SaveData::RandomGroup
theSLAYER Posted November 1, 2016 Posted November 1, 2016 Yes but it's still a random value: unsigned int __fastcall sub_4608F4(int a1, int a2){ _DWORD *savePtr; // r4@1 int trainerId; // r6@1 unsigned int rnd; // r0@1 int rnd_ctx; // [sp+0h] [bp-28h]@1 char ctx; // [sp+10h] [bp-18h]@1 savePtr = *(_DWORD **)(sub_14E348() + 28); trainerId = *(_DWORD *)(*savePtr + 0x129A8); init_rnc_ctx((int)&ctx); j_getGameTime(savePtr, (int)&ctx); j_gfl2::math::Random::Initialize((int)&rnd_ctx, *(_DWORD *)(*savePtr + 0x1048) + trainerId); rnd = j_MersenneTwister((int)&rnd_ctx); *(_WORD *)(a1 + 0x51DA) = rnd % 33 + 1; return rnd % 33 + 1;} //*(_DWORD *)(*savePtr + 0x1048) = the random value from SaveData::RandomGroup It's okay being a random value, as long as a spread from 1-33 can be calculated, it is cool!
suloku Posted November 1, 2016 Posted November 1, 2016 I'm a bit confused, I seem to understand that the SaveData::RandomGroup and TID are used to initialize the MersenneTwister algorythm for generating a random value that is used to calculate the daily spot, but I fail to see the role that these play: init_rnc_ctx((int)&ctx); j_getGameTime(savePtr, (int)&ctx); rnd_ctx I've looked at some MersenneTwister implementations and none seem to have an input argument beside getting it seeded, unlike this call j_MersenneTwister((int)&rnd_ctx). Just to clarify, the goal I'm after is to make a function such as this: u32 RandomGroup_MDV (u16 TID, u8 MirageSpot){ u32 randomgroup = 0; for (randomgroup = 0; randomgroup < 0xFFFFFFFF; i++) { //Algorythm that uses randomgroup and TID to generate a value between 1-33 (yes, I know you just posted the algorythm the game uses) if (result == MirageSpot) break; } return randomgroup;}
Falo Posted November 1, 2016 Posted November 1, 2016 It was just a quick analysis, init_rtc_ctx initializes a 8 byte structure this is then used by j_getGameTime, i'm not sure if it "gets" or "sets" the time, since "get" makes more sense i used that name. savePtr is a pointer to the Savedata:: Savedata structure, not the raw save. gfl2::math::Random::Initialize, the name comes from the sun&moon demo, not oras, this initializes a mersenne twister algo, here the rest of the functions: (pseudo c code) int __fastcall j_gfl2::math::Random::Initialize(int *ctx, int a2){ return gfl2::math::Random::Initialize(ctx, a2);}unsigned int __fastcall j_MersenneTwister(int *a1){ return MersenneTwister(a1);}int __fastcall gfl2::math::Random::Initialize(int *a1, int a2){ signed int v2; // r1@1 unsigned int v3; // r2@2 int v4; // r3@2 int *v5; // r2@2 int v6; // r3@2 *a1 = a2; a1[1] = 0x8F7011EE; v2 = 1; *((_QWORD *)a1 + 1) = 0x3793FDFFFC78FF1FLL; do { v3 = a1[(v2 - 1) % 4]; v4 = 1812433253 * (v3 ^ (v3 >> 30)); v5 = &a1[v2 % 4]; v6 = v4 + v2++; *v5 ^= v6; } while ( v2 < 8 ); return sub_11A29C((int)a1);}int *__fastcall sub_11A29C(int *result){ bool v1; // zf@1 int v2; // r1@5 bool v3; // zf@5 signed int v4; // r3@10 int v5; // r12@11 int v6; // r1@11 int v7; // r4@11 unsigned int v8; // r2@11 int v9; // r4@11 v1 = (*result & 0x7FFFFFFF) == 0; if ( !(*result & 0x7FFFFFFF) ) v1 = result[1] == 0; if ( v1 ) { v2 = result[2]; v3 = v2 == 0; if ( !v2 ) v3 = result[3] == 0; if ( v3 ) { *result = 84; result[1] = 73; result[2] = 78; result[3] = 89; } } v4 = 0; do { v5 = result[1]; ++v4; v6 = result[2]; v7 = *result & 0x7FFFFFFF ^ v5 ^ v6 ^ 2 * (*result & 0x7FFFFFFF ^ v5 ^ v6); v8 = result[3] ^ ((unsigned int)result[3] >> 1) ^ v7; v9 = v7 ^ (v8 << 10); result[3] = v8; if ( v8 & 1 ) { v6 ^= 0x8F7011EE; v9 ^= 0xFC78FF1F; } *result = v5; result[1] = v6; result[2] = v9; } while ( v4 < 8 ); return result;}unsigned int __fastcall MersenneTwister(int *a1){ int v1; // r2@1 int v2; // r3@1 int v3; // r12@1 unsigned int v4; // r1@1 unsigned int v5; // r12@1 int *v6; // r0@3 int v7; // r4@3 unsigned int result; // r0@3 v1 = a1[2]; v2 = a1[1]; v3 = *a1 & 0x7FFFFFFF ^ v2 ^ v1 ^ 2 * (*a1 & 0x7FFFFFFF ^ v2 ^ v1); v4 = a1[3] ^ ((unsigned int)a1[3] >> 1) ^ v3; v5 = v3 ^ (v4 << 10); if ( v4 & 1 ) { v1 ^= 0x8F7011EE; v5 ^= 0xFC78FF1F; } *a1 = v2; a1[3] = v4; v6 = a1 + 1; v7 = v2 + (v5 >> 8); *v6 = v1; v6[1] = v5; result = v4 ^ v7; if ( v7 & 1 ) v4 = 0x3793FDFF; if ( v7 & 1 ) result ^= v4; return result;} I found the algo online, it's "Tiny Mersenne Twister" https://gitlab-dev.in2p3.fr/SOPHYA/SophyaLib/blob/927c275e1bbe27c728119b9763ef174ece43fc47/BaseTools/tinymt32.c https://gitlab-dev.in2p3.fr/SOPHYA/SophyaLib/blob/927c275e1bbe27c728119b9763ef174ece43fc47/BaseTools/tinymt32.h
suloku Posted November 1, 2016 Posted November 1, 2016 It was just a quick analysis, init_rtc_ctx initializes a 8 byte structure this is then used by j_getGameTime, i'm not sure if it "gets" or "sets" the time, since "get" makes more sense i used that name. savePtr is a pointer to the Savedata:: Savedata structure, not the raw save. gfl2::math::Random::Initialize, the name comes from the sun&moon demo, not oras, this initializes a mersenne twister algo, here the rest of the functions: (pseudo c code) int __fastcall j_gfl2::math::Random::Initialize(int *ctx, int a2){ return gfl2::math::Random::Initialize(ctx, a2);}unsigned int __fastcall j_MersenneTwister(int *a1){ return MersenneTwister(a1);}int __fastcall gfl2::math::Random::Initialize(int *a1, int a2){ signed int v2; // r1@1 unsigned int v3; // r2@2 int v4; // r3@2 int *v5; // r2@2 int v6; // r3@2 *a1 = a2; a1[1] = 0x8F7011EE; v2 = 1; *((_QWORD *)a1 + 1) = 0x3793FDFFFC78FF1FLL; do { v3 = a1[(v2 - 1) % 4]; v4 = 1812433253 * (v3 ^ (v3 >> 30)); v5 = &a1[v2 % 4]; v6 = v4 + v2++; *v5 ^= v6; } while ( v2 < 8 ); return sub_11A29C((int)a1);}int *__fastcall sub_11A29C(int *result){ bool v1; // zf@1 int v2; // r1@5 bool v3; // zf@5 signed int v4; // r3@10 int v5; // r12@11 int v6; // r1@11 int v7; // r4@11 unsigned int v8; // r2@11 int v9; // r4@11 v1 = (*result & 0x7FFFFFFF) == 0; if ( !(*result & 0x7FFFFFFF) ) v1 = result[1] == 0; if ( v1 ) { v2 = result[2]; v3 = v2 == 0; if ( !v2 ) v3 = result[3] == 0; if ( v3 ) { *result = 84; result[1] = 73; result[2] = 78; result[3] = 89; } } v4 = 0; do { v5 = result[1]; ++v4; v6 = result[2]; v7 = *result & 0x7FFFFFFF ^ v5 ^ v6 ^ 2 * (*result & 0x7FFFFFFF ^ v5 ^ v6); v8 = result[3] ^ ((unsigned int)result[3] >> 1) ^ v7; v9 = v7 ^ (v8 << 10); result[3] = v8; if ( v8 & 1 ) { v6 ^= 0x8F7011EE; v9 ^= 0xFC78FF1F; } *result = v5; result[1] = v6; result[2] = v9; } while ( v4 < 8 ); return result;}unsigned int __fastcall MersenneTwister(int *a1){ int v1; // r2@1 int v2; // r3@1 int v3; // r12@1 unsigned int v4; // r1@1 unsigned int v5; // r12@1 int *v6; // r0@3 int v7; // r4@3 unsigned int result; // r0@3 v1 = a1[2]; v2 = a1[1]; v3 = *a1 & 0x7FFFFFFF ^ v2 ^ v1 ^ 2 * (*a1 & 0x7FFFFFFF ^ v2 ^ v1); v4 = a1[3] ^ ((unsigned int)a1[3] >> 1) ^ v3; v5 = v3 ^ (v4 << 10); if ( v4 & 1 ) { v1 ^= 0x8F7011EE; v5 ^= 0xFC78FF1F; } *a1 = v2; a1[3] = v4; v6 = a1 + 1; v7 = v2 + (v5 >> 8); *v6 = v1; v6[1] = v5; result = v4 ^ v7; if ( v7 & 1 ) v4 = 0x3793FDFF; if ( v7 & 1 ) result ^= v4; return result;} I found the algo online, it's "Tiny Mersenne Twister" https://gitlab-dev.in2p3.fr/SOPHYA/SophyaLib/blob/927c275e1bbe27c728119b9763ef174ece43fc47/BaseTools/tinymt32.c https://gitlab-dev.in2p3.fr/SOPHYA/SophyaLib/blob/927c275e1bbe27c728119b9763ef174ece43fc47/BaseTools/tinymt32.h Thank you very much for the functions! With this I can generate values for any given TID and Mirage Spot. I need to test in game, but seems it will work. I don't know what the time call does there, doesn't seem to impact the mirage spot in any way. If someone wants to test, this should produce cresscent isle: TID: 12345 (this is in decimal!) 0x1600: 3C 1C 12 91 (this is direct hex view!)
BlackShark Posted November 1, 2016 Posted November 1, 2016 If someone wants to test, this should produce cresscent isle:TID: 12345 (this is in decimal!) 0x1600: 3C 1C 12 91 (this is direct hex view!) Didn't work for me. Do I just have to edit my TID and the value at 0x1600, or is there something else I'm missing? By the way, nice work guys!
theSLAYER Posted November 1, 2016 Posted November 1, 2016 Didn't work for me.Do I just have to edit my TID and the value at 0x1600, or is there something else I'm missing? By the way, nice work guys! Edit TID, change the value, fix checksums, and inject the save, it should change and load Crescent Isle.
BlackShark Posted November 1, 2016 Posted November 1, 2016 Edit TID, change the value, fix checksums, and inject the save,it should change and load Crescent Isle. That's what I did. But Crescent Island isn't there.
theSLAYER Posted November 1, 2016 Posted November 1, 2016 That's what I did. But Crescent Island isn't there. did the island change, though? try this: TID 44271 and 0x1600 with 00 00 00 06 (0x06000000), it will change current to Cres Isle.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now