From 16174f5efd35dcec74026a6b3e61f6dfa73c77ad Mon Sep 17 00:00:00 2001 From: Hash Borgir Date: Mon, 16 May 2022 19:22:17 -0600 Subject: [PATCH] minimal wp/quest editing works, need refactor to better form --- d2_notes_wps.txt | 54 ++++++ d2s_notes.txt | 119 +++++++++++++ saveCharacter.php | 138 +++++++++++++++ src/D2SaveFile.php | 27 +-- src/D2SaveFileStructureData.php | 294 +++++++++++++++++--------------- src/tabs/Chars.php | 90 ++++++---- 6 files changed, 539 insertions(+), 183 deletions(-) create mode 100644 d2_notes_wps.txt create mode 100644 d2s_notes.txt create mode 100644 saveCharacter.php diff --git a/d2_notes_wps.txt b/d2_notes_wps.txt new file mode 100644 index 0000000..fb40114 --- /dev/null +++ b/d2_notes_wps.txt @@ -0,0 +1,54 @@ +Waypionts offset stuff + + +Get All WP + +643 - pack 5 hex bytes, FF FF FF FF 7F +667 +691 + + + + 01 => 'Rogue_Encampment', + 1 => 'Cold_Plains', + 2 => 'Stony_Field', + 3 => 'Dark_Wood', + 4 => 'Black_Marsh', + 5 => 'Outer_Cloister', + 6 => 'Jail_level_1', + 7 => 'Inner_Cloister', + + 8 => 'Catacombs_level_2', + 9 => 'Lut_Gholein', + 10 => 'Sewers_level_2', + 11 => 'Dry_Hills', + 12 => 'Halls_of_the_Dead_level_2', + 13 => 'Far_Oasis', + 14 => 'Lost_City', + 15 => 'Palace_Cellar_level_1', + + 16 => 'Arcane_Sanctuary', + 17 => 'Canyon_of_the_Magi', + 18 => 'Kurast_Docks', + 19 => 'Spider_Forest', + 20 => 'Great_Marsh', + 21 => 'Flayer_Jungle', + 22 => 'Lower_Kurast', + 23 => 'Kurast_Bazaar', + + 24 => 'Upper_Kurast', + 25 => 'Travincal', + 26 => 'Durance_of_Hate_level_2', + 27 => 'Pandemonium_Fortress', + 28 => 'City_of_the_Damned', + 29 => 'River_of_Flames', + 30 => 'Harrogath', + 31 => 'Frigid_Highlands', + + 32 => 'Arreat_Plateau', + 33 => 'Crystalline_Passage', + 34 => 'Halls_of_Pain', + 35 => 'Glacial_Trail', + 36 => 'Frozen_Tundra', + 37 => "The_Ancients_Way", + 38 => 'Worldstone_Keep_level_2' \ No newline at end of file diff --git a/d2s_notes.txt b/d2s_notes.txt new file mode 100644 index 0000000..f2a8fc8 --- /dev/null +++ b/d2s_notes.txt @@ -0,0 +1,119 @@ + +A1Q1 - If anything but not started, (meaning started) 345 SET TO 01 + +Not Started: +00 00 - (No Den, No Akara) 427,428 = 02 20 +00 00 - (Yes Den, No Akara) 427,428 = 02 20 +00 00 - (No Den, Yes Akara) 427,428 = 01 80 +00 00 - (Yes Den, Yes Akara) 427,428 = 01 80 + +Looking For: +04 00 - (No Den, No Akara) 427,428 = 02 20 +14 00 - (Yes Den, No Akara) 427,428 = 02 20 +04 00 - (No Den, Yes Akara) 427,428 = 01 80 +14 00 - (Yes Den, Yes Akara) 427,428 = 01 80 + +Just Finished: +EE FF - (No Den, No Akara) 427,428 = 02 20 +FE FF - (Yes Den, No Akara) 427,428 = 02 20 +EE FF - (No Den, Yes Akara) 427,428 = 01 80 +FE FF - (Yes Den, Yes Akara) 427,428 = 01 80 + +Long Finished: +ED 9F - (No Den, No Akara) 427,428 = 02 20 +FD 9F - (Yes Den, No Akara) 427,428 = 02 20 +ED 9F - (No Den, Yes Akara) 427,428 = 01 80 +FD 9F - (Yes Den, Yes Akara) 427,428 = 01 80 + +----------------------------------------------- + +A1Q2: If anything but not started, (meaning started) 345 SET TO 01 + +Looking For: +04 00 - No Enter BG +14 00 - Yes Enter BG + +Just Finished: +EE FF - No Enter BG +FE FF - Yes Enter BG + +Long Finished: +ED 9F - No Enter BG +FD 9F - Yes Enter BG + +----------------------------------------------- + +A1Q3 - Search For Caine + +Looking For: +04 00 - No Enter, No Rouge +14 00 - Enter, No Rogue +04 40 - No Enter, Yes Rogue +14 40 - Yes Enter, Yes Rogue + +Just Finished: +EE BB - No Enter, No Rouge +FE BB - Enter, No Rogue +EE FB - No Enter, Yes Rogue +FE FB - Yes Enter, Yes Rogue + +Long Finished: +ED 9B - No Enter, No Rouge +FD 9B - Enter, No Rogue +ED DB - No Enter, Yes Rogue +FD DB - Yes Enter, Yes Rogue + +----------------------------------------------- + +A1Q4: + +Looking For: +00 00 - no read, no enter +04 00 - yes read, no enter +40 00 - no read, yes enter +44 00 - yes read, yes enter + +Just Finished: +BA FF - no read, no enter +BE FF - yes read, no enter +FA FF - no read, yes enter +FE FF - yes read, yes enter + +Long Finished: +B9 9F - no read, no enter +BD 9F - yes read, no enter +F9 9F - no read, yes enter +FD 9F - yes read, yes enter + +----------------------------------------------- + +A1Q5: Tools of the Trade + +Looking For: +04 00 - no pick +44 00 - yes pick + + +Just Finished: +BE FF - no pick +FE FF - yes pick + +Long Finished: +BD 9F- no pick +FD 9F - yes pick + +----------------------------------------------- + +A1Q6: + +Looking For +04 00 + +Just Finished: +FE FF + +Long Finished: +FD 9F + + + diff --git a/saveCharacter.php b/saveCharacter.php new file mode 100644 index 0000000..3ff360e --- /dev/null +++ b/saveCharacter.php @@ -0,0 +1,138 @@ + $v) { + $q[$k] = ($dStruct->_qNorm[$k]); +} + +foreach($p['wp'] as $k => $v) { + $w[$k] = ($dStruct->_qNorm[$k]); +} + + +$filePath = $p['filePath']; +$filePath = str_replace("\\", "\\\\", $filePath); +$fp = fopen($filePath, "rb+"); + +// delete old checksum at offset 0x0C - byte 12 +fseek($fp, 12); +// (I) unsigned integer (machine dependent size and byte order) +fwrite($fp, pack('I', 0)); // produces 4 bytes + +// edit quests which are checked, to Just finished FE FF +foreach ($q as $k => $v) { + fseek($fp, $v); + fwrite($fp, pack('C', 0xFE)); + fseek($fp, $v+1); + fwrite($fp, pack('C', 0xFF)); +} + +if ($p['wp_all'] == "1") { + fseek($fp, 643); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 644); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 645); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 646); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 647); + fwrite($fp, pack('C', 0x7F)); + + fseek($fp, 667); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 668); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 669); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 670); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 671); + fwrite($fp, pack('C', 0x7F)); + + fseek($fp, 691); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 692); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 693); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 694); + fwrite($fp, pack('C', 0xFF)); + fseek($fp, 695); + fwrite($fp, pack('C', 0x7F)); + +} + else if ($p['wp_all'] == "0") +{ + fseek($fp, 643); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 644); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 645); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 646); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 647); + fwrite($fp, pack('C', 0x00)); + + fseek($fp, 667); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 668); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 669); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 670); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 671); + fwrite($fp, pack('C', 0x00)); + + fseek($fp, 691); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 692); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 693); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 694); + fwrite($fp, pack('C', 0x00)); + fseek($fp, 695); + fwrite($fp, pack('C', 0x00)); +} + + +$checksum = swapEndianness(shell_exec("bin\d2scs.exe \"$filePath\"")); + +// write NEW checksum at offset 0x0C - byte 12 +fseek($fp, 12); +// (I) unsigned integer (machine dependent size and byte order) +fwrite($fp, pack('H*', $checksum)); // produces 4 bytes + + +fclose($fp); + +header('Location: /'); \ No newline at end of file diff --git a/src/D2SaveFile.php b/src/D2SaveFile.php index 63f87c9..78a77d7 100644 --- a/src/D2SaveFile.php +++ b/src/D2SaveFile.php @@ -81,6 +81,9 @@ class D2SaveFile { $charData['Waypoints'] = $this->getWaypointsData($file); $charData['NPCIntroductions'] = $data[714]; + + $charData['filePath'] = $filePath; + $this->charData = $charData; @@ -118,21 +121,21 @@ class D2SaveFile { foreach ($questsNorm as $k => $v) { $x = (str_split(strtobits($v), 8)); - if ($x[0][0]) { + // if ($x[0][0]) { $quests['Norm'][$this->sData->qNorm[$k]] = $x[0][0]; - } + // } } foreach ($questsNM as $k => $v) { $x = array_filter(str_split(strtobits($v), 8)); - if ($x[0][0]) { + // if ($x[0][0]) { $quests['NM'][$this->sData->qNM[$k]] = $x[0][0]; - } + // } } foreach ($questsHell as $k => $v) { $x = array_filter(str_split(strtobits($v), 8)); - if ($x[0][0]) { + // if ($x[0][0]) { $quests['Hell'][$this->sData->qHell[$k]] = $x[0][0]; - } + // } } return $quests; @@ -188,21 +191,21 @@ class D2SaveFile { // ddump(str_split($wp['Norm'])); foreach ($wp['Norm'] as $k => $v) { - if ($v == 1) { + // if ($v == 1) { $waypoints['Norm'][$this->sData->wpNames[$k]] = $v; - } + // } } foreach ($wp['NM'] as $k => $v) { - if ($v == 1) { + // if ($v == 1) { $waypoints['NM'][$this->sData->wpNames[$k]] = $v; - } + // } } foreach ($wp['Hell'] as $k => $v) { - if ($v == 1) { + // if ($v == 1) { $waypoints['Hell'][$this->sData->wpNames[$k]] = $v; - } + // } } diff --git a/src/D2SaveFileStructureData.php b/src/D2SaveFileStructureData.php index 2bd95cc..3ca7d68 100644 --- a/src/D2SaveFileStructureData.php +++ b/src/D2SaveFileStructureData.php @@ -72,126 +72,126 @@ class D2SaveFileStructureData { ]; public $qNorm = [ //345 => 'introWarriv', - 347 => 'DenOfEvil', - 349 => 'SistersBurialGrounds', - 351 => 'ToolsOfTheTrade', - 353 => 'TheSearchForCain', - 355 => 'TheForgottenTower', - 357 => 'SistersToTheSlaughter', + 347 => 'Den_Of_Evil', + 349 => 'Sisters_Burial_Grounds', + 351 => 'Tools_Of_The_Trade', + 353 => 'The_Search_For_Cain', + 355 => 'The_Forgotten_Tower', + 357 => 'Sisters_To_The_Slaughter', //359 => 'traveledToAct2', //361 => 'introJerhyn', - 363 => 'RadamentsLair', - 365 => 'TheHoradricStaff', - 367 => 'TaintedSun', - 369 => 'ArcaneSanctuary', - 371 => 'TheSummoner', - 373 => 'TheSevenTombs', + 363 => 'Radaments_Lair', + 365 => 'TheHoradric_Staff', + 367 => 'Tainted_Sun', + 369 => 'Arcane_Sanctuary', + 371 => 'The_Summoner', + 373 => 'The_Seven_Tombs', //375 => 'traveledToAct3', //377 => 'introHratli', - 379 => 'LamEsensTome', - 381 => 'KhalimsWill', - 383 => 'BladeOfTheOldReligion', - 385 => 'TheGoldenBird', - 387 => 'TheBlackenedTemple', - 389 => 'TheGuardian', + 379 => 'LamEsens_Tome', + 381 => 'Khalims_Will', + 383 => 'Blade_Of_The_Old_Religion', + 385 => 'The_Golden_Bird', + 387 => 'The_Blackened_Temple', + 389 => 'The_Guardian', //391 => 'traveledtoAct4', //393 => 'introToAct4', - 395 => 'TheFallenAngel', - 397 => 'TerrorsEnd', - 399 => 'HellForge', + 395 => 'The_Fallen_Angel', + 397 => 'Terrors_End', + 399 => 'Hell_Forge', //401 => 'empty1', //403 => 'empty2', //405 => 'empty3', //407 => 'traveledToAct5', //409 => 'completedTerrorsEnd', - 414 => 'SiegeOnHarrogath', - 416 => 'RescueOnMountArreat', - 418 => 'PrisonOfIce', - 420 => 'BetrayalOfHarrogath', - 422 => 'RiteOfPassage', - 424 => 'EveOfDestruction', + 414 => 'Siege_On_Harrogath', + 416 => 'Rescue_On_MountArreat', + 418 => 'Prison_Of_Ice', + 420 => 'Betrayal_Of_Harrogath', + 422 => 'Rite_Of_Passage', + 424 => 'Eve_Of_Destruction', ]; public $qNM = [ //438 => 'introWarrivNM', - 440 => 'DenOfEvilNM', - 442 => 'SistersBurialGroundsNM', - 444 => 'ToolsOfTheTradeNM', - 446 => 'TheSearchForCainNM', - 448 => 'TheForgottenTowerNM', - 450 => 'SistersToTheSlaughterNM', - //452 => 'traveledToAct2NM', - //454 => 'introJerhynNM', - 456 => 'RadamentsLairNM', - 458 => 'TheHoradricStaffNM', - 460 => 'TaintedSunNM', - 462 => 'ArcaneSanctuaryNM', - 464 => 'TheSummonerNM', - 466 => 'TheSevenTombsNM', - //468 => 'traveledToAct3NM', - //470 => 'introHratliNM', - 472 => 'LamEsensTomeNM', - 474 => 'KhalimsWillNM', - 476 => 'BladeOfTheOldReligionNM', - 478 => 'TheGoldenBirdNM', - 480 => 'TheBlackenedTempleNM', - 482 => 'TheGuardianNM', - //484 => 'traveledtoAct4NM', - //486 => 'introToAct4NM', - 488 => 'TheFallenAngelNM', - 490 => 'TerrorsEndNM', - 492 => 'HellForgeNM', - //494 => 'emptyNM1', - //496 => 'emptyNM2', - //498 => 'emptyNM3', - //500 => 'traveledToAct5NM', - //502 => 'completedTerrorsEndNM', - 504 => 'SiegeOnHarrogathNM', - 506 => 'RescueOnMountArreatNM', - 508 => 'PrisonOfIceNM', - 510 => 'BetrayalOfHarrogathNM', - 512 => 'RiteOfPassageNM', - 514 => 'EveOfDestructionNM', + 440 => 'Den_Of_Evil_NM', + 442 => 'Sisters_Burial_Grounds_NM', + 444 => 'Tools_Of_The_Trade_NM', + 446 => 'The_Search_For_Cain_NM', + 448 => 'The_Forgotten_Tower_NM', + 450 => 'Sisters_To_The_Slaughter_NM', + //452 => 'traveledToAct2', + //454 => 'introJerhyn', + 456 => 'Radaments_Lair_NM', + 458 => 'The_Horadric_Staff_NM', + 460 => 'Tainted_Sun_NM', + 462 => 'Arcane_Sanctuary_NM', + 464 => 'The_Summoner_NM', + 466 => 'The_SevenTombs_NM', + //468 => 'traveledToAct3', + //470 => 'introHratli', + 472 => 'Lam_Esens_Tome_NM', + 474 => 'Khalims_Will_NM', + 476 => 'Blade_Of_The_OldReligion_NM', + 478 => 'The_Golden_Bird_NM', + 480 => 'The_Blackened_Temple_NM', + 482 => 'The_Guardian_NM', + //484 => 'traveledtoAct4', + //486 => 'introToAct4', + 488 => 'The_Fallen_Angel_NM', + 490 => 'Terrors_End_NM', + 492 => 'Hell_Forge_NM', + //494 => 'empty1', + //496 => 'empty2', + //498 => 'empty3', + //500 => 'traveledToAct5', + //502 => 'completedTerrorsEnd', + 504 => 'Siege_On_Harrogath_NM', + 506 => 'Rescue_On_MountArreat_NM', + 508 => 'Prison_Of_Ice_NM', + 510 => 'Betrayal_Of_Harrogath_NM', + 512 => 'Rite_Of_Passage_NM', + 514 => 'Eve_Of_Destruction_NM', ]; public $qHell = [ - //528 => 'introWarrivHell', - 530 => 'DenOfEvilHell', - 532 => 'SistersBurialGroundsHell', - 534 => 'ToolsOfTheTradeHell', - 536 => 'TheSearchForCainHell', - 538 => 'TheForgottenTowerHell', - 540 => 'SistersToTheSlaughterHell', - //542 => 'traveledToAct2Hell', - //544 => 'introJerhynHell', - 546 => 'RadamentsLairHell', - 548 => 'TheHoradricStaffHell', - 550 => 'TaintedSunHell', - 552 => 'ArcaneSanctuaryHell', - 554 => 'TheSummonerHell', - 556 => 'TheSevenTombsHell', - //558 => 'traveledToAct3Hell', - //560 => 'introHratliHell', - 562 => 'LamEsensTomeHell', - 564 => 'KhalimsWillHell', - 566 => 'BladeOfTheOldReligionHell', - 568 => 'TheGoldenBirdHell', - 570 => 'TheBlackenedTempleHell', - 572 => 'TheGuardianHell', - //574 => 'traveledtoAct4Hell', - //576 => 'introToAct4Hell', - 578 => 'TheFallenAngelHell', - 580 => 'TerrorsEndHell', - 582 => 'HellForgeHell', - //584 => 'emptyHell1', - //586 => 'emptyHell2', - //588 => 'emptyHell3', - //590 => 'traveledToAct5Hell', - //592 => 'completedTerrorsEndHell', - 594 => 'SiegeOnHarrogathHell', - 596 => 'RescueOnMountArreatHell', - 598 => 'PrisonOfIceHell', - 600 => 'BetrayalOfHarrogathHell', - 602 => 'RiteOfPassageHell', - 604 => 'EveOfDestructionHell', + //528 => 'introWarriv', + 530 => 'Den_Of_Evil_Hell', + 532 => 'Sisters_Burial_Grounds_Hell', + 534 => 'Tools_Of_The_Trade_Hell', + 536 => 'The_Search_For_Cain_Hell', + 538 => 'The_Forgotten_Tower_Hell', + 540 => 'Sisters_To_The_Slaughter_Hell', + //542 => 'traveledToAct2', + //544 => 'introJerhyn', + 546 => 'Radaments_Lair_Hell', + 548 => 'The_Horadric_Staff_Hell', + 550 => 'Tainted_Sun_Hell', + 552 => 'Arcane_Sanctuary_Hell', + 554 => 'The_Summoner_Hell', + 556 => 'The_SevenTombs_Hell', + //558 => 'traveledToAct3', + //560 => 'introHratli', + 562 => 'Lam_Esens_Tome_Hell', + 564 => 'KhalimsWill_Hell', + 566 => 'Blade_Of_The_Old_Religion_Hell', + 568 => 'The_Golden_Bird_Hell', + 570 => 'The_Blackened_Temple_Hell', + 572 => 'The_Guardian_Hell', + //574 => 'traveledtoAct4', + //576 => 'introToAct4', + 578 => 'The_Fallen_Angel_Hell', + 580 => 'Terrors_End_Hell', + 582 => 'Hell_Forge_Hell', + //584 => 'empty1', + //586 => 'empty2', + //588 => 'empty3', + //590 => 'traveledToAct5', + //592 => 'completedTerrorsEnd', + 594 => 'Siege_On_Harrogath_Hell', + 596 => 'Rescue_On_MountArreat_Hell', + 598 => 'Prison_Of_Ice_Hell', + 600 => 'Betrayal_Of_Harrogath_Hell', + 602 => 'Rite_Of_Passage_Hell', + 604 => 'Eve_Of_Destruction_Hell', ]; public $version = [ @@ -251,48 +251,52 @@ class D2SaveFileStructureData { ]; public $wpNames = [ - 0 => 'Rogue Encampment', - 1 => 'Cold Plains', - 2 => 'Stony Field', - 3 => 'Dark Wood', - 4 => 'Black Marsh', - 5 => 'Outer Cloister', - 6 => 'Jail, level 1', - 7 => 'Inner Cloister', - 8 => 'Catacombs, level 2', - 9 => 'Lut Gholein', - 10 => 'Sewers, level 2', - 11 => 'Dry Hills', - 12 => 'Halls of the Dead, level 2', - 13 => 'Far Oasis', - 14 => 'Lost City', - 15 => 'Palace Cellar, level 1', - 16 => 'Arcane Sanctuary', - 17 => 'Canyon of the Magi', - 18 => 'Kurast Docks', - 19 => 'Spider Forest', - 20 => 'Great Marsh', - 21 => 'Flayer Jungle', - 22 => 'Lower Kurast', - 23 => 'Kurast Bazaar', - 24 => 'Upper Kurast', + 0 => 'Rogue_Encampment', + 1 => 'Cold_Plains', + 2 => 'Stony_Field', + 3 => 'Dark_Wood', + 4 => 'Black_Marsh', + 5 => 'Outer_Cloister', + 6 => 'Jail_level_1', + 7 => 'Inner_Cloister', + 8 => 'Catacombs_level_2', + 9 => 'Lut_Gholein', + 10 => 'Sewers_level_2', + 11 => 'Dry_Hills', + 12 => 'Halls_of_the_Dead_level_2', + 13 => 'Far_Oasis', + 14 => 'Lost_City', + 15 => 'Palace_Cellar_level_1', + 16 => 'Arcane_Sanctuary', + 17 => 'Canyon_of_the_Magi', + 18 => 'Kurast_Docks', + 19 => 'Spider_Forest', + 20 => 'Great_Marsh', + 21 => 'Flayer_Jungle', + 22 => 'Lower_Kurast', + 23 => 'Kurast_Bazaar', + 24 => 'Upper_Kurast', 25 => 'Travincal', - 26 => 'Durance of Hate, level 2', - 27 => 'Pandemonium Fortress', - 28 => 'City of the Damned', - 29 => 'River of Flames', + 26 => 'Durance_of_Hate_level_2', + 27 => 'Pandemonium_Fortress', + 28 => 'City_of_the_Damned', + 29 => 'River_of_Flames', 30 => 'Harrogath', - 31 => 'Frigid Highlands', - 32 => 'Arreat Plateau', - 33 => 'Crystalline Passage', - 34 => 'Halls of Pain', - 35 => 'Glacial Trail', - 36 => 'Frozen Tundra', - 37 => "The Ancients' Way", - 38 => 'Worldstone Keep, level 2' + 31 => 'Frigid_Highlands', + 32 => 'Arreat_Plateau', + 33 => 'Crystalline_Passage', + 34 => 'Halls_of_Pain', + 35 => 'Glacial_Trail', + 36 => 'Frozen_Tundra', + 37 => "The_Ancients_Way", + 38 => 'Worldstone_Keep_level_2' ]; + public $_qNorm; + public $_qNM; + public $_qHell; + public $xorTable = [ "00" => 0x0, "01" => 0x77073096, @@ -553,10 +557,12 @@ class D2SaveFileStructureData { ]; + + /* Initialize Skills From Skills.txt */ - + public function __construct() { $sql = " @@ -576,6 +582,10 @@ class D2SaveFileStructureData { foreach ($res as $r) { $this->skills[$r['Id']] = $r['String']; } + + $this->_qNorm = array_flip($this->qNorm); + $this->_qNM = array_flip($this->qNM); + $this->_qHell = array_flip($this->qHell); } } diff --git a/src/tabs/Chars.php b/src/tabs/Chars.php index 07e53be..7ff7ae2 100644 --- a/src/tabs/Chars.php +++ b/src/tabs/Chars.php @@ -42,7 +42,7 @@ $form = new Formr\Formr(); SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// ddump($charData); + // ddump($charData); ?> @@ -82,28 +82,44 @@ EOT; $quests = null; foreach ($c->charData['Quests'] as $quest) { - foreach ($quest as $difficulty => $q) { + foreach ($quest as $difficulty => $q) { + $quests .= "

$difficulty

"; foreach ($q as $k => $v) { + $kD = str_replace("_", " ", $k); + $kD = str_replace(" NM", "", $kD); + $kD = str_replace(" Hell", "", $kD); + if ($v == 1) { - $quests .= "$k
"; + $quests .= "
"; } else { - $quests .= "$k
"; + $quests .= "
"; } } } } $wps = null; - foreach ($c->charData['Waypoints'] as $waypoints) { + $wps .= "

"; + foreach ($c->charData['Waypoints'] as $diff => $waypoints) { + $wps .= "

$diff

"; + array_pop($waypoints); foreach ($waypoints as $k => $v) { - if ($v == 1 && $k != ''){ - $wps .= "$k
"; + $kD = str_replace("_", " ", $k); + $kD = str_replace(" NM", "", $kD); + $kD = str_replace(" Hell", "", $kD); + if ($v == 1 && $k != ''){ + $wps .= "
"; } else { - $wps .= "$k
"; + $wps .= "
"; } } - } + } + + + + + $option = ''; if ($c->charData['CharacterClass'] == 'Amazon'){ @@ -171,36 +187,52 @@ EOT; + if ($c->charData['Quests'][0]['Norm']["DenOfEvil"]) $a1q1 = "checked"; + if ($c->charData['Quests'][0]['Norm']["SistersBurialGrounds"]) $a1q2 = "checked"; + if ($c->charData['Quests'][0]['Norm']["TheSearchForCain"]) $a1q3 = "checked"; + if ($c->charData['Quests'][0]['Norm']["TheForgottenTower"]) $a1q4 = "checked"; + if ($c->charData['Quests'][0]['Norm']["ToolsOfTheTrade"]) $a1q5 = "checked"; + if ($c->charData['Quests'][0]['Norm']["SistersToTheSlaughter"]) $a1q6 = "checked"; + + + + + // dump($c['Waypoints']); $tabContent .= << - -

{$c->charData['CharacterName']}

- - +
+
-
-
- -
-
- - -
- $radio -
-

Quests

$quests
-

Waypoints

$wps
+
+
+

{$c->charData['CharacterName']}

+ +
+ + +
+ $radio +
+

Quests

+ $quests +
+

Waypoints

+ $wps + +
+ +
- - + +
EOT;