/// <summary> /// Loads and decodes the strings.pak file as specificed by the Path. /// </summary> /// <param name="path">Path.</param> public void LoadStringsPak(string path) { //Set some default string numbers that are different from the default in uw2 switch (_RES) { case GAME_UW2: str_it_looks_to_be_that_of_ = 26; str_they_look_to_be_those_of_ = 27; str_you_are_not_ready_to_advance_ = 28; str_that_is_not_a_mantra_ = 29; str_knowledge_and_understanding_fill_you_ = 30; str_you_cannot_advance_any_further_in_that_skill_ = 31; str_you_have_advanced_greatly_in_ = 32; str_you_have_advanced_in_ = 33; str_none_of_your_skills_improved_ = 34; str_you_cannot_advance_in_ = 38; str_to_the_north = 40; str_to_the_northeast = 41; str_to_the_east = 42; str_to_the_southeast = 43; str_to_the_south = 44; str_to_the_southwest = 45; str_to_the_west = 46; str_to_the_northwest = 47; str_far_far_below_you_1 = 48; str_far_far_below_you_2 = 48; str_far_below_you_1 = 50; str_far_below_you_2 = 50; str_below_you_1 = 52; str_below_you_2 = 52; str_underneath_you = 54; str_above_you_1 = 56; str_above_you_2 = 56; str_above_you_3 = 56; str_far_above_you_1 = 59; str_far_above_you_2 = 59; str_far_far_above_you_1 = 61; str_far_far_above_you_2 = 61; str_you_detect_a_creature_ = 63; str_you_detect_a_few_creatures_ = 64; str_you_detect_the_activity_of_many_creatures_ = 65; str_you_detect_no_monster_activity_ = 66; str__is_currently_active_ = 67; str_you_are_currently_ = 68; str_you_are_on_the_ = 73; str__level_of_the_abyss_ = 74; str_it_is_the_ = 69; str__day_of_your_imprisonment_ = 70; str_it_has_been_an_uncountable_number_of_days_since_you_entered_the_abyss_ = 71; str_you_guess_that_it_is_currently_ = 72; str_night_1 = 84; str_night_2 = 84; str_dawn = 86; str_early_morning = 87; str_morning = 88; str_late_morning = 89; str_mid_day = 90; str_afternoon = 91; str_late_afternoon = 92; str_early_evening = 93; str_evening = 94; str_night_3 = 84; str__ = 96; str_barely = 97; str_mildly = 98; str_badly = 99; str_seriously = 100; str_egregiously = 101; str_your_current_vitality_is_ = 102; str_your_current_mana_points_are_ = 103; str_you_are_ = 104; str__poisoned_ = 105; str_that_is_too_far_away_to_take_ = 106; str_you_cannot_reach_that_ = 107; str_that_is_too_heavy_for_you_to_pick_up_ = 108; str_you_cannot_pick_that_up_ = 109; str_you_detect_no_traps_ = 110; str_you_found_a_trap__do_you_wish_to_try_to_disarm_it_1 = 111; str_you_catch_a_lovely_fish_ = 112; str_no_luck_this_time_ = 113; str_you_cannot_fish_there__perhaps_somewhere_else_ = 114; str_you_feel_a_nibble_but_the_fish_gets_away_ = 115; str__and_ = 116; str_starving = 117; str_famished = 118; str_very_hungry = 119; str_hungry = 120; str_peckish = 121; str_fed = 122; str_well_fed = 123; str_full = 124; str_satiated = 125; str_fatigued = 126; str_very_tired = 127; str_drowsy = 128; str_awake = 129; str_rested = 130; str_wide_awake = 131; str_you_can_only_use_those_individually__take_one_from_this_group_if_you_wish_to_use_it_ = 132; str_your_lockpicking_attempt_failed_ = 133; str_you_succeed_in_picking_the_lock_ = 135; str_that_is_not_locked_ = 136; str_lights_may_only_be_used_if_equipped_ = 137; str_that_light_is_already_used_up_ = 138; str_with_a_loud_snap_the_wand_cracks_ = 139; str_you_are_too_full_to_eat_that_now_ = 140; str_it_seems_to_have_no_effect_ = 146; str_you_thoughtfully_give_the_bones_a_final_resting_place_ = 148; str_the_rock_breaks_into_smaller_pieces_ = 149; str__is_nearly_done_ = 151; str__is_unstable_ = 152; str__is_stable_ = 153; str_you_destroyed_the_ = 154; str_you_damaged_the_ = 155; str_you_cannot_repair_that_ = 156; str_your_attempt_has_no_effect_on_the_ = 157; str_you_have_partially_repaired_the_ = 158; str_you_have_fully_repaired_the_ = 159; str_the_noise_you_made_has_attracted_attention_ = 160; str_you_have_attained_experience_level_ = 161; str_the_bowl_does_not_contain_the_correct_ingredients_ = 162; str_you_mix_the_ingredients_into_a_stew_ = 163; str_you_need_a_bowl_to_mix_the_ingredients_ = 164; str_enscribed_upon_the_scroll_is_your_map_ = 165; str_you_cannot_use_that_ = 166; str_why_is_this_being_printed_ = 167; str_you_see_nothing_ = 168; str_nothing_to_get_ = 169; str_you_cannot_talk_to_that_ = 170; str_using_the_pole_you_trigger_the_switch_ = 171; str_the_pole_cannot_be_used_on_that_ = 172; str_impossible_you_are_between_worlds_ = 173; str_you_cannot_select_options_partway_through_an_action_ = 174; str_no_save_game_there_ = 175; str_restore_game_complete_ = 176; str_restore_game_failed_ = 177; str_save_game_failed_ = 178; str_save_game_succeeded_ = 179; str_restoring_game_ = 181; str_saving_game_ = 182; str_please_enter_a_save_file_description_ = 183; str_error_bad_save_file = 184; //str_...=1; str_you_see_a_bridge_ = 186; str__tasted_putrid_ = 187; str__tasted_a_little_rancid_ = 188; str__tasted_kind_of_bland_ = 189; str__tasted_pretty_good_ = 190; str__tasted_great_ = 191; str_you_cannot_use_oil_on_that_ = 192; str_you_think_it_is_a_bad_idea_to_add_oil_to_the_lit_lantern_ = 193; str_adding_oil_you_refuel_the_lantern_ = 194; str_the_lantern_is_already_full_ = 195; str_dousing_a_cloth_with_oil_and_applying_it_to_the_wood_you_make_a_torch_ = 196; str_you_think_it_is_a_bad_idea_to_add_oil_to_the_lit_torch_ = 197; str_you_refresh_the_torch_ = 198; str_the_torch_is_unused_ = 199; str_you_are_unable_to_use_that_from_here_ = 200; str_you_cannot_barter_a_container__instead_remove_the_contents_you_want_to_trade_ = 201; str_a_level_ = 202; str_after_ = 204; str_you_press_in_the_button_1 = 209; str_you_press_in_the_button_2 = 209; str_you_press_in_the_button_3 = 209; str_you_flip_the_switch_1 = 212; str_you_flip_the_switch_2 = 212; str_you_pull_the_lever_1 = 214; str_you_pull_the_chain_1 = 215; str_you_pull_the_chain_2 = 215; str_the_button_returns_to_its_original_state_1 = 217; str_the_button_returns_to_its_original_state_2 = 217; str_the_button_returns_to_its_original_state_3 = 217; str_you_flip_the_switch_1 = 212; str_you_flip_the_switch_2 = 212; str_you_push_the_lever_2 = 222; str_you_return_the_chain_to_its_original_position_1 = 223; str_you_return_the_chain_to_its_original_position_2 = 223; str_you_are_not_experienced_enough_to_cast_spells_of_that_circle_ = 225; str_you_do_not_have_enough_mana_to_cast_the_spell_ = 226; str_the_incantation_failed_ = 227; str_casting_was_not_successful_ = 228; str_the_spell_backfires_ = 229; str_you_attempt_to_use_the_wand_ = 230; str_you_think_it_will_be_ = 231; str__to_repair_the_ = 232; str__make_an_attempt_ = 233; str_trivial = 234; str_simple = 235; str_possible = 236; str_hard = 237; str_very_difficult = 238; str_the_leeches_remove_the_poison_as_well_as_some_of_your_skin_and_blood_ = 239; str__is_angered_by_your_action_ = 240; str__is_annoyed_by_your_action_ = 241; str__notes_your_action_ = 242; str_your_vision_distorts_and_you_feel_light_headed_ = 243; str_you_manage_to_finish_eating_the_leeches__barely_ = 244; str_you_eat_the_candle_but_doubt_that_it_was_good_for_you_ = 245; str_the_toadstool_tastes_odd_and_you_begin_to_feel_ill_ = 246; str_the_mushroom_causes_your_head_to_spin_and_your_vision_to_blur_ = 247; str_the_plant_is_plain_tasting_but_nourishing_ = 248; str_although_you_have_to_eat_around_the_thorny_flowers_the_plant_is_quite_good_ = 251; str_the_water_refreshes_you_ = 252; str_you_drink_the_dark_ale_ = 254; str_you_quaff_the_potion_in_one_gulp_ = 255; str_as_the_alcohol_hits_you_you_stumble_and_collapse_into_sleep_ = 256; str_the_drink_makes_you_feel_a_little_better_for_now_ = 257; str_you_wake_feeling_somewhat_unstable_but_better_ = 258; str_you_found_a_trap__do_you_wish_to_try_to_disarm_it_2 = 259; str_your_rune_of_warding_has_been_set_off_ = 260; str_your_hands_are_full_ = 261; str_you_can_only_put_runes_in_the_rune_bag_ = 262; str_that_item_does_not_fit_ = 263; str_the_waters_of_the_fountain_renew_your_strength_ = 264; str_you_play_the_instrument_ = 265; str_you_put_the_instrument_down_ = 266; str_that_is_too_heavy_to_take_ = 268; str_there_is_no_space_to_drop_that_ = 269; str_you_need_more_space_to_fire_that_weapon_ = 270; str_there_is_not_enough_room_to_release_that_spell_ = 271; str_enters_the_abyss___ = 272; str_you_reenter_the_abyss___ = 273; str_there_is_no_place_to_put_that_ = 274; str_you_see_ = 276; str_the_spell_unlocks_the_lock_ = 286; str_the_spell_has_no_discernable_effect_ = 287; str_the_moonstone_is_not_available_ = 289; str_the_cauldron_is_empty_ = 290; str_gamename = 291; str_there_is_no_room_to_create_that_ = 293; str_a_rending_sound_fills_the_air_ = 294; str_you_cannot_save_or_restore_games_in_the_demo_version_ = 297; break; //default: //Restore=162; //IsAngered=225; //IsAnnoyed=226; //YouSee=260; //break; } string Result = ""; long address_pointer = 0; huffman_node[] hman; block_dir[] blocks; char[] Buffer; string Key = ""; GameStrings = new Hashtable(); EntryCounts = new Hashtable(); if (DataLoader.ReadStreamFile(path, out Buffer)) { long NoOfNodes = DataLoader.getValAtAddress(Buffer, address_pointer, 16); int i = 0; hman = new huffman_node [NoOfNodes]; address_pointer = address_pointer + 2; while (i < NoOfNodes) { hman[i].symbol = System.Convert.ToChar(Buffer[address_pointer + 0]); hman[i].parent = Buffer[address_pointer + 1]; hman[i].left = Buffer[address_pointer + 2]; hman[i].right = Buffer[address_pointer + 3]; i++; address_pointer = address_pointer + 4; } long NoOfStringBlocks = DataLoader.getValAtAddress(Buffer, address_pointer, 16); blocks = new block_dir[NoOfStringBlocks]; address_pointer = address_pointer + 2; i = 0; while (i < NoOfStringBlocks) { blocks[i].block_no = DataLoader.getValAtAddress(Buffer, address_pointer, 16); address_pointer = address_pointer + 2; blocks[i].address = DataLoader.getValAtAddress(Buffer, address_pointer, 32); address_pointer = address_pointer + 4; blocks[i].NoOfEntries = DataLoader.getValAtAddress(Buffer, blocks[i].address, 16); //look ahead and get no of entries. EntryCounts["_" + blocks[i].block_no] = blocks[i].NoOfEntries.ToString(); i++; } i = 0; // int Iteration = 0; while (i < NoOfStringBlocks) { address_pointer = 2 + blocks[i].address + blocks[i].NoOfEntries * 2; int blnFnd; for (int j = 0; j < blocks[i].NoOfEntries; j++) { //Based on abysmal /uwadv implementations. blnFnd = 0; //char c; int bit = 0; int raw = 0; long node = 0; do { node = NoOfNodes - 1; // starting node // huffman tree decode loop //This was -1 in the original code! while (hman[node].left != 255 && hman[node].right != 255) { if (bit == 0) { bit = 8; raw = Buffer[address_pointer++]; //stream.get<uint8_t>(); } Iteration++; //Debug.Log("raw=" + raw + "=" + (raw & 0x80)); // decide which node is next //node = raw & 0x80 ? hman[node].right // : hman[node].left; if ((raw & 0x80) == 128) { node = hman[node].right; } else { node = hman[node].left; } raw <<= 1; bit--; } // have a new symbol if ((hman[node].symbol != '|')) { if (blnFnd == 0) { Key = blocks[i].block_no.ToString("000") + "_" + j.ToString("000"); } Result += hman[node].symbol; blnFnd = 1; } else { if ((Result.Length > 0) && (Key.Length > 0)) { GameStrings[Key] = Result; Result = ""; Key = ""; } } } while (hman[node].symbol != '|'); } i++; } if ((Result.Length > 0) && (Key.Length > 0)) { //I still have the very last value to keep. GameStrings[Key] = Result; Result = ""; } } }
/// <summary> /// Loads and decodes the strings.pak file as specificed by the Path. /// </summary> /// <param name="path">Path.</param> public void LoadStringsPak(string path) { string Result = ""; long address_pointer = 0; huffman_node[] hman; block_dir[] blocks; char[] Buffer; string Key = ""; GameStrings = new Hashtable(); if (DataLoader.ReadStreamFile(path, out Buffer)) { long NoOfNodes = DataLoader.getValAtAddress(Buffer, address_pointer, 16); int i = 0; hman = new huffman_node [NoOfNodes]; address_pointer = address_pointer + 2; while (i < NoOfNodes) { hman[i].symbol = System.Convert.ToChar(Buffer[address_pointer + 0]); hman[i].parent = Buffer[address_pointer + 1]; hman[i].left = Buffer[address_pointer + 2]; hman[i].right = Buffer[address_pointer + 3]; i++; address_pointer = address_pointer + 4; } long NoOfStringBlocks = DataLoader.getValAtAddress(Buffer, address_pointer, 16); blocks = new block_dir[NoOfStringBlocks]; address_pointer = address_pointer + 2; i = 0; while (i < NoOfStringBlocks) { blocks[i].block_no = DataLoader.getValAtAddress(Buffer, address_pointer, 16); address_pointer = address_pointer + 2; blocks[i].address = DataLoader.getValAtAddress(Buffer, address_pointer, 32); address_pointer = address_pointer + 4; blocks[i].NoOfEntries = DataLoader.getValAtAddress(Buffer, blocks[i].address, 16); //look ahead and get no of entries. i++; } i = 0; // int Iteration = 0; while (i < NoOfStringBlocks) { address_pointer = 2 + blocks[i].address + blocks[i].NoOfEntries * 2; int blnFnd; for (int j = 0; j < blocks[i].NoOfEntries; j++) { //Based on abysmal /uwadv implementations. blnFnd = 0; //char c; int bit = 0; int raw = 0; long node = 0; do { node = NoOfNodes - 1; // starting node // huffman tree decode loop //This was -1 in the original code! while (hman[node].left != 255 && hman[node].right != 255) { if (bit == 0) { bit = 8; raw = Buffer[address_pointer++]; //stream.get<uint8_t>(); } Iteration++; //Debug.Log("raw=" + raw + "=" + (raw & 0x80)); // decide which node is next //node = raw & 0x80 ? hman[node].right // : hman[node].left; if ((raw & 0x80) == 128) { node = hman[node].right; } else { node = hman[node].left; } raw <<= 1; bit--; } // have a new symbol if ((hman[node].symbol != '|')) { if (blnFnd == 0) { Key = blocks[i].block_no.ToString("000") + "_" + j.ToString("000"); } Result += hman[node].symbol; blnFnd = 1; } else { if ((Result.Length > 0) && (Key.Length > 0)) { GameStrings[Key] = Result; Result = ""; Key = ""; } } } while (hman[node].symbol != '|'); } i++; } if ((Result.Length > 0) && (Key.Length > 0)) { //I still have the very last value to keep. GameStrings[Key] = Result; Result = ""; } } }