From ae56c9b31a19dc8337a6432c9bf2e1bc9f0a90bf Mon Sep 17 00:00:00 2001 From: patel-nikhil Date: Sat, 14 Aug 2021 16:26:21 -0400 Subject: [PATCH 1/7] Initial backend refactor --- UnofficialCrusaderPatch/AIC/AICChange.cs | 642 ---------- UnofficialCrusaderPatch/AIC/AICView.cs | 61 - UnofficialCrusaderPatch/AIV/AIVView.cs | 72 -- UnofficialCrusaderPatch/API/ModAPIContract.cs | 227 ++++ UnofficialCrusaderPatch/Configuration.cs | 189 --- UnofficialCrusaderPatch/Debug.cs | 26 - UnofficialCrusaderPatch/Graphics/shield.png | Bin 1287 -> 0 bytes .../Localization/Chinese.txt | 1072 ---------------- .../Localization/English.txt | 1071 ---------------- .../Localization/German.txt | 1075 ---------------- .../Localization/Hungarian.txt | 1061 ---------------- .../Localization/Localization.cs | 230 ---- .../Localization/Polish.txt | 1102 ----------------- .../Localization/Russian.txt | 1072 ---------------- .../Localization/TextReferencer.cs | 72 -- .../Model/AICConfiguration.cs | 38 + .../Model/AIVConfiguration.cs | 15 + .../Model/ChangeConfiguration.cs | 46 + .../Model/ChangeUIConfig.cs | 14 + UnofficialCrusaderPatch/Model/Mod.cs | 233 ++++ .../Model/ModSelectionType.cs | 6 + UnofficialCrusaderPatch/Model/ModUIConfig.cs | 16 + .../Model/Patching/Installer.cs | 216 ++++ .../Patching/Utils}/BinElements/BinCode.cs | 0 .../Utils}/BinElements/BinCollection.cs | 0 .../Patching/Utils}/BinElements/BinElement.cs | 0 .../Patching/Utils}/BinElements/BinNops.cs | 0 .../Patching/Utils}/BinElements/BinSkip.cs | 0 .../Patching/Utils}/BinElements/BinValue.cs | 0 .../Patching/Utils}/BinElements/OpCodes.cs | 3 - .../BinElements/Referencers/BinAddress.cs | 0 .../BinElements/Referencers/BinAlloc.cs | 13 +- .../Utils}/BinElements/Referencers/BinHook.cs | 5 +- .../BinElements/Referencers/BinLabel.cs | 0 .../BinElements/Referencers/BinRedirect.cs | 0 .../BinElements/Referencers/BinRefTo.cs | 0 .../Patching/Utils}/BinElements/Register.cs | 7 +- .../BinElements/StructTypes/BinBytes.cs | 10 +- .../BinElements/StructTypes/BinInt32.cs | 5 +- .../BinElements/StructTypes/BinShort.cs | 5 +- .../Model/Patching/Utils/Changes/AICChange.cs | 19 + .../Patching/Utils/Changes}/AIVChange.cs | 252 +--- .../Model/Patching/Utils/Changes/Change.cs | 53 + .../Patching/Utils}/Changes/ChangeArgs.cs | 0 .../Patching/Utils}/Changes/ChangeType.cs | 2 +- .../Utils/Changes/StartResourceChange.cs | 12 + .../Utils/Changes/StartTroopChange.cs | 12 + .../Patching/Utils}/EditTypes/BinArgs.cs | 0 .../Patching/Utils}/EditTypes/BinaryEdit.cs | 7 +- .../Utils}/EditTypes/BinaryEditBase.cs | 4 +- .../Patching/Utils}/EditTypes/ChangeEdit.cs | 6 +- .../Patching/Utils}/EditTypes/EditFailures.cs | 0 .../Patching/Utils}/EditTypes/UCPEdit.cs | 4 +- .../Model/Patching/Utils/GlobalLabels.cs | 22 + .../Patching/Utils}/LabelCollection.cs | 0 .../Patching/Utils}/Section/AddressSpace.cs | 0 .../Model/Patching/Utils/Section/PEHeader.cs | 61 + .../Patching/Utils}/Section/SectionEditor.cs | 78 +- .../Patching/Utils/Section/SectionHeader.cs | 70 ++ .../Model/Patching/Utils/Section/Utils.cs | 11 + .../Utils/SubChanges/DefaultSubChange.cs | 25 + .../Patching/Utils/SubChanges/SubChange.cs} | 2 +- .../Utils/SubChanges/ValuedSubChange.cs | 17 + .../Model/Patching/Utils/UI_Text.cs | 116 ++ .../Model/SelectionParameter.cs | 6 + .../Model/SelectionType.cs | 6 + .../Model/StartResourceConfiguration.cs | 15 + .../Model/StartTroopConfiguration.cs | 15 + UnofficialCrusaderPatch/Model/UIConfig.cs | 67 + .../Patching/Changes/Change.cs | 235 ---- .../Patching/Headers/ColorHeader.cs | 94 -- .../Patching/Headers/DefaultHeader.cs | 144 --- .../Patching/Headers/ParamHeader.cs | 17 - .../Patching/Headers/SliderHeader.cs | 87 -- .../Patching/Headers/ValueHeader.cs | 93 -- UnofficialCrusaderPatch/Patching/Patcher.cs | 234 ---- .../Patching/Percentage.cs | 49 - .../Patching/Section/PEHeader.cs | 64 - .../Patching/Section/SectionHeader.cs | 74 -- .../AIC}/descriptions.json | 0 .../Resources => Resources/AIC}/errors.json | 0 .../CodeBlocks/ai_access.block | 0 .../CodeBlocks/ai_addattack.block | 0 .../CodeBlocks/ai_addattack_alt.block | 0 .../CodeBlocks/ai_assaultswitch.block | 0 .../CodeBlocks/ai_attacklimit.block | 0 .../CodeBlocks/ai_attacktarget.block | 0 .../CodeBlocks/ai_attackwave.block | 0 .../CodeBlocks/ai_attackwave_lord.block | 0 .../CodeBlocks/ai_attackwave_wallcount.block | 0 .../CodeBlocks/ai_buildhousing.block | 0 .../CodeBlocks/ai_buywood.block | 0 .../CodeBlocks/ai_defense_affinity.block | 0 .../CodeBlocks/ai_defense_check.block | 0 .../CodeBlocks/ai_defense_count.block | 0 .../CodeBlocks/ai_defense_group.block | 0 .../CodeBlocks/ai_defense_reset.block | 0 .../CodeBlocks/ai_deletehousing.block | 0 .../CodeBlocks/ai_demolish_eco.block | 0 .../CodeBlocks/ai_demolish_trapped.block | 0 .../CodeBlocks/ai_demolish_walls.block | 0 .../ai_fix_crusader_archers_pitch.block | 0 .../ai_fix_crusader_archers_pitch_attr.block | 0 .../ai_fix_crusader_archers_pitch_fn.block | 0 .../ai_fix_laddermen_with_enclosed_keep.block | 0 .../CodeBlocks/ai_foodbuy_wazir.block | 0 .../CodeBlocks/ai_nosleep.block | 0 .../CodeBlocks/ai_overclock.block | 0 .../{ => Resources}/CodeBlocks/ai_prop.block | 0 .../CodeBlocks/ai_rebuildtowers.block | 0 .../CodeBlocks/ai_rebuildwalls.block | 0 .../CodeBlocks/ai_recruitinterval.block | 0 .../CodeBlocks/ai_recruitsleep.block | 0 .../ai_recruitstate_initialtimer.block | 0 .../CodeBlocks/ai_tethers.block | 0 .../CodeBlocks/ai_towerengines.block | 0 .../CodeBlocks/ai_wepbuy_abbot.block | 0 .../CodeBlocks/ai_wepbuy_emir.block | 0 .../CodeBlocks/ai_wepbuy_frederick.block | 0 .../CodeBlocks/ai_wepbuy_marshal.block | 0 .../fix_apple_orchard_build_size.block | 0 .../CodeBlocks/laddermadness.block | 0 .../CodeBlocks/menuversion.block | 0 ...armory_marketplace_weapon_order_fix1.block | 0 ...armory_marketplace_weapon_order_fix2.block | 0 ...armory_marketplace_weapon_order_fix3.block | 0 ...armory_marketplace_weapon_order_fix4.block | 0 ...armory_marketplace_weapon_order_fix5.block | 0 ...siege_engine_spawn_position_catapult.block | 0 ...e_engine_spawn_position_fireballista.block | 0 ...ange_siege_engine_spawn_position_ram.block | 0 ...e_siege_engine_spawn_position_shield.block | 0 ...ge_siege_engine_spawn_position_tower.block | 0 ...ege_engine_spawn_position_trebutchet.block | 0 .../o_default_multiplayer_speed.block | 0 .../o_default_multiplayer_speed_reset.block | 0 .../CodeBlocks/o_engineertent.block | 0 .../CodeBlocks/o_firecooldown.block | 0 .../CodeBlocks/o_fix_baker_disappear.block | 0 .../CodeBlocks/o_fix_fletcher_bug.block | 0 .../CodeBlocks/o_fix_ladderclimb.block | 0 .../CodeBlocks/o_fix_ladderclimb_2.block | 0 .../CodeBlocks/o_fix_ladderclimb_3.block | 0 .../CodeBlocks/o_fix_ladderclimb_4.block | 0 .../CodeBlocks/o_fix_ladderclimb_pre.block | 0 ...o_fix_moat_digging_unit_disappearing.block | 0 .../CodeBlocks/o_freetrader.block | 0 .../CodeBlocks/o_gamespeed_down.block | 0 .../CodeBlocks/o_gamespeed_up.block | 0 .../CodeBlocks/o_gatedistance.block | 0 .../CodeBlocks/o_gatetime.block | 0 .../CodeBlocks/o_healer_cmp.block | 0 .../CodeBlocks/o_healer_find.block | 0 .../CodeBlocks/o_healer_jesternext.block | 0 .../CodeBlocks/o_healer_next.block | 0 .../CodeBlocks/o_healer_plague.block | 0 .../CodeBlocks/o_healerroam.block | 0 .../o_increase_path_update_tick_rate.block | 0 .../CodeBlocks/o_jesterroam.block | 0 .../CodeBlocks/o_keys_down.block | 0 .../{ => Resources}/CodeBlocks/o_keys_l.block | 0 .../CodeBlocks/o_keys_loadname.block | 0 .../CodeBlocks/o_keys_menu.block | 0 .../{ => Resources}/CodeBlocks/o_keys_s.block | 0 .../CodeBlocks/o_keys_savefunc.block | 0 .../CodeBlocks/o_keys_savename.block | 0 .../CodeBlocks/o_keys_up.block | 0 .../CodeBlocks/o_moatvisibility.block | 0 .../{ => Resources}/CodeBlocks/o_onlyai.block | 0 .../CodeBlocks/o_onlyai_assassins.block | 0 .../CodeBlocks/o_onlyai_face.block | 0 .../CodeBlocks/o_onlyai_load1.block | 0 .../CodeBlocks/o_onlyai_load2.block | 0 .../CodeBlocks/o_onlyai_reset.block | 0 .../CodeBlocks/o_override_identity_menu.block | 0 ...playercolor_ai_allied_menu_ally_name.block | 0 ...ercolor_ai_allied_menu_attack_emblem.block | 0 .../o_playercolor_ai_allied_menu_emblem.block | 0 .../o_playercolor_ai_order_menu_emblem.block | 0 ..._playercolor_ai_video_message_emblem.block | 0 ..._playercolor_ai_video_message_shield.block | 0 ..._ai_video_message_shield_enemy_taunt.block | 0 ...yercolor_ai_video_message_shield_pre.block | 0 .../CodeBlocks/o_playercolor_chat.block | 0 .../CodeBlocks/o_playercolor_chat2.block | 0 .../CodeBlocks/o_playercolor_emblem1.block | 0 .../CodeBlocks/o_playercolor_emblem2.block | 0 .../CodeBlocks/o_playercolor_endscore.block | 0 .../CodeBlocks/o_playercolor_fade.block | 0 .../CodeBlocks/o_playercolor_gameover.block | 0 .../CodeBlocks/o_playercolor_ingame.block | 0 .../CodeBlocks/o_playercolor_list.block | 0 .../CodeBlocks/o_playercolor_minilist1.block | 0 .../CodeBlocks/o_playercolor_minilist2.block | 0 .../CodeBlocks/o_playercolor_minimap.block | 0 .../CodeBlocks/o_playercolor_mm_emblem1.block | 0 .../CodeBlocks/o_playercolor_mm_emblem2.block | 0 .../o_playercolor_mm_shield_drag.block | 0 .../o_playercolor_mm_shield_hover.block | 0 .../CodeBlocks/o_playercolor_mm_shields.block | 0 .../CodeBlocks/o_playercolor_scorename.block | 0 .../CodeBlocks/o_playercolor_table1.block | 0 .../CodeBlocks/o_playercolor_table2.block | 0 .../CodeBlocks/o_playercolor_table_back.block | 0 .../CodeBlocks/o_playercolor_table_drag.block | 0 .../CodeBlocks/o_playercolor_trail_name.block | 0 .../o_playercolor_trail_portrait.block | 0 .../o_playercolor_trail_shield.block | 0 .../o_playercolor_trail_shield2.block | 0 .../CodeBlocks/o_playercolor_trebuchet.block | 0 .../o_restore_arabian_engineer_speech.block | 0 ...store_arabian_engineer_speech_engine.block | 0 ...re_arabian_engineer_speech_lord_type.block | 0 ...ore_arabian_engineer_speech_purchase.block | 0 .../o_seed_modification_possibility.block | 0 .../o_seed_modification_possibility_fn1.block | 0 .../o_seed_modification_possibility_fn2.block | 0 .../o_seed_modification_possibility_fn3.block | 0 .../o_seed_modification_possibility_fn4.block | 0 .../o_seed_modification_possibility_fn5.block | 0 .../CodeBlocks/o_shfy_beerpopularity.block | 0 .../CodeBlocks/o_shfy_beerpopularitytab.block | 0 .../CodeBlocks/o_shfy_beertab.block | 0 .../CodeBlocks/o_shfy_peasantspawnrate.block | 0 .../o_shfy_religionpopularity.block | 0 .../o_shfy_religionpopularitytab.block | 0 .../CodeBlocks/o_shfy_religiontab.block | 0 .../CodeBlocks/o_shfy_resourcequantity.block | 0 .../o_stop_player_keep_rotation.block | 0 ...n_get_preferred_relative_orientation.block | 0 .../CodeBlocks/o_trooplimit.block | 0 .../CodeBlocks/o_xtreme_bar1.block | 0 .../CodeBlocks/o_xtreme_bar2.block | 0 .../{ => Resources}/CodeBlocks/random.block | 0 .../{ => Resources}/CodeBlocks/s_gold.block | 0 .../CodeBlocks/s_lordstrength.block | 0 .../CodeBlocks/s_lordtype.block | 0 .../CodeBlocks/s_resource.block | 0 .../{ => Resources}/CodeBlocks/s_troops.block | 0 .../CodeBlocks/u_arabwall.block | 0 .../CodeBlocks/u_arabxbow.block | 0 .../CodeBlocks/u_fireballistamonk.block | 0 .../CodeBlocks/u_fireballistatunneler.block | 0 .../CodeBlocks/u_fix_applefarm_blocking.block | 0 ...lord_animation_stuck_building_attack.block | 0 .../u_fix_lord_animation_stuck_movement.block | 0 .../CodeBlocks/u_ladderarmor_bow.block | 0 .../CodeBlocks/u_ladderarmor_sling.block | 0 .../CodeBlocks/u_ladderarmor_xbow.block | 0 .../CodeBlocks/u_laddergold.block | 0 .../CodeBlocks/u_spearbow.block | 0 .../CodeBlocks/u_spearmen_run.block | 0 .../CodeBlocks/u_spearxbow.block | 0 .../CodeBlocks/u_tanner_fix.block | 0 ...rmen_cost_display_in_engineers_guild.block | 0 .../Startup/ResourceView.cs | 72 -- .../Startup/StartTroopView.cs | 71 -- .../UnofficialCrusaderPatch.csproj | 531 ++++---- .../Util/Comparators/FileComparer.cs | 38 + .../Util/Enumerators/AICEnumerator.cs | 307 +++++ .../Util/Enumerators/AIVEnumerator.cs | 133 ++ .../Enumerators/StartResourceEnumerator.cs} | 221 +--- .../Enumerators/StartTroopEnumerator.cs} | 224 +--- .../Enumerators}/StartingEnums.cs | 0 .../{ => Util/Readers}/Extensions.cs | 9 +- .../{AIC => Util/Readers}/Utils/AICHelper.cs | 0 .../Utils/AICSerializationException.cs | 0 .../Readers}/Utils/AICharacter.cs | 0 .../Readers}/Utils/AICharacterName.cs | 0 .../AICharacterSerializationException.cs | 0 .../Readers}/Utils/AICollection.cs | 0 .../Readers}/Utils/AIPersonality.cs | 0 .../Readers}/Utils/AIPersonalityFieldsEnum.cs | 0 .../Readers}/Utils/AISerializer.cs | 0 .../Utils/PersonalityEnums/Buildings.cs | 0 .../Utils/PersonalityEnums/Resources.cs | 0 .../Utils/PersonalityEnums/SiegeEngines.cs | 0 .../Utils/PersonalityEnums/TargetingType.cs | 0 .../Readers}/Utils/PersonalityEnums/Units.cs | 0 .../PersonalityEnums/WorkshopSettings.cs | 0 .../Readers}/Utils/RWAttributes.cs | 0 UnofficialCrusaderPatch/Version.cs | 115 +- UnofficialCrusaderPatch/_Crusader/Building.cs | 10 - .../_Crusader/UI_Button.cs | 32 - UnofficialCrusaderPatch/_Crusader/Unit.cs | 9 - UnofficialCrusaderPatch/packages.config | 4 + 286 files changed, 2316 insertions(+), 10037 deletions(-) delete mode 100644 UnofficialCrusaderPatch/AIC/AICChange.cs delete mode 100644 UnofficialCrusaderPatch/AIC/AICView.cs delete mode 100644 UnofficialCrusaderPatch/AIV/AIVView.cs create mode 100644 UnofficialCrusaderPatch/API/ModAPIContract.cs delete mode 100644 UnofficialCrusaderPatch/Configuration.cs delete mode 100644 UnofficialCrusaderPatch/Debug.cs delete mode 100644 UnofficialCrusaderPatch/Graphics/shield.png delete mode 100644 UnofficialCrusaderPatch/Localization/Chinese.txt delete mode 100644 UnofficialCrusaderPatch/Localization/English.txt delete mode 100644 UnofficialCrusaderPatch/Localization/German.txt delete mode 100644 UnofficialCrusaderPatch/Localization/Hungarian.txt delete mode 100644 UnofficialCrusaderPatch/Localization/Localization.cs delete mode 100644 UnofficialCrusaderPatch/Localization/Polish.txt delete mode 100644 UnofficialCrusaderPatch/Localization/Russian.txt delete mode 100644 UnofficialCrusaderPatch/Localization/TextReferencer.cs create mode 100644 UnofficialCrusaderPatch/Model/AICConfiguration.cs create mode 100644 UnofficialCrusaderPatch/Model/AIVConfiguration.cs create mode 100644 UnofficialCrusaderPatch/Model/ChangeConfiguration.cs create mode 100644 UnofficialCrusaderPatch/Model/ChangeUIConfig.cs create mode 100644 UnofficialCrusaderPatch/Model/Mod.cs create mode 100644 UnofficialCrusaderPatch/Model/ModSelectionType.cs create mode 100644 UnofficialCrusaderPatch/Model/ModUIConfig.cs create mode 100644 UnofficialCrusaderPatch/Model/Patching/Installer.cs rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/BinCode.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/BinCollection.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/BinElement.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/BinNops.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/BinSkip.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/BinValue.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/OpCodes.cs (99%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Referencers/BinAddress.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Referencers/BinAlloc.cs (72%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Referencers/BinHook.cs (96%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Referencers/BinLabel.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Referencers/BinRedirect.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Referencers/BinRefTo.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/Register.cs (57%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/StructTypes/BinBytes.cs (80%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/StructTypes/BinInt32.cs (86%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/BinElements/StructTypes/BinShort.cs (86%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AICChange.cs rename UnofficialCrusaderPatch/{AIV => Model/Patching/Utils/Changes}/AIVChange.cs (54%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Changes/Change.cs rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/Changes/ChangeArgs.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/Changes/ChangeType.cs (88%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartResourceChange.cs create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartTroopChange.cs rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/EditTypes/BinArgs.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/EditTypes/BinaryEdit.cs (82%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/EditTypes/BinaryEditBase.cs (95%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/EditTypes/ChangeEdit.cs (65%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/EditTypes/EditFailures.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/EditTypes/UCPEdit.cs (91%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/GlobalLabels.cs rename UnofficialCrusaderPatch/{Patching/Headers => Model/Patching/Utils}/LabelCollection.cs (100%) rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/Section/AddressSpace.cs (100%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Section/PEHeader.cs rename UnofficialCrusaderPatch/{Patching => Model/Patching/Utils}/Section/SectionEditor.cs (72%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionHeader.cs create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/Section/Utils.cs create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/DefaultSubChange.cs rename UnofficialCrusaderPatch/{Patching/Headers/ChangeHeader.cs => Model/Patching/Utils/SubChanges/SubChange.cs} (93%) create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/ValuedSubChange.cs create mode 100644 UnofficialCrusaderPatch/Model/Patching/Utils/UI_Text.cs create mode 100644 UnofficialCrusaderPatch/Model/SelectionParameter.cs create mode 100644 UnofficialCrusaderPatch/Model/SelectionType.cs create mode 100644 UnofficialCrusaderPatch/Model/StartResourceConfiguration.cs create mode 100644 UnofficialCrusaderPatch/Model/StartTroopConfiguration.cs create mode 100644 UnofficialCrusaderPatch/Model/UIConfig.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Changes/Change.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Headers/ColorHeader.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Headers/DefaultHeader.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Headers/ParamHeader.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Headers/SliderHeader.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Headers/ValueHeader.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Patcher.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Percentage.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Section/PEHeader.cs delete mode 100644 UnofficialCrusaderPatch/Patching/Section/SectionHeader.cs rename UnofficialCrusaderPatch/{AIC/Resources => Resources/AIC}/descriptions.json (100%) rename UnofficialCrusaderPatch/{AIC/Resources => Resources/AIC}/errors.json (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_access.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_addattack.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_addattack_alt.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_assaultswitch.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_attacklimit.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_attacktarget.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_attackwave.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_attackwave_lord.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_attackwave_wallcount.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_buildhousing.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_buywood.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_defense_affinity.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_defense_check.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_defense_count.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_defense_group.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_defense_reset.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_deletehousing.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_demolish_eco.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_demolish_trapped.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_demolish_walls.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_fix_crusader_archers_pitch.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_fix_crusader_archers_pitch_attr.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_fix_crusader_archers_pitch_fn.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_fix_laddermen_with_enclosed_keep.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_foodbuy_wazir.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_nosleep.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_overclock.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_prop.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_rebuildtowers.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_rebuildwalls.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_recruitinterval.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_recruitsleep.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_recruitstate_initialtimer.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_tethers.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_towerengines.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_wepbuy_abbot.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_wepbuy_emir.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_wepbuy_frederick.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ai_wepbuy_marshal.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/fix_apple_orchard_build_size.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/laddermadness.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/menuversion.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_armory_marketplace_weapon_order_fix1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_armory_marketplace_weapon_order_fix2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_armory_marketplace_weapon_order_fix3.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_armory_marketplace_weapon_order_fix4.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_armory_marketplace_weapon_order_fix5.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_change_siege_engine_spawn_position_catapult.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_change_siege_engine_spawn_position_fireballista.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_change_siege_engine_spawn_position_ram.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_change_siege_engine_spawn_position_shield.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_change_siege_engine_spawn_position_tower.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_change_siege_engine_spawn_position_trebutchet.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_default_multiplayer_speed.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_default_multiplayer_speed_reset.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_engineertent.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_firecooldown.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_baker_disappear.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_fletcher_bug.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_ladderclimb.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_ladderclimb_2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_ladderclimb_3.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_ladderclimb_4.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_ladderclimb_pre.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_fix_moat_digging_unit_disappearing.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_freetrader.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_gamespeed_down.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_gamespeed_up.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_gatedistance.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_gatetime.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_healer_cmp.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_healer_find.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_healer_jesternext.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_healer_next.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_healer_plague.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_healerroam.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_increase_path_update_tick_rate.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_jesterroam.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_down.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_l.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_loadname.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_menu.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_s.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_savefunc.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_savename.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_keys_up.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_moatvisibility.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_onlyai.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_onlyai_assassins.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_onlyai_face.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_onlyai_load1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_onlyai_load2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_onlyai_reset.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_override_identity_menu.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_allied_menu_ally_name.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_allied_menu_attack_emblem.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_allied_menu_emblem.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_order_menu_emblem.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_video_message_emblem.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_video_message_shield.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_video_message_shield_enemy_taunt.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ai_video_message_shield_pre.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_chat.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_chat2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_emblem1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_emblem2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_endscore.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_fade.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_gameover.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_ingame.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_list.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_minilist1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_minilist2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_minimap.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_mm_emblem1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_mm_emblem2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_mm_shield_drag.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_mm_shield_hover.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_mm_shields.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_scorename.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_table1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_table2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_table_back.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_table_drag.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_trail_name.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_trail_portrait.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_trail_shield.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_trail_shield2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_playercolor_trebuchet.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_restore_arabian_engineer_speech.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_restore_arabian_engineer_speech_engine.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_restore_arabian_engineer_speech_lord_type.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_restore_arabian_engineer_speech_purchase.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_seed_modification_possibility.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_seed_modification_possibility_fn1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_seed_modification_possibility_fn2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_seed_modification_possibility_fn3.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_seed_modification_possibility_fn4.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_seed_modification_possibility_fn5.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_beerpopularity.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_beerpopularitytab.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_beertab.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_peasantspawnrate.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_religionpopularity.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_religionpopularitytab.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_religiontab.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_shfy_resourcequantity.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_stop_player_keep_rotation.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_stop_player_keep_rotation_get_preferred_relative_orientation.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_trooplimit.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_xtreme_bar1.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/o_xtreme_bar2.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/random.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/s_gold.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/s_lordstrength.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/s_lordtype.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/s_resource.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/s_troops.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_arabwall.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_arabxbow.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_fireballistamonk.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_fireballistatunneler.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_fix_applefarm_blocking.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_fix_lord_animation_stuck_building_attack.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_fix_lord_animation_stuck_movement.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_ladderarmor_bow.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_ladderarmor_sling.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_ladderarmor_xbow.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_laddergold.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_spearbow.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_spearmen_run.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_spearxbow.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/u_tanner_fix.block (100%) rename UnofficialCrusaderPatch/{ => Resources}/CodeBlocks/ui_fix_laddermen_cost_display_in_engineers_guild.block (100%) delete mode 100644 UnofficialCrusaderPatch/Startup/ResourceView.cs delete mode 100644 UnofficialCrusaderPatch/Startup/StartTroopView.cs create mode 100644 UnofficialCrusaderPatch/Util/Comparators/FileComparer.cs create mode 100644 UnofficialCrusaderPatch/Util/Enumerators/AICEnumerator.cs create mode 100644 UnofficialCrusaderPatch/Util/Enumerators/AIVEnumerator.cs rename UnofficialCrusaderPatch/{Startup/ResourceChange.cs => Util/Enumerators/StartResourceEnumerator.cs} (62%) rename UnofficialCrusaderPatch/{Startup/StartTroopChange.cs => Util/Enumerators/StartTroopEnumerator.cs} (59%) rename UnofficialCrusaderPatch/{Startup => Util/Enumerators}/StartingEnums.cs (100%) rename UnofficialCrusaderPatch/{ => Util/Readers}/Extensions.cs (86%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AICHelper.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AICSerializationException.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AICharacter.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AICharacterName.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AICharacterSerializationException.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AICollection.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AIPersonality.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AIPersonalityFieldsEnum.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/AISerializer.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/PersonalityEnums/Buildings.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/PersonalityEnums/Resources.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/PersonalityEnums/SiegeEngines.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/PersonalityEnums/TargetingType.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/PersonalityEnums/Units.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/PersonalityEnums/WorkshopSettings.cs (100%) rename UnofficialCrusaderPatch/{AIC => Util/Readers}/Utils/RWAttributes.cs (100%) delete mode 100644 UnofficialCrusaderPatch/_Crusader/Building.cs delete mode 100644 UnofficialCrusaderPatch/_Crusader/UI_Button.cs delete mode 100644 UnofficialCrusaderPatch/_Crusader/Unit.cs create mode 100644 UnofficialCrusaderPatch/packages.config diff --git a/UnofficialCrusaderPatch/AIC/AICChange.cs b/UnofficialCrusaderPatch/AIC/AICChange.cs deleted file mode 100644 index 0ee36c36..00000000 --- a/UnofficialCrusaderPatch/AIC/AICChange.cs +++ /dev/null @@ -1,642 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using System.Web.Script.Serialization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using UCP.Patching; -using UCPAIConversion; - -namespace UCP.AIC -{ - class AICChange : Change - { - private AICollection collection; - private List characters; - private List customCharacterNames; - private Button conflict; - - static Dictionary errorMessages; - static Dictionary errorHints; - - static Dictionary> availableSelection; - static Dictionary currentSelection; - - static LinkedList selectedChanges = new LinkedList(); - - static List _changes = new List(); - - public static List changes { get { return _changes; } } - - - /// - /// Read and store UCP-defined errors messages and field description hints - /// - static AICChange () { - currentSelection = new Dictionary(); - availableSelection = new Dictionary>(); - - StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.AIC.Resources.errors.json"), Encoding.UTF8); - string errorText = reader.ReadToEnd(); - reader.Close(); - - reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.AIC.Resources.descriptions.json"), Encoding.UTF8); - string errorHintText = reader.ReadToEnd(); - reader.Close(); - - - JavaScriptSerializer errorSerializer = new JavaScriptSerializer(); - errorMessages = errorSerializer.Deserialize>(errorText); - errorHints = errorSerializer.Deserialize>(errorHintText); - } - - public AICChange(string titleIdent, bool enabledDefault = false) - : base("aic_" + titleIdent, ChangeType.AIC, enabledDefault, true) - { - this.NoLocalization = true; - } - - /// - /// Initialize the UI of the Change including titleBox (checkbox), titleBox.Content (AIC title), saving localized description. - /// The titleBox object for built-in AICs is coloured white (unlike beige for user-loaded) - /// Built-in AICs have an export option available - /// - public override void InitUI() - { - string descr = GetLocalizedDescription(this.collection); - descr = descr == String.Empty ? this.TitleIdent : descr; - Localization.Add(this.TitleIdent + "_descr", descr); - this.titleBox = new CheckBox() - { - Content = new TextBlock() // Define title of AIC - { - Text = this.TitleIdent.Substring(4), - TextDecorations = this.GetTitle().EndsWith(".aic") ? TextDecorations.Strikethrough : null, - TextWrapping = TextWrapping.Wrap, - Margin = new Thickness(0, -1, 0, 0), - FontSize = 14, - Width = 400, - }, - IsChecked = currentSelection.ContainsValue(this.TitleIdent), - IsEnabled = !this.GetTitle().EndsWith(".aic"), - Background = new SolidColorBrush(Colors.White) - }; - - TreeViewItem tvi = new TreeViewItem() - { - IsExpanded = false, - Focusable = false, - Header = titleBox, - MinHeight = 22, - }; - - // Add custom handlers for tracking selected AIC files and AI Character definitions to use - titleBox.Checked += TitleBox_Checked; - titleBox.Unchecked += TitleBox_Unchecked; - - grid = new Grid() - { - Background = new SolidColorBrush(Color.FromArgb(150, 200, 200, 200)), - Width = 420, - Margin = new Thickness(-18, 5, -1, -1), - Focusable = false, - }; - - FillGrid(grid); - - tvi.Items.Add(grid); - tvi.Items.Add(null); // spacing - Grid panel = new Grid(); - panel.Children.Add(tvi); - panel.Margin = new Thickness(-20, 0, 0, 0); - - // Render warning with option to convert outdated .aic files to the newer JSON format - if (this.GetTitle().EndsWith(".aic")) - { - Button infoButton = new Button() - { - ToolTip = Localization.Get("ui_aicoldversion"), - Width = 17, - Height = 17, - Content = "!", - FontSize = 10, - FontWeight = FontWeights.Bold, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Top, - Margin = new Thickness(0, 0, 45, 0), - Background = new SolidColorBrush(Color.FromRgb(246, 53, 53)), - }; - infoButton.Click += (s, e) => - { - - MessageBoxResult result = MessageBox.Show(Localization.Get("ui_aicofferconvert"), Localization.Get("ui_aicconvertprompt"), MessageBoxButton.YesNo, MessageBoxImage.Question); - switch (result) - { - case MessageBoxResult.Yes: - ConvertAIC(); - break; - default: - break; - } - }; - panel.Children.Add(infoButton); - } - else - { - // Create warning button for indicating AIC conflicts - only visible when conflicts are present - this.conflict = new Button() - { - ToolTip = Localization.Get("ui_aicconflict"), - Width = 17, - Height = 17, - Content = "!", - FontSize = 10, - FontWeight = FontWeights.Bold, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Top, - Margin = new Thickness(0, 0, 45, 0), - Background = new SolidColorBrush(Color.FromRgb(255, 255, 0)), - Visibility = Visibility.Hidden - }; - panel.Children.Add(conflict); - } - this.uiElement = panel; - } - - /// - /// If the user presses Ctrl+Click then append to the current selection otherwise exclusively select the checked AIC - /// - /// - /// - protected override void TitleBox_Checked(object sender, RoutedEventArgs e) - { - if (!(System.Windows.Input.Keyboard.Modifiers == System.Windows.Input.ModifierKeys.Control)) - { - DeselectOthers(this); - selectedChanges.Clear(); - currentSelection.Clear(); - foreach (AICharacterName character in this.characters) - { - currentSelection.Add(character, this.TitleIdent); - } - selectedChanges.AddFirst(this); - } - else - { - // Update list of conflicts based on additional user selection - List conflicts = new List(); - int count = -1; - foreach (AICharacterName character in this.characters) - { - count++; - if (currentSelection.ContainsKey(character)) - { - String customName = this.customCharacterNames.ElementAt(count) ; - String name = Enum.GetName(typeof(AICharacterName), this.collection.GetCharacters().ElementAt(count)); - conflicts.Add(name + ((customName.Equals(String.Empty) || customName.Equals(name)) ? String.Empty : " (" + customName + ")")); - } - else - { - currentSelection.Add(character, this.TitleIdent); - } - } - if (conflicts.Count > 0) - { - this.conflict.Visibility = Visibility.Visible; - this.conflict.ToolTip = String.Join(",\n", conflicts) + "\n" + Localization.Get("ui_aicconflict"); - } - selectedChanges.AddLast(this); - } - Configuration.Save(); - base.TitleBox_Checked(sender, e); - } - - protected override void TitleBox_Unchecked(object sender, RoutedEventArgs e) - { - this.conflict.Visibility = Visibility.Hidden; - List namesToRemove = new List(); - foreach (KeyValuePair sel in currentSelection) - { - if (sel.Value == this.TitleIdent) - { - namesToRemove.Add(sel.Key); - } - } - foreach (AICharacterName name in namesToRemove) - { - currentSelection.Remove(name); - } - selectedChanges.Remove(this); - - // Update list of conflicts on user deselection of a change - foreach (AICChange change in selectedChanges) - { - change.conflict.Visibility = Visibility.Hidden; - List conflicts = new List(); - int count = -1; - foreach (AICharacterName character in change.characters) - { - count++; - if (!currentSelection.ContainsKey(character)) - { - currentSelection.Add(character, change.TitleIdent); - } - else - { - if (currentSelection[character] != change.TitleIdent && change.characters.Contains(character)) - { - String customName = change.customCharacterNames.ElementAt(count); - String name = Enum.GetName(typeof(AICharacterName), change.collection.GetCharacters().ElementAt(count)); - conflicts.Add(name + ((customName.Equals(String.Empty) || customName.Equals(name)) ? String.Empty : " (" + customName + ")")); - change.conflict.Visibility = Visibility.Visible; - } - } - } - change.conflict.ToolTip = String.Join(",\n", conflicts) + "\n" + Localization.Get("ui_aicconflict"); - } - Configuration.Save(); - base.TitleBox_Unchecked(sender, e); - } - - /// - /// Converts the associated .aic file to the newer JSON format - /// - private void ConvertAIC() - { - string workaroundFilename = this.TitleIdent.Substring(4); - string fileName = Path.Combine(Environment.CurrentDirectory, "resources", "aic", workaroundFilename); - string newFileName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(workaroundFilename) + ".json"); - - string backupFileName = fileName; - while (File.Exists(backupFileName)) - { - backupFileName = backupFileName + ".bak"; - } - try - { - bool result = AICHelper.Convert(fileName, newFileName); - if (result) - { - File.Move(fileName, backupFileName); - Debug.Show("AIC file successfully converted. Please click refresh to see updated AIC list"); - } - } - catch (Exception e) - { - File.WriteAllText("AICLoading.log", e.ToString()); - Debug.Show("Errors found in conversion. Please see convert manually and confirm valid JSON before reloading"); - } - } - - /// - /// Loads configuration of saved selections of AIC changes. - /// In the event of conflicts the first listed AIC is given priority. - /// The first listed AIC is the AIC that was selected first during the user's last session. - /// - /// - public static void LoadConfiguration(List configuration = null) - { - Load(); - if (configuration == null) - { - return; - } - - foreach (string change in configuration) - { - string[] changeLine = change.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(str => str.Trim()).ToArray(); - if (changeLine.Length < 2) - { - continue; - } - - string changeKey = changeLine[0]; - string changeSetting = changeLine[1]; - - bool selected = Regex.Replace(@"\s+", "", changeSetting.Split('=')[1]).Contains("True"); - - if (!changeKey.EndsWith(".aic")) - { - foreach (AICChange aicChange in changes) - { - if (aicChange.TitleIdent == changeKey && selected == true) - { - foreach (AICharacter character in aicChange.collection.AICharacters) - { - currentSelection[(AICharacterName)Enum.Parse(typeof(AICharacterName), character.Name.ToString())] = aicChange.TitleIdent; - } - } - } - } - } - } - - /// - /// Returns AIC selection to store in configuration file. - /// Only AIC files with AI Characters that will be used are set to selected. - /// - /// - public static List GetConfiguration() - { - List configuration = new List(); - foreach (AICChange aicChange in selectedChanges.Reverse()) - { - configuration.Add(aicChange.TitleIdent + "= { " + aicChange.TitleIdent + "={" + (currentSelection.ContainsValue(aicChange.TitleIdent)).ToString() + "} }"); - } - foreach (AICChange aicChange in changes) - { - if (selectedChanges.Contains(aicChange)) - { - continue; - } - configuration.Add(aicChange.TitleIdent + "= { " + aicChange.TitleIdent + "={" + (currentSelection.ContainsValue(aicChange.TitleIdent)).ToString() + "} }"); - } - return configuration; - } - - /// - /// Clears and reloads the set of AIC definitions. - /// Reapplies selections if the specified AIC is still present. - /// - /// - /// - public static void Refresh(object sender, RoutedEventArgs args) - { - String[] prevSelection = new String[currentSelection.Values.Count]; - currentSelection.Values.CopyTo(prevSelection, 0); - availableSelection.Clear(); - currentSelection.Clear(); - for (int i = 0; i < changes.Count; i++) - { - ((TreeView)((Grid)((Button)sender).Parent).Children[0]).Items.Remove(changes.ElementAt(i).UIElement); - Localization.Remove(changes.ElementAt(i) + "_descr"); - } - changes.Clear(); - LoadConfiguration(); - foreach (String selected in prevSelection) - { - foreach (AICChange aicChange in changes) - { - if (aicChange.TitleIdent == selected) - { - foreach (AICharacter character in aicChange.collection.AICharacters) - { - currentSelection[(AICharacterName)Enum.Parse(typeof(AICharacterName), character.Name.ToString())] = aicChange.TitleIdent; - } - } - } - } - Configuration.Save(); - } - - public static void DoChange(ChangeArgs args) - { - CreateEdit().Activate(args); - } - - private static void DeselectOthers(AICChange selected) - { - foreach (var change in changes) - { - if (change != selected) - { - change.titleBox.IsChecked = false; - } - } - } - - private static void Load() - { - if (Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "aic"))) - { - foreach (string file in Directory.EnumerateFiles(Path.Combine(Environment.CurrentDirectory, "resources", "aic"), "*.aic", SearchOption.TopDirectoryOnly)) - { - LoadAIC(file); - } - - List exceptions = new List(); - foreach (string file in Directory.EnumerateFiles(Path.Combine(Environment.CurrentDirectory, "resources", "aic"), "*.json", SearchOption.TopDirectoryOnly)) - { - try - { - LoadAIC(file); - } - catch (Exception) - { - exceptions.Add(file); - } - - } - if (exceptions.Count > 0) - { - Debug.Show("Error loading AIC files: " + String.Join(",", exceptions)); - } - } - } - - private static void LoadAIC(string fileName) - { - if (fileName.EndsWith(".aic")) - { - AICChange change = new AICChange(Path.GetFileName(fileName), true) - { - new DefaultHeader(String.Empty, true, true) - { - } - }; - changes.Add(change); - return; - } - - JavaScriptSerializer serializer = new JavaScriptSerializer(); - serializer.RegisterConverters(new ReadOnlyCollection(new List() { new AISerializer(errorMessages, errorHints) })); - StreamReader reader = new StreamReader(new FileStream(fileName, FileMode.Open), Encoding.UTF8); - string text = reader.ReadToEnd(); - reader.Close(); - - string aicName = Path.GetFileNameWithoutExtension(fileName); - try - { - if (availableSelection.ContainsKey(aicName)) - { - throw new Exception("AIC with the same filename has already been loaded"); - } - - AICollection ch = serializer.Deserialize(text);; - AICChange change = new AICChange(aicName, true) - { - new DefaultHeader("aic_" + aicName, true) - { - } - }; - change.collection = ch; - change.characters = ch.GetCharacters(); - change.customCharacterNames = ch.GetCustomCharacterNames(); - availableSelection[change.TitleIdent] = ch.GetCharacters(); - changes.Add(change); - } - catch (AICSerializationException e) - { - File.AppendAllText("AICParsing.log", e.ToErrorString(fileName)); - throw e; - } - catch (Exception e) - { - File.AppendAllText("AICParsing.log", "\n" + aicName + ": " + e.Message + "\n"); - throw e; - } - } - - /// - /// Retrieve localized description based on selected language preference. - /// If a description is not found then return first non-empty description. - /// - /// - /// - private static string GetLocalizedDescription(AICollection ch) - { - string currentLang = Localization.Translations.ToArray()[Localization.LanguageIndex].Ident; - string descr = String.Empty; - try - { - descr = ch.AICShortDescription[currentLang]; - if (descr == String.Empty) - { - foreach (var lang in Localization.Translations) - { - try - { - descr = ch.AICShortDescription[lang.Ident]; - if (descr != String.Empty) - { - break; - } - } - catch (Exception) - { - continue; - } - } - } - } - catch (Exception) - { - foreach (var lang in Localization.Translations) - { - try - { - descr = ch.AICShortDescription[lang.Ident]; - if (descr != String.Empty) - { - break; - } - } - catch (Exception) - { - continue; - } - } - } - return descr; - } - - private static ChangeHeader CreateEdit() - { - List characterChanges = new List(); - - foreach (AICharacterName name in Enum.GetValues(typeof(AICharacterName))) - { - if (!currentSelection.ContainsKey(name)) - { - continue; - } - string changeLocation = currentSelection[name]; - AICChange changeSource = null; - - foreach (AICChange change in changes) - { - if (change.TitleIdent == changeLocation) - { - changeSource = change; - break; - } - } - - foreach (AICharacter character in changeSource.collection.AICharacters) - { - if ((AICharacterName)Enum.Parse(typeof(AICharacterName), character.Name.ToString()) == name) - { - characterChanges.Add(character); - break; - } - } - } - - byte[] data; - using (MemoryStream ms = new MemoryStream()) - using (BinaryWriter bw = new BinaryWriter(ms)) - { - foreach (AICharacter aic in characterChanges) - { - // mov eax, index - bw.Write((byte)0xB8); - bw.Write((int)aic._Name * 0x2A4); - - // imul eax, 2A4 - /*bw.Write((byte)0x69); - bw.Write((byte)0xC0); - bw.Write(0x2A4);*/ - - // add eax, esi - bw.Write((byte)0x01); - bw.Write((byte)0xF0); - - // edit AI's properties - for (int i = 0; i < Enum.GetNames(typeof(AIPersonalityFieldsEnum)).Length; i++) - { - string propertyName = Enum.GetName(typeof(AIPersonalityFieldsEnum), i); - PropertyInfo property = typeof(AIPersonality).GetProperty("_" + propertyName); - if (property == null) - { - property = typeof(AIPersonality).GetProperty(propertyName); - } - if (property == null) throw new Exception(propertyName); - object objValue = property.GetValue(aic.Personality, null); - int value = Convert.ToInt32(objValue); - - // mov [eax + prop], value - bw.Write((byte)0xC7); - bw.Write((byte)0x80); - bw.Write((int)(i * 4)); - bw.Write(value); - } - } - data = ms.ToArray(); - } - - // 004D1928 - BinaryEdit be = new BinaryEdit("ai_prop") - { - new BinAddress("call", 0x1B+1, true), - - new BinSkip(0x1B), - new BinHook(5) - { - // ori code - 0xE8, new BinRefTo("call"), - - // edit ais - new BinBytes(data), - } - }; - - return new DefaultHeader("ai_prop") { be }; - } - } -} diff --git a/UnofficialCrusaderPatch/AIC/AICView.cs b/UnofficialCrusaderPatch/AIC/AICView.cs deleted file mode 100644 index 2e056c03..00000000 --- a/UnofficialCrusaderPatch/AIC/AICView.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Imaging; - -namespace UCP.AIC -{ - public class AICView - { - - public void InitUI(Grid grid, RoutedPropertyChangedEventHandler SelectionDisabler) - { - TreeView view = new TreeView() - { - Background = null, - BorderThickness = new Thickness(0, 0, 0, 0), - Focusable = false, - Name = "AICView" - }; - view.SelectedItemChanged += SelectionDisabler; - - foreach (AICChange change in AICChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - grid.Children.Add(view); - Button button = new Button - { - ToolTip = "Reload .aics", - Width = 20, - Height = 20, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Bottom, - Margin = new Thickness(0, 0, 20, 5), - Content = new Image() - { - Source = new BitmapImage(new Uri("pack://application:,,,/UnofficialCrusaderPatchGUI;component/Graphics/refresh.png")), - } - }; - grid.Children.Add(button); - button.Click += (s, e) => Refresh(s, e, view); - } - - /// - /// Clears and reloads the set of AIC changes - /// - /// - /// - /// - private void Refresh(object s, RoutedEventArgs e, TreeView view) - { - AICChange.Refresh(s, e); - foreach (AICChange change in AICChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - } - } -} diff --git a/UnofficialCrusaderPatch/AIV/AIVView.cs b/UnofficialCrusaderPatch/AIV/AIVView.cs deleted file mode 100644 index 1006acc2..00000000 --- a/UnofficialCrusaderPatch/AIV/AIVView.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Imaging; - -namespace UCP.AIV -{ - public class AIVView - { - public void InitUI(Grid grid, RoutedPropertyChangedEventHandler SelectionDisabler) - { - TreeView view = new TreeView() - { - Background = null, - BorderThickness = new Thickness(0, 0, 0, 0), - Focusable = false, - }; - view.SelectedItemChanged += SelectionDisabler; - - foreach (AIVChange change in AIVChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - grid.Children.Add(view); - - Button button = new Button - { - ToolTip = "Reload AIV", - Width = 20, - Height = 20, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Bottom, - Margin = new Thickness(0, 0, 20, 5), - Content = new Image() - { - Source = new BitmapImage(new Uri("pack://application:,,,/UnofficialCrusaderPatchGUI;component/Graphics/refresh.png")), - } - }; - grid.Children.Add(button); - button.Click += (s, e) => Refresh(s, e, view); - } - - private void Refresh(object s, RoutedEventArgs e, TreeView view) - { - String activeChange = AIVChange.activeChange == null ? String.Empty : AIVChange.activeChange.TitleIdent; - foreach (AIVChange change in AIVChange.changes) - { - Localization.Remove(change.TitleIdent + "_descr"); - view.Items.Remove(change.UIElement); - } - AIVChange.Refresh(); - foreach (AIVChange change in AIVChange.changes) - { - change.InitUI(); - change.IsChecked = false; - view.Items.Add(change.UIElement); - } - if (AIVChange.changes.Select(x => x.TitleIdent).Contains(activeChange)) - { - foreach (AIVChange change in AIVChange.changes) - { - if (change.TitleIdent == activeChange) - { - change.IsChecked = true; - } - } - } - } - } -} diff --git a/UnofficialCrusaderPatch/API/ModAPIContract.cs b/UnofficialCrusaderPatch/API/ModAPIContract.cs new file mode 100644 index 00000000..b3c4794a --- /dev/null +++ b/UnofficialCrusaderPatch/API/ModAPIContract.cs @@ -0,0 +1,227 @@ +using System.Collections.Generic; +using System.Linq; +using UCP.AIC; +using UCP.AIV; +using UCP.Model; +using UCP.Model.Patching; +using UCP.Patching; +using UCP.Startup; + +namespace UCP.API +{ + public static class ModAPIContract + { + #region AIC + + public static List ListAICConfigurations() + { + return AICEnumerator.GetAICConfiguration(); + } + + public static void SetAICConfiguration(object aicConfiguration) + { + if (aicConfiguration == null) + { + AICEnumerator.ResetAICConfiguration(); + } + + if (aicConfiguration is string) + { + AICEnumerator.SetAICConfiguration(aicConfiguration.ToString()); + } + else if (aicConfiguration is object[]) + { + AICEnumerator.SetAICConfiguration((object[])aicConfiguration); + } + else if (aicConfiguration is List) + { + AICEnumerator.SetAICConfiguration((List)aicConfiguration); + } + } + + + #endregion + + #region AIV + + public static Dictionary ListAIVConfigurations() + { + return AIVEnumerator.GetAIVConfiguration(); + } + + public static void SetAIVConfiguration(string aivName) + { + if (aivName == null) + { + AIVEnumerator.ResetAIVConfiguration(); + } + else + { + AIVEnumerator.SetAIVConfiguration(aivName); + } + } + + #endregion + + #region StartResource + + public static Dictionary ListStartResourceConfigurations() + { + return StartResourceEnumerator.GetStartResourceConfigurations(); + } + + public static void SetStartResourceConfiguration(string configName) + { + if (configName == null) + { + StartResourceEnumerator.ResetStartResourceConfiguration(); + } + else + { + StartResourceEnumerator.SetStartResourceConfiguration(configName); + } + } + + #endregion + + #region StartTroop + + public static Dictionary ListStartTroopConfigurations() + { + return StartTroopEnumerator.GetStartTroopConfigurations(); + } + + public static void SetStartTroopConfiguration(string configName) + { + if (configName == null) + { + StartTroopEnumerator.ResetStartTroopConfiguration(); + } + else + { + StartTroopEnumerator.SetStartTroopConfiguration(configName); + } + } + + #endregion + + #region GenericMod + + public static Dictionary> ListChanges() + { + return Mod.ModList; + } + + public static void SetModValues(IEnumerable modValueMap) + { + if (modValueMap == null) + { + return; + } + foreach (ChangeConfiguration changeConfig in modValueMap) + { + Mod currentMod = Mod.Items.ToList().SingleOrDefault(x => x.Identifier.Equals(changeConfig.Identifier)); + if (currentMod == null) + { + continue; + } + currentMod.ApplyChanges(changeConfig.SubChanges); + } + + List changeIdentifiers = modValueMap.Select(config => config.Identifier).ToList(); + foreach (Mod currentMod in Mod.Items.Where(mod => !changeIdentifiers.Contains(mod.Identifier))) + { + currentMod.Disable(); + } + } + + public static void SetModExtremeValues(IEnumerable modValueMap) + { + if (modValueMap == null) + { + return; + } + foreach (ChangeConfiguration changeConfig in modValueMap) + { + Mod currentMod = Mod.Items.ToList().SingleOrDefault(x => x.Identifier.Equals(changeConfig.Identifier)); + if (currentMod == null) + { + continue; + } + currentMod.ApplyExtremeChanges(changeConfig.SubChanges); + } + + List changeIdentifiers = modValueMap.Select(config => config.Identifier).ToList(); + foreach (Mod currentMod in Mod.Items.Where(mod => !changeIdentifiers.Contains(mod.Identifier))) + { + currentMod.Disable(); + } + } + + #endregion + + #region Installation + public static bool Install(UCPConfig config, bool overwrite = false, bool graphical = false) + { + ModAPIContract.SetAICConfiguration(config.AIC); + ModAPIContract.SetAIVConfiguration(config.AIV); + ModAPIContract.SetStartResourceConfiguration(config.StartResource); + ModAPIContract.SetStartTroopConfiguration(config.StartTroop); + ModAPIContract.SetModValues(config.GenericMods); + ModAPIContract.SetModExtremeValues(config.GenericMods); + + + AIVEnumerator.Install(config.Path, overwrite, graphical); + Installer.Initialize(config.Path); + if (Installer.crusaderArgs.HasValue) + { + SubChange header = AICEnumerator.CreateEdit(); + header?.Activate(Installer.crusaderArgs.Value); + StartResourceEnumerator.DoChange(Installer.crusaderArgs.Value); + StartTroopEnumerator.DoChange(Installer.crusaderArgs.Value); + foreach (Mod mod in Mod.Items) + { + mod.Install(Installer.crusaderArgs.Value); + } + } + + string errorMsg = Installer.WriteFinalize(); + + Installer.InitializeExtreme(config.Path); + if (Installer.extremeArgs.HasValue) + { + SubChange header = AICEnumerator.CreateEdit(); + header?.Activate(Installer.extremeArgs.Value); + StartResourceEnumerator.DoChange(Installer.extremeArgs.Value); + StartTroopEnumerator.DoChange(Installer.extremeArgs.Value); + foreach (Mod mod in Mod.Items) + { + mod.InitExtremeChange(); + mod.InstallExtreme(Installer.extremeArgs.Value); + } + } + errorMsg += Installer.WriteFinalizeExtreme(); + + /* Clear configuration until install called again */ + foreach (Mod currentMod in Mod.Items) + { + currentMod.Disable(); + } + AICEnumerator.ResetAICConfiguration(); + AIVEnumerator.ResetAIVConfiguration(); + StartResourceEnumerator.ResetStartResourceConfiguration(); + StartTroopEnumerator.ResetStartTroopConfiguration(); + + return true; + } + + public static bool Uninstall(UCPConfig config) + { + AIVEnumerator.Uninstall(config.Path); + Installer.RestoreOriginals(config.Path); + return true; + } + + #endregion + } +} diff --git a/UnofficialCrusaderPatch/Configuration.cs b/UnofficialCrusaderPatch/Configuration.cs deleted file mode 100644 index 091c6298..00000000 --- a/UnofficialCrusaderPatch/Configuration.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using UCP.AIC; -using UCP.AIV; -using UCP.Patching; -using UCP.Startup; - -namespace UCP -{ - public static class Configuration - { - public const string ConfigFile = "ucp.cfg"; - - private static Dictionary settings = new Dictionary() - { - { "Path", "" }, - { "Language", "-1" } - }; - public static string Path - { - get - { - return settings["Path"]; - } - set - { - settings["Path"] = value; - } - } - - public static int Language - { - get - { - return Convert.ToInt32(settings["Language"]); - } - set - { - settings["Language"] = value.ToString(); - } - } - - static bool loading = false; - - static Configuration() - { - - } - - public static void Save(string str = null) - { - if (loading) return; - - using (StreamWriter sw = new StreamWriter(ConfigFile)) - { - // install path - sw.Write("Path="); - sw.WriteLine(Path); - - // language - sw.Write("Language="); - sw.WriteLine(Language); - - // edits - foreach (Change change in Version.Changes) - { - if (change.Type != ChangeType.AIC && change.Type != ChangeType.AIV) - { - sw.WriteLine(change.ToString()); - } - } - - foreach (string line in AIVChange.GetConfiguration()) - { - sw.WriteLine(line); - } - - foreach (string line in AICChange.GetConfiguration()) - { - sw.WriteLine(line); - } - } - } - - public static void Load(bool changesOnly = false) - { - List aicConfigurationList = null; - List aivConfigurationList = null; - List resourceConfigurationList = null; - List startTroopConfigurationList = null; - if (File.Exists(ConfigFile)) - { - using (StreamReader sr = new StreamReader(ConfigFile)) - { - string line; - while ((line = sr.ReadLine()) != null) - { - - /* Separate configuration for change configurations that are handled within the respective submodule then - proceed to load generic change configurations */ - if (Regex.Replace(@"\s+","", line).Contains("aic_")) - { - if (aicConfigurationList == null) - { - aicConfigurationList = new List(); - } - aicConfigurationList.Add(line); - continue; - } - else if(Regex.Replace(@"\s+", "", line).StartsWith("aiv_")) - { - if (aivConfigurationList == null) - { - aivConfigurationList = new List(); - } - aivConfigurationList.Add(line); - continue; - } - else if (Regex.Replace(@"\s+", "", line).StartsWith("res_")) - { - if (resourceConfigurationList == null) - { - resourceConfigurationList = new List(); - } - resourceConfigurationList.Add(line); - continue; - } - else if (Regex.Replace(@"\s+", "", line).StartsWith("s_")) - { - if (startTroopConfigurationList == null) - { - startTroopConfigurationList = new List(); - } - startTroopConfigurationList.Add(line); - continue; - } - - string[] changeLine = line.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(str => str.Trim()).ToArray(); - if (changeLine.Length < 2) - { - continue; - } - - string changeKey = changeLine[0]; - string changeSetting = changeLine[1]; - - if (!changesOnly) - { - if (changeKey == "Path") - { - Configuration.Path = changeSetting; - } - else if (changeKey == "Language") - { - if (int.TryParse(changeSetting, out int result)) - Configuration.Language = result; - } - } - if (changeKey == "Path" || changeKey == "Language") - { - continue; - } - Change change = Version.Changes.Find(c => c.TitleIdent == changeKey); - if (change == null) continue; - - int numChanges = changeSetting.Count(ch => ch == '='); - string[] changes = changeSetting.Split(new char[] { '}' }, numChanges, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < numChanges; i++) - { - string headerKey = changes[i].Split('=')[0].Replace(" ", "").Replace("{", String.Empty); - string headerValue = changes[i].Split('=')[1].Replace(" ", "").Replace("{", String.Empty).Replace("}", String.Empty); - DefaultHeader header = change.FirstOrDefault(c => c.DescrIdent == headerKey); - header.LoadValueString(headerValue); - } - } - } - } - - // Calls change modules to set their selections based on the provided configuration list - AICChange.LoadConfiguration(aicConfigurationList); - AIVChange.LoadConfiguration(aivConfigurationList); - ResourceChange.LoadConfiguration(resourceConfigurationList); - StartTroopChange.LoadConfiguration(startTroopConfigurationList); - } - } -} diff --git a/UnofficialCrusaderPatch/Debug.cs b/UnofficialCrusaderPatch/Debug.cs deleted file mode 100644 index 558f60aa..00000000 --- a/UnofficialCrusaderPatch/Debug.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.IO; -using System.Windows; - -namespace UCP -{ - public static class Debug - { - public static void Show(object message, object title = null) - { - MessageBox.Show(message == null ? "" : message.ToString(), title == null ? "Info" : title.ToString()); - } - - public static void Error(string message) - { - Show(message, Localization.Get("ui_error")); - } - - public static void Error(Exception e) - { - string message = e.ToString(); - File.AppendAllText("icp_error_dump.txt", message + "\n\n\n"); - Error(message); - } - } -} diff --git a/UnofficialCrusaderPatch/Graphics/shield.png b/UnofficialCrusaderPatch/Graphics/shield.png deleted file mode 100644 index ae58aca301a5011dccb4c6f70e12bdeb5b882e61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1287 zcmV+i1^D`jP)ATD<$Zx?!u2qHe%H5 zVlJglH#P<3BNLhEvP94r7Xfur(j`+{6oah?Djie`uDf732c>*$xLxqvoaB9<=bYdB zzW?{h^Bh5=(fC_iTZxQ>hzMS}wY5QVvVl+lsT3A0fF(;_J;&SdND5He_|6L6ClIcfLr536vdzcUaxo9mwG%NT3TA@>FEhL*Z&Ql&lecP z)85XV>(@uJfbJp2{Tw>x50n=K(K(j z;H-yR2*Q;BB9s9s%Ru)g#76r4Q3GAN1fk;|Jo+U$8HJ)IFi58;pXqF@`8a4HW4A+g zc2|VUi+}9xoxv#3X_6b2>Kbs8>gs0N+o#*+&YinlVzF3Og1)M_ zSjLqrO~l0PM=E`YAdCl07vbU8QL7J7T--rCvw@j~3vGxmd)R|SM)Ak_9Fo?{FfTT212Kx1Y@?HaH%Pzo;8!=Dg;?}R&vuDqZ5j6lK0qM`qTeog4 zal6m2$;^C4W@exc4+;yRv{c@amX?>YZQHh=M%;;v0tBbiIqBH3!^PLGeX%wxD=>)J zOsC28*?aH4yQ)^DQZX(d05+Q~q^hd8sI2VhpgobxRb87m?_Ifkx#6-#qZ!{aAU;0+ xxkQq+$>YHfyu2@7g+h_KdiA=?!wEBx{Q+yZ%eM}#8}tAG002ovPDHLkV1hg&Zdw2U diff --git a/UnofficialCrusaderPatch/Localization/Chinese.txt b/UnofficialCrusaderPatch/Localization/Chinese.txt deleted file mode 100644 index 7397e6fc..00000000 --- a/UnofficialCrusaderPatch/Localization/Chinese.txt +++ /dev/null @@ -1,1072 +0,0 @@ -// ====================== -// 2.15 -// ====================== -u_spearmen_run -{ -"矛兵默认为奔跑状态而不是步行" -} - -u_spearmen_run_descr -{ -"矛兵在默认状态下将使用奔跑作为移动方式,而不是步行。" -} - -o_seed_modification_possibility_title -{ -"游戏种子" -} - -o_seed_modification_possibility_only_set -{ -"启用固定游戏随机种子" -} - -o_seed_modification_possibility_only_set_descr -{ -"如果使用相同的地图设置,设置游戏种子可以使只有AI的游戏对局每次都以相同的过程进行。对于既有玩家也有AI的游戏对局,设置游戏种子可以确保每次游戏的开始条件是相同的(例如相同的AIV)。若要设置游戏种子,请启用此选项并在game install/gameseeds目录中创建一个名为“live”的txt文件,并手动写上6位数字。注意:启动此功能后需要重新启动游戏!" -} - -o_seed_modification_possibility -{ -"启用或保存游戏随机种子" -} - -o_seed_modification_possibility_descr -{ -"这个选项可以保存你当前的游戏种子,前提是你当前没有设定游戏种子,你可以将保存的游戏种子重命名为“live”使其应用在之后的游戏中。" -} - -ai_recruitstate_initialtimer -{ -"AI在初期阶段只招募防御士兵" -} - -ai_recruitstate_initialtimervalue_descr -{ -"AI在游戏开始起的以下时间内只会招募防御士兵,除非防御士兵数量已达上限。" -} - -ai_defense -{ -"修复ai不会补充防守兵种" -} - -ai_defense_descr -{ -"当ai城墙防守部队出现减员时,如果城外防守部队仍然存在,那么ai将& -不会补充城墙防守部队。" -} - -ai_housing -{ -"AI建造民房更加智能" -} - -build_housing_descr -{ -"你可以设定AI的民房数量的浮动值,AI建造民房时,会额外建造该数值的民房,这样直到下次人口不足之前,AI都不需要建造民房;同样的,当AI工作人口减少时,AI也会最多保留该数值的超出工作人口部分的民房。这使得AI无需频繁的拆建民房,浪费木材资源,尤其是人口频繁波动时。" -} - -campfire_housing_descr -{ -"此处设置AI篝火处的空闲农民数量,当空闲农民数量多于此数值时,AI会停止建造民房。这个功能同时会禁止AI拆除民房。" -} - -delete_housing -{ -"禁止AI拆除民房" -} - -delete_housing_descr -{ -"打开这个功能,AI将不会拆除民房。" -} - -aiv_prompt -{ -"检测到自定义AIV。你希望创建一个备份吗?" -} - -aiv_cli_prompt -{ -"检测到自定义AIV。输入“delete”删除此AIV或者输入文件夹的名字将AIV复制进此文件夹。" -} - -install_abort_io -{ -"安装中止。该文件夹下已存在相同名称的文件,请再次尝试并选择一个不同的文件夹。" -} - -install_abort -{ -"安装中止" -} - -backup_aiv_select -{ -"选择备份AIV文件夹" -} - -o_change_siege_engine_spawn_position_catapult -{ -"器械建造完成时将位于帐篷中央" -} - -o_change_siege_engine_spawn_position_catapult_descr -{ -"器械建造完成时将不再位于帐篷的右上角,而是位于帐篷的中央。" -} - -o_stop_player_keep_rotation -{ -"玩家的大本营会根据所处地图方位进行旋转" -} - -o_stop_player_keep_rotation_descr -{ -"玩家的大本营将可以和AI一样,会根据所处地图方位进行旋转,使篝火处永远背向地图中央。" -} - -o_restore_arabian_engineer_speech -{ -"工程师切换为阿拉伯语音" -} - -o_restore_arabian_engineer_speech_descr -{ -"当玩家使用阿拉伯领主时,工程师的语音将会切换为阿拉伯语。" -} - -u_fix_lord_animation_stuck_movement -{ -"修正领主摧毁建筑物后的人物动画" -} - -u_fix_lord_animation_stuck_movement_descr -{ -"修正了领主的姿势,当领主停止移动或者摧毁一个建筑物后,他将会站立,而不是被卡在地上。" -} - -fix_apple_orchard_build_size -{ -"修正苹果园建造时的面积" -} - -fix_apple_orchard_build_size_descr -{ -"将建造时苹果园需求的面积修正为苹果园的实际面积,这也可以让AI正确的放置苹果园。" -} - -u_fix_applefarm_blocking -{ -"修复苹果园工人被堵路" -} - -u_fix_applefarm_blocking_descr -{ -"当农场的左上方被建筑堵住时,将不再阻止苹果园工人进入苹果园。" -} - -o_increase_path_update_tick_rate -{ -"寻路检测频率增加" -} - -o_increase_path_update_tick_rate_descr -{ -"在原版,每200游戏刻会检测一次可行通路,经常导致ai的单位在摧毁了敌人的城门或者塔楼时不能立刻进入城堡。 - -打开后,每50个游戏刻就会进行一次检测,使得单位的反应速度加快。" -} - -o_fix_ladderclimb -{ -"修复士兵爬上云梯后遗失目的地bug" -} - -o_fix_ladderclimb_descr -{ -"士兵现在爬上云梯后将会记住目的地,而不会被困在云梯上。" -} - -u_tanner_fix -{ -"修复所有皮革工人获取同一头牛" -} - -u_tanner_fix_descr -{ -"现在皮革工人到达牧场后,若发现想要牵走的牛已被其他工人牵去,会转而去牵另外一头牛,而不是直接回到作坊。极大提高皮革作坊的效率。" -} - -o_fix_fletcher_bug -{ -"修复弓弩工人的路线" -} - -o_fix_fletcher_bug_descr -{ -"现在弓弩工人在武器库放下弓弩后会直接去储存区拿原料,而不是先返回作坊。" -} - -ai_fix_crusader_archers_pitch -{ -"修复AI的欧洲弓箭手不会点燃沥青" -} - -ai_fix_crusader_archers_pitch_descr -{ -"AI的欧洲弓箭手可以和阿拉伯弓箭手一样点燃沥青。" -} - -o_fix_baker_disappear -{ -"修复面包工人消失" -} - -o_fix_baker_disappear_descr -{ -"当面包工人到达储存区却没有面粉时,不再会消失。" -} - -o_fix_moat_digging_unit_disappearing -{ -"修复挖河士兵消失" -} - -o_fix_moat_digging_unit_disappearing_descr -{ -"挖河士兵在挖护城河时不再会随机消失。注意的是,当挖河士兵正好位于无通路地区时,如果你对其下达命令,他仍会消失!" -} - -ui_welcometext -{ -"这是要塞十字军东征的非官方补丁编辑器。 -该项目在github上开源: -[GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). - -通常来说,这个编辑器支持所有游戏版本。但是该编辑器是基于steam上1.41版本制作的,使用更低版本可能会出错。 -安装补丁时若出现问题,会弹出错误信息。 -安装补丁时的UCP版本会显示在游戏主菜单界面的左下角,游戏版本号的右边。 -在安装补丁之前,编辑器会自动备份原始文件。你可以通过'复原'按钮来取消更改,也可以手动更改备份文件的后缀名来复原。 - -UCP制作团队 - -作者 -[Sh0wdown](https://github.com/Sh0wdown) - -项目负责 -[Kimberly Azula](https://github.com/ByBurton/) -[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) - -协力制作 -[LordHansCapon](https://github.com/LordHansCapon) -[np123](https://github.com/patel-nikhil) -[J-T-de](https://github.com/J-T-de) -[gynt](https://github.com/gynt) -[Le spec](https://github.com/LeSpec) -[Chaf1812](https://github.com/Chaf1812) - -翻译提供者 -[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (波兰语) -[Lolasik011](https://github.com/Lolasik011) (俄语) -[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (中文) -[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (匈牙利) - -内容创建者 -[Evrey](https://github.com/Evrey) (aiv) -[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) -[PitchNeeded](https://github.com/PitchNeeded) (aiv) -[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) - -特别鸣谢 -[Firefly Studios](https://fireflyworlds.com/) -for the creation of the Stronghold series - -其他 -[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) -[PodeCaradox](https://github.com/PodeCaradox) -[GRhin](https://www.twitch.tv/grhin) -[Heroesflorian](https://github.com/Heroesflorian)" -} - -// ====================== -// 2.14 -// ====================== - -ui_StartTroops -{ - "起始部队" -} - -ui_Resource -{ - "起始资金" -} - -ui_aicconflict -{ - "AIC存在ai冲突,第二个AIC的冲突ai会被忽略" -} - -o_shfy -{ - "要塞修改" -} - -o_shfy_beer -{ - "从啤酒中获取的声望" -} - -o_shfy_beer_descr -{ - " " -} - -o_shfy_religion -{ - "从宗教中获取的声望" -} - -o_shfy_religion_descr -{ - " " -} - -o_shfy_peasantspawnrate -{ - "农民产生速度" -} - -o_shfy_peasantspawnrate_descr -{ - " " -} - -o_shfy_resourcequantity -{ - "交付资源数量" -} - -o_shfy_resourcequantity_descr -{ - "将这些方面调整为要塞1的数值。注意:任何改变都会影响ai领主,最坏的情况是失效!" -} - -o_armory_marketplace_weapon_order_fix -{ - "调整武器库和市场中武器的顺序" -} - -o_armory_marketplace_weapon_order_fix_descr -{ - "调整了武器在武器库和市场中的排序,同时将皮甲移至链锤和弩之间,将铁甲移至戟和剑之间,使得在浏览时更方便。" -} - -ai_fix_laddermen_with_enclosed_keep -{ - "修复了ai在城堡无通路时不使用云梯兵的错误" -} - -ai_fix_laddermen_with_enclosed_keep_descr -{ - "当ai(尤其是蛇)在自己城堡无通路到外界时,不再会停止使用云梯兵。" -} - -o_override_identity_menu -{ - "在设置菜单里添加一些新的选择" -} - -o_override_identity_menu_descr -{ - "增加了玩家初始兵种的选择的功能,只在普通模式下生效。" -} - -o_default_multiplayer_speed -{ - "设置多人游戏中的默认游戏速度" -} - -o_default_multiplayer_speed_descr -{ - " " -} - -u_fireballistafix -{ - "巨火弩正确攻击僧侣和隧道工" -} - -u_fireballistafix_descr -{ - "巨火弩将会自动攻击敌人的僧侣和隧道工。" -} - - -ui_browsepath -{ - "请选择你的要塞十字军东征安装路径" -} - -ui_aicoldversion -{ - "检测到旧版本AIC文件,点击转化为新版本。" -} - -ui_aicofferconvert -{ - "确定将AIC文件转化为新版本吗?" -} - -ui_aicconvertprompt -{ - "AIC转化完成" -} - -ui_aicselect -{ - "请先选择AIC文件,以下aic文件可供选择: " -} - -// ====================== -// 2.13 -// ====================== - -o_firecooldown -{ - "调整刚灭火建筑的免疫火灾时间" -} - -o_firecooldown_descr -{ - "着火的建筑在火被扑灭后,会有一段免疫着火的时间,此处可修改时间长短。" -} - -u_ballistamonk -{ - "巨火弩攻击僧侣" -} - -u_ballistamonk_descr -{ - "打开后,巨火弩将会自动攻击僧侣。" -} - - -// ====================== -// 2.12 -// ====================== - -ui_AIC -{ - "AIC" -} - -ui_aicExport -{ - "导出" -} - -ui_aicExport_success -{ - "导出成功。" -} - -ui_aicHint -{ - "将.aic文件从安装程序导出到crusader文件夹中。" -} - - -// ====================== -// 1.00 -// ====================== - -Name -{ - "非官方要塞十字军东征补丁" -} - -u_ArabXBow -{ - "增强了阿拉伯剑士抵抗弩箭的能力" -} - -u_arabxbow_descr -{ - " -阿拉伯剑士在中3发弩箭后死亡改为6发弩箭后死亡。" -} - -u_ArabWall -{ - "阿拉伯剑士破坏城墙速度加快" -} - -u_ArabWall_descr -{ - "在原版,阿拉伯剑士破坏城墙的速度比其他任何单位都要更慢,& -打开这个选项后,破坏速度将会提升为原来的两倍,稍快于长矛手。" -} - -u_spearmen -{ - "增强长矛手抵抗箭矢的能力" -} - -u_spearmen_descr -{ - " - 长矛手在中3发箭后死亡改为5发箭后死亡, - - 长矛手承受1发弩箭后还可以刚好存活。" -} - -ai_buy -{ - "提升ai的市场使用" -} - -ai_buy_descr -{ - "在原版,部分ai不会正确使用市场,下列改动包含在此项中: - - 皇帝和元帅会购买武器装备 - - 修道院长和埃米尔会购买弓 - - 维奇尔会购买苹果。" -} - -ui_error -{ - "错误" -} - -ui_SearchPath -{ - " 请选择你的游戏安装路径" -} - -ui_search -{ - "浏览" -} - -ui_continue -{ - "继续" -} - -ui_wrongpath -{ - "该路径中未发现要塞十字军东征游戏程序!" -} - -ui_back -{ - "返回" -} - -ui_install -{ - "安装" -} - -ui_finished -{ - "完成" -} - -ui_chooseLangTitle -{ - "选择语言" -} - -ui_chooseLang -{ - "请在下列选项中选择一门语言" -} - -ui_accept -{ - "确定" -} - -ui_cancel -{ - "取消" -} - -ui_uninstall -{ - "复原" -} - -ui_uninstalldone -{ - "所有改动已复原。" -} - -ai_recruitinterval -{ - "加快所有ai的训练士兵速度" -} - -ai_recruitinterval_descr -{ - "将所有ai的训练时间间隔降低至最低(老鼠和狮心王的程度)" -} - -ai_recruitsleep -{ - "取消ai的训练暂停" -} - -ai_attacklimit -{ - "调整ai的进攻部队数量限制" -} - -ai_attacklimit_descr -{ - "ai的进攻部队的数量会随时间而增加,额外增加的部队数量上限& -在原版是200。你可以在此处修改这个值。" -} - -o_gamespeed -{ - "拓宽游戏速度限制" -} - -o_gamespeed_descr -{ - "游戏速度的限制更改为如下所示: - - 在10到90之间以5为间隔 - - 在90到200之间以10为间隔 - - 在200到1000之间以100为间隔 -新的游戏速度范围仅可通过键盘上的+ -号来改变,菜单中的游戏速度& -调整不到新的范围。" -} - -ui_bugfix -{ - "bug修复" -} - -ui_ailords -{ - "AI领主" -} - -ui_troops -{ - "单位" -} - -ui_other -{ - "其他" -} - -o_responsivegates -{ - "城门快速反应" -} - -o_responsivegates_descr -{ - "敌人在靠近城门一定距离时城门将会关闭,该距离由200调整至140。& -敌人在远离城门一定距离时城门将会打开,该距离由1200调整至100。" -} - -ai_addattack -{ - "调整ai每波进攻额外增加的兵力" -} - -ai_addattack_descr -{ - "在原版,ai每波进攻都会额外增加5的兵力,这个同时生效于& -所有ai的数值可以在此处改变。" -} - -ai_addattack_alt_descr -{ - "或者,每波额外增加的兵力可以和ai初次进攻的兵力有关,对于不同ai来说,& -初次进攻兵力可以是不同的,因此这个选项可以使不同ai的进攻士兵增速不同。 -举例: 倍率 = 0.5 -苏丹从第一波开始的进攻士兵数量 = 10, 15, 20, 25, ... -萨拉丁从第一波开始的进攻士兵数量 = 50, 75, 100, 125, ..." -} - -u_laddermen -{ - "增强云梯兵对于箭矢的抗性" -} - -u_laddermen_descr -{ - " - 云梯兵在中5发箭后死亡改为中12发箭后死亡 - - 云梯兵在中2发弩箭后死亡改为中5发弩箭后死亡 - - 云梯兵价钱从4提升为20" -} - -o_playercolor -{ - "改变玩家1号的颜色" -} - -o_playercolor_descr -{ - " " -} - -o_trooplimit -{ - "调整部队数量上限" -} - -o_trooplimit_descr -{ - "在原版,每位玩家最多可有2400名士兵,这个值可在此处改变" -} - -ai_demolish -{ - "停用ai拆毁以下类型建筑来获取资金" -} - -ai_demolish_walls -{ - "城堡建筑" -} - -ai_demolish_eco -{ - "经济建筑" -} - -ai_demolish_walls_descr -{ - " " -} - -ai_demolish_eco_descr -{ - "如果ai感受到了压力,他会通过拆毁城堡建筑或者经济建筑的方式来快速获取资金& -这在有时是没有必要的,你可以在此处取消这个行为。." -} - -ai_tethers -{ - "防止ai牛栏堆积" -} - -ai_tethers_descr -{ - "通常,ai会为每个新的采石场建筑一个新的牛栏,而不管已经存在多少牛栏。& -当采石场被反复摧毁时,会导致牛栏数量很多。打开此选项可以避免这种现象。" -} - -// ======================= -// 2.06 -// ======================= - -ai_nosleep -{ - "资源不足时ai不再休眠建筑" -} - -ai_nosleep_descr -{ - "ai通常会将正在生产中的建筑休眠,因为有部分建筑缺乏原料,哪怕原料& -正在运回的路上,打开此选项可以防止ai将建筑休眠。" -} - - -// ======================= -// 5.12.2018 -// ======================= - -o_onlyai -{ - "打开观察者模式" -} - -o_onlyai_descr -{ - "移除了玩家1使得玩家只能以观察的视角观看游戏,这使得8个ai同时出场成为了可能。该模式下保存的游戏可以被正常读取。偶尔可能会出现物体随机遍布在整个地图的bug,这只是视觉上的bug并不影响游戏本身,保存游戏,退出游戏,再读取游戏可以清除该bug。" -} - -o_moatvisibility -{ - "一直显示规划中的护城河" -} - -o_moatvisibility_descr -{ - "你将可以一直看到规划中的护城河,而不需要点选单位。" -} - -o_engineertent -{ - "无需重复选择工程师帐篷类型" -} - -o_engineertent_descr -{ - "打开这个选择之后,选择一次工程师帐篷类型后即可一直放置该类型的工程师& -帐篷,而不需要每次都再选择一次。" -} - - - - - - - - - - -// ================================ -// 2.07 -// ================================ - - -ai_demolish_trapped -{ - "城堡与外界隔绝" -} - -ai_demolish_trapped_descr -{ - " " -} - -o_freetrader -{ - "免费市场" -} - -o_freetrader_descr -{ - "有时ai的市场被拆除且没有木头时,ai将会彻底瘫痪。使市场免费可以避免此问题。" -} - -ai_towerengines -{ - "解除ai的器械数量限制" -} - -ai_towerengines_descr -{ - "在原版,每种器械ai最多只能放置3个,打开此选项可以解除此限制。" -} - -ai_buywood -{ - "购买足够木头" -} - -ai_buywood_descr -{ - "ai购买木头用于建筑时,将会购买2根额外的木头,防止刚购买的木头被& -工人拿走使得木头不足以建造目标建筑。" -} - -o_keys -{ - "WASD键移动以及Ctrl+S/L键保存读取" -} - -o_keys_descr -{ - "打开此选项后,可以使用WASD键移动屏幕,以及Ctrl+S键打开保存界面,& -Ctrl+L键打开读取界面。" -} - - - - - - - - - - - - - - - - - - - - - -// =========== -// 2.07a -// =========== - - - -ai_attacktarget -{ - "设置ai的目标敌人" -} - -ai_attacktarget_nearest -{ - "最近的敌人" -} - -ai_attacktarget_nearest_descr -{ - " " -} - -ai_attacktarget_richest -{ - "最富有的敌人" -} - -ai_attacktarget_richest_descr -{ - " " -} - -ai_attacktarget_weakest -{ - "最弱的敌人" -} - -ai_attacktarget_weakest_descr -{ - "该选项可以给所有ai设置相同的目标选择。" -} - - - - - - - - - -// ==================== -// 2.08 -// ==================== - - - - - -ai_assaultswitch -{ - "进攻时不改变目标" -} - -ai_assaultswitch_descr -{ - "当ai进攻时,如果目标发生改变,将会改变已派出部队的目标,比如ai目标若是最弱的敌人,当ai已派出进攻部队时,如果最弱的敌人改变了,将会改变进攻部队的路径转而攻击新目标。打开这个选项可以防止这种现象的发生。已派出的部队不会中途改变目标。" -} - - - -ai_rebuild -{ - "增强ai修复和建筑能力" -} - -ai_rebuild_descr -{ - "打开后,ai将会在废墟中重建塔楼,修复微小损坏的城墙。工程师协会,隧道工协会,油锅被摧毁后,如果后半截仍然存在,打开后ai将可以正确重建。采石场被摧毁后,如果存放石头点仍然存在,打开后ai可以无视存放石头点放置建筑。" -} - - - - - -// ==================== -// 2.09 -// ==================== - -o_healer -{ - "医生会治愈伤员" -} - -o_healer_descr -{ - "药房的医生现在会积极寻找兵治疗受伤的士兵,平民或者动物。 & -优先治疗最近的目标。每次治疗动画中,可恢复长矛兵血量的1/3。 游览& -花园和治疗瘟疫的功能依旧存在! 只有游览城堡的行为会被跳过,直到该& -地区不再有受伤的目标." -} - - - - - - -// ==================== -// 2.10 -// ==================== - - - -o_xtreme -{ - "移除增强版的技能条" -} - -o_xtreme_descr -{ - "移除要塞十字军东征增强版中的技能条。" -} - - -// ====================== -// 2.11 -// ====================== - - -ui_AIV -{ - "AIV" -} - -ai_access -{ - "不拆除无通路建筑" -} - -ai_access_descr -{ - "ai会反复建造又拆除无通路但需要通路的建筑,打开此选项可以避免此问题。" -} - -ai_moredef -{ - "老鼠,菲利普,狮心王将会有更多的防守部队" -} - -ai_moredef_descr -{ - "在原版,这三个ai只有很少的防守部队,打开此选项后可以增多他们的& -防守部队数量,如下: - -老鼠: 20 -> 40 -狮心王: 20 -> 40 -菲利普: 4 -> 32 - -需要注意的是,打开此选项后,会导致这三个ai的初次进攻时间延后。" -} - -ai_attackwave -{ - "提升ai的进攻" -} - -ai_attackwave_descr -{ - "在原版中,ai在进攻时,只会派出能够得着城墙的数量的士兵,比如说一圈城堡有50格城墙,那么只有50个人可以在不重叠的情况下砍城墙,此时哪怕有100名士兵集结在敌人城堡附近,也只会派出50人前去攻击城堡,打开此选项后将可以避免此现象。并且,打开此选项后,ai的士兵将会主动攻击城堡建筑和经济建筑。此外,ai将会派出更多的士兵去攻击敌人的领主。" -} diff --git a/UnofficialCrusaderPatch/Localization/English.txt b/UnofficialCrusaderPatch/Localization/English.txt deleted file mode 100644 index 5dd881c2..00000000 --- a/UnofficialCrusaderPatch/Localization/English.txt +++ /dev/null @@ -1,1071 +0,0 @@ -// ====================== -// 2.15 -// ====================== -u_spearmen_run -{ -"Spearmen run by default instead of walking" -} - -u_spearmen_run_descr -{ -"Makes spearmen run by default like slaves and macemen." -} - -o_seed_modification_possibility_title -{ -"Manipulate random number generator" -} - -o_seed_modification_possibility_only_set -{ -"Enable fixed game randomseed" -} - -o_seed_modification_possibility_only_set_descr -{ -"Setting the Game seed will allow AI-only games to play out the same way if the same map settings are used. For games involving human players, it will ensure the same starting conditions in the map (e.g. AIV selection). To set the game seed, enable this option and create a file called 'live' containing an integer in the [game install]/gameseeds directory. CAUTION: This feature only works after also restarting the game!" -} - -o_seed_modification_possibility -{ -"Enable & Save game randomseeds" -} - -o_seed_modification_possibility_descr -{ -"This option will save the seed from games that do not have a live seed set, so you can rename them to 'live' in order to recreate the match afterwards." -} - -ai_recruitstate_initialtimer -{ -"Set AIs initial time until they recruit by the AIC parameters" -} - -ai_recruitstate_initialtimervalue_descr -{ -"Set this value to number of months for which the AI will exclusively recruit defence troops, unless it has already filled up its defence total" -} - -ai_defense -{ -"Fix reinforcement of defense troops" -} - -ai_defense_descr -{ - "Fixes a bug which stopped the AI from reinforcing missing troops & -on walls and towers, as long as defensive patrols were still around." -} - -ai_housing -{ -"Let the AI build houses smarter" -} - -build_housing_descr -{ -"Difference between current and maximum population, above which the AI stops building houses. This is 0 in vanilla. This also disables deleting of houses for the AI." -} - -campfire_housing_descr -{ -"Number of idle peasants at the campfire before the AI stops building houses. This also disables deleting of houses for the AI." -} - -delete_housing -{ -"Disable the AI's ability to delete houses." -} - -delete_housing_descr -{ -"When this option is selected the AI will never delete houses." -} - -aiv_prompt -{ -"Custom AIVs detected. Do you want to create a backup Milord?" -} - -aiv_cli_prompt -{ -"Custom AIVs detected. Enter 'delete' to erase or enter folder name to copy files to." -} - -install_abort_io -{ -"Installation aborted. Files with the same name already exist in this folder. Please try again and select a different folder." -} - -install_abort -{ -"Installation aborted" -} - -backup_aiv_select -{ -"Select Backup AIV folder" -} - -o_change_siege_engine_spawn_position_catapult -{ -"Spawn siege engines in the center of their tent" -} - -o_change_siege_engine_spawn_position_catapult_descr -{ -"Siege engines are spawning in the middle of their construction tent, instead of the top right corner." -} - -o_stop_player_keep_rotation -{ -"Rotate player keeps same as AI's" -} - -o_stop_player_keep_rotation_descr -{ -"Player keeps now get rotated the same way, that AI keeps rotate on a map, facing with their campfire outwards towards the map edge." -} - -o_restore_arabian_engineer_speech -{ -"Restore engineer arabian speech" -} - -o_restore_arabian_engineer_speech_descr -{ -"Allows engineers to speak the originally recorded arabian voicelines when the player uses the Arabian lord." -} - -u_fix_lord_animation_stuck_movement -{ -"Reset lord animation after destroying buildings" -} - -u_fix_lord_animation_stuck_movement_descr -{ -"Reset the pose of the lord after it stops moving or destroys a building into the upright position. Usually it would get stuck bend down to the ground." -} - -fix_apple_orchard_build_size -{ -"Shrink apple orchard's build size" -} - -fix_apple_orchard_build_size_descr -{ -"Changes the apple orchard's build size to the size it occupies after the farm is placed down. This saves some space when building the farms and increases the rate with which the AI is able to put these farms down." -} - -u_fix_applefarm_blocking -{ -"Fix apple farm worker getting blocked" -} - -u_fix_applefarm_blocking_descr -{ -"Apple farmers can no longer be blocked by placing buildings at the top left side of the farm." -} - -o_increase_path_update_tick_rate -{ -"Check more often for available paths" -} - -o_increase_path_update_tick_rate_descr -{ -"In vanilla, it took 200 game ticks to check for new paths, often stopping units to move into the castle after destroying a gate or tower immediately. - -Availability is calculated every 50 gameticks now, allowing the units to 'realize' new paths more quickly." -} - -o_fix_ladderclimb -{ -"Fix ladder climbing destination bug" -} - -o_fix_ladderclimb_descr -{ -"Units will now remember their original destination after climbing a ladder, not getting stuck on the ladder." -} - -u_tanner_fix -{ -"Fix tanners getting all the same cow" -} - -u_tanner_fix_descr -{ -"Tanners will no longer return without a cow when another tanner took their target cow. They will now instead stand around a bit and then get another one." -} - -o_fix_fletcher_bug -{ -"Fix fletcher pathing" -} - -o_fix_fletcher_bug_descr -{ -"Fixes the behaviour where fletchers go back to the workplace after depositing the bow/crossbow instead of going straight to the stockpile." -} - -ai_fix_crusader_archers_pitch -{ -"Fix AI's crusader archers not lighting pitch" -} - -ai_fix_crusader_archers_pitch_descr -{ -"AI's European archers light pitch the same way arabian archers do, defending against enemy units." -} - -o_fix_baker_disappear -{ -"Fix bakers despawning" -} - -o_fix_baker_disappear_descr -{ -"Bakers no longer disappear when they don't find flour at their targeted stockpile." -} - -o_fix_moat_digging_unit_disappearing -{ -"Fix despawning of digging units" -} - -o_fix_moat_digging_unit_disappearing_descr -{ -"Fixes the bug where moat digging units would disappear while digging. Note that they can still disappear if you order them to move while standing on unwalkable terrain!" -} - -ui_welcometext -{ -"This is an unofficial patch for Stronghold Crusader. -The project ist available as open-source on [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). - -Any Crusader version is potentially supported, but since the changes were derived from the 1.41 Steam-Version, incompatibilities may appear. -The setup will then show error messages. The installed patch version is shown in the bottom left corner of the main menu of the game. -Before any changes, backup files will be created. These can be restored via the 'Uninstall'-button or manually. - -The team behind the UCP - -Creator of the UCP -[Sh0wdown](https://github.com/Sh0wdown) - -Project Management -[Kimberly Azula](https://github.com/ByBurton/) -[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) - -Developers -[LordHansCapon](https://github.com/LordHansCapon) -[np123](https://github.com/patel-nikhil) -[J-T-de](https://github.com/J-T-de) -[gynt](https://github.com/gynt) -[Le spec](https://github.com/LeSpec) -[Chaf1812](https://github.com/Chaf1812) - -Translators -[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polish) -[Lolasik011](https://github.com/Lolasik011) (Russian) -[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chinese) -[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Hungarian) - -Content Creators -[Evrey](https://github.com/Evrey) (aiv) -[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) -[PitchNeeded](https://github.com/PitchNeeded) (aiv) -[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) - -Special thanks of course go to -[Firefly Studios](https://fireflyworlds.com/) -for the creation of the Stronghold series - -And many more -[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) -[PodeCaradox](https://github.com/PodeCaradox) -[GRhin](https://www.twitch.tv/grhin) -[Heroesflorian](https://github.com/Heroesflorian)" -} - -// ====================== -// 2.14 -// ====================== - -ui_StartTroops -{ - "StartTroops" -} - -ui_Resource -{ - "StartGoods" -} - -ui_aicconflict -{ - "conflict and will be ignored" -} - -o_shfy -{ - "Strongholdify" -} - -o_shfy_beer -{ - "Popularity bonus from beer" -} - -o_shfy_beer_descr -{ - " " -} - -o_shfy_religion -{ - "Popularity bonus from cathedral and church" -} - -o_shfy_religion_descr -{ - " " -} - -o_shfy_peasantspawnrate -{ - "Spawnrate peasants" -} - -o_shfy_peasantspawnrate_descr -{ - " " -} - -o_shfy_resourcequantity -{ - "Quantity of delivered resources" -} - -o_shfy_resourcequantity_descr -{ - "Adapts listed aspects to match Stronghold 1. Attention: Every change influences the AI lords, in the worst case renders them useless!" -} - -o_armory_marketplace_weapon_order_fix -{ - "Fix armory/marketplace weapon orders to match" -} - -o_armory_marketplace_weapon_order_fix_descr -{ - "Reorders Weapon icons in Armory and Marketplace to have the same order. Also moves Leather Armor between Mace and Crossbow, and moves Metal Armor between Polearm and Sword for easier access while in Marketplace scrolling through items." -} - -ai_fix_laddermen_with_enclosed_keep -{ - "Fix AI not using laddermen if they are enclosed" -} - -ai_fix_laddermen_with_enclosed_keep_descr -{ - "AI (notably Snake) no longer stops using Laddermen with their sieging units if their keep is enclosed." -} - -o_override_identity_menu -{ - "Override the Set-up Identity menu adding new features" -} - -o_override_identity_menu_descr -{ - "Adds Ranged and Melee unit selection to Set-up Identity menu. ONLY FOR NORMAL GAME MODE!" -} - -o_default_multiplayer_speed -{ - "Set default multiplayer speed." -} - -o_default_multiplayer_speed_descr -{ - " " -} - -u_fireballistafix -{ - "Fire ballistae shoot monks and tunnelers" -} - -u_fireballistafix_descr -{ - "Fire ballistae automatically shoot at monks and tunnelers." -} - -ui_browsepath -{ - "Please choose your Stronghold Crusader installation directory." -} - -ui_aicoldversion -{ - "Old version detected. Click to convert" -} - -ui_aicofferconvert -{ - "Convert aic file to newer version?" -} - -ui_aicconvertprompt -{ - "AIC Conversion" -} - -ui_aicselect -{ - "Please deselect other AIC file(s) first. The following aic characters are already selected: " -} - -// ====================== -// 2.13 -// ====================== - -o_firecooldown -{ - "Extend fireproof duration of extinguished buildings" -} - -o_firecooldown_descr -{ - "The duration in which extinguished buildings cannot catch fire again can be extended here." -} - -u_ballistamonk -{ - "Fire ballistas shoot monks" -} - -u_ballistamonk_descr -{ - "Fire ballistas shoot automatically at monks with this setting." -} - - -// ====================== -// 2.12 -// ====================== - -ui_AIC -{ - "AIC" -} - -ui_aicExport -{ - "Export" -} - -ui_aicExport_success -{ - "Exported successfully." -} - -ui_aicHint -{ - "Exports the .aic-file from the installer into the crusader folder." -} - -// ====================== -// 1.00 -// ====================== - -Name -{ - "Unofficial Crusader Patcher" -} - -u_ArabXBow -{ - "Increased armor of Arabic Swordsmen against crossbows" -} - -u_arabxbow_descr -{ - " - Arabic Swordsmen only die after 6 crossbow hits intead of 3" -} - -u_ArabWall -{ - "Arabic Swordsmen destroy walls faster" -} - -u_ArabWall_descr -{ - "In Vanilla, arabic swordsmen destroy walls slower than any other melee unit. & -With this option, the tear down speed against walls is about doubled for them, & -putting them slightly above Spearmen." -} - -u_spearmen -{ - "Increased armor of spearmen against ranged units" -} - -u_spearmen_descr -{ - " - Spearmen only die after 5 arrow hits instead of 3 - - Spearmen barely survive one crossbow hit, instead of getting one-shot" -} - -ui_error -{ - "Error" -} - -ui_SearchPath -{ - " Please select your installation folder:" -} - -ui_search -{ - "Browse" -} - -ui_continue -{ - "Continue" -} - -ui_wrongpath -{ - "Stronghold Crusader could not be found in the specified path!" -} - -ui_back -{ - "Back" -} - -ui_install -{ - "Install" -} - -ui_finished -{ - "Finished" -} - -ui_chooseLangTitle -{ - "Setup language" -} - -ui_chooseLang -{ - "Please choose a language for this setup from the list below." -} - -ui_accept -{ - "OK" -} - -ui_cancel -{ - "Cancel" -} - -ui_uninstall -{ - "Uninstall" -} - -ui_uninstalldone -{ - "Uninstall completed." -} - -ai_recruitinterval -{ - "Increased recruitment speed" -} - -ai_recruitinterval_descr -{ - "Sets the recruitment interval of all AIs to the lowest value (Rat/Richard niveau)" -} - -ai_attacklimit -{ - "Increase of the attacking troops limit of the AIs" -} - -ai_attacklimit_descr -{ - "The number of additional units which are added after the first attack is & -limited to 200 in Vanilla. Here you can change this limit." -} - -o_gamespeed -{ - "Extended game speed limits" -} - -o_gamespeed_descr -{ - "The game speed can now be changed as follows: - - From 10 to 90 in intervals of 5 - - From 90 to 200 in intervals of 10 - - From 200 to 1000 in intervals of 100 -The new values are only available ingame via the +- keys, the slider in the & -game menu remains unchanged." -} - -ui_bugfix -{ - "Bugfixes" -} - -ui_ailords -{ - "AI lords" -} - -ui_troops -{ - "Units" -} - -ui_other -{ - "Other" -} - -o_responsivegates -{ - "Quicker responsiveness of gates towards enemies" -} - -o_responsivegates_descr -{ - "Gates close themselves later if enemies get into range and open faster & -when the danger is gone. The distance of an enemy for which the gates close & -will be reduced from 200 to 140. The time after which the gates open, after & -all enemies left will be reduced from 1200 to 100." -} - -ai_addattack -{ - "Increase of the rate of additional attack troops" -} - -ai_addattack_descr -{ - "In Vanilla the attack troop number is increased after each attack by 5 & -units on average. This value is the same for all AI lords and can be changed & -here." -} - -ai_addattack_alt_descr -{ - "Alternatively, the additional troop count can be made dependent on the & -troop count of the first attack. Since this value is different for each AI, & -the following attacks will also scale, instead of increasing by the same value & -for each AI lord. -Example: Scale factor = 0.5 -Sultan's attack troops = 10, 15, 20, 25, ... -Saladin's attack troops = 50, 75, 100, 125, ..." -} - -u_laddermen -{ - "Increased armor of laddermen against ranged units" -} - -u_laddermen_descr -{ - " - Laddermen die after 12 arrow hits instead of 5 - - Laddermen die after 5 crossbow or slinger hits instead of 2 - - Laddermen cost 20 gold instead of 4" -} - -o_playercolor -{ - "Change the color of player 1" -} - -o_playercolor_descr -{ - " " -} - -ai_demolish -{ - "Deactivate demolishing for money of the AI lords" -} - -ai_demolish_walls -{ - "fortification buildings" -} - -ai_demolish_eco -{ - "econonmy buildings" -} - -ai_demolish_walls_descr -{ - " " -} - -ai_demolish_eco_descr -{ - "If the AI feels pressured, it likes to demolishes its economy or & -fortification buildings to get quick money for troops. This feature sometimes & -seems to be triggered without any visible reason and thus can be disabled here." -} - -ai_tethers -{ - "Disable ox tether spam" -} - -ai_tethers_descr -{ - "Usually, the AI builds for each new stone quarry a new ox tether, & -independent of how many tether already exist. This can be disabled here, since & -it leads to ox tether spam if the AIs' quarries get destroyed repeatedly." -} - - - - - - - - - - -// ======================= -// 2.06 -// ======================= - -ai_nosleep -{ - "Disable sleeping mode for lack of resources" -} - -ai_nosleep_descr -{ - "The AI usually puts its processing buildings to sleep, as soon & -as the needed resource is missing. This is done without the regard for & -losing products which are just on the way f.e. to the weapon chamber. -This feature can be completely disabled here." -} - - - - - - - - -// 5.12.2018 - -o_onlyai -{ - "Activate Spectator-mode [bug possible]" -} - -o_onlyai_descr -{ - "Removes player 1 so that you can only spectate and makes 8 AIs in one & -round possible. Savegames now load properly in this mode. Sometimes a bug & -appears in which random objects spawn all over the map. This is just visually & -and can be removed by saving the game, ending the mission and reloading the & -save file." -} - -o_moatvisibility -{ - "Always show planned moat" -} - -o_moatvisibility_descr -{ - "Your own placed but not digged out moat will always be shown with this & -setting, even if you deselect the moat placing." -} - -o_engineertent -{ - "No siege tent deselection" -} - -o_engineertent_descr -{ - "With this setting, the game will not deselect your chosen siege equipment & -after placing one tent anymore. This way you can create several tents after another & -without having to reselect the same siege equipment every time." -} - - - - - - - - - - -// ================================ -// 2.07 -// ================================ - - -ai_demolish_trapped -{ - "If enclosed" -} - -ai_demolish_trapped_descr -{ - " " -} - -o_freetrader -{ - "Free trader post" -} - -o_freetrader_descr -{ - "Since the AI sometimes plays itself, when they're out of wood and their trader post & -is destroyed. With this setting, the trader post will become free of cost to prevent this." -} - -ai_towerengines -{ - "No limit for siege engines on towers" -} - -ai_towerengines_descr -{ - "Usually the AI only builds up to three mangonels and ballistae each on its towers. & -This limit can be lifted here." -} - -ai_buywood -{ - "Buy enough wood" -} - -ai_buywood_descr -{ - "To prevent thievish fletchers from stealing wood which the AI just bought for & -buildings, 2 extra wood will now be bought for each building." -} - -o_keys -{ - "WASD-Keys and quicksaves" -} - -o_keys_descr -{ - "The WASD-keys can be used to move around with this setting as well as & -CTRL-S and CTRL-L to quicksave and load respectively." -} - - - - - - - - - - - - - - - - - - - - - -// =========== -// 2.07a -// =========== - - - -ai_attacktarget -{ - "Set AI attack target" -} - -ai_attacktarget_nearest -{ - "Nearest enemy" -} - -ai_attacktarget_nearest_descr -{ - " " -} - -ai_attacktarget_richest -{ - "Richest Enemy" -} - -ai_attacktarget_richest_descr -{ - " " -} - -ai_attacktarget_weakest -{ - "Weakest Enemy" -} - -ai_attacktarget_weakest_descr -{ - "With this setting, all AI lords will chose their next attack target in & -the same way. This prevents troops switching targets during a castle assault & -as well as sending them past other enemies' castles to gather." -} - - - - - - - - - -// ==================== -// 2.08 -// ==================== - - - - - -ai_assaultswitch -{ - "No AI target change during sieges" -} - -ai_assaultswitch_descr -{ - "AI lords which attack the mightiest oder weakest enemy sometimes & -switch their target in the middle of an ongoing assault and send their & -troops to a different castle. This is prevented with this setting, as soon & -as the assault has started, i.e. during the troop gathering phase in front of & -a castle a change can still happen." -} - - - -ai_rebuild -{ - "Improved AI repairs" -} - -ai_rebuild_descr -{ - "The AI will repair tower ruins, slightly damaged walls, as well as & -destroyed engineer's and tunneler's guilds and oil smelters, of which the gathering place & -still exists. Furthermore, the AI can now build over the collection platform & -of quarries." -} - - - - - -// ==================== -// 2.09 -// ==================== - -o_healer -{ - "Healer heals casualties" -} - -o_healer_descr -{ - "The healer of the apothecary building now actively seeks out injured soldiers, & -civilists and animals to heal them. The nearest targets are treated first. With each & -healing animation ca. 1/3 of a spearman's health is recovered. The strolling through & -gardens and investigation of plague clouds is not replaced! Only the strolling through & -the castle is skipped until no more wounded targets are in the area." -} - - - - - - -// ==================== -// 2.10 -// ==================== - - - -o_xtreme -{ - "Remove the magic bar in Extreme" -} - -o_xtreme_descr -{ - "Removes the magic bar in Crusader Extreme." -} - - -// ====================== -// 2.11 -// ====================== - - -ui_AIV -{ - "AIV" -} - -ai_access -{ - "No demolishing of inaccessible buildings" -} - -ai_access_descr -{ - "Prevents the AI from demolishing buildings without access. This should & -stop the AI from continuously demolishing and rebuilding buildings where no & -access is available." -} - -ai_attackwave -{ - "Improve attack waves" -} - -ai_attackwave_descr -{ - "The AI in an attack in vanilla only sends as many troops at once as & -there are wall parts reachable. This causes units to drop in in small waves & -when the target castle has a lot of buildings directly at its walls. -This option makes units also attack civil and fortification buildings, as & -well as wall parts which are already being attacked by one unit. Moreover, -the AI sends more troops to the enemy lord as soon as it detects a breach." -} diff --git a/UnofficialCrusaderPatch/Localization/German.txt b/UnofficialCrusaderPatch/Localization/German.txt deleted file mode 100644 index 15ae5079..00000000 --- a/UnofficialCrusaderPatch/Localization/German.txt +++ /dev/null @@ -1,1075 +0,0 @@ -// ====================== -// 2.15 -// ====================== - -u_spearmen_run -{ -"Speerträger rennen standardmäßig" -} - -u_spearmen_run_descr -{ -"Speerträger rennen standardmäßig so schnell wie Sklaven und Streitkolbenkämpfer." -} - -o_seed_modification_possibility_title -{ -"Manipuliere Zufallszahlengenerator" -} - -o_seed_modification_possibility_only_set -{ -"Ermögliche Festlegung eines Zufallsstartwertes" -} - -o_seed_modification_possibility_only_set_descr -{ -"Das Setzen eines Startwertes für den Zufallszahlen Generator ermöglicht es für KI Spiele immer den gleichen Verlauf zu nehmen. Für Spiele mit menschlichen Spielern und KI können feste Startbedingungen ermöglicht werden (z.B. die gleiche Auswahl von AIV Dateien für die KI). Um den Zufallsstartwert zu setzen, erstelle eine Datei mit dem Namen 'live', welche eine ganze Zahl enthält im Ordner Installationsverzeichnis/gameseeds. ACHTUNG: Vor Beginn eines wiederholbaren Scharmützels muss das Spiel neu gestartet werden!" -} - -o_seed_modification_possibility -{ -"Ermögliche & Speichere Zufallsstartwerte" -} - -o_seed_modification_possibility_descr -{ -"Mit dieser Option werden Zufallsstartwerte von Spielen gespeichert, für die keiner im gameseeds Ordner gesetzt wurde. So können diese nachträglich in 'live' umbenannt werden um das Spiel zu wiederholen." -} - -ai_recruitstate_initialtimer -{ -"Setzt den Zeitpunkt, ab dem KIs anhand der AIC rekrutieren" -} - -ai_recruitstate_initialtimervalue_descr -{ -"Anzahl an Monaten, ab der die KI anhand der in der AIC festgelegten Rekrutierungswahrscheinlichkeiten rekrutiert. Bis dahin rekrutiert sie ausschließlich Defensivtruppen bis diese vollständig sind und daraufhin Angriffstruppen." -} - -ai_defense -{ -"Verstärkung der Burgverteidigung fixen" -} - -ai_defense_descr -{ -"Fixt den Bug, der die KI davon abhielt, fehlende Truppen auf Wällen und Türmen zu verstärken solange noch Defensivpatrouillien vorhanden waren." -} - -ai_housing -{ -"Intelligenteres Errichten und Abreißen von Häusern" -} - -build_housing_descr -{ -"Die Differenz aus aktueller und maximal möglicher Bevölkerung, ab der KIs keine Häuser mehr bauen. In Vanilla ist diese 0. Zudem deaktiviert diese Option das Abreißen von Häusern für KIs." -} - -campfire_housing_descr -{ -"Wenn mehr als diese Anzahl an freien Bauern am Lagerfeuer sitzen, baut die KI keine Häuser mehr. Zudem deaktiviert diese Option das Abreißen von Häusern für KIs." -} - -delete_housing -{ -"Kein Abreißen von Häusern der KIs" -} - -delete_housing_descr -{ -"Mit dieser Option reißen KIs keine Häuser mehr ab." -} - -aiv_prompt -{ -"Modifizierte AIVs erkannt. Wollen Eure Lordschaft jetzt ein Backup anlegen?" -} - -aiv_cli_prompt -{ -"Modifizierte AIVs erkannt. Schreibe 'delete', um sie zu löschen oder einen Ordnernamen, um ein Backup zu erstellen." -} - -install_abort_io -{ -"Installation abgebrochen. Dateien mit dem selben Namen waren bereits im gewählten Ordner vorhanden. Bitte wählen Eure Lordschaft einen anderen Ordner aus." -} - -install_abort -{ -"Installation abgebrochen" -} - -backup_aiv_select -{ -"Backup AIV Ordner auswählen" -} - -o_change_siege_engine_spawn_position_catapult -{ -"Belagerungsgeräte in der Mitte des Zelts aufbauen" -} - -o_change_siege_engine_spawn_position_catapult_descr -{ -"Belagerungsgeräte erscheinen nun nach dem Aufbauen am Punkt der Zeltmitte, statt wie bisher in der oberen rechten Ecke des Zelts." -} - -o_stop_player_keep_rotation -{ -"Drehe Spielerbergfriede wie die der KIs" -} - -o_stop_player_keep_rotation_descr -{ -"Die Bergfriede der Spieler richten sich nun so aus wie die der KI; sie drehen sich so, dass das Lagerfeuer in Richtung des Kartenrands zeigt." -} - -o_restore_arabian_engineer_speech -{ -"Baumeister arabischer Lords sprechen Arabisch" -} - -o_restore_arabian_engineer_speech_descr -{ -"Falls der Spieler den arabischen Lord auswählt nutzen Baumeister nun ihre arabischen Sprachdateien." -} - -u_fix_lord_animation_stuck_movement -{ -"Setzt die Lordanimation nach Zerstörung von Gebäuden zurück" -} - -u_fix_lord_animation_stuck_movement_descr -{ -"Der Lord wechselt mit dieser Änderung nach dem Zerstören eines Gebäudes in seine Ausgangsposition. Bisher blieb er in der Zerstöranimation stecken." -} - -fix_apple_orchard_build_size -{ -"Reduziert die Baugröße von Apfelfarmen" -} - -fix_apple_orchard_build_size_descr -{ -"Ändert die Bauvorschau von Apfelfarmen auf die Größe, die sie nach der Platzierung der Farm haben." -} - -u_fix_applefarm_blocking -{ -"Behebt das Blockieren des Apfelfarmers" -} - -u_fix_applefarm_blocking_descr -{ -"Apfelfarmer werden nicht länger inaktiv, wenn der Pfad links oben direkt neben der Farm blockiert wird." -} - -o_increase_path_update_tick_rate -{ -"Suche öfter nach verfügbaren Wegen" -} - -o_increase_path_update_tick_rate_descr -{ -"Das Spiel überprüft nun viermal so häufig, welche Bereiche der Karte verbunden sind. Dadurch können beispielsweise nach der Zerstörung eines Torhauses oder eines Turmes die Truppen schneller ins Innere einer zuvor unzugänglichen Burg beordert werden." -} - -o_fix_ladderclimb -{ -"Behebt Befehlsverlust beim Klettern auf Leitern" -} - -o_fix_ladderclimb_descr -{ -"Einheiten klettern nicht mehr direkt zurück und vergessen auch nicht mehr ihr Ziel, nachdem sie eine Leiter erklommen haben." -} - -u_tanner_fix -{ -"Gerberinnen holen sich unterschiedliche Kühe" -} - -u_tanner_fix_descr -{ -"Gerberinnen kehren nicht länger ohne Kuh zurück, falls ihre anvisierte Kuh bereits weg ist. Sie warten nun, bis sie eine andere Kuh mitnehmen können." -} - -o_fix_fletcher_bug -{ -"Entfernt den Extraweg des Pfeilmachers zur Werkstatt" -} - -o_fix_fletcher_bug_descr -{ -"Passt das Verhalten des Pfeilmachers an andere Waffenproduzenten an. Nach Abgabe seines Gutes geht er nun direkt zum Vorratslager, statt erneut zur Werkstatt zurückzukehren." -} - -ai_fix_crusader_archers_pitch -{ -"Europäische Bogenschützen der KI entzünden Pech." -} - -ai_fix_crusader_archers_pitch_descr -{ -"Bisher waren nur Arabische Bogenschützen der KIs in der Lage Pechgraben mit Feuerpfeilen zu entzünden; nun können dies auch Europäischen Bogenschützen." -} - -o_fix_baker_disappear -{ -"Behebt das Verschwinden von Bäckern" -} - -o_fix_baker_disappear_descr -{ -"Behebt den Fehler, der Bäcker verschwinden ließ, wenn sie kein Mehl am angestrebten Platz im Vorratslager vorfinden konnten." -} - -o_fix_moat_digging_unit_disappearing -{ -"Behebt das Verschwinden von Buddeleinheiten." -} - -o_fix_moat_digging_unit_disappearing_descr -{ -"Behebt das Verschwinden von Truppen, die mit dem Ausheben von Burggräben beschäftigt sind. Diese verschwinden allerdings weiterhin, falls diese neue Befehle bekommen und zeitgleich auf unbegehbarem Terrain stehen." -} - -ui_welcometext -{ -"Dies ist ein inoffizieller Patch für Stronghold Crusader. -Das Projekt ist Open-Source auf [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch) zu finden. - -Potenziell wird jede Crusader-Version unterstützt, die Änderungen wurden allerdings anhand der 1.41 Steam-Version hergeleitet. -Im Falle von Versionsinkompatibilität wird der Setup Fehlermeldungen zeigen. Die installierte Patchversion wird unten links im Hauptmenü angezeigt. -Vor jeglichen Änderungen werden Backup-Dateien erstellt, die über den 'Deinstallieren'-Button oder manuell wiederhergestellt werden können. - -Das Team hinter dem inoffiziellen Patch - -Erschaffer des UCP -[Sh0wdown](https://github.com/Sh0wdown) - -Projektleitung -[Kimberly Azula](https://github.com/ByBurton/) -[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) - -Entwickler -[LordHansCapon](https://github.com/LordHansCapon) -[np123](https://github.com/patel-nikhil) -[J-T-de](https://github.com/J-T-de) -[gynt](https://github.com/gynt) -[Le spec](https://github.com/LeSpec) -[Chaf1812](https://github.com/Chaf1812) - -Übersetzer -[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polnisch) -[Lolasik011](https://github.com/Lolasik011) (Russisch) -[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chinesisch) -[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Ungarisch) - -Inhaltliche Beiträge -[Evrey](https://github.com/Evrey) (aiv) -[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) -[PitchNeeded](https://github.com/PitchNeeded) (aiv) -[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) - -Besonderer Dank geht an -[Firefly Studios](https://fireflyworlds.com/) -für die Erstellung der Stronghold Serie - -Und viele mehr -[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) -[PodeCaradox](https://github.com/PodeCaradox) -[GRhin](https://www.twitch.tv/grhin) -[Heroesflorian](https://github.com/Heroesflorian)" -} - -// ====================== -// 2.14 -// ====================== - -ui_StartTroops -{ - "Starttruppen" -} - -ui_Resource -{ - "Startgüter" -} - -ui_aicconflict -{ - "Konflikt und wird ignoriert" -} - -o_shfy -{ - "Strongholdify" -} - -o_shfy_beer -{ - "Beliebtheitsbonus durch Bier" -} - -o_shfy_beer_descr -{ - " " -} - -o_shfy_religion -{ - "Beliebtheitsbonus Kathedrale und Kirche" -} - -o_shfy_religion_descr -{ - " " -} - -o_shfy_peasantspawnrate -{ - "Spawngeschwindigkeit Bauern" -} - -o_shfy_peasantspawnrate_descr -{ - " " -} - -o_shfy_resourcequantity -{ - "Anzahl der gelieferten Resourcen" -} - -o_shfy_resourcequantity_descr -{ - "Passt aufgelistete Aspekte an Stronghold 1 an. Achtung: Jede Annpassung nimmt Einfluss auf die KI Lords, schlimmstenfalls werden diese nutzlos!" -} - -o_armory_marketplace_weapon_order_fix -{ - "Vereinheitlicht Waffenreihenfolge" -} - -o_armory_marketplace_weapon_order_fix_descr -{ - "Vereinheitlicht Waffenreihenfolge in Waffenkammer und Marktplatz. Es befinden sich nun Lederrüstungen zwischen Streitkolben und Armbrüste, und Rüstungen zwischen Piken und Schwertern für einfacheres Scrollen im Marktplatz." -} - -ai_fix_laddermen_with_enclosed_keep -{ - "Korrigiert Leiternutzung" -} - -ai_fix_laddermen_with_enclosed_keep_descr -{ - "Mit diesem Fix können Belagerungseinheiten von KIs, deren Bergfried abgeschlossen ist, weiterhin die Leitern der Leiterträger nutzen (betrifft vanilla nur die Schlange)." -} - -o_override_identity_menu -{ - "Fügt neue Optionen zum Menüpunkt 'Identität zulegen' hinzu" -} - -o_override_identity_menu_descr -{ - "Im Menüpunkt 'Identität zulegen' kann man nun die Starteinheiten für 'Normales Spiel' ändern" -} - -o_default_multiplayer_speed -{ - "Setzt Mehrspieler Standardgeschwindigkeit" -} - -o_default_multiplayer_speed_descr -{ - " " -} - -u_fireballistafix -{ - "Feuerballisten schießen auf Mönche und Tunnelgräber" -} - -u_fireballistafix_descr -{ - "Feuerballisten erkennen nun Mönche und Tunnelgräber als Feinde und schießen auf diese." -} - -ui_browsepath -{ - "Bitte wähle dein Stronghold Crusader - Installationsverzeichnis." -} - -ui_aicoldversion -{ - "Alte Version erkannt. Klicken Sie zum Konvertieren" -} - -ui_aicofferconvert -{ - "AIC-Datei in neuere Version konvertieren?" -} - -ui_aicconvertprompt -{ - "AIC-Konvertierung" -} - -ui_aicselect -{ - "Bitte deaktivieren Sie zuerst andere AIC-Dateien. Die folgenden aic-Zeichen sind bereits ausgewählt: " -} - - -// ====================== -// 2.13 -// ====================== - -o_firecooldown -{ - "Feuerfeste Zeit gelöschter Gebäude verlängern" -} - -o_firecooldown_descr -{ - "Der Zeitraum in dem gelöschte Häuser nicht wieder brennen können kann hier verlängert werden." -} - -u_ballistamonk -{ - "Feuerballisten schießen auf Mönche" -} - -u_ballistamonk_descr -{ - "Lässt Feuerballisten automatisch auch auf Mönche schießen." -} - - -// ====================== -// 2.12 -// ====================== - -ui_AIC -{ - "AIC" -} - -ui_aicExport -{ - "Export" -} - -ui_aicExport_success -{ - "Erfolgreich exportiert." -} - -ui_aicHint -{ - "Exportiert die .aic-Datei aus dem Installer in das Crusader-Verzeichnis." -} - -// ====================== -// 1.00 -// ====================== - -Name -{ - "Inoffizieller Crusader Patcher" -} - -u_ArabXBow -{ - "Erhöhter Schutz von Arab. Schwertkämpfer vor Armbrüsten" -} - -u_arabxbow_descr -{ - " - Arabische Schwertkämpfer sterben erst nach 6 Armbrusttreffern statt 3" -} - -u_ArabWall -{ - "Arab. Schwertkämpfer reißen Mauern schneller ein" -} - -u_ArabWall_descr -{ - "In Vanilla reißen Arabische Schwertkämpfer Mauern am langsamsten ein unter & -den Nahkämpfern. Die Einreißgeschwindigkeit wird hiermit für sie ca. & -verdoppelt, sodass sie dabei knapp über Lanzenträgern sind." -} - -u_spearmen -{ - "Erhöhter Schutz von Lanzenträger gegen Fernkämpfer" -} - -u_spearmen_descr -{ - " - Lanzenträger sterben erst nach 5 Pfeiltreffern statt 3 - - Lanzenträger überleben knapp einen Armbrusttreffer" -} - -ui_error -{ - "Fehler" -} - -ui_SearchPath -{ - " Bitte wähle dein Installationverzeichnis:" -} - -ui_search -{ - "Suchen" -} - -ui_continue -{ - "Weiter" -} - -ui_wrongpath -{ - "Stronghold Crusader konnte nicht im angegebenen Pfad gefunden werden!" -} - -ui_back -{ - "Zurück" -} - -ui_install -{ - "Installieren" -} - -ui_finished -{ - "Fertig" -} - -ui_chooseLangTitle -{ - "Setup-Sprache" -} - -ui_chooseLang -{ - "Bitte wählen Sie eine Sprache für die Installation aus der unten & -aufgeführten Liste." -} - -ui_accept -{ - "OK" -} - -ui_cancel -{ - "Abbrechen" -} - -ui_uninstall -{ - "Deinstallieren" -} - -ui_uninstalldone -{ - "Deinstallation abgeschlossen." -} - -ai_recruitinterval -{ - "Erhöhtes Rekrutierungstempo" -} - -ai_recruitinterval_descr -{ - "Setzt das Rekrutierungsintervall aller KIs auf den niedrigsten Wert. & -(Ratte/Richard-Niveau)" -} - -ai_attacklimit -{ - "Erhöhung des Angriffstruppenlimits der KIs" -} - -ai_attacklimit_descr -{ - "In Vanilla is das Limit der zusätzlichen Truppen, die nach dem ersten & -Angriff dazukommen auf 200 begrenzt. Hier kann diese Grenze verändert werden." -} - -o_gamespeed -{ - "Erweiterte Spielgeschwindigkeitsgrenzen" -} - -o_gamespeed_descr -{ - "Die Spielgeschwindigkeit kann nun wie folgt geändert werden: - - Von 10 bis 90 in 5er Schritten - - Von 90 bis 200 in 10er Schritten - - Von 200 bis 1000 in 100er Schritten -Die neuen Werte sind nur im Spiel über die +- Tasten erreichbar, der Regler im & -Spielmenü bleibt ungeändert." -} - -ui_bugfix -{ - "Bugfixes" -} - -ui_ailords -{ - "KI-Lords" -} - -ui_troops -{ - "Einheiten" -} - -ui_other -{ - "Sonstiges" -} - -o_responsivegates -{ - "Torhäuser schneller auf Gegner reagieren lassen" -} - -o_responsivegates_descr -{ - "Torhäuser schließen sich jetzt später bei Gegnernähe und öffnen wieder & -schneller automatisch, sobald die Gefahr vorüber ist. Die Distanz die ein & -Gegner haben muss, damit sich das Tor automatisch schließt, wird von 200 auf & -140 gesenkt. Die Zeit nach der sich das Tor wieder öffnet, sofern kein Gegner & -mehr in der Nähe ist, wird von 1200 auf 100 reduziert." -} - -ai_addattack -{ - "Erhöhung der Rate von zusätzlichen Angriffstruppen" -} - -ai_addattack_descr -{ - "In Vanilla wird nach jedem Angriff die Truppenzahl für den nächsten & -Angriff durchschnittlich um 5 Einheiten erhöht. Dieser Wert ist für alle & -KI-Lords gleich und kann hier geändert werden." -} - -ai_addattack_alt_descr -{ - "Alternativ kann hier die hinzukommende Truppenanzahl von der Truppenstärke & -des ersten Angriffs abhängig gemacht werden. Da jede KI unterschiedliche & -Anzahlen für den Erstangriff hat, werden somit auch folgende Angriffe & -skalieren, anstatt für jede KI gleich anzusteigen. -Beispiel: Skalierungsfaktor = 0,5 -Sultans Angriffszahlen = 10, 15, 20, 25, ... -Saladins Angriffszahlen = 50, 75, 100, 125, ..." -} - -u_laddermen -{ - "Erhöhter Schutz für Leiterträger gegen Fernkämpfer" -} - -u_laddermen_descr -{ - " - Leiterträger sterben erst nach 12 Pfeiltreffern statt 5 - - Leiterträger sterben erst nach 5 Armbrust- oder Schleudertreffern statt 2 - - Leiterträger kosten 20 Gold statt 4" -} - -o_playercolor -{ - "Farbe von Spieler 1 wechseln" -} - -o_playercolor_descr -{ - " " -} - -ai_demolish -{ - "Einreißen für Geld der KI-Lords deaktivieren" -} - -ai_demolish_walls -{ - "Befestigungsanlagen" -} - -ai_demolish_eco -{ - "Wirtschaftsgebäude" -} - -ai_demolish_walls_descr -{ - " " -} - -ai_demolish_eco_descr -{ - "Wenn die KI sich bedrängt fühlt und schnell an Geld für Truppen kommen & -will, reißt sie gerne mal ihre komplette Wirtschaft oder Befestigungsanlagen & -ein. Manchmal wird dieses Feature aber auch völlig ohne scheinbaren Grund & -ausgelöst und kann darum hier ausgestellt werden." -} - -ai_tethers -{ - "Ochsenjoch-Spam deaktivieren" -} - -ai_tethers_descr -{ - "Die KI baut normalerweise mit jedem neuen Steinbruch auch ein neues & -Ochsenjoch, unabhängig davon wie viele sie schon hat. Dies kann hier & -deaktiviert werden, da es zu Ochsenjoch-Spam führt, wenn die Steinbrüche & -der AI immer wieder zerstört werden." -} - - - - - - - - -// ======================= -// 2.06 -// ======================= - - - -ai_nosleep -{ - "Schlafenlegen bei Rohstoffmangel deaktivieren" -} - -ai_nosleep_descr -{ - "Normalerweise legt die KI ihre Verarbeitungsgebäude schlafen, & -sobald der nötige Rohstoff nicht mehr im Lager vorhanden ist. Dabei & -wird keine Rücksicht genommen ob Produkte verloren gehen die & -z.B. gerade zur Waffenkammer gebracht werden. Diese Funktion kann hier & -komplett deaktiviert werden." -} - - - - - - - -// 5.12.2018 - -o_onlyai -{ - "Zuschauer-Modus aktivieren [bug möglich]" -} - -o_onlyai_descr -{ - "Entfernt Spieler 1 sodass man nur noch zugucken kann und 8 KIs in einem & -Kreuzzug möglich sind. Gespeicherte Spiele laden jetzt auch ordnungsgemäß in & -diesem Modus. Ab und zu tritt ein Bug auf, bei dem überall auf der Karte zufällige & -Objekte auftauchen. Diese sind jedoch nur visuell und können durch einfaches & -Spiel speichern -> Mission beenden -> Spiel laden behoben werden." -} - -o_moatvisibility -{ - "Geplanten Burggraben immer zeigen" -} - -o_moatvisibility_descr -{ - "Mit dieser Einstellung wird der gesetzte, aber noch nicht ausgehobene & -Burggraben immer angezeigt, auch wenn man die Burggrabenplatzierung abwählt." -} - - -o_engineertent -{ - "Belagerungsgeräte nicht automatisch abwählen" -} - -o_engineertent_descr -{ - "Mit dieser Einstellung wird das zuletzt zum Bau ausgewählte Belagerungsgerät & -bei Baumeistern nicht abgewählt, sodass man mehrere Zelte nacheinander bauen kann, & -ohne jedes mal neu wählen zu müssen." -} - - - - - - - -// ================================ -// 2.07 -// ================================ - - -ai_demolish_trapped -{ - "Falls eingeschlossen" -} - -ai_demolish_trapped_descr -{ - " " -} - - -o_freetrader -{ - "Kostenloser Marktplatz" -} - -o_freetrader_descr -{ - "Da die KI sich manchmal selbst Schachmatt setzt, wenn sie kein Holz hat und der & -Marktplatz zerstört wurde, kann hier der Bau des Marktplatzes kostenlos gemacht werden." -} - -ai_towerengines -{ - "Keine Grenze für Geräte auf Türmen" -} - -ai_towerengines_descr -{ - "Normalerweise baut die KI maximal je drei Ballisten und Mangen. & -Dieses Limit wird hiermit aufgehoben." -} - -ai_buywood -{ - "Genügend Holz kaufen" -} - -ai_buywood_descr -{ - "Damit Bogenmacher etc. nicht ständig gekauftes Bauholz wegschnappen, & -kauft die KI mit dieser Einstellung immer 2 Holz mehr als nötig für Gebäude." -} - -o_keys -{ - "WASD-Tasten und Quicksaves" -} - -o_keys_descr -{ - "Mit dieser Einstellung werden die WASD-Tasten für die Kamera aktiviert. -Außerdem kann mit STRG-S und STRG-L ein Quicksave erstellt und geladen werden." -} - - - - - - - - - - - - - -// =========== -// 2.07a -// =========== - - - -ai_attacktarget -{ - "AI-Angriffsziel einstellen" -} - -ai_attacktarget_nearest -{ - "Nahegelegenster Gegner" -} - -ai_attacktarget_nearest_descr -{ - " " -} - -ai_attacktarget_richest -{ - "Reichster Gegner" -} - -ai_attacktarget_richest_descr -{ - " " -} - -ai_attacktarget_weakest -{ - "Schwächster Gegner" -} - -ai_attacktarget_weakest_descr -{ - "Mit dieser Einstellung suchen sich die KI-Lords alle auf die selbe Weise, -das Ziel für ihren nächsten Angriff. Dies verhindert, dass die Truppen mittem & -im laufenden Angriff umschwenken oder an Gegnerburgen vorbeigeschickt werden & -zum Sammeln." -} - - - - - - - - - - - -// ================ -// 2.08 -// ================ - - -ai_assaultswitch -{ - "Kein KI-Angriffszielwechsel während Belagerung" -} - -ai_assaultswitch_descr -{ - "KI-Lords die den mächtigsten oder schwächsten Gegner angreifen, & -hatten manchmal die Tendenz mitten in einem Angriff das Ziel zu wechseln, & -und ihre Truppen zu einer anderen Burg schicken. Mit dieser Einstellung, & -passiert das nicht mehr, sobald der Angriff begonnen hat, d.h. während & -des Sammelns vor der Burg kann ein Wechsel noch passieren." -} - - - -ai_rebuild -{ - "Verbessertes KI-Reparieren" -} - -ai_rebuild_descr -{ - "Mit dieser Einstellung reparieren KI-Lords auch Turmruinen, leicht & -angeschlagene Mauern, sowie Baumeister-, Tunnelgilden und Ölkessel bei denen & -der Sammelplatz übergeblieben ist. Weiterhin kann die KI nun auch die Sammelstelle & -von Steinbrüchen überbauen." -} - - - - - - -// ==================== -// 2.09 -// ==================== - -o_healer -{ - "Heiler verarztet Verwundete" -} - -o_healer_descr -{ - "Der Heiler des Apothekengebäudes sucht nun verletzte Soldaten, Zivilisten & -und Tiere auf und heilt diese. Nahe Ziele werden dabei bevorzugt. Mit jeder Heilungs-Animation & -wird ca. 1/3 des Lebens eines Lanzenträgers geheilt. Das Schlendern durch die Gärten und & -Aufsuchen von Pestwolken wird dadurch nicht ersetzt! Nur das Schlendern durch die Burg & -wird ausgelassen, bis keine Verwundeten mehr in Reichweite sind." -} - - - - - - - -// ==================== -// 2.10 -// ==================== - - - -o_xtreme -{ - "Magie-Leiste in Extreme entfernen." -} - -o_xtreme_descr -{ - "Entfernt die Magie-Leiste in Crusader Extreme." -} - - - - - - - -// ====================== -// 2.11 -// ====================== - - -ui_AIV -{ - "AIV" -} - -ai_access -{ - "Kein Abreißen von unzugänglichen Gebäuden" -} - -ai_access_descr -{ - "Verhindert, dass die KI Gebäude abreißt zu denen es keinen Zuweg gibt. & -Damit soll der Bug verhindert werden, bei dem manche KIs in ihren Burgen & -andauernd Gebäude abreißen und wieder aufbauen zu denen es keinen Weg gibt." -} - -ai_attackwave -{ - "Angriffswellen verbessern" -} - -ai_attackwave_descr -{ - "In Vanilla schickt die KI bei einem Angriff immer nur & -so viele Einheiten auf einmal los wie Mauernstücke erreichbar & -sind. Bei Burgen die mit Gebäuden umbaut sind greifen die Einheiten & -dadurch nur tröpfchenweise an. -Durch die Aktivierung dieser Option greifen Einheiten auch Gebäude und & -Befestigungsanlagen an, sowie Mauerstücke die bereits von einem Angreifer & -besetzt sind. Außerdem schickt die KI jetzt auch mehr Truppen auf den & -gegnerischen Bergfried, sobald sie eine Bresche erkennt." -} diff --git a/UnofficialCrusaderPatch/Localization/Hungarian.txt b/UnofficialCrusaderPatch/Localization/Hungarian.txt deleted file mode 100644 index 2cd2fda0..00000000 --- a/UnofficialCrusaderPatch/Localization/Hungarian.txt +++ /dev/null @@ -1,1061 +0,0 @@ -// ====================== -// 2.15 -// ====================== - -u_spearmen_run -{ -"A lándzsás egység sétálás helyett alapból fut" -} - -u_spearmen_run_descr -{ -"A lándzsás egység lassú sétálás helyett alapból futni fog. A lándzsás olyan gyorsan fut, mint egy rabszolga vagy buzogányos." -} - -o_seed_modification_possibility_title -{ -"Random játék seed" -} - -o_seed_modification_possibility_only_set -{ -"Megadott Random játék seed engedélyezése" -} - -o_seed_modification_possibility_only_set_descr -{ -"A játék seed megadásával az MI harcoknak a kimenetele ugyanaz lesz, azonos pályabeállítások esetén. Játékos-MI harc esetén, ugyanazon kezdési feltételeket biztosítja a pályán (mint pl. az AIV kiválasztás). A játék seed megadásához, engedélyezd ezt a beállítást és hozz létre egy 6 darab számot tartalmazó 'live' nevű szöveges fájlt a játék könyvtár/gameseeds mappában. FIGYELEM: Ez a beállítás csak a játék újraindítása után működik!" -} - -o_seed_modification_possibility -{ -"Random játék seed-ek engedélyezése és mentése" -} - -o_seed_modification_possibility_descr -{ -"Ez a beállítás elmenti a seed-et azon játékokból amikhez nem lett megadva live seed érték, nevezd át a kívánt seed-et tartalmazó szöveges fájlt 'live'-ra hogy a későbbiekben újra rekonstruálhasd a harcot." -} - -ai_recruitstate_initialtimer -{ -"Az MI a megadott ideig az AIC paraméterek alapján toborozzon" -} - -ai_recruitstate_initialtimervalue_descr -{ -"Az értéknek add meg azon hónapok számát, amikor az MI az AIC fájlban megadott toborzási sebeséggel toboroz kizárólag védekező egységeket, ha már teljesen megerősítette a védelmét, akkor támadó egységeket fog toborozni" -} - -ai_defense -{ -"Várvédő egységek megerősítése kijavítva" -} - -ai_defense_descr -{ -"Kijavítja azt a hibát, ami megakadályozza az MI-t abban, hogy a hiányzó egységekkel megerősítse a várfalat és a tornyot, ameddig rendelkezik még védekező-járőröző egységekkel." -} - -ai_housing -{ -"Házak okosabb építése" -} - -build_housing_descr -{ -"A jelenlegi és a maximális népességszám közötti különbség, amely felett az MI nem épít több házat. Az eredeti játékban ez a szám 0. Ha ez a beállítás be van jelölve, akkor az MI nem rombolja le a házakat." -} - -campfire_housing_descr -{ -"Parasztok száma a tábortűznél, mielőtt az MI nem épít több házat. Ha ez a beállítás be van jelölve, akkor az MI nem rombolja le a házakat." -} - -delete_housing -{ -"Az MI ne rombolja le a házakat." -} - -delete_housing_descr -{ -"Ha ez a beállítás be van jelölve, akkor az MI soha nem rombolja le a házakat." -} - -aiv_prompt -{ -"Módosított AIV fájlok észlelve. Szeretne egy biztonsági másolatot készíteni, uram?" -} - -aiv_cli_prompt -{ -"Módosított AIV fájlok észlelve. Írd be a 'delete' szót az eltávolításukhoz vagy adj meg egy mappa nevet, ahova a fájlok települnek." -} - -install_abort_io -{ -"Telepítés megszakítva. Már léteznek ilyen nevű fájlok ebben a mappában. Kérjük válassz egy másik mappát és próbáld meg újra." -} - -install_abort -{ -"Telepítés megszakítva" -} - -backup_aiv_select -{ -"Válaszd ki az AIV Backup mappát" -} - -o_change_siege_engine_spawn_position_catapult -{ -"Elkészült ostromgépek középre pozicionálása" -} - -o_change_siege_engine_spawn_position_catapult_descr -{ -"Az elkészült ostromgépek a sátor közepénél jelennek meg a sátor jobb felső sarka helyett." -} - -o_stop_player_keep_rotation -{ -"Játékos vártornyok elforgatása" -} - -o_stop_player_keep_rotation_descr -{ -"A játékosok vártornyai mostantól ugyanolyan módon lesznek elforgatva, mint az MI vártornyok. A tábortűz mindig a térkép legközelebbi széle felé néz." -} - -o_restore_arabian_engineer_speech -{ -"Az arab mérnök arabul beszél" -} - -o_restore_arabian_engineer_speech_descr -{ -"Ha a játékos az Arab Lord-ot választja, akkor a mérnök beszédekor az eredeti felvett arab hangfájlt használja. - -Nincs túl sok variáció ezekben a hangfájlokban, így egy idő után zavaró lehet." -} - -u_fix_lord_animation_stuck_movement -{ -"Lord animáció visszaállítása az épületek lerombolása után" -} - -u_fix_lord_animation_stuck_movement_descr -{ -"Ezzel a változtatással egy épület lerombolása után a Lord a kiindulási animációra tér vissza. Mostantól nem marad a leromboló animációban." -} - -fix_apple_orchard_build_size -{ -"Almáskert építési méretének csökkentése" -} - -fix_apple_orchard_build_size_descr -{ -"Az almáskert elhelyezése előtt az előnézeti mérete nagyobb volt, mint amekkora valójában az almáskert az elhelyezés után. Ez a hiba kijavításra került. Ezzel a beállítással több szabad hely marad az almáskertek építésekor és megnöveli az MI mezőgazdasági épületek építésének rátáját." -} - -u_fix_applefarm_blocking -{ -"Almáskert blokkolása javítás" -} - -u_fix_applefarm_blocking_descr -{ -"Az almatermesztő nem várakozik, ha az almáskert bal felső részénél lévő utat blokkolja valami." -} - -o_increase_path_update_tick_rate -{ -"Elérhető útvonalak gyakoribb ellenőrzése" -} - -o_increase_path_update_tick_rate_descr -{ -"Az eredeti játékban minden 200. játékidő tick után kerültek ellenőrzésre az új útvonalak, ami azt eredményezte, hogy az egységek nem tudtak azonnal bemenni a várba miután lerombolták a kaput vagy a tornyot. - -Az elérhető útvonalakat mostantól minden 50. játékidő tick után ellenőrzi, így lehetővé téve hogy az egységek sokkal gyorsabban 'realizálják' az elérhető új útvonalat." -} - -o_fix_ladderclimb -{ -"Létramászás hibajavítás" -} - -o_fix_ladderclimb_descr -{ -"Az egységek mászás után nem felejtik el a számukra adott parancsot, és többé nem fognak lemászni miután már felmásztak." -} - -u_tanner_fix -{ -"A tímárok ugyanazt a tehenet választják javítás" -} - -u_tanner_fix_descr -{ -"A tímárok mostantól nem fognak tehén nélkül visszatérni, ha egy másik tímár már elvitte az általuk kiválasztott tehenet. Mostantól várakoznak egy ideig és elvisznek egy másikat." -} - -o_fix_fletcher_bug -{ -"Íjkészítő hibajavítás" -} - -o_fix_fletcher_bug_descr -{ -"Kijavítja az íjkészítő azon viselkedését, miszerint visszatér a munkahelyére ha leszállított egy íjat/íjpuskát, ahelyett hogy egyenesen a raktárhoz menne." -} - -ai_fix_crusader_archers_pitch -{ -"MI keresztes íjász nem gyújtja be az olajosárkot javítás" -} - -ai_fix_crusader_archers_pitch_descr -{ -"Az MI keresztes íjász most már begyújtja az olajosárkot, úgy mint az arab íjász amikor ellenséges egység lép az olajosárokra." -} - -o_fix_baker_disappear -{ -"Eltűnő pék hibajavítás" -} - -o_fix_baker_disappear_descr -{ -"Kijavítja azt a hibát, amikor a pék eltűnik ha a raktárban nem találja meg a kiválasztott helyen a lisztet." -} - -o_fix_moat_digging_unit_disappearing -{ -"Eltűnő árokásó egység hibajavítás" -} - -o_fix_moat_digging_unit_disappearing_descr -{ -"Kijavítja azt a hibát, amikor árokásás közben véletlenszerűen eltűnik az árkot ásó egység. Megjegyzés: Az egység még mindig eltűnhet, ha árokásás közben elküldöd máshova és éppen egy nem járható helyen van!" -} - -ui_welcometext -{ -"Ez egy nem hivatalos patch a Stronghold Crusader játékhoz. -A Projekt nyílt forráskódú, ami megtalálható a [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch) weboldalon. - -Elméletben minden Crusader verzió támogatott, viszont a változtatások eredetileg a 1.41 Steames verzióhoz lettek készítve. -Azonban ha a játék verziód nem kompatibilis, a telepítő hibaüzenetet fog megjeleníteni. A telepített patch-verzió a főmenü bal alsó sarkában fog megjelenni. -Minden változtatás előtt Backup fájl készül, ami visszaállítható a 'Eltávolítás' gombra kattintva vagy manuálisan visszahelyezhető. - -Az Unofficial Crusader Patch csapat - -UCP program alkotója -[Sh0wdown](https://github.com/Sh0wdown) - -Projektvezetők -[Kimberly Azula](https://github.com/ByBurton/) -[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) - -Fejlesztők -[LordHansCapon](https://github.com/LordHansCapon) -[np123](https://github.com/patel-nikhil) -[gynt](https://github.com/gynt) -[J-T-de](https://github.com/J-T-de) -[Le spec](https://github.com/LeSpec) -[Chaf1812](https://github.com/Chaf1812) - -Fordítók -[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Lengyel) -[Lolasik011](https://github.com/Lolasik011) (Orosz) -[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Kínai) -[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Magyar) - -Tartalom készítők -[Evrey](https://github.com/Evrey) (aiv) -[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) -[PitchNeeded](https://github.com/PitchNeeded) (aiv) -[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) - -Külön köszönet nekik: -[Firefly Studios](https://fireflyworlds.com/) -a Stronghold széria létrehozásáért - -Továbbá külön köszönet: -[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) -[PodeCaradox](https://github.com/PodeCaradox) -[GRhin](https://www.twitch.tv/grhin) -[Heroesflorian](https://github.com/Heroesflorian)" -} - -// ====================== -// 2.14 -// ====================== - -ui_StartTroops -{ - "Kezdőegységek" -} - -ui_Resource -{ - "Kezdőkészlet" -} - -ui_aicconflict -{ - "A konfliktusok figyelmen kívül lesznek hagyva" -} - -o_shfy -{ - "Strongholdify" -} - -o_shfy_beer -{ - "Sör általi népszerűségi bónusz" -} - -o_shfy_beer_descr -{ - " " -} - -o_shfy_religion -{ - "Templom és katedrális általi népszerűségi bónusz" -} - -o_shfy_religion_descr -{ - " " -} - -o_shfy_peasantspawnrate -{ - "Parasztok érkezésének sebessége" -} - -o_shfy_peasantspawnrate_descr -{ - " " -} - -o_shfy_resourcequantity -{ - "Leszállított erőforrások mennyisége" -} - -o_shfy_resourcequantity_descr -{ - "A felsorolt szempontokat a Stronghold 1-hez igazítja. Vigyázat: Minden változtatás hatással van az MI Lordokra, a legrosszabb esetben haszontalanná teszi őket!" -} - -o_armory_marketplace_weapon_order_fix -{ - "Megegyező fegyver sorrend a fegyverraktár/piacban" -} - -o_armory_marketplace_weapon_order_fix_descr -{ - "Újrarendezi a fegyver ikonokat a fegyverraktárban és a piacban, hogy egyforma legyen a sorrend. A bőrpáncél a buzogány és számszeríj között lesz, míg a vaspáncél a dárda és kard között, hogy könnyebben megtalálható legyen a piacban való kereséskor." -} - -ai_fix_laddermen_with_enclosed_keep -{ - "Javított létrahasználat" -} - -ai_fix_laddermen_with_enclosed_keep_descr -{ - "Ezzel a hibajavítással azok az MI-k, akiknek a vártornyuk körül van zárva, továbbra is tudják az ostromegységeik használni a létrahordozók létráit (az eredeti játékban ez csak a Kígyót érinti)." -} - -o_override_identity_menu -{ - "Új beállítások hozzáadása a 'Játékos szerkesztése' menühöz" -} - -o_override_identity_menu_descr -{ - "Távolsági és közelharci egységek kiválasztási lehetőségét adja hozzá a 'Játékos szerkesztése' menüponthoz. CSAK NORMÁL JÁTÉK MÓDHOZ!" -} - -o_default_multiplayer_speed -{ - "Többjátékos mód alapsebességének beállítása" -} - -o_default_multiplayer_speed_descr -{ - " " -} - -u_fireballistafix -{ - "A tűzhajítógépek lőnek a szerzetesekre és az alagútásókra" -} - -u_fireballistafix_descr -{ - "A tűzhajítógépek most már ellenségként észlelik a szerzeteseket és az alagútásókat, mostantól lőnek rájuk." -} - -ui_browsepath -{ - "Kérjük adja meg a Stronghold Crusader telepítési könyvtárát." -} - -ui_aicoldversion -{ - "Régi verzió észlelve. Kattintson a konvertáláshoz" -} - -ui_aicofferconvert -{ - "AIC fájlok konvertálása az új verzióhoz?" -} - -ui_aicconvertprompt -{ - "AIC konvertálás" -} - -ui_aicselect -{ - "Kérjük először szüntesse meg a többi AIC fájl(ok) kiválasztását. Az alábbi aic karakterek vannak kijelölve: " -} - -// ====================== -// 2.13 -// ====================== - -o_firecooldown -{ - "Eloltott épületek tűzálló időtartamának megnövelése" -} - -o_firecooldown_descr -{ - "Itt meghosszabbítható az az időtartam, amely alatt az eloltott épületek nem tudnak újra kigyulladni." -} - -u_ballistamonk -{ - "A tűzhajítógépek lőnek a szerzetesekre" -} - -u_ballistamonk_descr -{ - "A tűzhajítógépek automatikusan lőnek a szerzetesekre is." -} - - -// ====================== -// 2.12 -// ====================== - -ui_AIC -{ - "AIC" -} - -ui_aicExport -{ - "Exportálás" -} - -ui_aicExport_success -{ - "Exportálás sikeresen befejezve." -} - -ui_aicHint -{ - "Exportálja az .aic fájlokat a telepítőből a Crusader mappába." -} - -// ====================== -// 1.00 -// ====================== - -Name -{ - "Unofficial Crusader Patcher" -} - -u_ArabXBow -{ - "Megnövelt védelem az arab szablyás egységnek a számszeríj nyílvessző ellen" -} - -u_arabxbow_descr -{ - " - Az arab szablyás 3 helyett 6 számszeríj nyílvessző találat után hal meg" -} - -u_ArabWall -{ - "Az arab szablyás gyorsabban rombolja le a várfalat" -} - -u_ArabWall_descr -{ - "Az eredeti játékban az arab szablyás rombolja le a várfalat a leglassabban a közelharci egységek közül. A lerombolás sebessége ezentúl kb. megkétszereződik, így épphogy jobb lesz a lándzsás egységnél." -} - -u_spearmen -{ - "Megnövelt védelem a lándzsás egységnek a távolsági egységek ellen" -} - -u_spearmen_descr -{ - " - A lándzsás egység 3 helyett 5 nyíl találat után hal meg - - A lándzsás egység épphogy túlél egy számszeríj nyílvessző találatot" -} - -ai_buy -{ - "Javított piac elhelyezés az MI Lordoknak" -} - -ai_buy_descr -{ - "Az eredeti játékban egyes új MI Lordok nem helyezik jól el a piacot. -Az alábbi javítások lesznek ezentúl érvényesek: - - Frigyes és a Tábornok ezentúl vásárolnak fegyvert és páncélt - - Az Apát és az Emír ezentúl vásárolnak íjat - - Wazir ezentúl vásárol almát, mint Nizar és Emír" -} - -ui_error -{ - "Hiba" -} - -ui_SearchPath -{ - " Kérjük adja meg a telepítési útvonalat:" -} - -ui_search -{ - "Keresés" -} - -ui_continue -{ - "Tovább" -} - -ui_wrongpath -{ - "A Stronghold Crusader nem található a megadott elérési útvonalon!" -} - -ui_back -{ - "Vissza" -} - -ui_install -{ - "Telepítés" -} - -ui_finished -{ - "Kész" -} - -ui_chooseLangTitle -{ - "Telepítő nyelve" -} - -ui_chooseLang -{ - "Kérjük válasszon ki egy nyelvet a telepítéshez a lent megjelenített listából." -} - -ui_accept -{ - "OK" -} - -ui_cancel -{ - "Mégsem" -} - -ui_uninstall -{ - "Eltávolítás" -} - -ui_uninstalldone -{ - "Eltávolítás befejezve." -} - -ai_recruitinterval -{ - "Megnövelt toborzási sebesség" -} - -ai_recruitinterval_descr -{ - "Átállítja minden MI Lordnak a toborzási intervallumát a legkisebb értékre. (Patkány/Richárd szint)" -} - -ai_recruitsleep -{ - "Deaktiválja minden MI Lordnak a toborzási szünetét" -} - -ai_attacklimit -{ - "Megnövelt támadó egység limit az MI Lordoknak" -} - -ai_attacklimit_descr -{ - "Az eredeti játékban a további egységek limitje, akik az első támadás után csatlakoznak 200-ra van korlátozva. Itt tudod megváltoztatni ezt a korlátozást." -} - -o_gamespeed -{ - "Bővített játéksebesség limit" -} - -o_gamespeed_descr -{ - "A játéksebességet mostantól a következőképpen lehet megváltoztatni: - - 10-től 90-ig 5 lépésben - - 90-től 200-ig 10 lépésben - - 200-tól 1000-ig 100 lépésben -Az új értékek elérhetők a játékban a +- billentyűk segítségével, a csúszka a játékmenüben változatlanul maradt." -} - -ui_bugfix -{ - "Hibajavítások" -} - -ui_ailords -{ - "MI Lordok" -} - -ui_troops -{ - "Egységek" -} - -ui_other -{ - "Egyéb" -} - -o_responsivegates -{ - "A várkapuk gyorsabban reagálnak az ellenséges egységekre" -} - -o_responsivegates_descr -{ - "A várkapuk mostantól később záródnak be ha ellenség van a közelben és automatikusan gyorsabban kinyílnak, ha már nincs közelben ellenség. A távolság ami szükséges az ellenségnek, hogy a várkapu automatikusan bezáródjon, 200-ról 140-re lett csökkentve. Az idő amikor a várkapu ismét kinyílik, mihelyst nincs ellenség a közelben, 1200-ról 100-ra lett csökkentve." -} - -ai_addattack -{ - "Megnövelt további támadó egységek mértéke" -} - -ai_addattack_descr -{ - "Az eredeti játékban minden egyes támadás után az egységek száma a következő támadáskor átlagosan 5 egységgel lesz megnövelve. Ez az érték minden MI Lordnak ugyanannyi és itt tudod megváltoztatni." -} - -ai_addattack_alt_descr -{ - "Alternatív megoldásként, a további csatlakozó egységek számát az első támadás erősségétől függetlenné lehet tenni. De mivel minden MI Lord különböző számú egységet használ az első támadásnál, ezzel együtt a következő támadások is skálázódnak ahelyett, hogy minden MI Lordnak ugyanaz az értéke lenne. -Például: Skálázási faktor = 0,5 -Szultán támadásainak száma = 10, 15, 20, 25, ... -Szaladin támadásainak száma = 50, 75, 100, 125, ..." -} - -u_laddermen -{ - "Megnövelt védelem a létrás egységnek a távolsági egységek ellen" -} - -u_laddermen_descr -{ - " - A létrás egység 5 helyett 12 nyíl találat után hal meg - - A létrás egység 2 helyett 5 számszeríj nyílvessző találat vagy parittyakő találat után hal meg - - A létrás egység 4 helyett 20 aranyba kerül" -} - -o_playercolor -{ - "Játékos 1 színcsere" -} - -o_playercolor_descr -{ - " " -} - -o_trooplimit -{ - "Megnövelt egység limit" -} - -o_trooplimit_descr -{ - "Az eredeti játékban az egységek száma egy játékosnak -2400/játékosszám. Itt tudod megváltoztatni ezt a számot." -} - -ai_demolish -{ - "Az MI Lord lerombol mindent hogy pénzhez jusson deaktiválása" -} - -ai_demolish_walls -{ - "Várépületek" -} - -ai_demolish_eco -{ - "Ipari épületek" -} - -ai_demolish_walls_descr -{ - " " -} - -ai_demolish_eco_descr -{ - "Ha az MI Lord sarokba szorítva érzi magát és gyorsan pénzt akar szerezni az egységekhez, előszeretettel rombolja le a teljes iparát vagy várépületeit. Néha ez az esemény láthatólag minden indok nélkül megtörténik és emiatt itt ki tudod kapcsolni." -} - -ai_tethers -{ - "Ökör karám spam deaktiválása" -} - -ai_tethers_descr -{ - "Az MI általában minden új kőfejtő építésekor épít egy új ökör karámot is attól függetlenül, hogy mennyi van neki. Ezt itt tudod deaktiválni, mert különben spammelni fogja az ökör karámokat, ha az MI kőfejtőjét mindig lerombolják." -} - - - - - - - - -// ======================= -// 2.06 -// ======================= - - - -ai_nosleep -{ - "Ha nincs elég erőforrás, szünetel a munka deaktiválása" -} - -ai_nosleep_descr -{ - "Általában az MI szünetelteti a munkát az ipari épületeinél, ha a szükséges erőforrás már nem áll rendelkezésére a raktárban. Eközben a termék kárba veszik amit pl. éppen a fegyverraktárba visznek. Ezt a funkciót itt teljesen ki lehet kapcsolni." -} - - -// 5.12.2018 - -o_onlyai -{ - "Nézői mód aktiválása [hiba előfordulhat]" -} - -o_onlyai_descr -{ - "Eltávolítja az 1.játékost a nézői módhoz és így 8 MI harcolhat egymással az Egyedi játék módban. Az elmentett játék most már rendesen működik ebben a módban is. Néha előfordulhat olyan hiba, hogy az egész térképen véletlenszerűen feltűnhetnek tárgyak. De ezek csak vizuálisan jelennek meg és egyszerűen megoldható a Játék mentése -> Küldetés befejezése -> Játék betöltésével." -} - -o_moatvisibility -{ - "Mindig mutassa a tervezett várárkot" -} - -o_moatvisibility_descr -{ - "Ezzel a beállítással a lehelyezett, de a még nem felásott várárok mindig látható, még akkor is ha nincs kiválasztva a várárokásás." -} - - -o_engineertent -{ - "Ostromgépek kijelölve maradnak" -} - -o_engineertent_descr -{ - "Ezzel a beállítással az utoljára építésre kiválasztott ostromgép marad kijelölve ha több mérnököt kiválasztottál, így több ostromsátrat is lehet egymás után építeni." -} - - - - - - - -// ================================ -// 2.07 -// ================================ - - -ai_demolish_trapped -{ - "Ha bezárva" -} - -ai_demolish_trapped_descr -{ - " Ha az MI be van zárva és nem jutnak ki az egységei, lerombol mindent. Ezt itt tudod kikapcsolni. (pl. a játékos lerak egy épületet a várkapuja elé és nincs másik bejárata a várnak)" -} - - -o_freetrader -{ - "Ingyen piac" -} - -o_freetrader_descr -{ - "Mivel néha az MI magának add sakk-mattot, ha nincs elég fája és a piacát lerombolták. Itt tudod beállítani hogy a piac építése ingyenes legyen." -} - -ai_towerengines -{ - "Ne legyen korlátozás a tornyokon lévő szerkezeteknek" -} - -ai_towerengines_descr -{ - "Általában az MI maximálisan 3 hajítógépet és kővetőgépet épít minden tornyára. Ezen beállítással ez a korlátozás megszűnik." -} - -ai_buywood -{ - "Elegendő fa vásárlása" -} - -ai_buywood_descr -{ - "Ahhoz hogy az íjkészítők stb. ne vigyék el mindig a megvásárolt fát. Az MI ezzel a beállítással mindig 2 fával többet vesz, mint ami szükséges az épületek építéséhez." -} - -o_keys -{ - "WASD billentyűk és gyorsmentés" -} - -o_keys_descr -{ - "Ezzel a beállítással aktiválva lesznek a WASD billentyűk a kamerához. -Ezenkívül a CTRL-S és a CTRL-L billentyűkkel lehet gyorsmentést létrehozni és betölteni." -} - - - - - - - - - - - - - -// =========== -// 2.07a -// =========== - - - -ai_attacktarget -{ - "MI támadási-célpont beállítása" -} - -ai_attacktarget_nearest -{ - "A legközelebbi ellenség" -} - -ai_attacktarget_nearest_descr -{ - " " -} - -ai_attacktarget_richest -{ - "A leggazdagabb ellenség" -} - -ai_attacktarget_richest_descr -{ - " " -} - -ai_attacktarget_weakest -{ - "A leggyengébb ellenség" -} - -ai_attacktarget_weakest_descr -{ - "Ezzel a beállítással az MI Lordok a saját módjukon keresik meg a célpontot a következő támadásukhoz. Ez megakadályozza azt, hogy az egységek támadás közben célpontot változtassanak vagy az MI ne a másik ellenséges várhoz küldje gyülekezni a seregét." -} - - - - - - - - - - - -// ================ -// 2.08 -// ================ - - -ai_assaultswitch -{ - "Ostrom közben ne változtasson az MI támadási-célpontot" -} - -ai_assaultswitch_descr -{ - "Azok az MI Lordok akik a legerősebbet vagy a leggyengébbet támadták meg, néha hajlamosak voltak a támadás közepén célpontot változtatni, és az egységeiket elküldeni a másik várhoz. Ezzel a beállítással, ez már nem fordul elő, mihelyst a támadást megkezdte, viszont a vár előtti egységek gyülekezésekor még előfordulhat, hogy célpontot vált." -} - - - -ai_rebuild -{ - "Kijavított MI javítások" -} - -ai_rebuild_descr -{ - "Ezzel a beállítással az MI Lordok megjavítják a toronyromokat is, enyhén megrongált várfalakat, továbbá mérnökök-, alagútásók céhet és olajfőző kunyhót ha a helyük megmaradt. Továbbá az MI most már képes építeni a kőfejtők helye felett is." -} - - - - - - -// ==================== -// 2.09 -// ==================== - -o_healer -{ - "A gyógyító ellátja a sérülteket" -} - -o_healer_descr -{ - "A gyógyszertár gyógyítója mostantól megkeresi a sérült harcosokat, civileket, állatokat és meggyógyítja őket. A hozzá legközelebb lévő célpontokat gyógyítja először. Minden gyógyító animációval kb. egy lándzsás 1/3 életerejét állítja helyre. A kertekben való mászkálás és a pestisfelhő felkeresése ez által nem lesz lecserélve! Csak a várban való mászkálása lesz kihagyva, ha van sebesült a hatótávolságán belül." -} - - - - - - - -// ==================== -// 2.10 -// ==================== - - - -o_xtreme -{ - "Varázserő-sáv eltávolítása az Extreme kiegészítőből." -} - -o_xtreme_descr -{ - "Eltávolítja a Varázserő-sávot a Crusader Extreme kiegészítőben." -} - - - - - - - -// ====================== -// 2.11 -// ====================== - - -ui_AIV -{ - "AIV" -} - -ai_access -{ - "Az elérhetetlen épületek ne kerüljenek lerombolásra" -} - -ai_access_descr -{ - "Megakadályozza azt, hogy az MI lerombolja azt az épületet amihez nem lehet hozzáférni. Ezáltal kijavítható az a hiba, hogy az MI ne építse meg és rombolja le újra és újra mindig azt az épületet amihez nem tudnak eljutni." -} - -ai_moredef -{ - "Még több védekező egység Richárd, Patkány és Fülöp hercegnek" -} - -ai_moredef_descr -{ - "Az eredeti játékban Richárd, Patkány de leginkább Fülöpnek nagyon kevés védekező egysége volt a várfalakon, tornyokon. Ezzel a beállítással a távolsági harcosok száma a következőképpen változik meg: - -Patkány: 20 -> 40 -Richárd: 20 -> 40 -Fülöp: 4 -> 32 - -Viszont figyelembe kell venni, hogy ezáltal a legelső támadásuk egy kicsivel később következik be." -} - -ai_attackwave -{ - "Támadási hullámok feljavítása" -} - -ai_attackwave_descr -{ - "Az eredeti játékban az MI mindig csak annyi egységet küld el egyszerre amennyi elérhető várfal van. Azok a várak amik épületekkel vannak körülépítve, azokat az egységek csak elvétve támadják meg. Ezzel a beállítással az egységek az épületeket és az ostromsátrakat is megtámadják illetve azt a várfalat is amit már egy másik támadó egység rombol. Továbbá az MI mostantól több egységet küld az ellenséges vártoronyra, amint észrevesz egy oda vezető utat." -} diff --git a/UnofficialCrusaderPatch/Localization/Localization.cs b/UnofficialCrusaderPatch/Localization/Localization.cs deleted file mode 100644 index f5180553..00000000 --- a/UnofficialCrusaderPatch/Localization/Localization.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Text; - -namespace UCP -{ - public static class Localization - { - public class Language - { - string name; - public string Name => name; - - string ident; - public string Ident => ident; - - string culture; - public string Culture => culture; - - public Language(string name, string ident, string culture) - { - this.name = name; - this.ident = ident; - this.culture = culture; - } - } - - static int[] loadOrder = { 1, 0, 2, 3, 4}; - public static IEnumerable IndexLoadOrder => loadOrder; - - static List translations = new List() - { - new Language("Deutsch", "German", "de"), - new Language("English", "English", "en"), - new Language("Polski", "Polish", "pl"), - new Language("Русский", "Russian", "ru"), - new Language("中文", "Chinese", "ch"), - new Language("Magyar", "Hungarian", "hu") - }; - public static IEnumerable Translations => translations; - public static int GetLangByCulture(string culture) - { - return translations.FindIndex(l => l.Culture == culture); - } - - - static Dictionary localStrs = new Dictionary(StringComparer.OrdinalIgnoreCase); - - public static void Add(string identifier, string text) - { - if (localStrs.ContainsKey(identifier)) - { - localStrs[identifier] = text; - } - else - { - localStrs.Add(identifier, text); - } - } - - public static void Remove(string identifier) - { - if (localStrs.ContainsKey(identifier)) - { - localStrs.Remove(identifier); - } - } - - public static string Get(string identifier) - { - if (localStrs.TryGetValue(identifier, out string text)) - { - return text; - } - return string.Format("{{Unknown Identifier: {0}}}", identifier); - - } - - class Reader : IDisposable - { - StreamReader sr; - int lineNum = 0; - public int LineNumber { get { return this.lineNum; } } - - public Reader(Stream stream) - { - sr = new StreamReader(stream); - } - - public void Dispose() - { - sr.Dispose(); - } - - public bool ReadLine(out string line) - { - while (true) - { - line = sr.ReadLine(); lineNum++; - if (line == null) - break; - - line = line.Trim(); - if (line.Length == 0) - continue; - - if (!line.StartsWith("//")) - return true; - } - line = null; - return false; - } - - StringBuilder chars = new StringBuilder(100); - public bool ReadString(out string text) - { - int c; - int oldLineNum = lineNum; - - while (true) - { - if ((c = sr.Read()) < 0) - throw new Exception("ReadString: End of file after line " + oldLineNum); - - if (c == '\n') - lineNum++; - - if (char.IsWhiteSpace((char)c)) - continue; - - if (c != '\"') - { - sr.ReadLine(); - lineNum++; - text = null; - return false; - } - else - { - break; - } - } - - oldLineNum = lineNum; - while (true) - { - if ((c = sr.Read()) < 0) - throw new Exception("Could not find string closing after line " + oldLineNum); - - if (c == '&') - { - int peek = sr.Peek(); - if (peek == '\r') - { - sr.Read(); - sr.Read(); - lineNum++; - continue; - } - } - - if (c == '\n') - { - lineNum++; - } - - if (c == '\"') - break; - - chars.Append((char)c); - } - - sr.ReadLine(); lineNum++; - if (chars.Length > 0) - { - text = chars.ToString(); - chars.Clear(); - return true; - } - else - { - text = null; - return false; - } - } - } - - static int langIndex; - public static int LanguageIndex => langIndex; - - public static void Load(int index) - { - try - { - langIndex = index; - - string path = string.Format("UCP.Localization.{0}.txt", translations[index].Ident); - - Assembly asm = Assembly.GetExecutingAssembly(); - using (var s = asm.GetManifestResourceStream(path)) - using (Reader r = new Reader(s)) - { - localStrs.Clear(); - while (r.ReadLine(out string line)) - { - string ident = line; - - if (!r.ReadLine(out line) || !line.StartsWith("{")) - throw new Exception(ident + " Missing opening bracket at line " + r.LineNumber); - - if (!r.ReadString(out string text)) - throw new Exception(ident + " Missing string at " + r.LineNumber); - - if (!r.ReadLine(out line) || !line.StartsWith("}")) - throw new Exception(ident + " Missing closing bracket at line " + r.LineNumber); - - localStrs.Add(ident, text); - } - } - } - - catch (Exception e) - { - Debug.Error(e); - } - } - } -} diff --git a/UnofficialCrusaderPatch/Localization/Polish.txt b/UnofficialCrusaderPatch/Localization/Polish.txt deleted file mode 100644 index a1df384e..00000000 --- a/UnofficialCrusaderPatch/Localization/Polish.txt +++ /dev/null @@ -1,1102 +0,0 @@ -// ====================== -// 2.15 -// ====================== - -u_spearmen_run -{ -"Biegający włócznicy" -} - -u_spearmen_run_descr -{ -"Włócznicy będą cały czas biegać." -} - -o_seed_modification_possibility_title -{ -"Generowane ziarno gry" -} - -o_seed_modification_possibility_only_set -{ -"Włącza generowane ziarno gry" -} - -o_seed_modification_possibility_only_set_descr -{ -"Ta opcja pozwala na wygenerowanie ziarna gry (działa tylko na rozgrywki samych botów), aby rozgrywka była za każdym razem taka sama, jeśli wybrało się takie same ustawienia mapy. Aby to zrobić, włącz tę opcję i stwórz plik o nazwie 'live' z 6 cyframi w folderze z zainstalowaną grą/podfolderze z ziarnami (gameseed). UWAGA: Ta opcja działa po zrestartowaniu gry!" -} - -o_seed_modification_possibility -{ -"Włącz i zapisuj generowane ziarna gry" -} - -o_seed_modification_possibility_descr -{ -"This option will save the seed from games that do not have a live seed set, so you can rename them to 'live' in order to recreate the match afterwards." -} - -ai_recruitstate_initialtimer -{ -"Ustaw botom czas do rekrutacji jednostek zgodnie z parametrami AIC" -} - -ai_recruitstate_initialtimervalue_descr -{ -"Można tu ustawić liczbę miesięcy, do której boty będą rekrutować wyłącznie jednostki do obrony, chyba że wypełnili już limit żołnierzy na zamku" -} - -ai_defense -{ -"Usprawnione wysyłanie posiłków do obrony" -} - -ai_defense_descr -{ -"Naprawniono błąd, który uniemożliwiał SI dosyłanie brakujących jednostek & -na mury i wieże w momencie, gdy patrole defensywne były ciągle obecne." -} - -ai_housing -{ -"Mądrzejsze budowanie domów przez boty" -} - -build_housing_descr -{ -"Różnica między obecną a maksymalną populacją, po której bot przestaje stawiać domy. W oryginale jest to 0. Ta opcja wyłącza również usuwanie domów przez bota." -} - -campfire_housing_descr -{ -"Ilość wolnych chłopów przy ognisku, zanim bot przestanie stawiać domy. Ta opcja wyłącza również usuwanie domów przez bota." -} - -delete_housing -{ -"Wyłącz usuwanie domów." -} - -delete_housing_descr -{ -"Kiedy ta opcja jest zaznaczona, boty nie będą usuwać domów." -} - -aiv_prompt -{ -"Wykryto własne pliki AIV. Czy chcesz stworzyć kopię zapasową, mój Panie?" -} - -aiv_cli_prompt -{ -"Wykryto własne pliki AIV. Wpisz 'delete', aby usunąć lub podaj nazwę folderu w celu przekopiowania plików." -} - -install_abort_io -{ -"Instalacja przerwana. Pliki z taką samą nazwą znajdują się już w tym folderze. Wybierz inny folder i spróbuj ponownie." -} - -install_abort -{ -"Instalacja przerwana" -} - -backup_aiv_select -{ -"Wybierz zapasowy folder dla plików AIV" -} - -o_change_siege_engine_spawn_position_catapult -{ -"Wyśrodkuj pozycję pojawiania się machin oblężniczych" -} - -o_change_siege_engine_spawn_position_catapult_descr -{ -"Machiny oblężnicze będą pojawiać się na środku miejsca, w którym stał namiot oblężniczy." -} - -o_stop_player_keep_rotation -{ -"Odwróć siedziby graczy" -} - -o_stop_player_keep_rotation_descr -{ -"Siedziby graczy będą odwracać się ogniskiem (wejściem) w stronę krańca mapy." -} - -o_restore_arabian_engineer_speech -{ -"Przywróć arabskie teksty inżynierów" -} - -o_restore_arabian_engineer_speech_descr -{ -"Ta opcja pozwala inżynierom na korzystanie z nagranych arabskich tekstów, gdy gracz gra jako arabski lord. - -Tekstów nie ma zbyt wielu, więc mogą być irytujące po dłuższej chwili." -} - -u_fix_lord_animation_stuck_movement -{ -"Zresetuj animację lorda po zniszczeniu budynku" -} - -u_fix_lord_animation_stuck_movement_descr -{ -"Opcja pozwala zresetować animację lorda, gdy każemu mu zniszczyć budynek. Zazwyczaj po wykonaniu zadania stał w dziwnej pozie." -} - -fix_apple_orchard_build_size -{ -"Zmniejsz rozmiar budowy sadów jabłoni" -} - -fix_apple_orchard_build_size_descr -{ -"Opcja zmniejsza rozmiar budowy sadów jabłoni, aby był taki sam, jak rzeczywisty rozmiar całego budynku. Zaoszczędzi to miejsce na trawie i pomoże botom na lepszy rozwój." -} - -u_fix_applefarm_blocking -{ -"Napraw blokowanie sadów jabłoni" -} - -u_fix_applefarm_blocking_descr -{ -"Farmerzy nie będą już blokowani, gdy postawi się budynek w lewej, górnej stronie farmy." -} - -o_increase_path_update_tick_rate -{ -"Zwiększ częstotliwość odświeżania możliwych ścieżek" -} - -o_increase_path_update_tick_rate_descr -{ -"W oryginale jednostki potrzebowały dużo czasu, zanim mogły zrozumieć, że można wejść do zamku po zniszczeniu bramy lub wieży.. - -Ta opcja zwiększa czterokrotnie częstotliwość odświeżania możliwych ścieżek wykrywanych przez jednostki, dzięki czemu szybciej zrozumieją, że można już wejść do zamku." -} - -o_fix_ladderclimb -{ -"Napraw błąd związany z wchodzeniem po drabinie" -} - -o_fix_ladderclimb_descr -{ -"Jednostki nie będą już gubić się po wejściu na mury po drabinie i nie będą schodzić od razu na dół." -} - -u_tanner_fix -{ -"Zwiększ wydajność garbarzy" -} - -u_tanner_fix_descr -{ -"Garbarze nie będą już wracać do budynku, gdy ktoś inny zabrał krowę, po którą szli. Zamiast tego postoją chwilę w miejscu i wyruszą po kolejną krowę." -} - -o_fix_fletcher_bug -{ -"Napraw błąd łuczarza" -} - -o_fix_fletcher_bug_descr -{ -"Naprawia błąd, który powoduje, że łuczarz idzie do swojego budynku po odniesieniu broni do zbrojowni. Zamiast tego będzie teraz szedł od razu do składu zapasów po deski." -} - -ai_fix_crusader_archers_pitch -{ -"Napraw błąd z brakiem podpalania smoły przez łuczników europejskich" -} - -ai_fix_crusader_archers_pitch_descr -{ -"Łucznicy europejscy zarządzani przez SI nie podpalali smoły. Ta opcja naprawia ten błąd." -} - -o_fix_baker_disappear -{ -"Napraw błąd ze znikającym piekarzem" -} - -o_fix_baker_disappear_descr -{ -"Piekarze nie będą znikać, gdy dojdą do składu zapasów, w którym nie ma już mąki." -} - -o_fix_moat_digging_unit_disappearing -{ -"Napraw błąd ze znikającymi jednostkami kopiącymi fosę" -} - -o_fix_moat_digging_unit_disappearing_descr -{ -"Naprawia błąd, który powodował losowe znikanie jednostek kopiących fosę. Uwaga: jednostki mogą dalej znikać, jeśli każesz im przemieścić się w momencie, gdy stoją w miejscu, z którego nie da się normalnie ruszyć!" -} - -ui_welcometext -{ -"Jest to nieoficjalna łatka do Twierdzy Krzyżowiec. -Projekt jest dostępny jako otwarte oprogramowanie przez [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). - -Każda wersja Krzyżowca jest potencjalnie obsługiwana, ale wprowadzone zmiany pochodzą z wersji 1.41 Steam, dlatego mogą pojawić się problemy. -Instalator wyświetli wtedy komunikat o błędzie. Wersja tej łatki jest pokazana w lewym dolnym rogu głównego menu gry. -Przed zmianami zostaną utworzone pliki. kopii zapasowej. Można je przywrócić za pomocą przycisku 'Odinstaluj' lub ręcznie. - -Zespół odpowiedzialny za UCP - -Oryginalny twórca UCP -[Sh0wdown](https://github.com/Sh0wdown) - -Zarządzanie projektem -[Kimberly Azula](https://github.com/ByBurton/) -[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) - -Twórcy -[LordHansCapon](https://github.com/LordHansCapon) -[np123](https://github.com/patel-nikhil) -[J-T-de](https://github.com/J-T-de) -[gynt](https://github.com/gynt) -[Le spec](https://github.com/LeSpec) -[Chaf1812](https://github.com/Chaf1812) - -Tłumacze -[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polski) -[Lolasik011](https://github.com/Lolasik011) (Rosyjski) -[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chiński) -[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (język węgierski) - -Twórcy dodatkowych funkcji -[Evrey](https://github.com/Evrey) (aiv) -[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) -[PitchNeeded](https://github.com/PitchNeeded) (aiv) -[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) - -Specjalne podziękowania dla -[Firefly Studios](https://fireflyworlds.com/) -za stworzenie serii Twierdza. - -Oraz dla -[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) -[PodeCaradox](https://github.com/PodeCaradox) -[GRhin](https://www.twitch.tv/grhin) -[Heroesflorian](https://github.com/Heroesflorian)" -} - -// ====================== -// 2.14 -// ====================== - -ui_StartTroops -{ - "JednostkiPoczątkowe" -} - -ui_Resource -{ - "ZasobyPoczątkowe" -} - -ui_aicconflict -{ - "Konflikty zostaną zignorowane" -} - -o_shfy -{ - "Strongholdify" -} - -o_shfy_beer -{ - "Bonus do popularności za piwo" -} - -o_shfy_beer_descr -{ - " " -} - -o_shfy_religion -{ - "Bonus do popularności za katedrę i kościół" -} - -o_shfy_religion_descr -{ - " " -} - -o_shfy_peasantspawnrate -{ - "Szybkość pojawiania się wieśniaków" -} - -o_shfy_peasantspawnrate_descr -{ - " " -} - -o_shfy_resourcequantity -{ - "Ilośc otrzymywanych surowców" -} - -o_shfy_resourcequantity_descr -{ - "Podane aspekty są zbliżone do tych z pierwszej Twierdzy. Uwaga: Każda zmiana wpływa na przeciwników komputerowych. W najgorszym wypadku mogą stać się bezużyteczni!" -} - -o_armory_marketplace_weapon_order_fix -{ - "Ustaw broń na targowisku i w zbrojowni w tej samej kolejności" -} - -o_armory_marketplace_weapon_order_fix_descr -{ - "Ustawia broń na targowisku i w zbrojowni w tej samej kolejności. Zbroja skórzana na targowisku zostaje przesunięta między wekiery i kusze, natomiast zbroja metalowa między piki i miecze." -} - -ai_fix_laddermen_with_enclosed_keep -{ - "Napraw błąd, który powoduje, że komputer nie korzysta z drabiniarzy, gdy ma otoczoną siedzibę" -} - -ai_fix_laddermen_with_enclosed_keep_descr -{ - "Komputer (głównie Wąż) będzie od teraz korzystał z drabiniarzy, gdy jego siedziba zostanie otoczona." -} - -o_override_identity_menu -{ - "Dodaje nowe funkcje do opcji ustawień tożsamości" -} - -o_override_identity_menu_descr -{ - "Dodaje jednostki do własnego ustawienia w opcji dostosowania tożsamości. TYLKO W NORMALNYM TRYBIE GRY!" -} - -o_default_multiplayer_speed -{ - "Ustaw domyślną prędkość gry multiplayer." -} - -o_default_multiplayer_speed_descr -{ - " " -} - -u_fireballistafix -{ - "Balista ogniowa strzela do mnichów i kopaczy" -} - -u_fireballistafix_descr -{ - "Balista ogniowa automatycznie strzela w mnichów i kopaczy." -} - -ui_browsepath -{ - "Wybierz katalog instalacyjny Stronghold Crusader." -} - -ui_aicoldversion -{ - "Wykryto starą wersję. Kliknij, aby przekonwertować" -} - -ui_aicofferconvert -{ - "Konwertuj plik AIC do nowszej wersji?" -} - -ui_aicconvertprompt -{ - "Konwersja AIC" -} - -ui_aicselect -{ - "Najpierw usuń zaznaczenie innych plików AIC. Następujące znaki AIC są już wybrane: " -} - -// ====================== -// 2.13 -// ====================== - -o_firecooldown -{ - "Wydłuż czas, po którym budynek może ponownie się zapalić" -} - -o_firecooldown_descr -{ - "Można tutaj wydłużyć czas, po którym budynek może ponownie się zapalić po ugaszeniu." -} - -u_ballistamonk -{ - "Balista ogniowa strzela do mnichów" -} - -u_ballistamonk_descr -{ - "Balisty ogniowe strzelają automatycznie do mnichów." -} - - -// ====================== -// 2.12 -// ====================== - -ui_AIC -{ - "AIC" -} - -ui_aicExport -{ - "Eksport" -} - -ui_aicExport_success -{ - "Eksportowanie powiodło się." -} - -ui_aicHint -{ - "Eksportuje plik .aic z instalatora do folderu z grą." -} - -// ====================== -// 1.00 -// ====================== - - - -Name -{ - "Nieoficjalna aktualizacja do Krzyżowca" -} - -u_ArabXBow -{ - "Zwiększona obrona arabskich zbrojnych przeciwko kusznikom" -} - -u_arabxbow_descr -{ - " - Arabscy zbrojni umierają po 6 strzałach z kuszy zamiast 3" -} - -u_ArabWall -{ - "Arabscy zbrojni szybciej niszczą mury" -} - -u_ArabWall_descr -{ - "W oryginalnej grze arabscy zbrojni niszczą mury najwolniej ze wszystkich jednostek walczących wręcz. & -Dzięki tej opcji prędkość niszczenia murów przez arabskich zbrojnych jest dwukrotnie większa, & -nieco powyżej prędkości włóczników." -} - -u_spearmen -{ - "Zwiększona obrona włóczników przeciwko jednostkom strzelającym" -} - -u_spearmen_descr -{ - " - Włócznicy giną po 5 strzałach z łuku zamiast 3 - - Włócznicy ledwie przeżywają jeden strzał z kuszy, zamiast od razu ginąć" -} - -ui_error -{ - "Błąd" -} - -ui_SearchPath -{ - "Wybierz folder instalacyjny gry Twierdza Krzyżowiec:" -} - -ui_search -{ - "Wyszukaj" -} - -ui_continue -{ - "Kontynuuj" -} - -ui_wrongpath -{ - "Nie można znaleźć gry Twierdza Krzyżowiec w podanej ścieżce!" -} - -ui_back -{ - "Wróć" -} - -ui_install -{ - "Instalacja" -} - -ui_finished -{ - "Ukończono" -} - -ui_chooseLangTitle -{ - "Wybierz język" -} - -ui_chooseLang -{ - "Wybierz język instalatora z poniższej listy." -} - -ui_accept -{ - "Akceptuj" -} - -ui_cancel -{ - "Anuluj" -} - -ui_uninstall -{ - "Odinstaluj" -} - -ui_uninstalldone -{ - "Odinstalowywanie patcha zakończone prawidłowo." -} - -ai_recruitinterval -{ - "Zwiększona prędkość rekrutacji" -} - -ai_recruitinterval_descr -{ - "Ustawia odstęp między rekrutacją jednostek przez wszystkich przeciwników komputerowych na najniższą wartość & - (poziom Szczura/Ryszarda)" -} - -ai_attacklimit -{ - "Zwiększenie limitu ataku przeciwników komputerowych" -} - -ai_attacklimit_descr -{ - "Liczba dodatkowych jednostek dodawanych po pierwszym ataku jest & -ograniczona do 200 w oryginalnej grze. Tutaj możesz zmienić ten limit." -} - -o_gamespeed -{ - "Jeszcze większa prędkość gry" -} - -o_gamespeed_descr -{ - "Szybkość gry można teraz zmienić w następujący sposób: - - Od 10 do 90 w odstępach 5 - - Od 90 do 200 w odstępach 10 - - Od 200 do 1000 w odstępach 100 -Nowe wartości są dostępne w grze wyłącznie za pomocą klawiszy + i -, suwak w menu & -gry pozostaje niezmieniony." -} - -ui_bugfix -{ - "Naprawione błędy" -} - -ui_ailords -{ - "Przeciwnicy komputerowi" -} - -ui_troops -{ - "Jednostki" -} - -ui_other -{ - "Pozostałe" -} - -o_responsivegates -{ - "Szybsza reakcja bram" -} - -o_responsivegates_descr -{ - "Bramy zamykają się później, gdy wrogowie znajdą się w zasięgu i otworzą się szybciej, & -kiedy niebezpieczeństwo zniknie. Odległość wroga od bramy, która wpływa na jej automatyczne zamykanie się & -zostanie zmniejszona z 200 do 140. Czas, po którym otwierają się bramy, gdy & -wszyscy wrogowie znikną, zostaje zmniejszony z 1200 do 100." -} - -ai_addattack -{ - "Zwiększenie liczby dodatkowych jednostek w kolejnych atakach SI" -} - -ai_addattack_descr -{ - "W oryginalnej grze liczba żołnierzy wzrasta po każdym ataku średnio o 5 & -jednostek. Ta wartość jest taka sama dla wszystkich przeciwników komputerowych i można ją zmienić & -tutaj." -} - -ai_addattack_alt_descr -{ - "Ewentualnie dodatkowa liczba żołnierzy może być uzależniona od & -liczby jednostek z pierwszego ataku. Ponieważ ta wartość jest inna dla każdego przeciwnika komputerowego, & -następne ataki będą zmieniać rozmiar zależnie od tej początkowej wartości. -Przykład: współczynnik zmiany rozmiaru = 0,5 -Ataki wysyłane przez Sułtana = 10, 15, 20, 25, ... -Ataki wysyłane przez Saladyna = 50, 75, 100, 125, ..." -} - -u_laddermen -{ - "Zwiększona obrona drabiniarzy przeciwko jednostkom strzelającym" -} - -u_laddermen_descr -{ - " - Drabiniarz ginie po 12 strzałach z łuku zamiast po 5 - - Drabiniarz ginie po 5 trafieniach z kuszy lub procy zamiast 2 - - Drabiniarz kosztuje 20 złota zamiast 4" -} - -o_playercolor -{ - "Zmiana koloru pierwszego gracza" -} - -o_playercolor_descr -{ - " " -} - -ai_demolish -{ - "Dezaktywuj burzenie budynków dla pieniędzy przez przeciwników komputerowych" -} - -ai_demolish_walls -{ - "fortyfikacje obronne" -} - -ai_demolish_eco -{ - "budynki ekonomiczne" -} - -ai_demolish_walls_descr -{ - " " -} - -ai_demolish_eco_descr -{ - "Jeśli przeciwnik komputerowy czuje presję, lubi burzyć gospodarkę lub & -budynki fortyfikacyjne, aby uzyskać pieniądze w celu rekrutacji żołnierzy. Ta funkcja czasami & -wydaje się być uruchamiana bez widocznego powodu i dlatego można to tutaj wyłączyć." -} - -ai_tethers -{ - "Wyłącz niepotrzebne stawianie wołów pociągowych przez przeciwników komputerowych" -} - -ai_tethers_descr -{ - "Zazwyczaj sztuczna inteligencja buduje dla każdego nowego kamieniołomu kolejne & -woły, niezależnie od tego, ile już postawiła wcześniej. Można to wyłączyć tutaj, ponieważ & -prowadzi to do spamu wołami pociągowymi, gdy kamieniołomy sztucznej inteligencji są wielokrotnie niszczone." -} - - - - - - - - - - -// ======================= -// 2.06 -// ======================= - -ai_nosleep -{ - "Wyłącz usypianie budynków z powodu braku zasobów" -} - -ai_nosleep_descr -{ - "Sztuczna inteligencja zwykle usypia budynki produkcyjne, gdy tylko & -brakuje wymaganego zasobu. Odbywa się to bez względu na to, & -czy straci produkty, które są już w drodze, np. do zbrojowni. -Tę funkcję można tutaj całkowicie wyłączyć." -} - - - - - - - - - -// 5.12.2018 - -o_onlyai -{ - "Aktywuj tryb Obserwatora [możliwy błąd]" -} - -o_onlyai_descr -{ - "Usuwa głównego gracza, dzięki czemu możesz tylko obserwować i tworzyć & -pojedynki między ośmioma botami. Zapisy gry ładują się teraz poprawnie w tym & -trybie. Czasami pojawia się błąd, w którym losowe obiekty pojawiają się na całej mapie. & -Jest to tylko wizualny błąd i można go usunąć zapisując grę, kończąc misję i & -ponownie wczytując zapis." -} - -o_moatvisibility -{ - "Zawsze pokazuj zaplanowaną fosę" -} - -o_moatvisibility_descr -{ - "Zaplanowana, ale jeszcze nie wykopana fosa będzie zawsze pokazywana z tym & -ustawieniem, nawet jeśli odznaczysz opcję rozmieszczania fosy." -} - -o_engineertent -{ - "Brak anulowania wybranego namiotu oblężniczego" -} - -o_engineertent_descr -{ - "Przy tym ustawieniu gra nie odznacza wybranej machiny oblężniczej & -po umieszczeniu już jednego namiotu. W ten sposób możesz stworzyć kilka namiotów & -bez konieczności ponownego wybierania tego samego sprzętu oblężniczego za każdym razem." -} - - - - - - - - - - - -// ================================ -// 2.07 -// ================================ - - -ai_demolish_trapped -{ - "Jeśli siedziba jest otoczona" -} - -ai_demolish_trapped_descr -{ - " " -} - - -ai_attacknearest -{ - "Zawsze atakuj najbliższego wroga" -} - -ai_attacknearest_descr -{ - "Przy tym ustawieniu przeciwnicy komputerowi zawsze atakują najbliższych wrogów. & -Dzięki temu oddziały nie rozchodzą się podczas oblężenia zamku, ani nie giną z powodu przechodzenia obok & -zamku wroga, którego nie atakują w danej chwili." -} - - -o_freetrader -{ - "Darmowe targowisko" -} - -o_freetrader_descr -{ - "Czasami sztuczna inteligencja może nic nie robić, gdy nie ma drewna, a targowisko & -zostało zniszczone. Aby temu zapobiec, można włączyć tę opcję, dzięki czemu targowisko będzie darmowe." -} - -ai_towerengines -{ - "Brak ograniczeń dla machin oblężniczych na wieżach" -} - -ai_towerengines_descr -{ - "Zazwyczaj sztuczna inteligencja buduje maksymalnie trzy mangonele i balisty na swoich wieżach. & -Ten limit można tutaj znieść." -} - -ai_buywood -{ - "Kupuj wystarczającą ilość drewna" -} - -ai_buywood_descr -{ - "Aby uniemożliwić złodziejskim rzemieślnikom kradzież drewna, które gracz komputerowy właśnie kupił, aby postawić & -budynki, boty będą kupować o 2 deski więcej za każdym razem." -} - -o_keys -{ - "Klawisze WASD i szybki zapis" -} - -o_keys_descr -{ - "Klawisze WASD mogą być używane do poruszania kamerą. Dodatkowo & -kombinacja klawiszy CTRL-S i CTRL-L służy do szybkiego zapisania i wczytania gry." -} - - - - - - - - - - - - - - - - - - - - - -// =========== -// 2.07a -// =========== - - - -ai_attacktarget -{ - "Ustaw cel ataku graczy komputerowych" -} - -ai_attacktarget_nearest -{ - "Najbliższy przeciwnik" -} - -ai_attacktarget_nearest_descr -{ - " " -} - -ai_attacktarget_richest -{ - "Najbogatszy przeciwnik" -} - -ai_attacktarget_richest_descr -{ - " " -} - -ai_attacktarget_weakest -{ - "Najsłabszy przeciwnik" -} - -ai_attacktarget_weakest_descr -{ - "Dzięki tej opcji gracze komputerowi będą zawsze wybierać ten sam cel & -ataku. Dzięki temu oddziały nie rozchodzą się podczas oblężenia zamku, & -ani nie giną z powodu przechodzenia obok zamku wroga, którego nie atakują w danej chwili." -} - - - - - -// ================= -// 2.08 -// ================= - - - - -ai_assaultswitch -{ - "Brak zmiany celu podczas oblężenia" -} - -ai_assaultswitch_descr -{ - "Przeciwnicy komputerowi, którzy atakują najlepszego albo najsłabszego wroga, & -czasami wysyłają swoich żołnierzy w trakcie oblężenia do innego & -zamku. Ta opcja to uniemożliwia, & -gdy atak już się rozpocznie. Jeżeli atak jeszcze się nie rozpoczął, np. w momencie & -zbierania armii przed zamkiem, zmiana może nastąpić." -} - - - -ai_rebuild -{ - "Ulepszona naprawa budynków przez graczy komputerowych" -} - -ai_rebuild_descr -{ - "Gracze komputerowi będą naprawiać ruiny wież, trochę zniszczone mury oraz & -zniszczone cechy inżynierów i kopaczy, a także kotły z olejem, których punkt zbiórki & -dalej istnieje. Dodatkowo gracze komputerowi mogą teraz budować na składach kamienia & -z kamieniołomów." -} - - - - - - -// ==================== -// 2.09 -// ==================== - -o_healer -{ - "Zielarz leczy rannych" -} - -o_healer_descr -{ - "Zielarz będzie teraz szukał rannych żołnierzy, & -zwierzęta i mieszkańców, aby ich uleczyć. Zielarz zaczyna leczyć od najbliższego celu. Każda & -animacja leczenia leczy 1/3 życia włócznika. Chodzenie po ogrodach & -i pozbywanie się zarazy nie zostało zastąpione! Zielarz pomija jedynie chodzenie & -po zamku, dopóki nie wyleczy wszystkich rannych." -} - - - - - - - - -// ==================== -// 2.10 -// ==================== - - - -o_xtreme -{ - "Usuń pasek mocy w wersji Extreme" -} - -o_xtreme_descr -{ - "Usuwa pasek umiejętności w Twierdzy Krzyżowiec Extreme." -} - - - - - - - - - - - - - - -// ====================== -// 2.11 -// ====================== - - -ui_AIV -{ - "AIV" -} - -ai_access -{ - "Brak niszczenia niedostępnych budynków" -} - -ai_access_descr -{ - "Ta opcja zapobiega niszczeniu budynków, do których nie ma dojścia. Dzięki temu & -Sztuczna Inteligencja przestanie ciągle niszczyć i odbudowywać budynki, do których & -nie da się dojść." -} - -ai_attackwave -{ - "Popraw fale ataków" -} - -ai_attackwave_descr -{ - "W oryginalnej grze sztuczna inteligencja wysyła tylko tyle żołnierzy za jednym razem, ile jest wolnych & -kawałków murów. Powoduje to, że jednostki poruszają się w małych grupach, & -gdy atakowany zamek ma wiele budynków bezpośrednio przy murach. -Ta opcja sprawia, że żołnierze atakują również budynki cywilne i fortyfikacyjne, a także & -te części murów, które są już atakowane przez inną jednostkę. Dodatkowo -SI wysyła więcej jednostek do wrogiego lorda, gdy przełamie mury." -} diff --git a/UnofficialCrusaderPatch/Localization/Russian.txt b/UnofficialCrusaderPatch/Localization/Russian.txt deleted file mode 100644 index c34191a1..00000000 --- a/UnofficialCrusaderPatch/Localization/Russian.txt +++ /dev/null @@ -1,1072 +0,0 @@ -// ====================== -// 2.15 -// ====================== - -u_spearmen_run -{ -"Копейщики бегут по умолчанию вместо того, чтобы ходить пешком." -} - -u_spearmen_run_descr -{ -"Вместо медленной ходьбы копейщики бегут медленно." -} - -o_seed_modification_possibility_title -{ -"Игровой случайный сид" -} - -o_seed_modification_possibility_only_set -{ -"Включить фиксированную игру случайным сидом" -} - -o_seed_modification_possibility_only_set_descr -{ -"Установка игрового сида позволит играм только с AI играть точно так же, если используются те же настройки карты. Для игр с AI, он обеспечит такие же условия запуска на карте (например, выбор AIV). Для установки игрового сида, включите эту опцию и создайте файл под названием (live) с 6-значным номером в каталоге установки игры/игр. -ВНИМАНИЕ: Эта функция работает только после перезапуска игры!" -} - -o_seed_modification_possibility -{ -"Включить и сохранить игру случайных сидов" -} - -o_seed_modification_possibility_descr -{ -"Эта опция сохранит сид от игр, которые не имеют "live" сида, так что вы можете переименовать их в "live", чтобы потом воссоздать матч." -} - -ai_recruitstate_initialtimer -{ -"Настройка первоначального времени вербовки AI в защиту" -} - -ai_recruitstate_initialtimervalue_descr -{ -"Установите это значение на количество месяцев, в течение которых AI будет вербовать исключительно войска обороны, если только он уже не заполнил всю оборону." -} - -ai_defense -{ -"Исправляет подкрепление войск обороны AI" -} - -ai_defense_descr -{ -"Исправлен баг, из-за которого AI не усиливал недостающие войска на стенах и башнях, пока оборонительные патрули все еще были вокруг." -} - -ai_housing -{ -"Настройка решения AI о строительстве и удалении домов" -} - -build_housing_descr -{ -"Количество дополнительного доступного жилья до того, как AI прекратит строительство домов" -} - -campfire_housing_descr -{ -"Количество крестьян у костра перед тем, как AI остановит строительство домов." -} - -delete_housing -{ -"Отключает способность AI удалять дома." -} - -delete_housing_descr -{ -"Когда эта опция выбрана, AI никогда не будет удалять дома" -} - -aiv_prompt -{ -"Обнаружены пользовательские AIV. Вы хотите создать резервную копию Милорд?" -} - -aiv_cli_prompt -{ -"Обнаружены пользовательские AIV. Введите 'delete' для удаления или введите имя папки для копирования файлов." -} - -install_abort_io -{ -"Установка отменена. В этой папке уже существуют файлы с таким же именем. Попробуйте еще раз и выберите другую папку." -} - -install_abort -{ -"Установка отменена" -} - -backup_aiv_select -{ -"Выберите резервную папку AIV" -} - -o_change_siege_engine_spawn_position_catapult -{ -"Положение спавна осадных механизмов посредине" -} - -o_change_siege_engine_spawn_position_catapult_descr -{ -"Осадные механизмы теперь появляется по центру , вместо появления в верхнем углу палатки." -} - -o_stop_player_keep_rotation -{ -"Поворот крепости игрока" -} - -o_stop_player_keep_rotation_descr -{ -"Крепость игрока вращяется таким же образом как и крепости AI. Точней стоит лицом к костру AI , а другой стороной к краю карты" -} - -o_restore_arabian_engineer_speech -{ -"Восстановление арабской речи инженера" -} - -o_restore_arabian_engineer_speech_descr -{ -"Позволяет инженерам говорить на изначально записанных арабских голосовых дорожках, когда игрок использует арабского лорда. - -Голосовые линии не сильно отличаются друг от друга, так что через некоторое время они могут стать раздражающими." -} - -u_fix_lord_animation_stuck_movement -{ -"Исправляет анимацию замирания Лорда" -} - -u_fix_lord_animation_stuck_movement_descr -{ -"Исправляет анимацию замирания Лорда когда тот стоит, либо когда разрушает здание." -} - -fix_apple_orchard_build_size -{ -"Размер площади яблоневой фермы" -} - -fix_apple_orchard_build_size_descr -{ -"Изменяет размер постройки яблоневого сада на размер который он занимает после расположение фермы. Это экономит место при строительстве ферм и увеличивает скорость, с которой AI может располагать эти фермы." -} - -u_fix_applefarm_blocking -{ -"Исправить блокировку яблочных ферм" -} - -u_fix_applefarm_blocking_descr -{ -"Яблочные фермеры больше нельзя блокировать, размещая здания в верхней левой части фермы." -} - -o_increase_path_update_tick_rate -{ -"Более частая проверка доступного пути" -} - -o_increase_path_update_tick_rate_descr -{ -"В ваниле, это заняло 200 игровых тиков, чтобы проверить новые пути, часто останавливая юнитов, чтобы перейти в замок после уничтожения ворот или башни немедленно. - Доступность рассчитывается теперь каждые 50 игровых тиков, что позволяет юнитам реализовывать новые пути быстрее." -} - -o_fix_ladderclimb -{ -"Исправить ошибку подъёма по лестнице" -} - -o_fix_ladderclimb_descr -{ -"Отряды больше не забывают о своем предназначении после восхождения на стену, и они больше не начнут подниматься или спускаться вниз сразу же после того, как они только что поднялись." -} - -u_tanner_fix -{ -"Исправляет кожевников которые получают одну и ту же корову" -} - -u_tanner_fix_descr -{ -"Кожевники больше не вернутся без коровы, когда другой кожевник забрал их целевую корову. Вместо этого они немного подождут, а потом возьмут еще одну корову." -} - -o_fix_fletcher_bug -{ -"Исправляет баг стрельника" -} - -o_fix_fletcher_bug_descr -{ -"Исправление поведения, при котором стрельник возвращается на рабочее место после сдачи на хранение лука/арбалета вместо того, чтобы идти прямо на склад." -} - -ai_fix_crusader_archers_pitch -{ -"Исправляет европейских лучников которые не стреляют в нефтяной ров" -} - -ai_fix_crusader_archers_pitch_descr -{ -"Исправляет, что (AI) европейские лучники не зажигают рвы, как арабские лучники, когда на них попадают вражеские юниты." -} - -o_fix_baker_disappear -{ -"Исправить ошибку исчезновения пекаря" -} - -o_fix_baker_disappear_descr -{ -"Исправляет ошибку, при которой пекарни исчезали бы, если бы пекари не нашли муку на складе запасов." -} - -o_fix_moat_digging_unit_disappearing -{ -"Исправляет исчезания юнитов при копании рва" -} - -o_fix_moat_digging_unit_disappearing_descr -{ -"Исправлена ошибка, при которой копатели рва исчезали случайно во время раскопок. Обратите внимание, что они все равно могут исчезнуть, если вы прикажете им двигаться во время раскопок, и они случайно встанут на непешеходную плитку!" -} - -ui_welcometext -{ -"Это неофициальный патч для Stronghold Crusader. -Проект доступен в виде открытого исходного кода по адресу [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). - -Любая версия Crusader потенциально поддерживается, но так как изменения были получены из версии 1.41 Steam-Version, могут появиться несовместимости. -После этого в настройках появятся сообщения об ошибках. Установленная версия патча отображается в левом нижнем углу главного меню игры. -Перед любыми изменениями будут созданы резервные файлы. Их можно восстановить с помощью кнопки 'Удалить' или вручную. - -Команда, стоящая за UCP - -Создатель UCP -[Sh0wdown](https://github.com/Sh0wdown) - -Управление проектами -[Kimberly Azula](https://github.com/ByBurton/) -[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) - -Разработчики -[LordHansCapon](https://github.com/LordHansCapon) -[np123](https://github.com/patel-nikhil) -[J-T-de](https://github.com/J-T-de) -[gynt](https://github.com/gynt) -[Le spec](https://github.com/LeSpec) -[Chaf1812](https://github.com/Chaf1812) - -Переводчики -[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polish) -[Lolasik011](https://steamcommunity.com/profiles/76561198399248341) (Russian) -[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chinese) -[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Hungarian) - -Создатели контента -[Evrey](https://github.com/Evrey) (aiv) -[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) -[PitchNeeded](https://github.com/PitchNeeded) (aiv) -[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) - -Особая благодарность, конечно же, выражается -[Firefly Studios](https://fireflyworlds.com/) -за создания серии игр Stronghold - -И многие другие -[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) -[PodeCaradox](https://github.com/PodeCaradox) -[GRhin](https://www.twitch.tv/grhin) -[Heroesflorian](https://github.com/Heroesflorian)" -} - -// ====================== -// 2.14 -// ====================== - -ui_StartTroops -{ - "Стартовые войска" -} - -ui_Resource -{ - "Стартовые товары" -} - -ui_aicconflict -{ - "конфликт AI будет игнорироваться" -} - -o_shfy -{ - "Strongholdify" -} - -o_shfy_beer -{ - "Бонус за популярность от пива" -} - -o_shfy_beer_descr -{ - " " -} - -o_shfy_religion -{ - "Бонус за популярность от собора налогов и церкви" -} - -o_shfy_religion_descr -{ - " " -} - -o_shfy_peasantspawnrate -{ - "Скорость появления крестьян (спавн)" -} - -o_shfy_peasantspawnrate_descr -{ - " " -} - -o_shfy_resourcequantity -{ - "Количество предоставленных ресурсов" -} - -o_shfy_resourcequantity_descr -{ - "Адаптирует перечисленные аспекты в соответствии с Stronghold 1. Внимание: Каждое изменение влияет на повелителей AI, в худшем случае делает их бесполезными!" -} - -o_armory_marketplace_weapon_order_fix -{ - "Исправить оружейный склад/рыночное оружие, чтобы соответствовать порядку" -} - -o_armory_marketplace_weapon_order_fix_descr -{ - "Изменение порядка иконок оружия в Оружейной и на Рынке, чтобы они располагались в одинаковом порядке. Также перемещает кожаную броню между булавой и арбалетом, а металлическую броню - между пиками и мечом для более легкого доступа во время прокрутки предметов на Рынке." -} - -ai_fix_laddermen_with_enclosed_keep -{ - "Исправить AI, не использующий лестниц, если они есть в наличии." -} - -ai_fix_laddermen_with_enclosed_keep_descr -{ - "AI (в частности, Змея) больше не прекращает использование Лестниц с Осадными орудиями, если они находится в замкнутом пространстве." -} - -o_override_identity_menu -{ - "Переопределить меню "Set-up Identity", добавляя новые функции." -} - -o_override_identity_menu_descr -{ - "Добавляет выбор юнитов дальнего и ближнего боя в меню Set-up Identity". ТОЛЬКО ДЛЯ ОБЫЧНОГО ИГРОВОГО РЕЖИМА!" -} - -o_default_multiplayer_speed -{ - "Установить скорость мультиплеера по умолчанию." -} - -o_default_multiplayer_speed_descr -{ - " " -} - -u_fireballistafix -{ - "Огненные баллисты стреляют в монахов и тунелекопателей" -} - -u_fireballistafix_descr -{ - "Огненные баллисты автоматически стреляют в монахов и тунелекопателей." -} - -ui_browsepath -{ - "Пожалуйста, выберите каталог установки Stronghold Crusader." -} - -ui_aicoldversion -{ - "Обнаружена старая версия. Нажмите чтобы конвертировать" -} - -ui_aicofferconvert -{ - "Конвертировать файл в новую версию?" -} - -ui_aicconvertprompt -{ - "Преобразование AIC" -} - -ui_aicselect -{ - "Сначала отмените выбор других файлов AIC. Следующие символы aic уже выбраны: " -} - -// ====================== -// 2.13 -// ====================== - -o_firecooldown -{ - "Увеличить пожаробезопасную продолжительность потушенных зданий" -} - -o_firecooldown_descr -{ - "Здесь можно продлить срок, в течение которого потухшие здания больше не смогут загореться." -} - -u_ballistamonk -{ - "Огненные баллисты стреляют в монахов." -} - -u_ballistamonk_descr -{ - "Огненные баллисты стреляют автоматически в монахов с этой настройкой." -} - - -// ====================== -// 2.12 -// ====================== - - -ui_AIC -{ - "AIC" -} - -ui_aicExport -{ - "Экспорт" -} - -ui_aicExport_success -{ - "Экспортирование успешно." -} - -ui_aicHint -{ - "Экспортирует .aic-файл из установщика в папку Stronghold Crusader." -} - -// ====================== -// 1.00 -// ====================== - - -Name -{ - "Неофициальный Stronghold Crusader Патч" -} - -u_ArabXBow -{ - "Увеличенная броня арабского мечника против стрел арбалетчика" -} - -u_arabxbow_descr -{ - " - Арабские мечники умирают после 6 стрел из арбалета вместо 3" -} - -u_ArabWall -{ - "Арабские мечники разрушают стены быстрее" -} - -u_ArabWall_descr -{ - "В Ваниле арабские мечники разрушают стены медленнее любого другого подразделения ближнего боя. -С этой опцией скорость удара (анимации) против стен удваивается для них,поставив их немного выше копейщиков. (по скорости анимации атаки)" -} - -u_spearmen -{ - "Увеличенная броня копейщиков против урона дальних юнитов" -} - -u_spearmen_descr -{ - " - Копейщики умирают после 5 попаданий стрел из лука, вместо 3 -  - Копейщики едва выдерживали один выстрел из арбалета, вместо того чтобы умереть от одного выстрела" -} - -ui_error -{ - "Ошибка" -} - -ui_SearchPath -{ - "Выберите папку установки:" -} - -ui_search -{ - "Просматривать" -} - -ui_continue -{ - "Продолжить" -} - -ui_wrongpath -{ - "Stronghold Crusader не может быть найден по указанному пути!" -} - -ui_back -{ - "Назад" -} - -ui_install -{ - "Установить" -} - -ui_finished -{ - "Завершение" -} - -ui_chooseLangTitle -{ - "Язык установки" -} - -ui_chooseLang -{ - "Пожалуйста, выберите язык для этой настройки из списка ниже." -} - -ui_accept -{ - "ОК" -} - -ui_cancel -{ - "Отмена" -} - -ui_uninstall -{ - "Удаление" -} - -ui_uninstalldone -{ - "Удаление завершено." -} - -ai_recruitinterval -{ - "Увеличенная скорость набора рекрутов" -} - -ai_recruitinterval_descr -{ - "Устанавливает интервал набора всех AI до самого низкого значения (Крыса/Ричард)" -} - -ai_attacklimit -{ - "Увеличение предела атакующих войск AI" -} - -ai_attacklimit_descr -{ - "Количество дополнительных единиц, которые добавляются после первой атаки & -в Ваниле - до 200. Здесь вы можете изменить этот предел." -} - -o_gamespeed -{ - "Расширенные ограничения скорости игры" -} - -o_gamespeed_descr -{ - "Теперь скорость игры можно изменить следующим образом: - - От 10 до 90 с интервалом 5 -  - от 90 до 200 с интервалом 10 -  - от 200 до 1000 с интервалом в 100 - - от 1100 - 9000 (Но после 1100 уже не происходит увеличение) -Новые значения доступны только с помощью клавиш + -, ползунка в & -меню игры остается неизменным." -} - -ui_bugfix -{ - "Исправления ошибок" -} - -ui_ailords -{ - "AI Лорды" -} - -ui_troops -{ - "Юниты" -} - -ui_other -{ - "Другое" -} - -o_responsivegates -{ - "Быстрая реакция юнитов на врагов" -} - -o_responsivegates_descr -{ - "Ворота закрывается позже & -когда опасность исчезнет. Расстояние врага, для которого закрываются ворота & -будет уменьшено с 200 до 140. Время, после которого ворота открываются, & -будет уменьшены с 1200 до 100." -} - -ai_addattack -{ - "Увеличение скорости дополнительных атакующих войск" -} - -ai_addattack_descr -{ - "В Ваниле количество единиц атаки увеличивается на 5 & -единиц в среднем. Это значение для всех здесь." - -} - -ai_addattack_alt_descr -{ - "В качестве альтернативы, дополнительное количество войск может быть выполнено в зависимости от & -число войск первой атаки. Поскольку это значение отличается для каждого AI & -следующие атаки будут масштабироваться, а не на одну и ту же величину & -для каждого лорда AI. -Пример: Масштабный коэффициент = 0,5 -Войска Султана атакуют = 10, 15, 20, 25, ... -Атакующие войска Саладина = 50, 75, 100, 125, ... " -} - -u_laddermen -{ - "Увеличенная броня Крестьян с лесницами против дальних войск" -} - -u_laddermen_descr -{ - " - Крестияне с лестницами умирают после 12 стрел вместо 5 -  - Крестияне с лестницами умирают после 5 выстрелов арбалетов или пращников вместо 2 -  - Крестияне с лестницами стоят 20 золотых вместо 4" -} - -o_playercolor -{ - "Изменить цвет Игрока 1" -} - -o_playercolor_descr -{ - " " -} - -ai_demolish -{ - "Деактивировать снос за деньги AI Лордов" -} - -ai_demolish_walls -{ - "фортификационные сооружения" -} - -ai_demolish_eco -{ - "экономические сооружения" -} - -ai_demolish_walls_descr -{ - " " -} - -ai_demolish_eco_descr -{ - "Если AI чуствует прессинг, он начинает разрушать свою экономику или & -фортификационные здания, чтобы получить быстрые деньги для сбора войск." -} - -ai_tethers -{ - "Отключит спам привязей" -} - -ai_tethers_descr -{ - "Как правило, AI строит для каждой новой каменоломни новую привязь & -независимо от того сколько привязей уже существует. Здесь это можно отключить, так как & -это приводит к спаму если карьеры AI будут уничтожены повторно." -} - - - - - - - - - - -// ======================= -// 2.06 -// ======================= - -ai_nosleep -{ - "Отключить спящий режим из-за нехватки ресурсов" -} - -ai_nosleep_descr -{ - "AI обычно ставит свои обрабатывающие здания в сон поскольку необходимый ресурс отсутствует. -Это делается без учета потери продуктов, и оружия которые находятся на пути в Оружейную. -Эта функция может быть полностью отключена здесь." -} - - - - - - - - - - -// 5.12.2018 - -o_onlyai -{ - "Активировать Режим - Зрителя (Только AI) [Возможны баги]" -} - -o_onlyai_descr -{ - "Убирает игрока 1, чтобы вы могли видеть только 8 AI в одном и том же режиме. & -Сохранения игры теперь правильно загружаются в этом режиме. Иногда ошибка & -появляется, когда случайные объекты появляются на всей карте. Это просто визуальный баг & -и его можно убрать сохранив игру, завершая миссию и перезагружая & -сохранить файл." -} - -o_moatvisibility -{ - "Всегда показывать планированый ров" -} - -o_moatvisibility_descr -{ - "Ваш собственный,но не выкопанный ров всегда будет показан с этой опцией, даже если вы отмените выбор размещения рва." -} - -o_engineertent -{ - "Нету выбора осадной палатки" -} - -o_engineertent_descr -{ - "С помощью этой настройки игра не отменяет выбранное вами осадное оборудование после размещения больше одной палатки -Таким образом вы можете создать несколько палаток одну за другим,без необходимости повторного выбора одного и того же осадного оборудования." -} - - - - - - - - - - - -// ================================ -// 2.07 -// ================================ - - -ai_demolish_trapped -{ - "Если приложено" -} - -ai_demolish_trapped_descr -{ - " " -} - -o_freetrader -{ - "Бесплатный рынок" -} - -o_freetrader_descr -{ - "Поскольку АI иногда играет сам, когда он находится далеко от леса и его рынок уничтожен. & - С этим параметром рынок станет бесплатным, чтобы предотвратить это." -} - -ai_towerengines -{ - "Нет лимита на осадные машины на башнях" -} - -ai_towerengines_descr -{ - "Обычно АI строит на своих башнях до трех мангонелей и баллист. & -Этот лимит можно снять здесь." -} - -ai_buywood -{ - "Купить достаточно древесины" -} - -ai_buywood_descr -{ - "Чтобы воры стрельники не могли украсть древесину которую АI только что купил для здания. - 2 единицы дополнительной деревесины AI теперь будет покупать для каждого здания." -} - -o_keys -{ - "WASD-Кнопки и быстрые сохранения" -} - -o_keys_descr -{ - "Клавиши WASD можно использовать для перемещения с этой настройкой, а также & -CTRL-S и CTRL-L для быстрого сохранения и загрузки соответственно." -} - - - - - - - - - - - - - - - - - - - - - -// =========== -// 2.07a -// =========== - - - -ai_attacktarget -{ - "Установить цель атаки AI" -} - -ai_attacktarget_nearest -{ - "Ближайший враг" -} - -ai_attacktarget_nearest_descr -{ - " " -} - -ai_attacktarget_richest -{ - "Богатый враг" -} - -ai_attacktarget_richest_descr -{ - " " -} - -ai_attacktarget_weakest -{ - "Слабый враг" -} - -ai_attacktarget_weakest_descr -{ - "С этим параметром все лорды AI выберут свою следующую цель атаки. & -Это предотвращает переключение войск во время штурма замка, а также отправку & -их мимо замков других врагов." -} - - - -// ===================== -// 2.08 -// ===================== - - -ai_assaultswitch -{ - "Нет изменения цели AI во время осады" -} - -ai_assaultswitch_descr -{ - "Лорды AI, которые иногда нападают на самого могущественного или самого слабого врага & -они переключают свою цель в середине продолжающегося нападения и отправляют свои войска & -в другой замок. Это предотвращается с помощью этой настройки, как только начался штурм, & -т. е. на этапе сбора войск перед замком, изменения все еще могут произойти." -} - - - -ai_rebuild -{ - "Улучшенный ремонт AI" -} - -ai_rebuild_descr -{ - "AI будет ремонтировать руины башни, слегка поврежденные стены, а также & -уничтожит инженерные и туннельные гильдии и нефтеперерабатывающие платформы, место сбора которых & -все еще существует. Кроме того, AI теперь может строить на платформе сбора & -карьеров." -} - - - - - - -// ==================== -// 2.09 -// ==================== - -o_healer -{ - "Целитель лечит раненых солдат" -} - -o_healer_descr -{ - "Целитель здания аптеки теперь активно ищет раненых солдат,жителей и жывотных чтобы исцелить их. Ближайшие цели он лечит первыми. -Проигрывается анимация ,и он исцеляет за 1/3 секунды здоровье копейщика. Когда Целитель прогуливается он может разсеять облако чумы которое он заметит. -Он будет лечить в одной области замка всех пока не вылечет до конца, а только потом он перейдет к другому участку замка. -Также он не начнет разсеивать облака чумы пока он не сходит в сады." -} - - - - - - - - - - -// ==================== -// 2.10 -// ==================== - - - -o_xtreme -{ - "Убраны значки магии в Stronghold Crusader Extreme" -} - -o_xtreme_descr -{ - "Убирает значки магии в Stronghold Crusader Extreme." -} - - - - - - - - - - -// ====================== -// 2.11 -// ====================== - - -ui_AIV -{ - "AIV" -} - -ai_access -{ - "Нет сноса недоступных зданий" -} - -ai_access_descr -{ - "Предотвращает AI от разрушения зданий без доступа. Это должно остановить AI -непрерывного разрушения и восстановления зданий где нет доступа к ним." -} - -ai_attackwave -{ - "Улучшение волны атаки" -} - -ai_attackwave_descr -{ - "AI в атаке в ванили посылает сразу столько же войск, как и тогда когда стены целые. Это заставляет единицы умирать в маленьких волнах -когда у целевого замка много зданий прямо у его стен. Этот вариант позволяет подразделениям атаковать гражданские и фортификационные здания, а также -стены которые уже атакованы одной единицей. Более того AI посылает больше войск к вражескому лорду, как только обнаруживает что стена разрушена." -} diff --git a/UnofficialCrusaderPatch/Localization/TextReferencer.cs b/UnofficialCrusaderPatch/Localization/TextReferencer.cs deleted file mode 100644 index 1e49e00b..00000000 --- a/UnofficialCrusaderPatch/Localization/TextReferencer.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Diagnostics; - -namespace UCP -{ - public static class TextReferencer - { - struct TextRef - { - string keyword; - public string Keyword { get { return this.keyword; } } - - string reference; - public string Reference { get { return this.reference; } } - - public TextRef(string keyword, string reference) - { - this.keyword = keyword; - this.reference = reference; - } - } - - public static void SetText(TextBlock tb, string text) - { - int last = 0, index = 0; - while (index < text.Length) - { - if (text[index] == '[') - { - int start1 = index + 1; - int end1 = text.IndexOf(']', start1); - if (end1 >= 0 && end1 < text.Length - 2 && text[end1 + 1] == '(') - { - int start2 = end1 + 2; - int end2 = text.IndexOf(')', start2); - if (end2 >= 0) - { - string url = text.Substring(start2, end2 - start2); - string urltext = text.Substring(start1, end1 - start1); - - if (index > last) - { - tb.Inlines.Add(text.Substring(last, index - last)); - } - - Hyperlink hyperlink = new Hyperlink(new Run(urltext)); - hyperlink.RequestNavigate += (s, e) => Process.Start(url); - hyperlink.NavigateUri = new Uri(url); - hyperlink.ToolTip = url; - tb.Inlines.Add(hyperlink); - - last = end2 + 1; - index = end2; - } - } - } - - index++; - } - - if (index > last) - { - tb.Inlines.Add(text.Substring(last, index - last)); - } - } - } -} diff --git a/UnofficialCrusaderPatch/Model/AICConfiguration.cs b/UnofficialCrusaderPatch/Model/AICConfiguration.cs new file mode 100644 index 00000000..0a7c1c62 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/AICConfiguration.cs @@ -0,0 +1,38 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace UCP.Model +{ + public class AICConfiguration + { + public string Identifier { get; set; } + public List CharacterList { get; set; } + + [JsonIgnore] + public List CustomCharacterList { get; set; } + + [JsonIgnore] + public Dictionary Description { get; set; } + + public AICConfiguration withIdentifier(string identifier) + { + this.Identifier = identifier; + return this; + } + public AICConfiguration withCharacterList(List characterList) + { + this.CharacterList = characterList; + return this; + } + public AICConfiguration withCustomCharacterList(List customCharacterList) + { + this.CustomCharacterList = customCharacterList; + return this; + } + public AICConfiguration withDescription(Dictionary description) + { + this.Description = description; + return this; + } + } +} diff --git a/UnofficialCrusaderPatch/Model/AIVConfiguration.cs b/UnofficialCrusaderPatch/Model/AIVConfiguration.cs new file mode 100644 index 00000000..c03db5d2 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/AIVConfiguration.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace UCP.Model +{ + public class AIVConfiguration + { + public Dictionary Description { get; set; } + + public AIVConfiguration withDescription(Dictionary description) + { + this.Description = description; + return this; + } + } +} diff --git a/UnofficialCrusaderPatch/Model/ChangeConfiguration.cs b/UnofficialCrusaderPatch/Model/ChangeConfiguration.cs new file mode 100644 index 00000000..c57922a5 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/ChangeConfiguration.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; + +namespace UCP.Model +{ + public class ChangeConfiguration + { + public string Identifier { get; set; } + public Dictionary SubChanges { get; set; } + + int hashCode; + + // override object.Equals + public override bool Equals(object obj) + { + // + // See the full list of guidelines at + // http://go.microsoft.com/fwlink/?LinkID=85237 + // and also the guidance for operator== at + // http://go.microsoft.com/fwlink/?LinkId=85238 + // + + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + return Identifier.Equals(((ChangeConfiguration)obj).Identifier); + } + + // override object.GetHashCode + public override int GetHashCode() + { + if (hashCode != 0) + { + return hashCode; + } + + int h = 0; + for (int i = 0; i < Identifier.Length; i++) + { + h = 31 * h + Identifier[i]; + } + hashCode = h; + return hashCode; + } + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/ChangeUIConfig.cs b/UnofficialCrusaderPatch/Model/ChangeUIConfig.cs new file mode 100644 index 00000000..0e6a9e32 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/ChangeUIConfig.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace UCP.Model +{ + public class ChangeUIConfig + { + public IEnumerable compatibility { get; set; } + public string identifier { get; set; } + public SelectionType selectionType { get; set; } + public SelectionParameter selectionParameters { get; set; } + public object defaultValue { get; set; } + public Dictionary description { get; set; } + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/Mod.cs b/UnofficialCrusaderPatch/Model/Mod.cs new file mode 100644 index 00000000..7c472fc0 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Mod.cs @@ -0,0 +1,233 @@ +using System.Collections.Generic; +using UCP.Patching; + +namespace UCP.Model +{ + public class Mod + { + #region Central Initialization + internal static HashSet Items { get; } + + public static Dictionary> ModList { get; } + + static Mod() + { + Items = new HashSet(); + ModList = new Dictionary>(); + + // Can be repaced/reordered with individual or grouped mod initializations as needed + InitModAILords(); + InitModBugfixes(); + InitModOther(); + InitModTroops(); + } + + private static void InitModAILords() + { + /*new Mod_Change_AI_AddAttack(); + new Mod_Change_AI_AttackLimit(); + new Mod_Change_AI_AttackTarget(); + new Mod_Change_AI_AttackWave(); + new Mod_Change_AI_Demolish(); + new Mod_Change_AI_NoSleep(); + new Mod_Change_AI_Overclock(); + new Mod_Change_AI_RecruitInterval();*/ + } + + private static void InitModBugfixes() + { + /*new Mod_Fix_AI_Access(); + new Mod_Fix_AI_AssaultSwitch(); + new Mod_Fix_AI_BuyWood(); + new Mod_Fix_AI_Defense(); + new Mod_Fix_AI_LaddermenUsage(); + new Mod_Fix_AI_Rebuild(); + new Mod_Fix_AI_Tethers(); + new Mod_Fix_AI_TowerEngines(); + new Mod_Fix_FireBallista();*/ + } + + private static void InitModOther() + { + /*new Mod_Change_Other_AlwaysShowPlannedMoat(); + new Mod_Change_Other_ArmoryMarketplaceWeaponOrderFix(); + new Mod_Change_Other_DefaultMultiplayerSpeed(); + new Mod_Change_Other_ExtendedGameSpeed(); + new Mod_Change_Other_FireCooldown(); + new Mod_Change_Other_FreeTradePost(); + new Mod_Change_Other_Healer(); + new Mod_Change_Other_NewKeybindings(); + new Mod_Change_Other_NoSiegeTentDeselection(); + new Mod_Change_Other_OnlyAI(); + new Mod_Change_Other_OverrideIdentityMenu(); + new Mod_Change_Other_PlayerColorChange(); + new Mod_Change_Other_RemoveExtremeBar(); + new Mod_Change_Other_ResponsiveGates(); + new Mod_Change_Other_Strongholdify();*/ + } + + private static void InitModTroops() + { + /*new Mod_Change_Units_ArabianArcher(); + new Mod_Change_Units_ArabianSwordsmen(); + new Mod_Change_Units_Laddermen(); + new Mod_Change_Units_Spearmen();*/ + } + + #endregion + + #region Mod configuration members + protected string identifier { get; set; } + + public string Identifier { get => identifier; } + + protected List changeList { get; set; } + + public IEnumerable ChangeList { get => changeList; } + + /** + * The HD Change of the modification. + */ + protected Change change; + + /** + * The Extreme Change of the modification. + */ + protected Change extremeChange; + + /** + * The HD Change of the modification. + */ + public Change Change { get { return change; } } + + /** + * The Extreme Change of the modification. + */ + public Change ExtremeChange { get { return extremeChange; } } + + public Mod(string identifier) + { + this.identifier = identifier; + change = CreateChange(); + extremeChange = CreateExtremeChange(); + + Items.Add(this); + ModList.Add(this.Identifier, this.ChangeList); + } + + /** + * Initialize Extreme change on demand. + * This is needed due to how the UI is stitched together tightly with Changes, + * and how the GlobalLabels work. + * Extreme changes are not initialized, only the HD changes at startup, and the + * UI is built with the HD changes and NOT with the Extreme changes. + * + * Extreme changes are inited when the patcher runs on the Extreme file, and + * before that, the GlobalLabels collection is emptied to avoid duplication + * exception. + */ + public void InitExtremeChange() + { + extremeChange = CreateExtremeChange(); + } + + /** + * Creates the HD change, but also should cache it. + */ + protected virtual Change CreateChange() + { + // Overridden. + return null; + } + + /** + * Creates the Extreme change, but also should cache it. + */ + protected virtual Change CreateExtremeChange() + { + // Overridden. + return null; + } + + #endregion + + + #region Mod installation methods + public void ApplyChanges(Dictionary modConfiguration) + { + if (this.change == null) + { + return; + } + + foreach (DefaultSubChange header in this.change) + { + double? value; + if (modConfiguration.TryGetValue(header.Identifier, out value)) + { + if (header is ValuedSubChange valueHeader && value != null) + { + valueHeader.Value = value.Value; + } + header.IsEnabled = true; + } + } + } + + public void ApplyExtremeChanges(Dictionary modConfiguration) + { + if (this.extremeChange == null) + { + return; + } + + foreach (DefaultSubChange header in this.extremeChange) + { + double? value; + if (modConfiguration.TryGetValue(header.Identifier, out value)) + { + if (header is ValuedSubChange valueHeader && value != null) + { + valueHeader.Value = value.Value; + } + header.IsEnabled = true; + } + } + } + + public void Disable() + { + if (this.change != null) + { + foreach (DefaultSubChange header in this.Change) + { + header.IsEnabled = false; + } + } + if (this.extremeChange != null) + { + foreach (DefaultSubChange header in this.extremeChange) + { + header.IsEnabled = false; + } + } + } + + public void Install(ChangeArgs args) + { + if (change != null) + { + change.Activate(args); + } + } + + public void InstallExtreme(ChangeArgs args) + { + if (extremeChange != null) + { + extremeChange.Activate(args); + } + } + #endregion + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/ModSelectionType.cs b/UnofficialCrusaderPatch/Model/ModSelectionType.cs new file mode 100644 index 00000000..9ce05cb9 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/ModSelectionType.cs @@ -0,0 +1,6 @@ +namespace UCP.Model +{ + public enum ModSelectionType + { + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/ModUIConfig.cs b/UnofficialCrusaderPatch/Model/ModUIConfig.cs new file mode 100644 index 00000000..cb762754 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/ModUIConfig.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UCP.Patching; + +namespace UCP.Model +{ + class ModUIConfig + { + public ChangeType modType { get; set; } + public Dictionary modDescription { get; set; } + public ModSelectionType selectionType { get; set; } + public IEnumerable changes { get; set; } + } +} diff --git a/UnofficialCrusaderPatch/Model/Patching/Installer.cs b/UnofficialCrusaderPatch/Model/Patching/Installer.cs new file mode 100644 index 00000000..ffe62bac --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Installer.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UCP.Patching; + +namespace UCP.Model.Patching +{ + class Installer + { + + public const string BackupIdent = "ucp_backup"; + public const string BackupFileEnding = "." + BackupIdent; + + const string CrusaderExe = "Stronghold Crusader.exe"; + const string XtremeExe = "Stronghold_Crusader_Extreme.exe"; + + static Func crusaderPath = (folderPath) => GetOriginalBinary(folderPath, CrusaderExe); + static Func extremePath = (folderPath) => GetOriginalBinary(folderPath, XtremeExe); + + static byte[] crusaderOriData; + static byte[] crusaderData; + + static byte[] extremeOriData; + static byte[] extremeData; + + static string crusaderFilePath; + static string extremeFilePath; + + internal static ChangeArgs? crusaderArgs; + internal static ChangeArgs? extremeArgs; + + public static string PatcherVersion = "2.14"; + + // change version 0x424EF1 + 1 + public static readonly SubChange MenuChange = new SubChange() + { + BinRedirect.CreateEdit("menuversion", false, Encoding.ASCII.GetBytes("V1.%d UCP" + PatcherVersion + '\0')) + }; + public static readonly SubChange MenuChange_XT = new SubChange() + { + BinRedirect.CreateEdit("menuversion", false, Encoding.ASCII.GetBytes("V1.%d-E UCP" + PatcherVersion + '\0')) + }; + + public static void RestoreOriginals(string dir) + { + RestoreBinary(dir, CrusaderExe); + RestoreBinary(dir, XtremeExe); + } + + public static void Initialize(string shcPath) + { + crusaderFilePath = crusaderPath(shcPath); + crusaderfails.Clear(); + SectionEditor.Reset(); + + // Read original data & perform section preparation adding .ucp section to binary + if (crusaderFilePath != null) + { + crusaderOriData = File.ReadAllBytes(crusaderFilePath); + crusaderData = (byte[])crusaderOriData.Clone(); + SectionEditor.Init(crusaderData); + crusaderArgs = new ChangeArgs(crusaderData, crusaderOriData); + + // Change version display in main menu + MenuChange.Activate(crusaderArgs.Value); + } + } + + public static void InitializeExtreme(string shcPath) + { + extremeFilePath = extremePath(shcPath); + extremefails.Clear(); + SectionEditor.Reset(); + + // Read original data & perform section preparation adding .ucp section to binary + if (extremeFilePath != null) + { + extremeOriData = File.ReadAllBytes(extremeFilePath); + extremeData = (byte[])extremeOriData.Clone(); + SectionEditor.Init(extremeData); + extremeArgs = new ChangeArgs(extremeData, extremeOriData); + + // Change version display in main menu + MenuChange_XT.Activate(extremeArgs.Value); + } + } + + internal static string WriteFinalize() + { + if (crusaderArgs != null) + { + // Write everything to file + crusaderData = SectionEditor.AttachSection(crusaderData); + if (crusaderFilePath.EndsWith(BackupFileEnding)) + { + crusaderFilePath = crusaderFilePath.Remove(crusaderFilePath.Length - BackupFileEnding.Length); + } + else + { + File.WriteAllBytes(crusaderFilePath + BackupFileEnding, crusaderOriData); // create backup + } + File.WriteAllBytes(crusaderFilePath, crusaderData); + } + string crusaderFailures = ListFailures(crusaderFilePath); + return crusaderFailures; + } + + + internal static string WriteFinalizeExtreme() + { + if (extremeArgs != null) + { + // Write everything to file + extremeData = SectionEditor.AttachSection(extremeData); + if (extremeFilePath.EndsWith(BackupFileEnding)) + { + extremeFilePath = extremeFilePath.Remove(extremeFilePath.Length - BackupFileEnding.Length); + } + else + { + File.WriteAllBytes(extremeFilePath + BackupFileEnding, extremeOriData); // create backup + } + File.WriteAllBytes(extremeFilePath, extremeData); + } + string extremeFailures = ListFailures(extremeFilePath); + return extremeFailures; + } + + + + + + + + + + // Retrieve path to the original SHC or SHC Extreme binary + static string GetOriginalBinary(string folderPath, string exe) + { + if (Directory.Exists(folderPath)) + { + // remove old file ending from v1.0 + string path = Path.Combine(folderPath, exe + ".ori"); + if (File.Exists(path)) + { + string dest = path.Remove(path.Length - ".ori".Length); + File.Delete(dest); + File.Move(path, dest); + } + + path = Path.Combine(folderPath, exe + BackupFileEnding); + if (File.Exists(path)) + return path; + + path = path.Remove(path.Length - BackupFileEnding.Length); + if (File.Exists(path)) + return path; + } + return null; + } + + + /// + /// Rename the backed-up version of SHC and/or SHC Extreme executable + /// + /// + /// + static void RestoreBinary(string dir, string exe) + { + string oriPath = Path.Combine(dir, exe); + string backupPath = oriPath + BackupFileEnding; + if (File.Exists(backupPath)) + { + if (File.Exists(oriPath)) + File.Delete(oriPath); + + File.Move(backupPath, oriPath); + } + } + + static string ListFailures(string filePath) + { + if (crusaderfails.Count > 0) + { + StringBuilder sb = new StringBuilder(); + sb.Append("Version Differences in "); + sb.Append(Path.GetFileName(filePath)); + sb.AppendLine(":"); + foreach (var f in crusaderfails) + sb.AppendLine(f.Ident + " " + f.Type); + + crusaderfails.Clear(); + return sb.ToString(); + } + return null; + } + + struct EditFail + { + public string Ident; + public EditFailure Type; + } + static readonly List crusaderfails = new List(); + static readonly List extremefails = new List(); + public static void AddFailure(string ident, EditFailure failure) + { + crusaderfails.Add(new EditFail() { Ident = ident, Type = failure }); + } + + public static void AddExtremeFailure(string ident, EditFailure failure) + { + extremefails.Add(new EditFail() { Ident = ident, Type = failure }); + } + } +} diff --git a/UnofficialCrusaderPatch/Patching/BinElements/BinCode.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinCode.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/BinCode.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinCode.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/BinCollection.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinCollection.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/BinCollection.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinCollection.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/BinElement.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinElement.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/BinElement.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinElement.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/BinNops.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinNops.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/BinNops.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinNops.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/BinSkip.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinSkip.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/BinSkip.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinSkip.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/BinValue.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinValue.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/BinValue.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/BinValue.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/OpCodes.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/OpCodes.cs similarity index 99% rename from UnofficialCrusaderPatch/Patching/BinElements/OpCodes.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/OpCodes.cs index 872e5451..1db26758 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/OpCodes.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/OpCodes.cs @@ -1,9 +1,6 @@ using System; -using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; -using System.Text; using static UCP.Patching.BinElements.Register; namespace UCP.Patching.BinElements diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinAddress.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinAddress.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinAddress.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinAddress.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinAlloc.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinAlloc.cs similarity index 72% rename from UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinAlloc.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinAlloc.cs index 2b68701d..92dcaa6a 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinAlloc.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinAlloc.cs @@ -8,16 +8,23 @@ public class BinAlloc : BinElement, IEnumerable string name; public string Name => name; - public BinAlloc(string name, uint size) + public BinAlloc(string name, uint size, bool isGlobal = false) : this(name, new byte[size]) { } - public BinAlloc(string name, byte[] data) + public BinAlloc(string name, byte[] data, bool isGlobal = false) { this.name = name; - editData.Add(new BinLabel(name)); + BinLabel newBinLabel = new BinLabel(name); + + if (isGlobal) + { + GlobalLabels.Add(newBinLabel); + } + + editData.Add(newBinLabel); if (data != null && data.Length > 0) editData.Add(new BinBytes(data)); editData.Add(new BinNops(4)); diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinHook.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinHook.cs similarity index 96% rename from UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinHook.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinHook.cs index bc55f962..2b9451a8 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinHook.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinHook.cs @@ -1,4 +1,5 @@ using System; +using UCP.Model; namespace UCP.Patching { @@ -52,9 +53,9 @@ public override void Add(BinElement input) public static Change Change(string ident, ChangeType type, bool checkedDefault, int hookLen, params BinElement[] code) { - return new Change(ident, type, checkedDefault) + return new Change(ident, type) { - new DefaultHeader(ident, true) + new DefaultSubChange(ident) { CreateEdit(ident, hookLen, code) } diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinLabel.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinLabel.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinLabel.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinLabel.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinRedirect.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinRedirect.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinRedirect.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinRedirect.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinRefTo.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinRefTo.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/BinElements/Referencers/BinRefTo.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Referencers/BinRefTo.cs diff --git a/UnofficialCrusaderPatch/Patching/BinElements/Register.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Register.cs similarity index 57% rename from UnofficialCrusaderPatch/Patching/BinElements/Register.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Register.cs index 85494848..02f213c4 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/Register.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/Register.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace UCP.Patching.BinElements +namespace UCP.Patching.BinElements { public enum Register { diff --git a/UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinBytes.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinBytes.cs similarity index 80% rename from UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinBytes.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinBytes.cs index 8836c995..0d5a0fab 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinBytes.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinBytes.cs @@ -1,4 +1,6 @@ -namespace UCP.Patching +using UCP.Model; + +namespace UCP.Patching { /// /// Convenience class for defining an array of bytes to be written to target CodeBlock @@ -20,15 +22,15 @@ public override void Write(BinArgs data) public static Change Change(string ident, ChangeType type, bool checkedDefault, params byte[] input) { - return new Change(ident, type, checkedDefault) + return new Change(ident, type) { Header(ident, true, input) }; } - public static DefaultHeader Header(string ident, bool suggested, params byte[] input) + public static DefaultSubChange Header(string ident, bool suggested, params byte[] input) { - return new DefaultHeader(ident, suggested) + return new DefaultSubChange(ident) { CreateEdit(ident, input) }; diff --git a/UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinInt32.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinInt32.cs similarity index 86% rename from UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinInt32.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinInt32.cs index de3ad162..9e91fe7b 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinInt32.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinInt32.cs @@ -1,4 +1,5 @@ using System; +using UCP.Model; namespace UCP.Patching { @@ -14,9 +15,9 @@ public BinInt32(int input) public static Change Change(string locIdent, ChangeType type, int newValue, bool checkedDefault = true) { - return new Change(locIdent, type, checkedDefault) + return new Change(locIdent, type) { - new DefaultHeader(locIdent, true) + new DefaultSubChange(locIdent) { CreateEdit(locIdent, newValue) } diff --git a/UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinShort.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinShort.cs similarity index 86% rename from UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinShort.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinShort.cs index 572f6424..7c458de2 100644 --- a/UnofficialCrusaderPatch/Patching/BinElements/StructTypes/BinShort.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/BinElements/StructTypes/BinShort.cs @@ -1,4 +1,5 @@ using System; +using UCP.Model; namespace UCP.Patching { @@ -14,9 +15,9 @@ public BinShort(short input) public static Change Change(string locIdent, ChangeType type, short newValue, bool checkedDefault = true) { - return new Change(locIdent, type, checkedDefault) + return new Change(locIdent, type) { - new DefaultHeader(locIdent, true) + new DefaultSubChange(locIdent) { CreateEdit(locIdent, newValue) } diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AICChange.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AICChange.cs new file mode 100644 index 00000000..f5b76248 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AICChange.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using UCP.Model; +using UCP.Patching; +using UCPAIConversion; + +namespace UCP.AIC +{ + class AICChange : Change + { + internal AICollection collection; + internal List characters; + internal List customCharacterNames; + internal AICChange(string identifier) + : base(identifier, ChangeType.AIC) + { + } + } +} diff --git a/UnofficialCrusaderPatch/AIV/AIVChange.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AIVChange.cs similarity index 54% rename from UnofficialCrusaderPatch/AIV/AIVChange.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AIVChange.cs index 5577197e..095421d4 100644 --- a/UnofficialCrusaderPatch/AIV/AIVChange.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/AIVChange.cs @@ -4,150 +4,32 @@ using System.Linq; using System.Reflection; using System.Security.Cryptography; -using System.Text.RegularExpressions; using System.Threading; using System.Windows; -using System.Windows.Controls; using System.Windows.Forms; -using System.Windows.Media; +using UCP.Model; using UCP.Patching; namespace UCP.AIV { class AIVChange : Change { - public bool isInternal = false; - string resFolder; - const string BackupIdent = "ucp_backup"; - public static AIVChange activeChange = null; - static List _changes = new List(); - - private static string selectedChange = String.Empty; - - static AIVChange ActiveChange { get { return activeChange; } } - - public static List changes { get { return _changes; } } - - /// - /// Loads AIV sets from subfolders present in resources\aiv path using foldername as change title - /// - static AIVChange() { - if (Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "aiv"))) - { - foreach (string aivDir in Directory.EnumerateDirectories(Path.Combine(Environment.CurrentDirectory, "resources", "aiv"), "*", SearchOption.TopDirectoryOnly)) - { - changes.Add(CreateExternal(Path.GetFileName(aivDir.TrimEnd(Path.DirectorySeparatorChar)))); - } - } - } - - public AIVChange(string titleIdent, bool enabledDefault = false, bool isInternal = false) - : base("aiv_" + titleIdent, ChangeType.AIV, true, true) - { - this.resFolder = titleIdent; - this.isInternal = isInternal; - } - - public override void InitUI() - { - string descr = GetLocalizedDescription(this.TitleIdent); - descr = descr == String.Empty ? this.TitleIdent.Substring(4) : descr; - Localization.Add(this.TitleIdent + "_descr", descr); - base.InitUI(); - this.titleBox.Background = new SolidColorBrush(Colors.White); - - if (!this.resFolder.StartsWith("UCP.AIV")) - { - ((TextBlock)this.titleBox.Content).Text = this.TitleIdent.Substring(4); - } - this.IsChecked = selectedChange.Equals(this.TitleIdent); - this.titleBox.IsChecked = selectedChange.Equals(this.TitleIdent); - if (this.IsChecked) - activeChange = this; - } - - public static AIVChange CreateExternal(string titleIdent, bool enabledDefault = false) + internal AIVChange(string identifier) + : base(identifier, ChangeType.AIV) { - return new AIVChange(titleIdent, enabledDefault, false) - { - new DefaultHeader("aiv_" + titleIdent) - { - } - }; } - protected override void TitleBox_Checked(object sender, RoutedEventArgs e) + internal AIVChange withResFolder(string resFolder) { - base.TitleBox_Checked(sender, e); - - if (activeChange != null) - activeChange.IsChecked = false; - - activeChange = this; - selectedChange = this.TitleIdent; + this.resFolder = resFolder; + return this; } - protected override void TitleBox_Unchecked(object sender, RoutedEventArgs e) - { - base.TitleBox_Unchecked(sender, e); - - if (activeChange == this) - { - activeChange = null; - selectedChange = String.Empty; - } - } - public static IEnumerable GetConfiguration() - { - List config = new List(); - if (selectedChange != String.Empty) - { - config.Add(selectedChange + "= { " + selectedChange + "={True} }"); - } - foreach (AIVChange change in changes) - { - if (selectedChange != null && !(change.TitleIdent.Equals(selectedChange))){ - config.Add(change.TitleIdent + "= { " + change.TitleIdent + "={False} }"); - } - } - return config; - } - - public static void LoadConfiguration(List configuration = null) - { - if (configuration == null) - { - return; - } - - foreach (string change in configuration) - { - string[] changeLine = change.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(str => str.Trim()).ToArray(); - if (changeLine.Length < 2) - { - continue; - } - - string changeKey = changeLine[0]; - string changeSetting = changeLine[1]; - - bool selected = Regex.Replace(@"\s+", "", changeSetting.Split('=')[1]).Contains("True"); - if (selected == true) - { - selectedChange = changeKey; - activeChange = changes.Where(x => x.TitleIdent.Equals(changeKey)).FirstOrDefault(); - } - } - } - - /// - /// Copies AIV sets to aivDir (aiv subdirectory of SHC installation) - /// - /// internal bool CopyAIVs(DirectoryInfo destinationDir, bool overwrite, bool graphical) { + Assembly asm = Assembly.GetExecutingAssembly(); List resourceFiles = Directory.GetFiles(Path.Combine("resources", "aiv", resFolder)).Where(x => x.EndsWith(".aiv")).Select(x => Path.GetFileName(ReplaceFirst(x, resFolder + Path.PathSeparator, ""))).ToList(); @@ -282,7 +164,7 @@ internal bool CopyAIVs(DirectoryInfo destinationDir, bool overwrite, bool graphi */ if (!backupIdentical && graphical) // Clear backup folder of aiv files { - MessageBoxResult result = System.Windows.MessageBox.Show(Localization.Get("aiv_prompt"), "", MessageBoxButton.YesNoCancel); + MessageBoxResult result = System.Windows.MessageBox.Show(System.Windows.Application.Current.Resources["aiv_prompt"].ToString(), "", MessageBoxButton.YesNoCancel); if (result == MessageBoxResult.No) { foreach (FileInfo file in destinationDir.GetFiles()) @@ -294,7 +176,7 @@ internal bool CopyAIVs(DirectoryInfo destinationDir, bool overwrite, bool graphi { using (var dialog = new FolderBrowserDialog()) { - dialog.Description = Localization.Get("backup_aiv_select"); + dialog.Description = System.Windows.Application.Current.Resources["backup_aiv_select"].ToString(); dialog.RootFolder = Environment.SpecialFolder.Desktop; DialogResult folderResult = DialogResult.Cancel; var thread = new Thread(obj => { @@ -313,7 +195,8 @@ internal bool CopyAIVs(DirectoryInfo destinationDir, bool overwrite, bool graphi { file.MoveTo(Path.Combine(savePath.FullName, Path.GetFileName(file.Name))); } - } else + } + else { throw new Exception(); } @@ -329,7 +212,7 @@ internal bool CopyAIVs(DirectoryInfo destinationDir, bool overwrite, bool graphi string input = ""; while (!input.ToLower().Equals("delete") && (input.IndexOfAny(Path.GetInvalidPathChars()) != -1 || (input.Equals("") || Directory.Exists(Path.Combine(destinationDir.FullName, input))))) { - Console.WriteLine(Localization.Get("aiv_cli_prompt")); + Console.WriteLine(System.Windows.Application.Current.Resources["aiv_cli_prompt"]); input = Console.ReadLine().Replace("\n", ""); }; @@ -369,65 +252,7 @@ internal bool CopyAIVs(DirectoryInfo destinationDir, bool overwrite, bool graphi return true; } - public static void Refresh() - { - changes.Clear(); - - if (Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "aiv"))) - { - foreach (string aivDir in Directory.EnumerateDirectories(Path.Combine(Environment.CurrentDirectory, "resources", "aiv"), "*", SearchOption.TopDirectoryOnly)) - { - changes.Add(CreateExternal(Path.GetFileName(aivDir.TrimEnd(Path.DirectorySeparatorChar)))); - } - } - - - Version.RemoveChanges(ChangeType.AIV); - Version.Changes.AddRange(changes); - } - - /// - /// Restores the most recently backed-up AIV set found in the aiv subfolder of SHC installation - /// - /// - internal static void Restore(string path) - { - DirectoryInfo destinationDir = new DirectoryInfo(Path.Combine(path, "aiv")); - DirectoryInfo backupDir = new DirectoryInfo(Path.Combine(destinationDir.FullName, "original")); - if (!backupDir.Exists) - { - return; - } - else - { - foreach (FileInfo file in destinationDir.GetFiles()) - { - if (file.Extension.Equals(".aiv")) - { - file.Delete(); - } - } - - foreach (FileInfo file in backupDir.GetFiles()) - { - file.MoveTo(Path.Combine(destinationDir.FullName, Path.GetFileName(file.Name))); - } - backupDir.Delete(); - } - } - /// - /// Creates timestamped backup of existing AIV sets and copies selected AIV set to aivDir (aiv subdirectory of SHC installation) - /// - /// - public static void DoChange(string folderPath, bool overwrite, bool graphical) - { - if (activeChange == null) - { - return; - } - activeChange.CopyAIVs(new DirectoryInfo(Path.Combine(folderPath, "aiv")), overwrite, graphical); - } static string ReplaceFirst(string text, string search, string replace) { @@ -439,58 +264,5 @@ static string ReplaceFirst(string text, string search, string replace) return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); } - private static String GetLocalizedDescription(string titleIdent) - { - string folderPath = Path.Combine("resources", "aiv", titleIdent.Substring(4)); - string currentLang = Localization.Translations.ToArray()[Localization.LanguageIndex].Ident; - string descr = String.Empty; - try - { - descr = ReadDescription(Path.Combine(folderPath, currentLang)); - if (descr == String.Empty) - { - foreach (var lang in Localization.Translations) - { - try - { - descr = ReadDescription(Path.Combine(folderPath, lang.Ident)); - if (descr != String.Empty) - { - break; - } - } - catch (Exception) - { - continue; - } - } - } - } - catch (Exception) - { - foreach (var lang in Localization.Translations) - { - try - { - descr = ReadDescription(Path.Combine(folderPath, lang.Ident)); - if (descr != String.Empty) - { - break; - } - } - catch (Exception) - { - continue; - } - } - } - return descr; - } - - private static String ReadDescription(String file) - { - String text = File.ReadAllText(file + ".txt"); - return text.Substring(0, Math.Min(text.Length, 1000)); - } } } diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/Change.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/Change.cs new file mode 100644 index 00000000..d911d1ab --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/Change.cs @@ -0,0 +1,53 @@ +using System.Collections; +using System.Collections.Generic; +using UCP.Patching; + +namespace UCP.Model +{ + public class Change: IEnumerable + { + public string Identifier { get; set; } + public ChangeType Type { get; set; } + public object Value { get; set; } + + public Change() { } + public Change(string ident, ChangeType type) + { + this.Identifier = ident; + this.Type = type; + } + + public Change withType(ChangeType type) + { + this.Type = type; + return this; + } + + public Change withIdentifier(string identifier) + { + this.Identifier = identifier; + return this; + } + + List headerList = new List(); + public IEnumerator GetEnumerator() => headerList.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); + + public void Add(DefaultSubChange header) + { + headerList.Add(header); + header.SetParent(this); + } + + public virtual void Activate(ChangeArgs args) + { + foreach (DefaultSubChange header in headerList) + { + if (header.IsEnabled) + { + header.Activate(args); + } + } + } + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Patching/Changes/ChangeArgs.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/ChangeArgs.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/Changes/ChangeArgs.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/Changes/ChangeArgs.cs diff --git a/UnofficialCrusaderPatch/Patching/Changes/ChangeType.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/ChangeType.cs similarity index 88% rename from UnofficialCrusaderPatch/Patching/Changes/ChangeType.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/Changes/ChangeType.cs index 6dc09226..c65530d4 100644 --- a/UnofficialCrusaderPatch/Patching/Changes/ChangeType.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/ChangeType.cs @@ -8,7 +8,7 @@ public enum ChangeType Other, AIV, AIC, - Resource, + StartResource, StartTroops } } diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartResourceChange.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartResourceChange.cs new file mode 100644 index 00000000..8cc22dbd --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartResourceChange.cs @@ -0,0 +1,12 @@ +using UCP.Patching; + +namespace UCP.Model +{ + class StartResourceChange : Change + { + public StartResourceChange(string identifier) + : base(identifier, ChangeType.StartResource) + { + } + } +} diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartTroopChange.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartTroopChange.cs new file mode 100644 index 00000000..3dc2c9f2 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Changes/StartTroopChange.cs @@ -0,0 +1,12 @@ +using UCP.Patching; + +namespace UCP.Model +{ + class StartTroopChange : Change + { + public StartTroopChange(string identifier) + : base(identifier, ChangeType.StartTroops) + { + } + } +} diff --git a/UnofficialCrusaderPatch/Patching/EditTypes/BinArgs.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinArgs.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/EditTypes/BinArgs.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinArgs.cs diff --git a/UnofficialCrusaderPatch/Patching/EditTypes/BinaryEdit.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinaryEdit.cs similarity index 82% rename from UnofficialCrusaderPatch/Patching/EditTypes/BinaryEdit.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinaryEdit.cs index 1c04376c..1648a73c 100644 --- a/UnofficialCrusaderPatch/Patching/EditTypes/BinaryEdit.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinaryEdit.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Reflection; +using UCP.Model.Patching; namespace UCP.Patching { @@ -18,7 +19,7 @@ public BinaryEdit(string blockIdent) Assembly asm = Assembly.GetExecutingAssembly(); // check if code block file is there - string file = string.Format("UCP.CodeBlocks.{0}.block", blockIdent); + string file = string.Format("UCP.Resources.CodeBlocks.{0}.block", blockIdent); if (!asm.GetManifestResourceNames().Contains(file)) throw new Exception("MISSING BLOCK FILE " + file); @@ -37,12 +38,12 @@ protected override bool GetAddresses(byte[] original, out int rawAddr, out int v if (count > 1) { - Patcher.AddFailure(this.blockFile, EditFailure.MultipleBlocks); + Installer.AddFailure(this.blockFile, EditFailure.MultipleBlocks); return false; } else if (count == 0) { - Patcher.AddFailure(this.blockFile, EditFailure.BlockNotFound); + Installer.AddFailure(this.blockFile, EditFailure.BlockNotFound); return false; } return true; diff --git a/UnofficialCrusaderPatch/Patching/EditTypes/BinaryEditBase.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinaryEditBase.cs similarity index 95% rename from UnofficialCrusaderPatch/Patching/EditTypes/BinaryEditBase.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinaryEditBase.cs index 74675267..53c47e97 100644 --- a/UnofficialCrusaderPatch/Patching/EditTypes/BinaryEditBase.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/BinaryEditBase.cs @@ -8,7 +8,7 @@ public abstract class BinaryEditBase : ChangeEdit, IEnumerable int length; public int Length => length; - public override void SetParent(ChangeHeader parent) + public override void SetParent(SubChange parent) { base.SetParent(parent); @@ -83,7 +83,7 @@ void InitElement(BinElement element, ref int rawAddr, ref int virtAddr, byte[] o public override void Activate(ChangeArgs args) { - double value = Parent is ValueHeader vHeader ? vHeader.Value : 0; + double value = Parent is ValuedSubChange vHeader ? vHeader.Value : 0; BinArgs binArgs = new BinArgs(args.Data, this.Parent.Labels, value); foreach (BinElement e in elements) diff --git a/UnofficialCrusaderPatch/Patching/EditTypes/ChangeEdit.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/ChangeEdit.cs similarity index 65% rename from UnofficialCrusaderPatch/Patching/EditTypes/ChangeEdit.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/ChangeEdit.cs index 61272cdf..3eee8b77 100644 --- a/UnofficialCrusaderPatch/Patching/EditTypes/ChangeEdit.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/ChangeEdit.cs @@ -5,10 +5,10 @@ public abstract class ChangeEdit public abstract bool Initialize(ChangeArgs args); public abstract void Activate(ChangeArgs args); - ChangeHeader parent; - public ChangeHeader Parent => parent; + SubChange parent; + public SubChange Parent => parent; - public virtual void SetParent(ChangeHeader parent) + public virtual void SetParent(SubChange parent) { this.parent = parent; } diff --git a/UnofficialCrusaderPatch/Patching/EditTypes/EditFailures.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/EditFailures.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/EditTypes/EditFailures.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/EditFailures.cs diff --git a/UnofficialCrusaderPatch/Patching/EditTypes/UCPEdit.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/UCPEdit.cs similarity index 91% rename from UnofficialCrusaderPatch/Patching/EditTypes/UCPEdit.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/UCPEdit.cs index e966c2cb..a7a6db31 100644 --- a/UnofficialCrusaderPatch/Patching/EditTypes/UCPEdit.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/EditTypes/UCPEdit.cs @@ -1,4 +1,6 @@ -namespace UCP.Patching +using UCP.Model.Patching; + +namespace UCP.Patching { public class UCPEdit : BinaryEditBase { diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/GlobalLabels.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/GlobalLabels.cs new file mode 100644 index 00000000..fbd67e36 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/GlobalLabels.cs @@ -0,0 +1,22 @@ +namespace UCP.Patching +{ + internal class GlobalLabels + { + private static LabelCollection labels = new LabelCollection(); + + public static int GetLabel(string labelName) + { + return labels.GetLabel(labelName); + } + + public static void Add(BinLabel label) + { + labels.Add(label); + } + + public static void Clear() + { + labels.Clear(); + } + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Patching/Headers/LabelCollection.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/LabelCollection.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/Headers/LabelCollection.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/LabelCollection.cs diff --git a/UnofficialCrusaderPatch/Patching/Section/AddressSpace.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/AddressSpace.cs similarity index 100% rename from UnofficialCrusaderPatch/Patching/Section/AddressSpace.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/Section/AddressSpace.cs diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Section/PEHeader.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/PEHeader.cs new file mode 100644 index 00000000..e4f03aa6 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/PEHeader.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +namespace UCP.Model.Patching.Section +{ + internal class PEHeader + { + int offset; + ushort numberOfSections; + public ushort NumberOfSections => numberOfSections; + + uint sectionAlignment; + public uint SectionAlignment => sectionAlignment; + + uint fileAlignment; + public uint FileAlignment => fileAlignment; + + List sections; + public IEnumerable Sections => sections; + + public PEHeader(byte[] input, int offset) + { + this.offset = offset; + + numberOfSections = BitConverter.ToUInt16(input, offset + 0x06); + sectionAlignment = BitConverter.ToUInt32(input, offset + 0x38); + fileAlignment = BitConverter.ToUInt32(input, offset + 0x3C); + + sections = new List(numberOfSections); + for (int i = 0; i < numberOfSections; i++) + { + sections.Add(new SectionHeader(input, offset + 0xF8 + SectionHeader.HeaderSize * i)); + } + } + + public static PEHeader Find(byte[] input) + { + int index = input.FindIndex(0x4550); // "PE" + return index < 0 ? null : new PEHeader(input, index); + } + + public byte[] AddSection(byte[] input, SectionHeader sec) + { + // make space + byte[] data = new byte[sec.RawAddr + sec.RawSize]; + Buffer.BlockCopy(input, 0, data, 0, (int)sec.RawAddr); + + // number of sections + ushort sectionCount = (ushort)(this.NumberOfSections + 1); + BitConverter.GetBytes(sectionCount).CopyTo(data, offset + 0x06); + + // size of image + uint imageSize = sec.VirtAddr + Utils.GetMultiples(sec.VirtSize, sectionAlignment); + BitConverter.GetBytes(imageSize).CopyTo(data, offset + 0x50); + + sec.Write(data, offset + 0xF8 + SectionHeader.HeaderSize * this.NumberOfSections); + + return data; + } + } +} diff --git a/UnofficialCrusaderPatch/Patching/Section/SectionEditor.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionEditor.cs similarity index 72% rename from UnofficialCrusaderPatch/Patching/Section/SectionEditor.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionEditor.cs index 206f40c5..51e85d12 100644 --- a/UnofficialCrusaderPatch/Patching/Section/SectionEditor.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionEditor.cs @@ -1,47 +1,18 @@ using System; using System.Linq; +using UCP.Model.Patching.Section; +using UCP.Patching; -namespace UCP.Patching +namespace UCP.Model.Patching { - public static partial class SectionEditor + class SectionEditor { - public static void Reset() - { - currentLen = 0; - } + static PEHeader header; + static SectionHeader ucpSec; static uint currentLen = 0; static byte[] buffer = new byte[0]; - public static AddressSpace ReserveBufferSpace(uint size) - { - uint newLen = currentLen + size; - - uint rawSize = GetMultiples(newLen, header.FileAlignment); - if (buffer.Length < rawSize) - { - byte[] newBuffer = new byte[rawSize]; - buffer.CopyTo(newBuffer, 0); - buffer = newBuffer; - } - - var space = new AddressSpace(ucpSec.VirtAddr + currentLen, currentLen); - currentLen = newLen; - return space; - } - - public static byte[] GetBuffer() - { - return buffer; - } - - - - - - static PEHeader header; - static SectionHeader ucpSec; - public static void Init(byte[] input) { // find headers entry @@ -54,21 +25,21 @@ public static void Init(byte[] input) // new code section ucpSec = new SectionHeader(".ucp") { - VirtAddr = prevSec.VirtAddr + GetMultiples(prevSec.VirtSize, header.SectionAlignment), - RawAddr = prevSec.RawAddr + GetMultiples(prevSec.RawSize, header.FileAlignment), + VirtAddr = prevSec.VirtAddr + Utils.GetMultiples(prevSec.VirtSize, header.SectionAlignment), + RawAddr = prevSec.RawAddr + Utils.GetMultiples(prevSec.RawSize, header.FileAlignment), Characteristics = 0xE0000020 // writable, //0x60000020, // executable, readable, contains code }; } - + public static byte[] AttachSection(byte[] input) { if (buffer.Length == 0) return input; uint size = (uint)buffer.Length; - ucpSec.VirtSize = GetMultiples(size, header.SectionAlignment); - ucpSec.RawSize = GetMultiples(size, header.FileAlignment); + ucpSec.VirtSize = Utils.GetMultiples(size, header.SectionAlignment); + ucpSec.RawSize = Utils.GetMultiples(size, header.FileAlignment); byte[] data = header.AddSection(input, ucpSec); Buffer.BlockCopy(buffer, 0, data, (int)ucpSec.RawAddr, buffer.Length); @@ -76,10 +47,31 @@ public static byte[] AttachSection(byte[] input) return data; } - static uint GetMultiples(uint size, uint mult) + public static AddressSpace ReserveBufferSpace(uint size) + { + uint newLen = currentLen + size; + + uint rawSize = Utils.GetMultiples(newLen, header.FileAlignment); + if (buffer.Length < rawSize) + { + byte[] newBuffer = new byte[rawSize]; + buffer.CopyTo(newBuffer, 0); + buffer = newBuffer; + } + + var space = new AddressSpace(ucpSec.VirtAddr + currentLen, currentLen); + currentLen = newLen; + return space; + } + + public static byte[] GetBuffer() { - uint num = size + mult - 1; - return num - num % mult; + return buffer; + } + + public static void Reset() + { + currentLen = 0; } } } diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionHeader.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionHeader.cs new file mode 100644 index 00000000..9e342b3c --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/SectionHeader.cs @@ -0,0 +1,70 @@ +using System; +using System.Text; + +namespace UCP.Model.Patching.Section +{ + internal class SectionHeader + { + public const int HeaderSize = 40; + public const int NameLength = 8; + + public string GetNameStr() + { + return Encoding.ASCII.GetString(Name); + } + + public void SetNameStr(string nameStr) + { + byte[] buf = Encoding.ASCII.GetBytes(nameStr); + Buffer.BlockCopy(buf, 0, this.Name, 0, buf.Length); + for (int i = buf.Length; i < NameLength; i++) + this.Name[i] = 0; + } + + public readonly byte[] Name = new byte[NameLength]; + public uint VirtSize; + public uint VirtAddr; + public uint RawSize; + public uint RawAddr; + public uint RelocAddr; + public uint LineNums; + public ushort RelocNum; + public ushort LineNumsNum; + public uint Characteristics; + + public SectionHeader(string nameStr) + { + SetNameStr(nameStr); + } + + public SectionHeader(byte[] data, int offset) + { + Buffer.BlockCopy(data, offset, Name, 0, NameLength); + + VirtSize = BitConverter.ToUInt32(data, offset + 8); + VirtAddr = BitConverter.ToUInt32(data, offset + 12); + RawSize = BitConverter.ToUInt32(data, offset + 16); + RawAddr = BitConverter.ToUInt32(data, offset + 20); + RelocAddr = BitConverter.ToUInt32(data, offset + 24); + LineNums = BitConverter.ToUInt32(data, offset + 28); + RelocNum = BitConverter.ToUInt16(data, offset + 32); + LineNumsNum = BitConverter.ToUInt16(data, offset + 34); + Characteristics = BitConverter.ToUInt32(data, offset + 36); + } + + public void Write(byte[] data, int offset) + { + Buffer.BlockCopy(Name, 0, data, offset, NameLength); + + BitConverter.GetBytes(VirtSize).CopyTo(data, offset + 8); + BitConverter.GetBytes(VirtAddr).CopyTo(data, offset + 12); + BitConverter.GetBytes(RawSize).CopyTo(data, offset + 16); + BitConverter.GetBytes(RawAddr).CopyTo(data, offset + 20); + BitConverter.GetBytes(RelocAddr).CopyTo(data, offset + 24); + BitConverter.GetBytes(LineNums).CopyTo(data, offset + 28); + BitConverter.GetBytes(RelocNum).CopyTo(data, offset + 32); + BitConverter.GetBytes(LineNumsNum).CopyTo(data, offset + 34); + BitConverter.GetBytes(Characteristics).CopyTo(data, offset + 36); + } + } +} diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/Section/Utils.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/Utils.cs new file mode 100644 index 00000000..14adec68 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/Section/Utils.cs @@ -0,0 +1,11 @@ +namespace UCP.Model.Patching.Section +{ + internal class Utils + { + internal static uint GetMultiples(uint size, uint mult) + { + uint num = size + mult - 1; + return num - num % mult; + } + } +} diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/DefaultSubChange.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/DefaultSubChange.cs new file mode 100644 index 00000000..6291864e --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/DefaultSubChange.cs @@ -0,0 +1,25 @@ +using UCP.Model; + +namespace UCP.Patching +{ + public class DefaultSubChange : SubChange + { + Change parent; + public Change Parent => parent; + public virtual void SetParent(Change change) + { + this.parent = change; + } + + string identifier; + public string Identifier => identifier; + + public bool IsEnabled { get; set; } + + public DefaultSubChange(string identifier) + { + this.identifier = identifier; + this.IsEnabled = false; + } + } +} diff --git a/UnofficialCrusaderPatch/Patching/Headers/ChangeHeader.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/SubChange.cs similarity index 93% rename from UnofficialCrusaderPatch/Patching/Headers/ChangeHeader.cs rename to UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/SubChange.cs index d290f0c7..bfde2bd1 100644 --- a/UnofficialCrusaderPatch/Patching/Headers/ChangeHeader.cs +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/SubChange.cs @@ -3,7 +3,7 @@ namespace UCP.Patching { - public class ChangeHeader : IEnumerable + public class SubChange : IEnumerable { LabelCollection labels = new LabelCollection(); public LabelCollection Labels => labels; diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/ValuedSubChange.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/ValuedSubChange.cs new file mode 100644 index 00000000..f8a7facc --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/SubChanges/ValuedSubChange.cs @@ -0,0 +1,17 @@ +using UCP.Model; + +namespace UCP.Patching +{ + public class ValuedSubChange : DefaultSubChange + { + public ValuedSubChange(string identifier) : base(identifier) + { + } + + public override void SetParent(Change change) + { + base.SetParent(change); + } + public double Value { get; set; } + } +} diff --git a/UnofficialCrusaderPatch/Model/Patching/Utils/UI_Text.cs b/UnofficialCrusaderPatch/Model/Patching/Utils/UI_Text.cs new file mode 100644 index 00000000..7fabcdbd --- /dev/null +++ b/UnofficialCrusaderPatch/Model/Patching/Utils/UI_Text.cs @@ -0,0 +1,116 @@ +using System; +using System.Text; + +namespace UCP.Patching +{ + public class UI_Text + { + /** + * Alpha. 0 is 0% transparency. + */ + protected byte alpha = 0x00; + + /** + * Font size. + */ + protected byte fontSize = 0x12; + + /** + * Color in hexadecimal. + */ + protected int color = 0x00C00200; + + /** + * Width of the textbox. + */ + protected int width = 200; + + /** + * X position. + */ + protected int y = 0; + + /** + * Y position. + */ + protected int x = 0; + + + private string text; + private string label; + + + public UI_Text(string label, string text) + { + this.text = text; + this.label = label; + } + + public UI_Text SetAlpha(byte value) + { + alpha = value; + return this; + } + + public UI_Text SetColor(int value) + { + color = value; + return this; + } + + public UI_Text SetFontSize(byte value) + { + fontSize = value; + return this; + } + + public UI_Text SetWidth(int value) + { + width = value; + return this; + } + + public UI_Text SetXPosition(int value) + { + x = value; + return this; + } + + public UI_Text SetYPosition(int value) + { + y = value; + return this; + } + + public BinAlloc GetData() + { + return new BinAlloc(label, null) + { + new BinAlloc(label+"TEXT", null) + { + // Choose your color + Encoding.ASCII.GetBytes(text), + 0x00, 0x00, 0x00, 0x00, + }, + + 0x6A, alpha, + 0x6A, fontSize, + 0x68, BitConverter.GetBytes(color), + 0x68, BitConverter.GetBytes(width), // push 000000A5 { 165 } + 0xB9, BitConverter.GetBytes(y), // mov ecx,00000200 { 512 } + 0x51, // push ecx + 0xBF, BitConverter.GetBytes(x), // mov edi,00000180 { 384 } + 0x57, // push edi + 0x6A, 0x00, // push 00 { 0 } + 0x6A, 0x00, // push 00 { 0 } + 0xB9, 0x78, 0x75, 0x15, 0x02, // mov ecx,"Stronghold Crusader.exe"+1D57578 { [000000B1] } + 0xFF, 0x15, new BinRefTo("TextRenderer1", false), // call "Stronghold Crusader.exe"+6A050 { ->Stronghold Crusader.exe+6A050 } + 0xB8, new BinRefTo(label+"TEXT", false), + 0x50, // push eax + 0xB9, 0x78, 0x75, 0x15, 0x02, // mov ecx,"Stronghold Crusader.exe"+1D57578 { [000000B1] } + 0xFF, 0x15, new BinRefTo("TextRenderer2", false), // call "Stronghold Crusader.exe"+73A70 { ->Stronghold Crusader.exe+73A70 } + 0xC3 // ret + }; + } + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/SelectionParameter.cs b/UnofficialCrusaderPatch/Model/SelectionParameter.cs new file mode 100644 index 00000000..3f8504d5 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/SelectionParameter.cs @@ -0,0 +1,6 @@ +namespace UCP.Model +{ + public interface SelectionParameter + { + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/SelectionType.cs b/UnofficialCrusaderPatch/Model/SelectionType.cs new file mode 100644 index 00000000..52f1a9a3 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/SelectionType.cs @@ -0,0 +1,6 @@ +namespace UCP.Model +{ + public enum SelectionType + { + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/StartResourceConfiguration.cs b/UnofficialCrusaderPatch/Model/StartResourceConfiguration.cs new file mode 100644 index 00000000..8ff6d878 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/StartResourceConfiguration.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace UCP.Model +{ + public class StartResourceConfiguration + { + public Dictionary Description { get; set; } + + public StartResourceConfiguration withDescription(Dictionary description) + { + this.Description = description; + return this; + } + } +} diff --git a/UnofficialCrusaderPatch/Model/StartTroopConfiguration.cs b/UnofficialCrusaderPatch/Model/StartTroopConfiguration.cs new file mode 100644 index 00000000..27ed8ffa --- /dev/null +++ b/UnofficialCrusaderPatch/Model/StartTroopConfiguration.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace UCP.Model +{ + public class StartTroopConfiguration + { + public Dictionary Description { get; set; } + + public StartTroopConfiguration withDescription(Dictionary description) + { + this.Description = description; + return this; + } + } +} diff --git a/UnofficialCrusaderPatch/Model/UIConfig.cs b/UnofficialCrusaderPatch/Model/UIConfig.cs new file mode 100644 index 00000000..b4832743 --- /dev/null +++ b/UnofficialCrusaderPatch/Model/UIConfig.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; + +namespace UCP.Model +{ + public class UCPConfig + { + public string schema; + public string hash = BitConverter.ToString(SHA256.Create().ComputeHash(Encoding.ASCII.GetBytes(Environment.MachineName))); + public string Path; + public string AIV; + public string StartTroop; + public string StartResource; + public List GenericMods; + public object AIC; + + public UCPConfig withAIV(string AIV) + { + this.AIV = AIV; + return this; + } + + public UCPConfig withStartTroop(string startTroop) + { + this.StartTroop = startTroop; + return this; + } + + public UCPConfig withStartResource(string startResource) + { + this.StartResource = startResource; + return this; + } + + public UCPConfig withGenericMods(List genericMods) + { + this.GenericMods = genericMods; + return this; + } + + public UCPConfig withAIC(object aic) + { + this.AIC = aic; + return this; + } + + public UCPConfig withPath(string path) + { + this.Path = path; + return this; + } + + public UCPConfig withSchema(string schema) + { + this.schema = schema; + return this; + } + + public UCPConfig withHash(string hash) + { + this.hash = hash; + return this; + } + } +} diff --git a/UnofficialCrusaderPatch/Patching/Changes/Change.cs b/UnofficialCrusaderPatch/Patching/Changes/Change.cs deleted file mode 100644 index 1b9cfcaf..00000000 --- a/UnofficialCrusaderPatch/Patching/Changes/Change.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace UCP.Patching -{ - public class Change : IEnumerable - { - public bool NoLocalization = false; - Func>, DefaultHeader> multiChange; - string titleIdent; - public string TitleIdent => titleIdent; - public string GetTitle() { return NoLocalization ? titleIdent : Localization.Get(titleIdent); } - - ChangeType type; - public ChangeType Type => type; - - bool exclusive, enabledDefault; - public bool EnabledDefault => enabledDefault; - List headerList = new List(); - - public IEnumerator GetEnumerator() => headerList.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); - - public void Add(DefaultHeader header) - { - headerList.Add(header); - header.SetParent(this); - } - - public Change(string titleIdent, ChangeType type, bool enabledDefault = true, bool exclusive = true, Func>, ParamHeader> multiChange = null) - { - this.type = type; - this.titleIdent = titleIdent; - this.exclusive = exclusive; - this.enabledDefault = enabledDefault; - this.multiChange = multiChange; - } - - public virtual void Activate(ChangeArgs args) - { - if (multiChange != null) - { - Dictionary> parameters = new Dictionary>(); - foreach (var header in headerList) - { - parameters.Add(header.DescrIdent, new Dictionary() - { - { "isEnabled", header.IsEnabled }, - { "value", (object)header is ValueHeader && header.IsEnabled ? (header as ValueHeader).Value : (object)header.IsEnabled } - }); - } - multiChange(parameters).Activate(args); - return; - } - foreach (var header in headerList) - { - if (header.IsEnabled) - header.Activate(args); - } - } - - public override string ToString() - { - string str = TitleIdent + "={ "; - foreach (DefaultHeader h in headerList) - { - str += h.ToString(); - } - str += "}"; - return str; - } - - #region UI - - public void SetUIEnabled(bool enabled) - { - titleBox.IsEnabled = enabled; - headerList.ForEach(h => h.SetUIEnabled(enabled)); - } - - public bool IsChecked - { - get { return headerList.Exists(h => h.IsEnabled); } - set { titleBox.IsChecked = value; } - } - - protected UIElement uiElement; - public UIElement UIElement { get { return this.uiElement; } } - - protected CheckBox titleBox; - protected Grid grid; - - public virtual void InitUI() - { - this.titleBox = new CheckBox() - { - Content = new TextBlock() - { - Text = this.GetTitle(), - TextWrapping = TextWrapping.Wrap, - Margin = new Thickness(0, -1, 0, 0), - FontSize = 14, - Width = 400, - }, - IsChecked = headerList.Exists(h => h.IsEnabled), - }; - - TreeViewItem tvi = new TreeViewItem() - { - IsExpanded = false, - Focusable = false, - Header = titleBox, - MinHeight = 22, - }; - - if (headerList.Exists(h => h is ColorHeader)) - { - titleBox.IsEnabled = false; - tvi.MouseDown += (s, e) => tvi.IsExpanded = !tvi.IsExpanded; - } - else - { - titleBox.Checked += TitleBox_Checked; - titleBox.Unchecked += TitleBox_Unchecked; - } - - grid = new Grid() - { - Background = new SolidColorBrush(Color.FromArgb(150, 200, 200, 200)), - Width = 420, - Margin = new Thickness(-18, 5, 0, 0), - Focusable = false, - }; - - FillGrid(grid); - - tvi.Items.Add(grid); - tvi.Items.Add(null); // spacing - - this.uiElement = tvi; - } - - protected virtual void TitleBox_Unchecked(object sender, RoutedEventArgs e) - { - headerList.ForEach(h => h.IsEnabled = false); - - Configuration.Save(this.titleIdent); - } - - bool noCheck = false; - protected virtual void TitleBox_Checked(object sender, RoutedEventArgs e) - { - if (noCheck) return; - headerList.ForEach(h => h.IsEnabled = h.DefaultIsEnabled); - noCheck = true; - titleBox.IsChecked = this.IsChecked; - noCheck = false; - - Configuration.Save(this.titleIdent); - } - - protected void FillGrid(Grid grid) - { - bool singleDefault = headerList.Count == 1 && headerList[0].GetType() == typeof(DefaultHeader); - - double height = 5; - for (int i = 0; i < headerList.Count; i++) - { - var header = headerList[i]; - - if (!singleDefault) - { - header.OnEnabledChange += Header_OnEnable; - - // ui element - var uiElement = header.InitUI(headerList.Count > 1); - uiElement.HorizontalAlignment = HorizontalAlignment.Left; - uiElement.VerticalAlignment = VerticalAlignment.Top; - uiElement.Margin = new Thickness(6, height, 0, 0); - height += uiElement.Height + 5; - - grid.Children.Add(uiElement); - } - - string headerDescr = header.NoLocalization ? header.DescrIdent : Localization.Get(header.DescrIdent + "_descr"); - if (!string.IsNullOrWhiteSpace(headerDescr)) - { - // Description - TextBlock description = new TextBlock() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - Margin = new Thickness(6, height, 0, 0), - TextWrapping = TextWrapping.Wrap, - FontSize = 13, - Width = grid.Width - 12, - }; - - TextReferencer.SetText(description, headerDescr); - grid.Children.Add(description); - height += description.MeasureHeight(); - - if (i != headerList.Count - 1) - height += 22; - } - } - grid.Height = height + 10; - } - - void Header_OnEnable(DefaultHeader header, bool enabled) - { - if (this.exclusive && enabled) - { - foreach (DefaultHeader h in headerList) - if (h != header) - h.IsEnabled = false; - } - - bool newChecked = this.IsChecked; - if (this.titleBox.IsChecked != newChecked) - { - noCheck = true; - this.titleBox.IsChecked = newChecked; - noCheck = false; - } - } - - #endregion - } -} diff --git a/UnofficialCrusaderPatch/Patching/Headers/ColorHeader.cs b/UnofficialCrusaderPatch/Patching/Headers/ColorHeader.cs deleted file mode 100644 index 28ea745d..00000000 --- a/UnofficialCrusaderPatch/Patching/Headers/ColorHeader.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -namespace UCP.Patching -{ - public class ColorHeader : ValueHeader - { - public ColorHeader(string descrIdent) - : base(descrIdent, false, 1, 1) - { - } - - static readonly List Colors = new List() - { - Color.FromArgb(255, 240, 32, 0), // red - Color.FromArgb(255, 248, 120, 0), // orange - Color.FromArgb(255, 224, 224, 0), // yellow - Color.FromArgb(255, 0, 0, 248), // blue - Color.FromArgb(255, 80, 80, 80), // black - Color.FromArgb(255, 184, 0, 248), // purple - Color.FromArgb(255, 0, 208, 240), // light blue - Color.FromArgb(255, 0, 216, 0) // green - }; - - Image focus; - const int ButtonSpacing = 53; - - List buttons = new List(); - public override void SetUIEnabled(bool enabled) - { - base.SetUIEnabled(enabled); - buttons.ForEach(b => b.IsEnabled = enabled); - } - - protected override FrameworkElement CreateUI() - { - Grid grid = new Grid() - { - Width = 410, - Height = 30, - }; - - focus = new Image() - { - Source = new BitmapImage(new Uri("pack://application:,,,/UnofficialCrusaderPatch;component/Graphics/shield.png")), - Margin = new Thickness(7, 4, 0, 0), - Width = 22, - Height = 22, - }; - - Canvas canvas = new Canvas(); - canvas.Children.Add(focus); - - grid.Children.Add(canvas); - - for (int i = 0; i < 8; i++) - { - Border button = new Border() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - Margin = new Thickness(i * ButtonSpacing, 0, 0, 0), - BorderThickness = new Thickness(1, 1, 1, 1), - BorderBrush = Brushes.Black, - Background = new SolidColorBrush(Colors[i]), - Height = 30, - Width = 38, - }; - - int value = i + 1; - button.MouseUp += (s, e) => SetValue(value); - - grid.Children.Insert(0, button); - buttons.Add(button); - } - - this.OnValueChange += ValueChange; - ValueChange(); - - return grid; - } - - void ValueChange() - { - Canvas.SetLeft(focus, ButtonSpacing * (this.Value - 1)); - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Headers/DefaultHeader.cs b/UnofficialCrusaderPatch/Patching/Headers/DefaultHeader.cs deleted file mode 100644 index fc00fd26..00000000 --- a/UnofficialCrusaderPatch/Patching/Headers/DefaultHeader.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; - -namespace UCP.Patching -{ - public class DefaultHeader : ChangeHeader - { - public bool NoLocalization = false; - - Change parent; - public Change Parent => parent; - public virtual void SetParent(Change change) - { - this.parent = change; - this.isEnabled = parent.EnabledDefault && this.DefaultIsEnabled; - } - - string descrIdent; - public string DescrIdent => descrIdent; - public string GetDescription() { return NoLocalization ? descrIdent : Localization.Get(descrIdent); } - - bool defaultIsEnabled; - public bool DefaultIsEnabled => defaultIsEnabled; - - public DefaultHeader(string descrIdent, bool suggested = true, bool noLocalization = false) - { - this.descrIdent = descrIdent; - this.defaultIsEnabled = suggested; - this.NoLocalization = noLocalization; - } - - #region UI - - public virtual void SetUIEnabled(bool enabled) - { - if (box != null) - this.box.IsEnabled = enabled; - } - - public event Action OnEnabledChange; - - CheckBox box; - public CheckBox CheckBox => box; - - public FrameworkElement InitUI(bool createCheckBox) - { - FrameworkElement content = CreateUI(); - if (createCheckBox) - { - box = new CheckBox() - { - IsChecked = isEnabled, - Content = content, - Height = content.Height, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - }; - - box.Checked += Box_Checked; - box.Unchecked += Box_Unchecked; - - return box; - } - return content; - } - - void Box_Unchecked(object sender, RoutedEventArgs e) - { - if (this.IsEnabled) - { - SetEnabled(false); - } - } - - void Box_Checked(object sender, RoutedEventArgs e) - { - if (!this.IsEnabled) - { - SetEnabled(true); - } - } - - protected virtual FrameworkElement CreateUI() - { - return new TextBlock() - { - Text = this.GetDescription(), - Height = 16, - }; - } - - bool isEnabled; - public virtual bool IsEnabled - { - get => isEnabled; - set - { - if (isEnabled == value) - return; - - isEnabled = value; - - if (box != null) - box.IsChecked = value; - } - } - - protected void SetEnabled(bool enabled) - { - if (IsEnabled == enabled) - return; - - IsEnabled = enabled; - OnEnabledChange?.Invoke(this, enabled); - Configuration.Save(this.Parent.TitleIdent); - } - - #endregion - - - #region Load & Save - - public virtual string GetValueString() - { - return this.isEnabled.ToString(); - } - - public virtual void LoadValueString(string valueStr) - { - if (Boolean.TryParse(valueStr, out bool result)) - { - this.isEnabled = result; - } - } - - public override string ToString() - { - return DescrIdent + "={" + GetValueString() + "} "; - } - - #endregion - } -} diff --git a/UnofficialCrusaderPatch/Patching/Headers/ParamHeader.cs b/UnofficialCrusaderPatch/Patching/Headers/ParamHeader.cs deleted file mode 100644 index 18c0460e..00000000 --- a/UnofficialCrusaderPatch/Patching/Headers/ParamHeader.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Globalization; - -namespace UCP.Patching -{ - public class ParamHeader : DefaultHeader - { - public ParamHeader(string descrIdent) : base(descrIdent, true) - { - } - - public override void SetParent(Change change) - { - base.SetParent(change); - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Headers/SliderHeader.cs b/UnofficialCrusaderPatch/Patching/Headers/SliderHeader.cs deleted file mode 100644 index 82e7dc72..00000000 --- a/UnofficialCrusaderPatch/Patching/Headers/SliderHeader.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace UCP.Patching -{ - public class SliderHeader : ValueHeader - { - double min, max, delta; - - public SliderHeader(string descrIdent, bool isEnabled, double min, double max, double delta, double oriVal, double suggested) - : base(descrIdent, isEnabled, oriVal, suggested) - { - this.min = min; - this.max = max; - this.delta = delta; - } - - Slider slider; - TextBlock sliderText; - - public override void SetUIEnabled(bool enabled) - { - base.SetUIEnabled(enabled); - slider.IsEnabled = enabled; - } - - protected override FrameworkElement CreateUI() - { - const int sliderWidth = 260; - const int sliderHeight = 18; - - Grid grid = new Grid - { - Width = 300, - Height = sliderHeight, - }; - - slider = new Slider() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Top, - Margin = new Thickness(0, 0, 0, 0), - Width = sliderWidth, - Height = sliderHeight, - - Value = this.Value, - IsSnapToTickEnabled = true, - TickFrequency = delta, - Minimum = min, - Maximum = max, - }; - slider.ValueChanged += Slider_ValueChanged; - this.OnValueChange += SliderHeader_OnValueChange; - grid.Children.Add(slider); - - sliderText = new TextBlock() - { - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Center, - Margin = new Thickness(sliderWidth + 5, 0, 0, 0), - Text = this.Value.ToString(), - Height = sliderHeight, - }; - grid.Children.Add(sliderText); - - return grid; - } - - void SliderHeader_OnValueChange() - { - if (this.Value == slider.Value) - return; - - slider.Value = this.Value; - this.sliderText.Text = this.Value.ToString(); - } - - void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) - { - if (this.Value == slider.Value) - return; - - this.SetValue(slider.Value); - this.sliderText.Text = this.Value.ToString(); - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Headers/ValueHeader.cs b/UnofficialCrusaderPatch/Patching/Headers/ValueHeader.cs deleted file mode 100644 index e268c4ca..00000000 --- a/UnofficialCrusaderPatch/Patching/Headers/ValueHeader.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Globalization; - -namespace UCP.Patching -{ - public class ValueHeader : DefaultHeader - { - double oriVal, suggested; - public double OriginalValue => oriVal; - public double SuggestedValue => suggested; - - public ValueHeader(string descrIdent, bool isEnabled, double oriVal, double suggested) : base(descrIdent, isEnabled) - { - this.oriVal = oriVal; - this.suggested = suggested; - } - - public override void SetParent(Change change) - { - base.SetParent(change); - this.value = this.IsEnabled ? suggested : oriVal; - } - - double value; - public double Value => value; - - public override bool IsEnabled - { - get => base.IsEnabled; - set - { - if (this.IsEnabled == value) - return; - - base.IsEnabled = value; - if (IsEnabled) - { - if (this.value == oriVal) - this.SetValue(suggested); - } - else - { - this.SetValue(oriVal); - } - } - } - - protected event Action OnValueChange; - protected void SetValue(double value) - { - try - { - if (this.value == value) - return; - - this.value = value; - - bool enable = value != oriVal; - if (enable != this.IsEnabled) - { - SetEnabled(enable); - } - else - { - Configuration.Save(this.Parent.TitleIdent); - } - - this.OnValueChange?.Invoke(); - } - catch (Exception e) - { - Debug.Show(e, "ay"); - } - } - - public override string GetValueString() - { - return string.Format("{0};{1}", this.IsEnabled, this.value.ToString(CultureInfo.InvariantCulture)); - } - - public override void LoadValueString(string valueStr) - { - int index = valueStr.IndexOf(';'); - if (index < 0) return; - - base.LoadValueString(valueStr.Remove(index)); - - valueStr = valueStr.Substring(index + 1).Trim(); - if (Double.TryParse(valueStr, NumberStyles.Any, CultureInfo.InvariantCulture, out double result)) - this.value = result; - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Patcher.cs b/UnofficialCrusaderPatch/Patching/Patcher.cs deleted file mode 100644 index 6c22886d..00000000 --- a/UnofficialCrusaderPatch/Patching/Patcher.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using UCP.AIC; -using UCP.AIV; -using UCP.Startup; - -namespace UCP.Patching -{ - public static class Patcher - { - public const string BackupIdent = "ucp_backup"; - public const string BackupFileEnding = "." + BackupIdent; - - const string CrusaderExe = "Stronghold Crusader.exe"; - const string XtremeExe = "Stronghold_Crusader_Extreme.exe"; - const string GAME_SEEDS_FOLDER = "gameseeds"; - - /// - /// Test existence of SHC of SHC Extreme executables inside specified directory - /// - /// - /// - public static bool CrusaderExists(string folderPath) - { - if (!Directory.Exists(folderPath)) - return false; - - string path = Path.Combine(folderPath, CrusaderExe); - if (File.Exists(path)) return true; - - path = Path.Combine(folderPath, XtremeExe); - return File.Exists(path); - } - public static void Install(string folderPath, Percentage.SetHandler SetPercent, bool overwrite, bool graphical) - { - Percentage perc = new Percentage(SetPercent); - perc.SetTotal(0); - - perc.NextLimit = 0.1; - - try - { - AIVChange.DoChange(folderPath, overwrite, graphical); - } catch (IOException) { - Debug.Show(Localization.Get("install_abort_io")); - return; - } catch (Exception) - { - Debug.Show(Localization.Get("install_abort")); - return; - } - perc.Set(1.0); - - DoChanges(folderPath, perc); - - perc.SetTotal(1); - } - - public static void RestoreOriginals(string dir) - { - RestoreBinary(dir, CrusaderExe); - RestoreBinary(dir, XtremeExe); - AIVChange.Restore(dir); - } - - // Retrieve path to the original SHC or SHC Extreme binary - static string GetOriginalBinary(string folderPath, string exe) - { - if (Directory.Exists(folderPath)) - { - // remove old file ending from v1.0 - string path = Path.Combine(folderPath, exe + ".ori"); - if (File.Exists(path)) - { - string dest = path.Remove(path.Length - ".ori".Length); - File.Delete(dest); - File.Move(path, dest); - } - - path = Path.Combine(folderPath, exe + BackupFileEnding); - if (File.Exists(path)) - return path; - - path = path.Remove(path.Length - BackupFileEnding.Length); - if (File.Exists(path)) - return path; - } - return null; - } - - - static void DoChanges(string folderPath, Percentage perc) - { - string cPath = GetOriginalBinary(folderPath, CrusaderExe); - string ePath = GetOriginalBinary(folderPath, XtremeExe); - - if (cPath != null) - { - perc.NextLimit = ePath == null ? 1.0 : 0.55; - DoBinaryChanges(cPath, false, perc); - } - - if (ePath != null) - { - perc.NextLimit = 1; - DoBinaryChanges(ePath, true, perc); - } - } - - - static void DoBinaryChanges(string filePath, bool xtreme, Percentage perc) - { - fails.Clear(); - SectionEditor.Reset(); - - string gameSeedsFolder = Path.Combine(Configuration.Path, GAME_SEEDS_FOLDER); - - if (!Directory.Exists(gameSeedsFolder)) - { - Directory.CreateDirectory(gameSeedsFolder); - } - - // Retrieve set of selected binary changes - var changes = Version.Changes.Where(c => c.IsChecked && c is Change && !(c is ResourceChange) && !(c is StartTroopChange)); - List todoList = new List(changes); - - int todoIndex = 0; - double todoCount = 9 + todoList.Count; // +2 for AIprops +3 for read, +1 for version edit, +3 for writing data - - // Read original data & perform section preparation adding .ucp section to binary - byte[] oriData = File.ReadAllBytes(filePath); - byte[] data = (byte[])oriData.Clone(); - SectionEditor.Init(data); - todoIndex += 3; - - perc.Set(todoIndex / todoCount); - - ChangeArgs args = new ChangeArgs(data, oriData); - - // Change version display in main menu - try - { - (xtreme ? Version.MenuChange_XT : Version.MenuChange).Activate(args); - } - catch (Exception e) - { - Debug.Error(e); - } - perc.Set(++todoIndex / todoCount); - - // Apply each selected binary change - foreach (Change change in todoList) - { - change.Activate(args); - perc.Set(++todoIndex / todoCount); - } - - // Apply changes handled in their respective submodules - AICChange.DoChange(args); - StartTroopChange.DoChange(args); - ResourceChange.DoChange(args); - - todoIndex += 2; - perc.Set(todoIndex / todoCount); - - - - // Write everything to file - data = SectionEditor.AttachSection(data); - - if (filePath.EndsWith(BackupFileEnding)) - { - filePath = filePath.Remove(filePath.Length - BackupFileEnding.Length); - } - else - { - File.WriteAllBytes(filePath + BackupFileEnding, oriData); // create backup - } - File.WriteAllBytes(filePath, data); - - perc.Set(1); - - ShowFailures(filePath); - } - - /// - /// Rename the backed-up version of SHC and/or SHC Extreme executable - /// - /// - /// - static void RestoreBinary(string dir, string exe) - { - string oriPath = Path.Combine(dir, exe); - string backupPath = oriPath + BackupFileEnding; - if (File.Exists(backupPath)) - { - if (File.Exists(oriPath)) - File.Delete(oriPath); - - File.Move(backupPath, oriPath); - } - } - - static void ShowFailures(string filePath) - { - if (fails.Count > 0) - { - StringBuilder sb = new StringBuilder(); - sb.Append("Version Differences in "); - sb.Append(Path.GetFileName(filePath)); - sb.AppendLine(":"); - foreach (var f in fails) - sb.AppendLine(f.Ident + " " + f.Type); - - fails.Clear(); - Debug.Show(sb.ToString()); - } - } - - struct EditFail - { - public string Ident; - public EditFailure Type; - } - static readonly List fails = new List(); - public static void AddFailure(string ident, EditFailure failure) - { - fails.Add(new EditFail(){ Ident=ident, Type=failure }); - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Percentage.cs b/UnofficialCrusaderPatch/Patching/Percentage.cs deleted file mode 100644 index bee71925..00000000 --- a/UnofficialCrusaderPatch/Patching/Percentage.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; - -namespace UCP.Patching -{ - /// - /// Percentage handler which can be given limits for subdividing - /// - public class Percentage - { - SetHandler handler; - public delegate void SetHandler(double percent); - public Percentage(SetHandler handler) - { - this.handler = handler; - } - - double nextLimit; - public double NextLimit - { - get { return this.nextLimit; } - set - { - this.lastLimit = total; - this.nextLimit = value; - if (nextLimit < lastLimit) - throw new Exception("value < lastLimit"); - } - } - - double lastLimit; - public double LastLimit { get { return lastLimit; } } - - double total; - public double Total { get { return total; } } - public void SetTotal(double value) - { - this.total = value; - if (handler != null) - { - handler.Invoke(value); - } - } - - public void Set(double value) - { - SetTotal((NextLimit - LastLimit) * value + LastLimit); - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Section/PEHeader.cs b/UnofficialCrusaderPatch/Patching/Section/PEHeader.cs deleted file mode 100644 index feb82fee..00000000 --- a/UnofficialCrusaderPatch/Patching/Section/PEHeader.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace UCP.Patching -{ - public static partial class SectionEditor - { - class PEHeader - { - int offset; - ushort numberOfSections; - public ushort NumberOfSections => numberOfSections; - - uint sectionAlignment; - public uint SectionAlignment => sectionAlignment; - - uint fileAlignment; - public uint FileAlignment => fileAlignment; - - List sections; - public IEnumerable Sections => sections; - - public PEHeader(byte[] input, int offset) - { - this.offset = offset; - - numberOfSections = BitConverter.ToUInt16(input, offset + 0x06); - sectionAlignment = BitConverter.ToUInt32(input, offset + 0x38); - fileAlignment = BitConverter.ToUInt32(input, offset + 0x3C); - - sections = new List(numberOfSections); - for (int i = 0; i < numberOfSections; i++) - { - sections.Add(new SectionHeader(input, offset + 0xF8 + SectionHeader.HeaderSize * i)); - } - } - - public static PEHeader Find(byte[] input) - { - int index = input.FindIndex(0x4550); // "PE" - return index < 0 ? null : new PEHeader(input, index); - } - - public byte[] AddSection(byte[] input, SectionHeader sec) - { - // make space - byte[] data = new byte[sec.RawAddr + sec.RawSize]; - Buffer.BlockCopy(input, 0, data, 0, (int)sec.RawAddr); - - // number of sections - ushort sectionCount = (ushort)(this.NumberOfSections + 1); - BitConverter.GetBytes(sectionCount).CopyTo(data, offset + 0x06); - - // size of image - uint imageSize = sec.VirtAddr + GetMultiples(sec.VirtSize, sectionAlignment); - BitConverter.GetBytes(imageSize).CopyTo(data, offset + 0x50); - - sec.Write(data, offset + 0xF8 + SectionHeader.HeaderSize * this.NumberOfSections); - - return data; - } - } - } -} diff --git a/UnofficialCrusaderPatch/Patching/Section/SectionHeader.cs b/UnofficialCrusaderPatch/Patching/Section/SectionHeader.cs deleted file mode 100644 index be6e42c7..00000000 --- a/UnofficialCrusaderPatch/Patching/Section/SectionHeader.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Text; - -namespace UCP.Patching -{ - - public static partial class SectionEditor - { - class SectionHeader - { - public const int HeaderSize = 40; - public const int NameLength = 8; - - public string GetNameStr() - { - return Encoding.ASCII.GetString(Name); - } - - public void SetNameStr(string nameStr) - { - byte[] buf = Encoding.ASCII.GetBytes(nameStr); - Buffer.BlockCopy(buf, 0, this.Name, 0, buf.Length); - for (int i = buf.Length; i < NameLength; i++) - this.Name[i] = 0; - } - - public readonly byte[] Name = new byte[NameLength]; - public uint VirtSize; - public uint VirtAddr; - public uint RawSize; - public uint RawAddr; - public uint RelocAddr; - public uint LineNums; - public ushort RelocNum; - public ushort LineNumsNum; - public uint Characteristics; - - public SectionHeader(string nameStr) - { - SetNameStr(nameStr); - } - - public SectionHeader(byte[] data, int offset) - { - Buffer.BlockCopy(data, offset, Name, 0, NameLength); - - VirtSize = BitConverter.ToUInt32(data, offset + 8); - VirtAddr = BitConverter.ToUInt32(data, offset + 12); - RawSize = BitConverter.ToUInt32(data, offset + 16); - RawAddr = BitConverter.ToUInt32(data, offset + 20); - RelocAddr = BitConverter.ToUInt32(data, offset + 24); - LineNums = BitConverter.ToUInt32(data, offset + 28); - RelocNum = BitConverter.ToUInt16(data, offset + 32); - LineNumsNum = BitConverter.ToUInt16(data, offset + 34); - Characteristics = BitConverter.ToUInt32(data, offset + 36); - } - - public void Write(byte[] data, int offset) - { - Buffer.BlockCopy(Name, 0, data, offset, NameLength); - - BitConverter.GetBytes(VirtSize).CopyTo(data, offset + 8); - BitConverter.GetBytes(VirtAddr).CopyTo(data, offset + 12); - BitConverter.GetBytes(RawSize).CopyTo(data, offset + 16); - BitConverter.GetBytes(RawAddr).CopyTo(data, offset + 20); - BitConverter.GetBytes(RelocAddr).CopyTo(data, offset + 24); - BitConverter.GetBytes(LineNums).CopyTo(data, offset + 28); - BitConverter.GetBytes(RelocNum).CopyTo(data, offset + 32); - BitConverter.GetBytes(LineNumsNum).CopyTo(data, offset + 34); - BitConverter.GetBytes(Characteristics).CopyTo(data, offset + 36); - } - } - } -} diff --git a/UnofficialCrusaderPatch/AIC/Resources/descriptions.json b/UnofficialCrusaderPatch/Resources/AIC/descriptions.json similarity index 100% rename from UnofficialCrusaderPatch/AIC/Resources/descriptions.json rename to UnofficialCrusaderPatch/Resources/AIC/descriptions.json diff --git a/UnofficialCrusaderPatch/AIC/Resources/errors.json b/UnofficialCrusaderPatch/Resources/AIC/errors.json similarity index 100% rename from UnofficialCrusaderPatch/AIC/Resources/errors.json rename to UnofficialCrusaderPatch/Resources/AIC/errors.json diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_access.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_access.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_access.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_access.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_addattack.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_addattack.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_addattack.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_addattack.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_addattack_alt.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_addattack_alt.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_addattack_alt.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_addattack_alt.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_assaultswitch.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_assaultswitch.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_assaultswitch.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_assaultswitch.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_attacklimit.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attacklimit.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_attacklimit.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attacklimit.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_attacktarget.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attacktarget.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_attacktarget.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attacktarget.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_attackwave.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attackwave.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_attackwave.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attackwave.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_attackwave_lord.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attackwave_lord.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_attackwave_lord.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attackwave_lord.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_attackwave_wallcount.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attackwave_wallcount.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_attackwave_wallcount.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_attackwave_wallcount.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_buildhousing.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_buildhousing.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_buildhousing.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_buildhousing.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_buywood.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_buywood.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_buywood.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_buywood.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_defense_affinity.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_affinity.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_defense_affinity.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_affinity.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_defense_check.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_check.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_defense_check.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_check.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_defense_count.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_count.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_defense_count.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_count.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_defense_group.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_group.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_defense_group.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_group.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_defense_reset.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_reset.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_defense_reset.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_defense_reset.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_deletehousing.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_deletehousing.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_deletehousing.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_deletehousing.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_demolish_eco.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_demolish_eco.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_demolish_eco.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_demolish_eco.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_demolish_trapped.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_demolish_trapped.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_demolish_trapped.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_demolish_trapped.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_demolish_walls.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_demolish_walls.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_demolish_walls.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_demolish_walls.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_fix_crusader_archers_pitch.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_crusader_archers_pitch.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_fix_crusader_archers_pitch.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_crusader_archers_pitch.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_fix_crusader_archers_pitch_attr.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_crusader_archers_pitch_attr.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_fix_crusader_archers_pitch_attr.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_crusader_archers_pitch_attr.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_fix_crusader_archers_pitch_fn.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_crusader_archers_pitch_fn.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_fix_crusader_archers_pitch_fn.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_crusader_archers_pitch_fn.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_fix_laddermen_with_enclosed_keep.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_laddermen_with_enclosed_keep.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_fix_laddermen_with_enclosed_keep.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_fix_laddermen_with_enclosed_keep.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_foodbuy_wazir.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_foodbuy_wazir.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_foodbuy_wazir.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_foodbuy_wazir.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_nosleep.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_nosleep.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_nosleep.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_nosleep.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_overclock.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_overclock.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_overclock.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_overclock.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_prop.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_prop.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_prop.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_prop.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_rebuildtowers.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_rebuildtowers.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_rebuildtowers.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_rebuildtowers.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_rebuildwalls.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_rebuildwalls.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_rebuildwalls.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_rebuildwalls.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_recruitinterval.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_recruitinterval.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_recruitinterval.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_recruitinterval.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_recruitsleep.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_recruitsleep.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_recruitsleep.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_recruitsleep.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_recruitstate_initialtimer.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_recruitstate_initialtimer.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_recruitstate_initialtimer.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_recruitstate_initialtimer.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_tethers.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_tethers.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_tethers.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_tethers.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_towerengines.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_towerengines.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_towerengines.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_towerengines.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_abbot.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_abbot.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_abbot.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_abbot.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_emir.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_emir.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_emir.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_emir.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_frederick.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_frederick.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_frederick.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_frederick.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_marshal.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_marshal.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ai_wepbuy_marshal.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ai_wepbuy_marshal.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/fix_apple_orchard_build_size.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/fix_apple_orchard_build_size.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/fix_apple_orchard_build_size.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/fix_apple_orchard_build_size.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/laddermadness.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/laddermadness.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/laddermadness.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/laddermadness.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/menuversion.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/menuversion.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/menuversion.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/menuversion.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix3.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix3.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix3.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix3.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix4.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix4.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix4.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix4.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix5.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix5.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_armory_marketplace_weapon_order_fix5.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_armory_marketplace_weapon_order_fix5.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_catapult.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_catapult.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_catapult.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_catapult.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_fireballista.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_fireballista.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_fireballista.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_fireballista.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_ram.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_ram.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_ram.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_ram.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_shield.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_shield.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_shield.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_shield.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_tower.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_tower.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_tower.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_tower.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_trebutchet.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_trebutchet.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_change_siege_engine_spawn_position_trebutchet.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_change_siege_engine_spawn_position_trebutchet.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_default_multiplayer_speed.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_default_multiplayer_speed.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_default_multiplayer_speed.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_default_multiplayer_speed.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_default_multiplayer_speed_reset.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_default_multiplayer_speed_reset.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_default_multiplayer_speed_reset.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_default_multiplayer_speed_reset.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_engineertent.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_engineertent.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_engineertent.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_engineertent.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_firecooldown.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_firecooldown.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_firecooldown.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_firecooldown.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_baker_disappear.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_baker_disappear.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_baker_disappear.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_baker_disappear.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_fletcher_bug.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_fletcher_bug.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_fletcher_bug.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_fletcher_bug.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_3.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_3.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_3.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_3.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_4.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_4.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_4.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_4.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_pre.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_pre.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_ladderclimb_pre.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_ladderclimb_pre.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_fix_moat_digging_unit_disappearing.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_moat_digging_unit_disappearing.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_fix_moat_digging_unit_disappearing.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_fix_moat_digging_unit_disappearing.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_freetrader.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_freetrader.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_freetrader.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_freetrader.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_gamespeed_down.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_gamespeed_down.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_gamespeed_down.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_gamespeed_down.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_gamespeed_up.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_gamespeed_up.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_gamespeed_up.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_gamespeed_up.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_gatedistance.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_gatedistance.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_gatedistance.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_gatedistance.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_gatetime.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_gatetime.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_gatetime.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_gatetime.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_healer_cmp.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_cmp.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_healer_cmp.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_cmp.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_healer_find.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_find.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_healer_find.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_find.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_healer_jesternext.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_jesternext.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_healer_jesternext.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_jesternext.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_healer_next.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_next.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_healer_next.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_next.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_healer_plague.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_plague.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_healer_plague.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_healer_plague.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_healerroam.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_healerroam.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_healerroam.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_healerroam.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_increase_path_update_tick_rate.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_increase_path_update_tick_rate.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_increase_path_update_tick_rate.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_increase_path_update_tick_rate.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_jesterroam.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_jesterroam.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_jesterroam.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_jesterroam.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_down.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_down.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_down.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_down.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_l.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_l.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_l.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_l.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_loadname.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_loadname.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_loadname.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_loadname.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_menu.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_menu.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_menu.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_menu.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_s.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_s.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_s.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_s.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_savefunc.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_savefunc.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_savefunc.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_savefunc.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_savename.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_savename.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_savename.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_savename.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_keys_up.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_up.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_keys_up.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_keys_up.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_moatvisibility.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_moatvisibility.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_moatvisibility.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_moatvisibility.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_onlyai.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_onlyai.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_onlyai_assassins.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_assassins.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_onlyai_assassins.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_assassins.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_onlyai_face.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_face.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_onlyai_face.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_face.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_onlyai_load1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_load1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_onlyai_load1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_load1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_onlyai_load2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_load2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_onlyai_load2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_load2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_onlyai_reset.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_reset.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_onlyai_reset.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_onlyai_reset.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_override_identity_menu.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_override_identity_menu.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_override_identity_menu.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_override_identity_menu.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_allied_menu_ally_name.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_allied_menu_ally_name.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_allied_menu_ally_name.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_allied_menu_ally_name.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_allied_menu_attack_emblem.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_allied_menu_attack_emblem.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_allied_menu_attack_emblem.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_allied_menu_attack_emblem.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_allied_menu_emblem.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_allied_menu_emblem.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_allied_menu_emblem.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_allied_menu_emblem.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_order_menu_emblem.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_order_menu_emblem.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_order_menu_emblem.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_order_menu_emblem.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_emblem.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_emblem.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_emblem.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_emblem.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_shield.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_shield.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_shield.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_shield.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_shield_enemy_taunt.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_shield_enemy_taunt.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_shield_enemy_taunt.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_shield_enemy_taunt.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_shield_pre.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_shield_pre.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ai_video_message_shield_pre.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ai_video_message_shield_pre.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_chat.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_chat.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_chat.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_chat.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_chat2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_chat2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_chat2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_chat2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_emblem1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_emblem1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_emblem1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_emblem1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_emblem2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_emblem2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_emblem2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_emblem2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_endscore.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_endscore.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_endscore.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_endscore.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_fade.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_fade.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_fade.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_fade.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_gameover.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_gameover.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_gameover.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_gameover.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ingame.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ingame.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_ingame.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_ingame.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_list.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_list.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_list.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_list.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_minilist1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_minilist1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_minilist1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_minilist1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_minilist2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_minilist2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_minilist2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_minilist2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_minimap.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_minimap.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_minimap.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_minimap.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_emblem1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_emblem1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_emblem1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_emblem1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_emblem2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_emblem2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_emblem2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_emblem2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_shield_drag.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_shield_drag.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_shield_drag.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_shield_drag.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_shield_hover.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_shield_hover.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_shield_hover.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_shield_hover.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_shields.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_shields.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_mm_shields.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_mm_shields.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_scorename.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_scorename.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_scorename.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_scorename.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table_back.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table_back.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table_back.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table_back.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table_drag.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table_drag.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_table_drag.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_table_drag.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_name.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_name.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_name.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_name.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_portrait.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_portrait.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_portrait.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_portrait.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_shield.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_shield.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_shield.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_shield.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_shield2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_shield2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trail_shield2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trail_shield2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trebuchet.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trebuchet.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_playercolor_trebuchet.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_playercolor_trebuchet.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech_engine.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech_engine.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech_engine.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech_engine.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech_lord_type.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech_lord_type.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech_lord_type.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech_lord_type.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech_purchase.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech_purchase.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_restore_arabian_engineer_speech_purchase.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_restore_arabian_engineer_speech_purchase.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn3.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn3.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn3.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn3.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn4.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn4.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn4.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn4.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn5.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn5.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_seed_modification_possibility_fn5.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_seed_modification_possibility_fn5.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_beerpopularity.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_beerpopularity.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_beerpopularity.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_beerpopularity.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_beerpopularitytab.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_beerpopularitytab.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_beerpopularitytab.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_beerpopularitytab.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_beertab.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_beertab.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_beertab.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_beertab.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_peasantspawnrate.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_peasantspawnrate.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_peasantspawnrate.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_peasantspawnrate.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_religionpopularity.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_religionpopularity.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_religionpopularity.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_religionpopularity.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_religionpopularitytab.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_religionpopularitytab.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_religionpopularitytab.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_religionpopularitytab.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_religiontab.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_religiontab.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_religiontab.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_religiontab.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_shfy_resourcequantity.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_resourcequantity.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_shfy_resourcequantity.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_shfy_resourcequantity.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_stop_player_keep_rotation.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_stop_player_keep_rotation.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_stop_player_keep_rotation.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_stop_player_keep_rotation.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_stop_player_keep_rotation_get_preferred_relative_orientation.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_stop_player_keep_rotation_get_preferred_relative_orientation.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_stop_player_keep_rotation_get_preferred_relative_orientation.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_stop_player_keep_rotation_get_preferred_relative_orientation.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_trooplimit.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_trooplimit.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_trooplimit.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_trooplimit.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_xtreme_bar1.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_xtreme_bar1.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_xtreme_bar1.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_xtreme_bar1.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/o_xtreme_bar2.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/o_xtreme_bar2.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/o_xtreme_bar2.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/o_xtreme_bar2.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/random.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/random.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/random.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/random.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/s_gold.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/s_gold.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/s_gold.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/s_gold.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/s_lordstrength.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/s_lordstrength.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/s_lordstrength.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/s_lordstrength.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/s_lordtype.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/s_lordtype.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/s_lordtype.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/s_lordtype.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/s_resource.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/s_resource.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/s_resource.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/s_resource.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/s_troops.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/s_troops.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/s_troops.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/s_troops.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_arabwall.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_arabwall.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_arabwall.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_arabwall.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_arabxbow.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_arabxbow.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_arabxbow.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_arabxbow.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_fireballistamonk.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_fireballistamonk.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_fireballistamonk.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_fireballistamonk.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_fireballistatunneler.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_fireballistatunneler.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_fireballistatunneler.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_fireballistatunneler.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_fix_applefarm_blocking.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_fix_applefarm_blocking.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_fix_applefarm_blocking.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_fix_applefarm_blocking.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_fix_lord_animation_stuck_building_attack.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_fix_lord_animation_stuck_building_attack.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_fix_lord_animation_stuck_building_attack.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_fix_lord_animation_stuck_building_attack.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_fix_lord_animation_stuck_movement.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_fix_lord_animation_stuck_movement.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_fix_lord_animation_stuck_movement.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_fix_lord_animation_stuck_movement.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_ladderarmor_bow.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_ladderarmor_bow.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_ladderarmor_bow.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_ladderarmor_bow.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_ladderarmor_sling.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_ladderarmor_sling.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_ladderarmor_sling.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_ladderarmor_sling.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_ladderarmor_xbow.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_ladderarmor_xbow.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_ladderarmor_xbow.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_ladderarmor_xbow.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_laddergold.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_laddergold.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_laddergold.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_laddergold.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_spearbow.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_spearbow.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_spearbow.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_spearbow.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_spearmen_run.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_spearmen_run.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_spearmen_run.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_spearmen_run.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_spearxbow.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_spearxbow.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_spearxbow.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_spearxbow.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/u_tanner_fix.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/u_tanner_fix.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/u_tanner_fix.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/u_tanner_fix.block diff --git a/UnofficialCrusaderPatch/CodeBlocks/ui_fix_laddermen_cost_display_in_engineers_guild.block b/UnofficialCrusaderPatch/Resources/CodeBlocks/ui_fix_laddermen_cost_display_in_engineers_guild.block similarity index 100% rename from UnofficialCrusaderPatch/CodeBlocks/ui_fix_laddermen_cost_display_in_engineers_guild.block rename to UnofficialCrusaderPatch/Resources/CodeBlocks/ui_fix_laddermen_cost_display_in_engineers_guild.block diff --git a/UnofficialCrusaderPatch/Startup/ResourceView.cs b/UnofficialCrusaderPatch/Startup/ResourceView.cs deleted file mode 100644 index 562e2f16..00000000 --- a/UnofficialCrusaderPatch/Startup/ResourceView.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Imaging; - -namespace UCP.Startup -{ - public class ResourceView - { - public void InitUI(Grid grid, RoutedPropertyChangedEventHandler SelectionDisabler) - { - TreeView view = new TreeView() - { - Background = null, - BorderThickness = new Thickness(0, 0, 0, 0), - Focusable = false, - Name = "ResourceView" - }; - view.SelectedItemChanged += SelectionDisabler; - - foreach (ResourceChange change in ResourceChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - grid.Children.Add(view); - Button button = new Button - { - ToolTip = "Reload configs", - Width = 20, - Height = 20, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Bottom, - Margin = new Thickness(0, 0, 20, 5), - Content = new Image() - { - Source = new BitmapImage(new Uri("pack://application:,,,/UnofficialCrusaderPatchGUI;component/Graphics/refresh.png")), - } - }; - grid.Children.Add(button); - button.Click += (s, e) => Refresh(s, e, view); - } - - private void Refresh(object s, RoutedEventArgs e, TreeView view) - { - String activeChange = ResourceChange.activeChange == null ? String.Empty : ResourceChange.activeChange.TitleIdent; - for (int i = 0; i < ResourceChange.changes.Count; i++) - { - view.Items.Remove(ResourceChange.changes.ElementAt(i).UIElement); - Localization.Remove(ResourceChange.changes.ElementAt(i) + "_descr"); - } - ResourceChange.Refresh(s, e); - foreach (ResourceChange change in ResourceChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - - if (ResourceChange.changes.Select(x => x.TitleIdent).Contains(activeChange)) - { - foreach (ResourceChange change in ResourceChange.changes) - { - if (change.TitleIdent == activeChange) - { - change.IsChecked = true; - } - } - } - } - } -} diff --git a/UnofficialCrusaderPatch/Startup/StartTroopView.cs b/UnofficialCrusaderPatch/Startup/StartTroopView.cs deleted file mode 100644 index 9774255f..00000000 --- a/UnofficialCrusaderPatch/Startup/StartTroopView.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Imaging; - -namespace UCP.Startup -{ - public class StartTroopView - { - public void InitUI(Grid grid, RoutedPropertyChangedEventHandler SelectionDisabler) - { - TreeView view = new TreeView() - { - Background = null, - BorderThickness = new Thickness(0, 0, 0, 0), - Focusable = false, - }; - view.SelectedItemChanged += SelectionDisabler; - - foreach (StartTroopChange change in StartTroopChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - grid.Children.Add(view); - Button button = new Button - { - ToolTip = "Reload configs", - Width = 20, - Height = 20, - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Bottom, - Margin = new Thickness(0, 0, 20, 5), - Content = new Image() - { - Source = new BitmapImage(new Uri("pack://application:,,,/UnofficialCrusaderPatchGUI;component/Graphics/refresh.png")), - } - }; - grid.Children.Add(button); - button.Click += (s, e) => Refresh(s, e, view); - } - - private void Refresh(object s, RoutedEventArgs e, TreeView view) - { - String activeChange = StartTroopChange.activeChange == null ? String.Empty : StartTroopChange.activeChange.TitleIdent; - for (int i = 0; i < StartTroopChange.changes.Count; i++) - { - view.Items.Remove(StartTroopChange.changes.ElementAt(i).UIElement); - Localization.Remove(StartTroopChange.changes.ElementAt(i).TitleIdent + "_descr"); - } - StartTroopChange.Refresh(s, e); - foreach (StartTroopChange change in StartTroopChange.changes) - { - change.InitUI(); - view.Items.Add(change.UIElement); - } - - if (StartTroopChange.changes.Select(x => x.TitleIdent).Contains(activeChange)) - { - foreach (StartTroopChange change in StartTroopChange.changes) - { - if (change.TitleIdent == activeChange) - { - change.IsChecked = true; - } - } - } - } - } -} diff --git a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj index b98485a7..1af248d1 100644 --- a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj +++ b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj @@ -55,6 +55,9 @@ OnBuildSuccess + + ..\packages\Newtonsoft.Json.13.0.1\lib\net40\Newtonsoft.Json.dll + @@ -76,79 +79,85 @@ CodeBlocks\CodeBlock.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - @@ -164,215 +173,201 @@ Settings.settings True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ResXFileCodeGenerator Resources.Designer.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + SettingsSingleFileGenerator Settings.Designer.cs - - - - - - - - - - - - - - - - - - - + - + + + + diff --git a/UnofficialCrusaderPatch/Util/Comparators/FileComparer.cs b/UnofficialCrusaderPatch/Util/Comparators/FileComparer.cs new file mode 100644 index 00000000..fc70b5ef --- /dev/null +++ b/UnofficialCrusaderPatch/Util/Comparators/FileComparer.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; + + +namespace UCP.Util.Comparators +{ + // This implementation defines a very simple comparison + // between two FileInfo objects. It only compares the name + // of the files being compared and their length in bytes. + class FileComparer : IEqualityComparer + { + public bool Equals(FileInfo f1, FileInfo f2) + { + return SHA256CheckSum(f1).Equals(SHA256CheckSum(f2)); + } + + // Return a hash that reflects the comparison criteria. According to the + // rules for IEqualityComparer, if Equals is true, then the hash codes must + // also be equal. Because equality as defined here is a simple value equality, not + // reference identity, it is possible that two or more objects will produce the same + // hash code. + public int GetHashCode(FileInfo fi) + { + return SHA256CheckSum(fi).GetHashCode(); + } + + public string SHA256CheckSum(FileInfo fi) + { + using (SHA256 SHA256 = SHA256.Create()) + { + using (FileStream fileStream = fi.OpenRead()) + return Convert.ToBase64String(SHA256.ComputeHash(fileStream)); + } + } + } +} diff --git a/UnofficialCrusaderPatch/Util/Enumerators/AICEnumerator.cs b/UnofficialCrusaderPatch/Util/Enumerators/AICEnumerator.cs new file mode 100644 index 00000000..6bf4b8e7 --- /dev/null +++ b/UnofficialCrusaderPatch/Util/Enumerators/AICEnumerator.cs @@ -0,0 +1,307 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Web.Script.Serialization; +using UCP.Model; +using UCP.Patching; +using UCPAIConversion; + +namespace UCP.AIC +{ + class AICEnumerator + { + static Dictionary errorMessages; + static Dictionary errorHints; + + static List availableSelection { get; } + static Dictionary activeSelection; + + + static Dictionary _changes { get; } + + #region Initialization + static AICEnumerator() + { + activeSelection = new Dictionary(); + availableSelection = new List(); + _changes = new Dictionary(); + + StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.Resources.AIC.errors.json"), Encoding.UTF8); + string errorText = reader.ReadToEnd(); + reader.Close(); + + reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.Resources.AIC.descriptions.json"), Encoding.UTF8); + string errorHintText = reader.ReadToEnd(); + reader.Close(); + + JavaScriptSerializer errorSerializer = new JavaScriptSerializer(); + errorMessages = errorSerializer.Deserialize>(errorText); + errorHints = errorSerializer.Deserialize>(errorHintText); + + try + { + Load(); + } catch (ArgumentException) + { + availableSelection = null; + activeSelection = null; + } + + } + + private static void Load() + { + if (Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "aic"))) + { + List exceptions = new List(); + foreach (string file in Directory.EnumerateFiles(Path.Combine(Environment.CurrentDirectory, "resources", "aic"), "*.json", SearchOption.TopDirectoryOnly)) + { + try + { + LoadAIC(file); + } + catch (Exception) + { + exceptions.Add(file); + } + } + if (exceptions.Count > 0) + { + File.AppendAllText("AICParsing.log", "\n" + "Error loading AIC files: " + String.Join(",", exceptions) + "\n"); + } + } + } + + #endregion + + internal static List GetAICConfiguration() + { + availableSelection.Clear(); + Load(); + return availableSelection; + } + + internal static void SetAICConfiguration(string aicConfiguration) + { + activeSelection.Clear(); + List aiCharacterNames = new List(); + + if (availableSelection.Exists(x => x.Identifier.Equals(aicConfiguration))) + { + aiCharacterNames.AddRange(availableSelection.Single(x => x.Identifier.Equals(aicConfiguration)).CharacterList); + foreach (string name in aiCharacterNames) + { + activeSelection[(AICharacterName)Enum.Parse(typeof(AICharacterName), name)] = aicConfiguration.ToString(); + } + } + } + + internal static void SetAICConfiguration(List aicConfigurationList) + { + activeSelection.Clear(); + List aiCharacterNames = new List(); + + foreach(string aicConfiguration in aicConfigurationList.AsEnumerable().Reverse()) + { + if (availableSelection.Exists(x => x.Identifier.Equals(aicConfiguration))) + { + aiCharacterNames.AddRange(availableSelection.Single(x => x.Identifier.Equals(aicConfiguration)).CharacterList); + foreach (string name in aiCharacterNames) + { + activeSelection[(AICharacterName)Enum.Parse(typeof(AICharacterName), name)] = aicConfiguration.ToString(); + } + } + } + } + + internal static void SetAICConfiguration(object[] aicConfiguration) + { + activeSelection.Clear(); + List aiCharacterNames = new List(); + + foreach (Dictionary aicOption in aicConfiguration) + { + if (!aicOption.ContainsKey("Name") || !aicOption.ContainsKey("Characters")) + { + return; + } + string aicName = aicOption["Name"].ToString(); + if (availableSelection.Exists(x => x.Identifier.Equals(aicName))) + { + foreach (string aiCharacterName in (object[])aicOption["Characters"]) + { + if (availableSelection.Single(x => x.Identifier.Equals(aicName)).CharacterList.Contains(aiCharacterName) && !aiCharacterNames.Contains(aiCharacterName)) + { + aiCharacterNames.Add(aiCharacterName); + activeSelection[(AICharacterName)Enum.Parse(typeof(AICharacterName), aiCharacterName)] = aicName; + } + } + } + } + } + + internal static void SetAICConfiguration(List aicConfiguration) + { + activeSelection.Clear(); + List aiCharacterNames = new List(); + + foreach (AICConfiguration aicOption in aicConfiguration) + { + string aicName = aicOption.Identifier; + if (availableSelection.Exists(x => x.Identifier.Equals(aicName))) + { + foreach (string aiCharacterName in aicOption.CharacterList) + { + if (availableSelection.Single(x => x.Identifier.Equals(aicName)).CharacterList.Contains(aiCharacterName) && !aiCharacterNames.Contains(aiCharacterName)) + { + aiCharacterNames.Add(aiCharacterName); + activeSelection[(AICharacterName)Enum.Parse(typeof(AICharacterName), aiCharacterName)] = aicName; + } + } + } + } + } + + internal static void ResetAICConfiguration() + { + activeSelection.Clear(); + } + + internal static SubChange CreateEdit() + { + if (activeSelection.Count == 0) + { + return null; + } + + List characterChanges = new List(); + + foreach (AICharacterName name in Enum.GetValues(typeof(AICharacterName))) + { + if (!activeSelection.ContainsKey(name)) + { + continue; + } + string changeLocation = activeSelection[name]; + AICChange changeSource; + if (!_changes.TryGetValue(changeLocation, out changeSource)) + { + break; + } + + foreach (AICharacter character in changeSource.collection.AICharacters) + { + if ((AICharacterName)Enum.Parse(typeof(AICharacterName), character.Name.ToString()) == name) + { + characterChanges.Add(character); + break; + } + } + } + + byte[] data; + using (MemoryStream ms = new MemoryStream()) + using (BinaryWriter bw = new BinaryWriter(ms)) + { + foreach (AICharacter aic in characterChanges) + { + // mov eax, index + bw.Write((byte)0xB8); + bw.Write((int)aic._Name * 0x2A4); + + // add eax, esi + bw.Write((byte)0x01); + bw.Write((byte)0xF0); + + // edit AI's properties + for (int i = 0; i < Enum.GetNames(typeof(AIPersonalityFieldsEnum)).Length; i++) + { + string propertyName = Enum.GetName(typeof(AIPersonalityFieldsEnum), i); + PropertyInfo property = typeof(AIPersonality).GetProperty("_" + propertyName); + if (property == null) + { + property = typeof(AIPersonality).GetProperty(propertyName); + } + if (property == null) throw new Exception(propertyName); + object objValue = property.GetValue(aic.Personality, null); + int value = Convert.ToInt32(objValue); + + // mov [eax + prop], value + bw.Write((byte)0xC7); + bw.Write((byte)0x80); + bw.Write((int)(i * 4)); + bw.Write(value); + } + } + data = ms.ToArray(); + } + + // 004D1928 + BinaryEdit be = new BinaryEdit("ai_prop") + { + new BinAddress("call", 0x1B+1, true), + + new BinSkip(0x1B), + new BinHook(5) + { + // ori code + 0xE8, new BinRefTo("call"), + + // edit ais + new BinBytes(data), + } + }; + return new DefaultSubChange("ai_prop") { be }; + } + + private static void LoadAIC(string fileName) + { + JavaScriptSerializer serializer = new JavaScriptSerializer(); + serializer.RegisterConverters(new ReadOnlyCollection(new List() { new AISerializer(errorMessages, errorHints) })); + StreamReader reader = new StreamReader(new FileStream(fileName, FileMode.Open), Encoding.UTF8); + + string text = reader.ReadToEnd(); + reader.Close(); + + string aicName = Path.GetFileNameWithoutExtension(fileName).Replace("UCP.Resources.AIC.", ""); + try + { + if (availableSelection.Exists(x => x.Identifier.Equals(aicName))) + { + throw new Exception("AIC with the same filename has already been loaded"); + } + + AICollection ch = serializer.Deserialize(text); ; + AICChange change = new AICChange(aicName) + { + new DefaultSubChange(aicName) + { + } + }; + change.collection = ch; + change.characters = ch.GetCharacters(); + change.customCharacterNames = ch.GetCustomCharacterNames(); + _changes[aicName] = change; + availableSelection.Add(new AICConfiguration().withIdentifier(aicName) + .withCharacterList(ch.GetCharacters().Select(x => x.ToString()).ToList()) + .withCustomCharacterList(ch.GetCustomCharacterNames().Select(x => x.ToString()).ToList()) + .withDescription(ch.AICShortDescription) + ); + } + catch (AICSerializationException e) + { + File.AppendAllText("AICParsing.log", e.ToErrorString(fileName)); + throw e; + } + catch (Exception e) + { + File.AppendAllText("AICParsing.log", "\n" + aicName + ": " + e.Message + "\n"); + throw e; + } + } + } +} diff --git a/UnofficialCrusaderPatch/Util/Enumerators/AIVEnumerator.cs b/UnofficialCrusaderPatch/Util/Enumerators/AIVEnumerator.cs new file mode 100644 index 00000000..a048bc63 --- /dev/null +++ b/UnofficialCrusaderPatch/Util/Enumerators/AIVEnumerator.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Web.Script.Serialization; +using UCP.Model; +using UCP.Patching; + +namespace UCP.AIV +{ + static class AIVEnumerator + { + static AIVChange activeChange = null; + static List _changes = new List(); + static Dictionary aivConfig; + static AIVChange ActiveChange { get { return activeChange; } } + + static AIVEnumerator() + { + aivConfig = new Dictionary(); + Load(); + } + + private static void Load() + { + try + { + if (Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "aiv"))) + { + foreach (string aivDir in Directory.EnumerateDirectories(Path.Combine(Environment.CurrentDirectory, "resources", "aiv"), "*", SearchOption.TopDirectoryOnly)) + { + _changes.Add(CreateExternal(Path.GetFileName(aivDir.TrimEnd(Path.DirectorySeparatorChar)))); + } + } + } + catch (ArgumentException) + { + aivConfig = null; + } + } + + internal static Dictionary GetAIVConfiguration() + { + _changes.Clear(); + aivConfig.Clear(); + Load(); + ResetAIVConfiguration(); + return aivConfig; + } + + internal static void SetAIVConfiguration(string aivName) + { + activeChange = _changes.Where(x => x.Identifier.Equals(aivName)).ToList().SingleOrDefault(); + } + + internal static void ResetAIVConfiguration() + { + activeChange = null; + } + + internal static void Install(string path, bool overwrite, bool graphical) + { + if (activeChange == null) + { + return; + } + AIVChange change = _changes.Single(x => x.Identifier.Equals(activeChange.Identifier)); + change.CopyAIVs(new DirectoryInfo(Path.Combine(path, "aiv")), overwrite, graphical); + } + + internal static void Uninstall(string path) + { + DirectoryInfo destinationDir = new DirectoryInfo(Path.Combine(path, "aiv")); + DirectoryInfo backupDir = new DirectoryInfo(Path.Combine(destinationDir.FullName, "original")); + if (!backupDir.Exists) + { + return; + } else + { + foreach (FileInfo file in destinationDir.GetFiles()) + { + if (file.Extension.Equals(".aiv")) + { + file.Delete(); + } + } + + foreach (FileInfo file in backupDir.GetFiles()) + { + file.MoveTo(Path.Combine(destinationDir.FullName, Path.GetFileName(file.Name))); + } + backupDir.Delete(); + } + } + + private static AIVChange CreateExternal(string identifier, bool enabledDefault = false) + { + AIVChange change = new AIVChange(identifier).withResFolder(identifier); + change.Add(new DefaultSubChange(identifier) { }); + aivConfig.Add(change.Identifier, new AIVConfiguration().withDescription(GetDescriptions(change.Identifier))); + return change; + } + + private static Dictionary GetDescriptions(string identifier) + { + List Languages = new List() { "English", "German", "Polish", "Russian", "Chinese", "Hungarian" }; + string folderPath = Path.Combine("resources", "aiv", identifier); + + Dictionary descriptions = new Dictionary(); + + foreach(string language in Languages) + { + try + { + descriptions.Add(language, ReadDescription(Path.Combine(folderPath, language))); + } + catch (Exception) + { + continue; + } + } + return descriptions; + } + + private static String ReadDescription(String file) + { + String text = File.ReadAllText(file + ".txt"); + return text.Substring(0, Math.Min(text.Length, 1000)); + } + } +} diff --git a/UnofficialCrusaderPatch/Startup/ResourceChange.cs b/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs similarity index 62% rename from UnofficialCrusaderPatch/Startup/ResourceChange.cs rename to UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs index 0f7e8b6a..6ce83cde 100644 --- a/UnofficialCrusaderPatch/Startup/ResourceChange.cs +++ b/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs @@ -4,16 +4,13 @@ using System.Linq; using System.Reflection; using System.Text; -using System.Text.RegularExpressions; using System.Web.Script.Serialization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; +using UCP.Model; using UCP.Patching; namespace UCP.Startup { - public class ResourceChange : Change + class StartResourceEnumerator { const int normalOffset = 0; const int crusaderOffset = 0x64; @@ -22,81 +19,44 @@ public class ResourceChange : Change const int goldArrayLength = 0x28; const int aiGoldOffset = 0x10; const int fairnessLevels = 5; - string description; - bool IsValid = true; - public static ResourceChange activeChange = null; + public static Change activeChange = null; + + public static List _changes = new List(); + static Dictionary startResourceConfig; - public static List changes = new List(); - public static TreeView View; - private static string selectedChange = String.Empty; private static object resourceBlockFile = "s_resource"; private static object goldBlockFile = "s_gold"; private static byte[] resourceBlock; private static byte[] goldBlock; - public ResourceChange(string title, bool enabledDefault = false, bool isIntern = false) - : base("res_" + title, ChangeType.Resource, enabledDefault, false) + internal static Dictionary GetStartResourceConfigurations() { - this.NoLocalization = true; - } - - public override void InitUI() - { - Localization.Add(this.TitleIdent + "_descr", this.description); - base.InitUI(); - if (this.IsChecked) - { - activeChange = this; - } - ((TextBlock)this.titleBox.Content).Text = this.TitleIdent.Substring(4); - - if (this.IsValid == false) - { - ((TextBlock)this.titleBox.Content).TextDecorations = TextDecorations.Strikethrough; - this.titleBox.IsEnabled = false; - this.titleBox.ToolTip = this.description; - ((TextBlock)this.titleBox.Content).Foreground = new SolidColorBrush(Color.FromRgb(255, 0, 0)); - } - else - { - this.titleBox.IsChecked = selectedChange.Equals(this.TitleIdent); - } - this.titleBox.Background = new SolidColorBrush(Colors.White); + _changes.Clear(); + startResourceConfig.Clear(); + Load(); + ResetStartResourceConfiguration(); + return startResourceConfig; } - protected override void TitleBox_Checked(object sender, RoutedEventArgs e) + internal static void SetStartResourceConfiguration(string configName) { - base.TitleBox_Checked(sender, e); - - if (activeChange != null) - activeChange.IsChecked = false; - - selectedChange = this.TitleIdent; - activeChange = this; + activeChange = _changes.Where(x => x.Identifier.Equals(configName)).ToList().SingleOrDefault(); } - protected override void TitleBox_Unchecked(object sender, RoutedEventArgs e) + internal static void ResetStartResourceConfiguration() { - base.TitleBox_Unchecked(sender, e); - - if (activeChange == this) - { - activeChange = null; - selectedChange = String.Empty; - } + activeChange = null; } - /// - /// Read and store CodeBlocks defining the original starting resources. - /// - static ResourceChange() + static StartResourceEnumerator() { + startResourceConfig = new Dictionary(); Assembly asm = Assembly.GetExecutingAssembly(); // check if code block file is there - string file = string.Format("UCP.CodeBlocks.{0}.block", resourceBlockFile); + string file = string.Format("UCP.Resources.CodeBlocks.{0}.block", resourceBlockFile); if (!asm.GetManifestResourceNames().Contains(file)) throw new Exception("MISSING BLOCK FILE " + file); @@ -105,47 +65,32 @@ static ResourceChange() resourceBlock = new CodeBlox.CodeBlock(stream).Elements.ToArray().Select(x => x.Value).ToArray(); // check if code block file is there - file = string.Format("UCP.CodeBlocks.{0}.block", goldBlockFile); + file = string.Format("UCP.Resources.CodeBlocks.{0}.block", goldBlockFile); if (!asm.GetManifestResourceNames().Contains(file)) throw new Exception("MISSING BLOCK FILE " + file); // read code block file using (Stream stream = asm.GetManifestResourceStream(file)) goldBlock = new CodeBlox.CodeBlock(stream).Elements.ToArray().Select(x => x.Value).ToArray(); - } - public static void LoadConfiguration(List configuration = null) - { - if (configuration == null) + try { - return; + Load(); } - - foreach (string change in configuration) + catch (ArgumentException e) { - string[] changeLine = change.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(str => str.Trim()).ToArray(); - if (changeLine.Length < 2) - { - continue; - } - - string changeKey = changeLine[0]; - string changeSetting = changeLine[1]; - - bool selected = Regex.Replace(@"\s+", "", changeSetting.Split('=')[1]).Contains("True"); - if (selected == true) - { - selectedChange = changeKey; - } + startResourceConfig = null; } } + /// /// Load built-in vanilla starting resource file and user-provided JSON starting gooods files located in resources\goods subfolder /// public static void Load() { JavaScriptSerializer serializer = new JavaScriptSerializer(); + if (!Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "goods"))) { return; @@ -162,36 +107,27 @@ public static void Load() { resourceConfig = serializer.Deserialize>>(resourceText); } - catch (Exception) + catch (Exception e) { - CreateNullChange(Path.GetFileNameWithoutExtension(file), "Invalid JSON detected"); + File.AppendAllText("StartResourceParsing.log", "\n" + Path.GetFileNameWithoutExtension(file) + ": " + e.Message + "\n"); continue; } - - try + StartResourceChange change = new StartResourceChange(Path.GetFileNameWithoutExtension(file)) { - string description = GetLocalizedDescription(file, resourceConfig); - ResourceChange change = new ResourceChange(Path.GetFileNameWithoutExtension(file), false) - { - CreateResourceHeader("res_" + Path.GetFileNameWithoutExtension(file), resourceConfig), - }; - change.description = description; - changes.Add(change); - } - catch (Exception e) + CreateSubChange("res_" + Path.GetFileNameWithoutExtension(file), resourceConfig), + }; + Dictionary languageConfig = new Dictionary(); + if (resourceConfig.ContainsKey("description")) { - CreateNullChange(Path.GetFileNameWithoutExtension(file), e.Message); + foreach (KeyValuePair description in resourceConfig["description"]) + { + languageConfig.Add(description.Key, description.Value.ToString()); + } } - } - } + startResourceConfig.Add(change.Identifier, new StartResourceConfiguration().withDescription(languageConfig)); + _changes.Add(change); - public static void Refresh(object sender, RoutedEventArgs args) - { - changes.Clear(); - Load(); - - Version.RemoveChanges(ChangeType.AIV); - Version.Changes.AddRange(changes); + } } static byte[] ParseResources(Dictionary> resourceConfig) @@ -400,77 +336,11 @@ static void AssignResourceBytes(int offset, int field, Dictionary> resourceConfig) - { - String description = file; - string currentLang = Localization.Translations.ToArray()[Configuration.Language].Ident; - try - { - description = resourceConfig["description"][currentLang].ToString(); - } - catch (Exception) - { - foreach (var lang in Localization.Translations) - { - try - { - description = resourceConfig["description"][lang.Ident].ToString(); - break; - } - catch (Exception) - { - continue; - } - } - } - if (!description.Equals(file)) - { - description = description.Substring(0, Math.Min(description.Length, 1000)); - } - - return description; - } - - - static void CreateNullChange(string file, string message) - { - ResourceChange change = new ResourceChange(Path.GetFileNameWithoutExtension(file).Replace(" ", ""), false) - { - new DefaultHeader(file, true) - { - new BinaryEdit("s_resource") - { - new BinSkip(0x124), - }, - new BinaryEdit("s_gold") - { - new BinSkip(0x58), - } - } - }; - change.description = message; - change.IsValid = false; - changes.Add(change); - } - - - #region Binary Edit - internal static void DoChange(ChangeArgs args) { - Change change = activeChange; - if (!selectedChange.Equals(String.Empty)) + if (activeChange != null) { - if (activeChange == null) - { - change = changes.Where(x => x.TitleIdent.Equals(selectedChange)).First(); - foreach (var header in change) - { - header.Activate(args); - } - return; - } - foreach (var header in change) + foreach (var header in activeChange) { header.Activate(args); } @@ -478,14 +348,14 @@ internal static void DoChange(ChangeArgs args) } } - static DefaultHeader CreateResourceHeader(String file, Dictionary> resourceConfig) + static DefaultSubChange CreateSubChange(String file, Dictionary> resourceConfig) { try { byte[] resources = ParseResources(resourceConfig); byte[] gold = ParseGold(resourceConfig); - return new DefaultHeader(file, true) + return new DefaultSubChange(file) { BinBytes.CreateEdit("s_resource", resources), BinBytes.CreateEdit("s_gold", gold) @@ -496,8 +366,5 @@ static DefaultHeader CreateResourceHeader(String file, Dictionary lordDots => new Dictionary() { @@ -44,120 +38,39 @@ enum LordType {"Yellow", new int[]{ 0, 6, 7, 8, 9, 10 } } }; - public static List changes = new List(); + public static List _changes = new List(); + static Dictionary startTroopConfig; - public StartTroopChange(string title, bool enabledDefault = false, bool isIntern = false) - : base("s_" + title, ChangeType.StartTroops, enabledDefault, false) - { - this.NoLocalization = true; - } - - public override void InitUI() - { - Localization.Add(this.TitleIdent + "_descr", this.description); - base.InitUI(); - if (this.IsChecked) - { - activeChange = this; - } - ((TextBlock)this.titleBox.Content).Text = this.TitleIdent.Substring(2); - - if (this.IsValid == false) - { - ((TextBlock)this.titleBox.Content).TextDecorations = TextDecorations.Strikethrough; - this.titleBox.IsEnabled = false; - this.titleBox.ToolTip = this.description; - ((TextBlock)this.titleBox.Content).Foreground = new SolidColorBrush(Color.FromRgb(255, 0, 0)); - } - else - { - this.titleBox.IsChecked = selectedChange.Equals(this.TitleIdent); - } - this.titleBox.Background = new SolidColorBrush(Colors.White); - } - - protected override void TitleBox_Checked(object sender, RoutedEventArgs e) - { - base.TitleBox_Checked(sender, e); - - if (activeChange != null) + static StartTroopEnumerator() { + startTroopConfig = new Dictionary(); + try { - activeChange.IsChecked = false; + Load(); } - selectedChange = this.TitleIdent; - activeChange = this; - } - - protected override void TitleBox_Unchecked(object sender, RoutedEventArgs e) - { - base.TitleBox_Unchecked(sender, e); - - if (activeChange == this) + catch (ArgumentException) { - selectedChange = String.Empty; - activeChange = null; + startTroopConfig = null; } + } - public static void Refresh(object sender, RoutedEventArgs args) + internal static Dictionary GetStartTroopConfigurations() { - changes.Clear(); + _changes.Clear(); + startTroopConfig.Clear(); Load(); - - Version.RemoveChanges(ChangeType.Troops); - Version.Changes.AddRange(changes); + ResetStartTroopConfiguration(); + return startTroopConfig; } - public static void LoadConfiguration(List configuration = null) + internal static void SetStartTroopConfiguration(string configName) { - if (configuration == null) - { - return; - } - - foreach (string change in configuration) - { - string[] changeLine = change.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(str => str.Trim()).ToArray(); - if (changeLine.Length < 2) - { - continue; - } - - string changeKey = changeLine[0]; - string changeSetting = changeLine[1]; - - bool selected = Regex.Replace(@"\s+", "", changeSetting.Split('=')[1]).Contains("True"); - if (selected == true) - { - selectedChange = changeKey; - } - } + activeChange = _changes.Where(x => x.Identifier.Equals(configName)).ToList().SingleOrDefault(); } - - static void CreateNullChange(string file, string message) + internal static void ResetStartTroopConfiguration() { - StartTroopChange change = new StartTroopChange(Path.GetFileNameWithoutExtension(file), false) - { - new DefaultHeader("s_" + file, false) - { - new BinaryEdit(troopBlockFile) - { - new BinSkip(0x50), - }, - new BinaryEdit(lordStrengthBlockFile) - { - new BinSkip(0x80), - }, - new BinaryEdit(lordTypeBlockFile) - { - new BinSkip(0x16), - } - } - }; - change.description = message; - change.IsValid = false; - changes.Add(change); + activeChange = null; } internal static void DoChange(ChangeArgs args) @@ -167,7 +80,7 @@ internal static void DoChange(ChangeArgs args) { if (activeChange == null) { - change = changes.Where(x => x.TitleIdent.Equals(selectedChange)).First(); + change = _changes.Where(x => x.Identifier.Equals(selectedChange)).First(); foreach (var header in change) { header.Activate(args); @@ -186,7 +99,6 @@ internal static void DoChange(ChangeArgs args) /// Load built-in starting troops files and user-provided JSON starting troops files located in resources\troops subfolder /// public static void Load() - { if (!Directory.Exists(Path.Combine(Environment.CurrentDirectory, "resources", "troops"))) { @@ -202,39 +114,38 @@ public static void Load() private static void Load(string fileName) { StreamReader reader = new StreamReader(new FileStream(fileName, FileMode.Open), Encoding.UTF8); + string starttroopsText = reader.ReadToEnd(); reader.Close(); - string startTroopConfigName = Path.GetFileNameWithoutExtension(fileName); + string troopConfigName = Path.GetFileNameWithoutExtension(fileName); JavaScriptSerializer serializer = new JavaScriptSerializer(); - Dictionary> startTroopConfig; + Dictionary> troopConfig; try { - startTroopConfig = serializer.Deserialize>>(starttroopsText); + troopConfig = serializer.Deserialize>>(starttroopsText); } - catch (Exception) + catch (Exception e) { - CreateNullChange(Path.GetFileNameWithoutExtension(startTroopConfigName), "Invalid JSON detected"); + File.AppendAllText("StartTroopsParsing.log", "\n" + troopConfigName + ": " + e.Message + "\n"); return; } - try - { - string description = GetLocalizedDescription(startTroopConfigName, startTroopConfig); - StartTroopChange change = new StartTroopChange(startTroopConfigName, false) - { - CreateStartTroopHeader(startTroopConfigName, startTroopConfig), - }; - change.description = description; - changes.Add(change); - } - //TODO error handling! - catch (Exception e) + StartTroopChange change = new StartTroopChange(troopConfigName) { - CreateNullChange(Path.GetFileNameWithoutExtension(startTroopConfigName).Replace(" ", ""), e.Message); - File.AppendAllText("StartTroopsParsing.log", "\n" + startTroopConfigName + ": " + e.Message + "\n"); + CreateSubChange(troopConfigName, troopConfig), + }; + Dictionary languageConfig = new Dictionary(); + if (troopConfig.ContainsKey("description")) + { + foreach (KeyValuePair description in troopConfig["description"]) + { + languageConfig.Add(description.Key, description.Value.ToString()); + } } + startTroopConfig.Add(change.Identifier, new StartTroopConfiguration().withDescription(languageConfig)); + _changes.Add(change); } static void AssignBytes(int type, int count, byte[] config) @@ -376,7 +287,7 @@ static Dictionary ParseLordType(Dictionary g try { - resultConfig["Type"] = new BinBytes(new byte[] { (byte) Enum.Parse(typeof(LordType), lordConfig["Type"]) }); + resultConfig["Type"] = new BinBytes(new byte[] { (byte)Enum.Parse(typeof(LordType), lordConfig["Type"]) }); } catch (KeyNotFoundException) { } catch (Exception) @@ -392,39 +303,8 @@ static Dictionary ParseLordType(Dictionary g return resultConfig; } - static String GetLocalizedDescription(String file, Dictionary> resourceConfig) - { - String description = file; - string currentLang = Localization.Translations.ToArray()[Configuration.Language].Ident; - try - { - description = resourceConfig["description"][currentLang].ToString(); - } - catch (Exception) - { - foreach (var lang in Localization.Translations) - { - try - { - description = resourceConfig["description"][lang.Ident].ToString(); - break; - } - catch (Exception) - { - continue; - } - } - } - if (!description.Equals(file)) - { - description = description.Substring(0, Math.Min(description.Length, 1000)); - } - - return description; - } - - static DefaultHeader CreateStartTroopHeader(String file, Dictionary> starttroopConfig) + static DefaultSubChange CreateSubChange(String file, Dictionary> starttroopConfig) { List startTroopChanges = new List(); List lordStrengthChanges = new List(); @@ -461,24 +341,6 @@ static DefaultHeader CreateStartTroopHeader(String file, Dictionary jne to jmp BinBytes.Change("ai_tethers", ChangeType.Bugfix, true, 0x90, 0xE9), - /* + *//* * IMPROVE WOOD BUYING - */ + *//* // 00457DF4 new Change("ai_buywood", ChangeType.Bugfix, true) @@ -281,16 +281,16 @@ public class Version } }, - /* + *//* * UNLIMITED SIEGE ENGINES ON TOWERS - */ + *//* // 004D20A2 BinBytes.Change("ai_towerengines", ChangeType.Bugfix, true, 0xEB), - /* + *//* * NO ASSAULT SWITCHES - */ + *//* new Change("ai_assaultswitch", ChangeType.Bugfix) @@ -324,9 +324,9 @@ public class Version }, - /* + *//* * AI REBUILD STUFF - */ + *//* new Change("ai_rebuild", ChangeType.Bugfix, true) { @@ -495,9 +495,9 @@ public class Version } }, - /* + *//* * Fletcher bugfix - */ + *//* new Change("o_fix_fletcher_bug", ChangeType.Bugfix) { new DefaultHeader("o_fix_fletcher_bug") @@ -642,9 +642,9 @@ public class Version }, - /* + *//* * AI RECRUIT ADDITIONAL ATTACK TROOPS - */ + *//* // 115EEE0 + (AI1 = 73E8) = stay home troops? // +8 attack troops @@ -662,9 +662,9 @@ public class Version }, - /* + *//* * IMPROVED ATTACKS - */ + *//* new Change("ai_attackwave", ChangeType.AILords) { @@ -727,9 +727,9 @@ public class Version }, - /* + *//* * ALWAYS ATTACK NEAREST NEIGHBOR - */ + *//* // 004D47B2 new Change("ai_attacktarget", ChangeType.AILords, false) @@ -750,9 +750,9 @@ public class Version }, }, - /* + *//* * AI NO SLEEP - */ + *//* // 004CBCD5 new Change("ai_nosleep", ChangeType.AILords, false) @@ -786,9 +786,9 @@ public class Version } }, - /* + *//* * ECONOMY DEMOLISHING - */ + *//* // 004D0280 new Change("ai_demolish", ChangeType.AILords, false, false) @@ -887,9 +887,9 @@ public class Version }, }, - /* + *//* * AI RECRUIT INTERVALS - */ + *//* // AI_OFFSET = AI_INDEX * 169 @@ -927,9 +927,9 @@ public class Version //BinBytes.Change("ai_recruitsleep", ChangeType.Balancing, false, 0x75, 0x2E), - /* + *//* * AI RECRUITMENT ATTACK LIMITS - */ + *//* // attack start troops: 023FC8E8 + AI_OFFSET * 4 + 1F4 // rat => 20 @@ -1074,9 +1074,9 @@ public class Version #region OTHER - /* + *//* * FIRE COOLDOWN - */ + *//* // 0x00410A30 + 8 ushort default = 2000 new Change("o_firecooldown", ChangeType.Other, false) @@ -1092,9 +1092,9 @@ public class Version }, - /* + *//* * EXTREME - */ + *//* new Change("o_xtreme", ChangeType.Other, false) { @@ -1109,9 +1109,9 @@ public class Version }, - /* + *//* * PLAYER 1 COLOR - */ + *//* new Change("o_playercolor", ChangeType.Other, false) { @@ -1749,9 +1749,9 @@ public class Version }, }, - /* + *//* * WASD - */ + *//* new Change("o_keys", ChangeType.Other, false) { @@ -1933,9 +1933,9 @@ public class Version } }, - /* + *//* * Override Identity Menu - */ + *//* new Change("o_override_identity_menu", ChangeType.Other, false, false) { @@ -2304,9 +2304,9 @@ public class Version }, - /* + *//* * HEALER - */ + *//* new Change("o_healer", ChangeType.Other) { @@ -2681,26 +2681,26 @@ public class Version - /* + *//* * FREE TRADER POST - */ + *//* // trader post: runtime 01124EFC // 005C23D8 BinBytes.Change("o_freetrader", ChangeType.Other, true, 0x00), - /* + *//* * SIEGE EQUIPMENT BUILDING - */ + *//* // 0044612B // nop out: mov [selection], ebp = 0 BinBytes.Change("o_engineertent", ChangeType.Other, true, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90), - /* + *//* * MOAT VISIBILITY - */ + *//* new Change("o_moatvisibility", ChangeType.Other) { @@ -2717,9 +2717,9 @@ public class Version - /* + *//* * EXTENDED GAME SPEED - */ + *//* new Change("o_gamespeed", ChangeType.Other) { @@ -2772,9 +2772,9 @@ public class Version - /* + *//* * GATES - */ + *//* new Change("o_responsivegates", ChangeType.Other) { @@ -2792,9 +2792,9 @@ public class Version - /* + *//* * ONLY AI / SPECTATOR MODE - */ + *//* new Change("o_onlyai", ChangeType.Other, false) { @@ -3513,3 +3513,4 @@ public static void RemoveChanges(ChangeType type) } } } +*/ \ No newline at end of file diff --git a/UnofficialCrusaderPatch/_Crusader/Building.cs b/UnofficialCrusaderPatch/_Crusader/Building.cs deleted file mode 100644 index e9207d25..00000000 --- a/UnofficialCrusaderPatch/_Crusader/Building.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace UCP._Crusader -{ - class Building - { - public const int Size = 0x32C; - - // 0x2D2 = fire? - // 0x2D8 = fire cooldown? - } -} diff --git a/UnofficialCrusaderPatch/_Crusader/UI_Button.cs b/UnofficialCrusaderPatch/_Crusader/UI_Button.cs deleted file mode 100644 index 18717610..00000000 --- a/UnofficialCrusaderPatch/_Crusader/UI_Button.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace UCP._Crusader -{ - class UI_Button - { - public enum Header - { - Default = 0x02000003, - EndItem = 0x66, // empty item - } - - public Header Var1 = Header.Default; - public int PosX; - public int PosY; - public int Var04 = 0x48; - public int Var05 = 0x48; - public int ClickFunc = 0x4AE7D0; - public int Argument; - public int RenderFunc = 0x4AE950; - public int Var09 = 0; - public int Var10 = 1; - public int Var11 = 0; - public int Var12 = 0; - public int Var13 = 0xFFFF; - public int Var14 = 0; - public int Var15 = 0; - public int Var16 = 0; - public int Var17 = 0; - public int Var18 = 0; - public int Var19 = 0; - public int Var20 = 0xB96560; - } -} diff --git a/UnofficialCrusaderPatch/_Crusader/Unit.cs b/UnofficialCrusaderPatch/_Crusader/Unit.cs deleted file mode 100644 index 273faaad..00000000 --- a/UnofficialCrusaderPatch/_Crusader/Unit.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace UCP._Crusader -{ - class Unit - { - public const int Size = 0x490; - - // 0x8E4 / 0x454 = soldier? bool - } -} diff --git a/UnofficialCrusaderPatch/packages.config b/UnofficialCrusaderPatch/packages.config new file mode 100644 index 00000000..d9261b81 --- /dev/null +++ b/UnofficialCrusaderPatch/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 20845eeb1ce0c98f416ed87490bc12910c89e069 Mon Sep 17 00:00:00 2001 From: patel-nikhil Date: Sat, 14 Aug 2021 18:34:15 -0400 Subject: [PATCH 2/7] Update package structure --- UnofficialCrusaderPatch/API/ModAPIContract.cs | 85 +++++++++++++++++++ .../ClientConfig/ChangeUIConfig.cs | 30 +++++++ .../ModSelectionType.cs | 1 + .../{Model => ClientConfig}/ModUIConfig.cs | 0 .../SelectionParameter.cs | 0 .../{Model => ClientConfig}/SelectionType.cs | 3 + .../Model/ChangeUIConfig.cs | 14 --- .../Model/{UIConfig.cs => UCPConfig.cs} | 0 .../Resources/Config/mods.json | 70 +++++++++++++++ .../UnofficialCrusaderPatch.csproj | 13 +-- 10 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 UnofficialCrusaderPatch/ClientConfig/ChangeUIConfig.cs rename UnofficialCrusaderPatch/{Model => ClientConfig}/ModSelectionType.cs (79%) rename UnofficialCrusaderPatch/{Model => ClientConfig}/ModUIConfig.cs (100%) rename UnofficialCrusaderPatch/{Model => ClientConfig}/SelectionParameter.cs (100%) rename UnofficialCrusaderPatch/{Model => ClientConfig}/SelectionType.cs (58%) delete mode 100644 UnofficialCrusaderPatch/Model/ChangeUIConfig.cs rename UnofficialCrusaderPatch/Model/{UIConfig.cs => UCPConfig.cs} (100%) create mode 100644 UnofficialCrusaderPatch/Resources/Config/mods.json diff --git a/UnofficialCrusaderPatch/API/ModAPIContract.cs b/UnofficialCrusaderPatch/API/ModAPIContract.cs index b3c4794a..be8c730e 100644 --- a/UnofficialCrusaderPatch/API/ModAPIContract.cs +++ b/UnofficialCrusaderPatch/API/ModAPIContract.cs @@ -1,5 +1,9 @@ using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Reflection; +using System.Text; +using System.Web.Script.Serialization; using UCP.AIC; using UCP.AIV; using UCP.Model; @@ -11,6 +15,87 @@ namespace UCP.API { public static class ModAPIContract { + #region Configuration + public static object GetUCPConfiguration() + { + StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.Resources.AIC.errors.json"), Encoding.UTF8); + string configText = reader.ReadToEnd(); + reader.Close(); + + JavaScriptSerializer serializer = new JavaScriptSerializer(); + var config = serializer.Deserialize>(configText); + return null; + } + + + /*public static object GetUCPConfiguration() + { + Dictionary aivConfiguration = AIVEnumerator.GetAIVConfiguration(); + List aicConfiguration = AICEnumerator.GetAICConfiguration(); + Dictionary startResourceConfiguration = StartResourceEnumerator.GetStartResourceConfigurations(); + Dictionary startTroopConfiguration = StartTroopEnumerator.GetStartTroopConfigurations(); + Dictionary> modConfiguration = Mod.ModList; + + List ucpConfiguration = new List(); + foreach (KeyValuePair keyValuePair in aivConfiguration) + { + dynamic modConfig = new object(); + modConfig.name = keyValuePair.Key; + modConfig.type = "AIV"; + modConfig.description = keyValuePair.Value.Description; + + IEnumerable castles = keyValuePair.Value.Description.Values.AsEnumerable(); + //keyValuePair.Value.Castles: { filename/id, description, image } + // modConfig.changes = keyValuePair.Value.Castles + // modConfig.selectionRules = "*" + + //modConfig.changes + //ucpConfiguration.Add() + } + + foreach (AICConfiguration aic in aicConfiguration) + { + dynamic modConfig = new object(); + modConfig.name = aic.Identifier; + modConfig.type = "AIC"; + modConfig.description = aic.Description; + modConfig.changes = aic.CustomCharacterList; + } + + foreach (KeyValuePair troop in startTroopConfiguration) + { + dynamic modConfig = new object(); + modConfig.name = troop.Key; + modConfig.type = "troop"; + modConfig.description = troop.Value.Description; + modConfig.changes = troop.Key; + } + + foreach (KeyValuePair res in startResourceConfiguration) + { + dynamic modConfig = new object(); + modConfig.name = res.Key; + modConfig.type = "resource"; + modConfig.description = res.Value.Description; + modConfig.changes = res.Key; + } + + foreach (KeyValuePair> mod in modConfiguration) + { + dynamic modConfig = new object(); + modConfig.name = mod.Key; + modConfig.type = "generic"; + //modConfig.description = mod.Value.Description; + //modConfig.changes = mod.Value.Changes; + //Change = { id, description, selectiontype, selectionparameter, compatibility, defaultValue } + } + + return null; + }*/ + + #endregion + + #region AIC public static List ListAICConfigurations() diff --git a/UnofficialCrusaderPatch/ClientConfig/ChangeUIConfig.cs b/UnofficialCrusaderPatch/ClientConfig/ChangeUIConfig.cs new file mode 100644 index 00000000..42bbba48 --- /dev/null +++ b/UnofficialCrusaderPatch/ClientConfig/ChangeUIConfig.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; + +namespace UCP.Model +{ + public class ChangeUIConfig + { + public ChangeUIConfig( + IEnumerable compatibility, + string identifier, + SelectionType selectionType, + SelectionParameter selectionParameters, + object defaultValue, + Dictionary description) + { + this.Compatibility = compatibility; + this.Identifier = identifier; + this.SelectionType = selectionType; + this.SelectionParameters = selectionParameters; + this.DefaultValue = defaultValue; + this.Description = description; + } + + IEnumerable Compatibility { get; } + string Identifier { get; } + SelectionType SelectionType { get; } + SelectionParameter SelectionParameters { get; } + object DefaultValue { get; set; } + Dictionary Description { get; } + } +} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/ModSelectionType.cs b/UnofficialCrusaderPatch/ClientConfig/ModSelectionType.cs similarity index 79% rename from UnofficialCrusaderPatch/Model/ModSelectionType.cs rename to UnofficialCrusaderPatch/ClientConfig/ModSelectionType.cs index 9ce05cb9..d681af6e 100644 --- a/UnofficialCrusaderPatch/Model/ModSelectionType.cs +++ b/UnofficialCrusaderPatch/ClientConfig/ModSelectionType.cs @@ -2,5 +2,6 @@ { public enum ModSelectionType { + EXCLUSIVE } } \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/ModUIConfig.cs b/UnofficialCrusaderPatch/ClientConfig/ModUIConfig.cs similarity index 100% rename from UnofficialCrusaderPatch/Model/ModUIConfig.cs rename to UnofficialCrusaderPatch/ClientConfig/ModUIConfig.cs diff --git a/UnofficialCrusaderPatch/Model/SelectionParameter.cs b/UnofficialCrusaderPatch/ClientConfig/SelectionParameter.cs similarity index 100% rename from UnofficialCrusaderPatch/Model/SelectionParameter.cs rename to UnofficialCrusaderPatch/ClientConfig/SelectionParameter.cs diff --git a/UnofficialCrusaderPatch/Model/SelectionType.cs b/UnofficialCrusaderPatch/ClientConfig/SelectionType.cs similarity index 58% rename from UnofficialCrusaderPatch/Model/SelectionType.cs rename to UnofficialCrusaderPatch/ClientConfig/SelectionType.cs index 52f1a9a3..306727e5 100644 --- a/UnofficialCrusaderPatch/Model/SelectionType.cs +++ b/UnofficialCrusaderPatch/ClientConfig/SelectionType.cs @@ -2,5 +2,8 @@ { public enum SelectionType { + CHECKBOX, + COLOUR, + SLIDER } } \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/ChangeUIConfig.cs b/UnofficialCrusaderPatch/Model/ChangeUIConfig.cs deleted file mode 100644 index 0e6a9e32..00000000 --- a/UnofficialCrusaderPatch/Model/ChangeUIConfig.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; - -namespace UCP.Model -{ - public class ChangeUIConfig - { - public IEnumerable compatibility { get; set; } - public string identifier { get; set; } - public SelectionType selectionType { get; set; } - public SelectionParameter selectionParameters { get; set; } - public object defaultValue { get; set; } - public Dictionary description { get; set; } - } -} \ No newline at end of file diff --git a/UnofficialCrusaderPatch/Model/UIConfig.cs b/UnofficialCrusaderPatch/Model/UCPConfig.cs similarity index 100% rename from UnofficialCrusaderPatch/Model/UIConfig.cs rename to UnofficialCrusaderPatch/Model/UCPConfig.cs diff --git a/UnofficialCrusaderPatch/Resources/Config/mods.json b/UnofficialCrusaderPatch/Resources/Config/mods.json new file mode 100644 index 00000000..78ceb9a1 --- /dev/null +++ b/UnofficialCrusaderPatch/Resources/Config/mods.json @@ -0,0 +1,70 @@ +[ + { + "modType": "AIV", + "modDescription": { + "English": "English Description" + }, + "changes": [ + { + "identifier": "rat", + "selectionType": "checkbox", + "selectionParameters": { + "Castles": [ + { + "name": "rat1.aiv", + "description": { + "English": "English Description" + }, + "previewUrl": "url" + } + ] + } + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_addattack", + "modDescription": { + "English": "English Description" + }, + "modSelectionType": "exclusive", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_addattack", + "selectionType": "checkbox", + "defaultValue": "true", + "description": { + "English": "English Description" + } + }, + { + "exeVersion": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_addattack_alt", + "selectionType": "slider", + "selectionParameters": { + "minimum": 1, + "maximum": 20, + "suggested": 10 + }, + "defaultValue": "0.3", + "description": { + "English": "English Description" + } + }, + { + "exeVersion": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_addattack_alt", + "selectionType": "colour", + "selectionParameters": { + "options": [ "red", "blue", "yellow", "orange", "green", "cyan", "black", "purple" ] + }, + "defaultValue": "red", + "description": { + "English": "English Description" + } + } + ] + } +] \ No newline at end of file diff --git a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj index 1af248d1..f5df8071 100644 --- a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj +++ b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj @@ -126,15 +126,15 @@ - + - - - - + + + + - + @@ -359,6 +359,7 @@ SettingsSingleFileGenerator Settings.Designer.cs + From cf86009e19df5f0f7023608ebbcd7f81c19674cb Mon Sep 17 00:00:00 2001 From: patel-nikhil Date: Sun, 15 Aug 2021 16:49:45 -0400 Subject: [PATCH 3/7] Update API and config --- UnofficialCrusaderPatch/API/ModAPIContract.cs | 233 ++++- .../Resources/modConfig.json | 958 ++++++++++++++++++ .../UnofficialCrusaderPatch.csproj | 1 + .../Enumerators/StartResourceEnumerator.cs | 2 +- 4 files changed, 1183 insertions(+), 11 deletions(-) create mode 100644 UnofficialCrusaderPatch/Resources/modConfig.json diff --git a/UnofficialCrusaderPatch/API/ModAPIContract.cs b/UnofficialCrusaderPatch/API/ModAPIContract.cs index be8c730e..d819609c 100644 --- a/UnofficialCrusaderPatch/API/ModAPIContract.cs +++ b/UnofficialCrusaderPatch/API/ModAPIContract.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; @@ -18,13 +19,225 @@ public static class ModAPIContract #region Configuration public static object GetUCPConfiguration() { - StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.Resources.AIC.errors.json"), Encoding.UTF8); + StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.Resources.modConfig.json"), Encoding.UTF8); string configText = reader.ReadToEnd(); reader.Close(); JavaScriptSerializer serializer = new JavaScriptSerializer(); - var config = serializer.Deserialize>(configText); - return null; + List config = serializer.Deserialize>(configText); + + List modules = new List(); + foreach (var mod in config) + { + dynamic transformedMod = ConstructMod(mod); + modules.Add(transformedMod); + } + + Dictionary aivConfiguration = AIVEnumerator.GetAIVConfiguration(); + foreach (KeyValuePair aivPair in aivConfiguration) + { + Dictionary modConfig = new Dictionary(); + modConfig["modIdentifier"] = aivPair.Key; + modConfig["modType"] = "AIV"; + modConfig["modDescription"] = aivPair.Value.Description; + modConfig["modSelectionRule"] = "*"; + //IEnumerable castles = keyValuePair.Value.Description.Values.AsEnumerable(); + //keyValuePair.Value.Castles: { filename/id, description, image } + // modConfig["modChanges"] = keyValuePair.Value.Castles + modules.Add(modConfig); + } + + List aicConfiguration = AICEnumerator.GetAICConfiguration(); + foreach (AICConfiguration aic in aicConfiguration) + { + Dictionary modConfig = new Dictionary(); + modConfig["modIdentifier"] = aic.Identifier; + modConfig["modType"] = "AIC"; + modConfig["modDescription"] = aic.Description; + modConfig["modChanges"] = aic.CustomCharacterList; + modConfig["modSelectionRule"] = "*"; + modules.Add(modConfig); + } + + Dictionary startTroopConfiguration = StartTroopEnumerator.GetStartTroopConfigurations(); + foreach (KeyValuePair troop in startTroopConfiguration) + { + Dictionary modConfig = new Dictionary(); + modConfig["modIdentifier"] = troop.Key; + modConfig["modType"] = "troop"; + modConfig["modDescription"] = troop.Value.Description; + modConfig["modSelectionRule"] = "*"; + modules.Add(modConfig); + } + + Dictionary startResourceConfiguration = StartResourceEnumerator.GetStartResourceConfigurations(); + foreach (KeyValuePair res in startResourceConfiguration) + { + Dictionary modConfig = new Dictionary(); + modConfig["modIdentifier"] = res.Key; + modConfig["modType"] = "resource"; + modConfig["modDescription"] = res.Value.Description; + modConfig["modSelectionRule"] = "*"; + modules.Add(modConfig); + } + return modules; + } + + static object ConstructMod(dynamic mod) + { + JavaScriptSerializer serializer = new JavaScriptSerializer(); + dynamic transformedMod = serializer.Deserialize(serializer.Serialize(mod)); + + try + { + transformedMod["modDescription"] = GetTranslations(mod["modIdentifier"]); + } + catch (Exception) + { + throw new Exception("Invalid modIdentifier present in mod"); + } + + List changes = new List(); + foreach (var change in mod["changes"]) + { + if (!IsValidChange(change)) + { + throw new Exception("Invalid change configuration for mod: " + mod["modIdentifier"]); + } + dynamic changeCopy = serializer.Deserialize(serializer.Serialize(change)); + changeCopy["description"] = GetTranslations(changeCopy["identifier"]); + changes.Add(changeCopy); + } + transformedMod["changes"] = changes; + return transformedMod; + } + + static List compatibilityList = new List { "crusader", "extreme", "singleplayer", "multiplayer" }; + + static bool IsValidChange(dynamic change) + { + try + { + var compatibility = change["compatibility"]; + foreach (var env in compatibility) + { + if (!compatibilityList.Contains(env)) + { + return false; + } + } + } + catch (KeyNotFoundException e) + { + throw new Exception("compatibility key is missing", e); + } + + try + { + var identifier = change["identifier"]; + } + catch (KeyNotFoundException e) + { + throw new Exception("identifier key is missing", e); + } + + try + { + string selectionType = change["selectionType"]; + Dictionary selectionParameters = change["selectionParameters"]; + + if (selectionType == "checkbox") + { + if (selectionParameters.Count > 0) + { + return false; + } + try + { + var defaultValue = change["defaultValue"]; + if (defaultValue != "true" && defaultValue != "false") + { + return false; + } + } + catch (KeyNotFoundException e) + { + throw new Exception("defaultValue key is missing" + e.Message, e); + } + } + + if (selectionType == "radio") + { + if (selectionParameters.Count != 1) + { + return false; + } + if (!selectionParameters.ContainsKey("options")) + { + return false; + } + + object[] options = selectionParameters["options"] as dynamic; + try + { + var defaultValue = change["defaultValue"]; + if (defaultValue != "false") + { + if (!options.Contains(defaultValue as string)) + { + return false; + } + } + } + catch (KeyNotFoundException e) + { + throw new Exception("defaultValue key is missing", e); + } + } + + if (selectionType == "slider") + { + if (selectionParameters.Count != 5) + { + return false; + } + if ( + !selectionParameters.ContainsKey("minimum") || + !selectionParameters.ContainsKey("maximum") || + !selectionParameters.ContainsKey("interval") || + !selectionParameters.ContainsKey("default") || + !selectionParameters.ContainsKey("suggested") + ) + { + return false; + } + try + { + var defaultValue = change["defaultValue"]; + if (defaultValue != "true" && defaultValue != "false") + { + return false; + } + } + catch (KeyNotFoundException e) + { + throw new Exception("defaultValue key is missing", e); + } + } + } + catch (KeyNotFoundException e) + { + throw new Exception(change["identifier"] + ": selectionType and/or selectionParameters key is missing: " + e.Message, e); + } + return true; + } + + static Dictionary GetTranslations(string identifier) + { + return new Dictionary + { + { "English", "English" } + }; } @@ -46,10 +259,10 @@ public static object GetUCPConfiguration() IEnumerable castles = keyValuePair.Value.Description.Values.AsEnumerable(); //keyValuePair.Value.Castles: { filename/id, description, image } - // modConfig.changes = keyValuePair.Value.Castles + // modConfig["modChanges"] = keyValuePair.Value.Castles // modConfig.selectionRules = "*" - //modConfig.changes + //modConfig["modChanges"] //ucpConfiguration.Add() } @@ -59,7 +272,7 @@ public static object GetUCPConfiguration() modConfig.name = aic.Identifier; modConfig.type = "AIC"; modConfig.description = aic.Description; - modConfig.changes = aic.CustomCharacterList; + modConfig["modChanges"] = aic.CustomCharacterList; } foreach (KeyValuePair troop in startTroopConfiguration) @@ -68,7 +281,7 @@ public static object GetUCPConfiguration() modConfig.name = troop.Key; modConfig.type = "troop"; modConfig.description = troop.Value.Description; - modConfig.changes = troop.Key; + modConfig["modChanges"] = troop.Key; } foreach (KeyValuePair res in startResourceConfiguration) @@ -77,7 +290,7 @@ public static object GetUCPConfiguration() modConfig.name = res.Key; modConfig.type = "resource"; modConfig.description = res.Value.Description; - modConfig.changes = res.Key; + modConfig["modChanges"] = res.Key; } foreach (KeyValuePair> mod in modConfiguration) @@ -86,7 +299,7 @@ public static object GetUCPConfiguration() modConfig.name = mod.Key; modConfig.type = "generic"; //modConfig.description = mod.Value.Description; - //modConfig.changes = mod.Value.Changes; + //modConfig["modChanges"] = mod.Value.Changes; //Change = { id, description, selectiontype, selectionparameter, compatibility, defaultValue } } diff --git a/UnofficialCrusaderPatch/Resources/modConfig.json b/UnofficialCrusaderPatch/Resources/modConfig.json new file mode 100644 index 00000000..0277f371 --- /dev/null +++ b/UnofficialCrusaderPatch/Resources/modConfig.json @@ -0,0 +1,958 @@ +[ + { + "modType": "Bugfixes", + "modIdentifier": "o_fix_ladderclimb", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_fix_ladderclimb", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "u_fireballistafix", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_fireballistafix", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_access", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_access", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_defense", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_defense", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_tethers", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_tethers", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_buywood", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_buywood", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_towerengines", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_towerengines", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_assaultswitch", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_assaultswitch", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_rebuild", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_rebuild", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_fix_laddermen_with_enclosed_keep", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_fix_laddermen_with_enclosed_keep", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "u_fix_lord_animation_stuck_movement", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_fix_lord_animation_stuck_movement", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "u_fix_applefarm_blocking", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_fix_applefarm_blocking", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "u_tanner_fix", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_tanner_fix", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "o_fix_fletcher_bug", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_fix_fletcher_bug", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "ai_fix_crusader_archers_pitch", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_fix_crusader_archers_pitch", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "o_fix_baker_disappear", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_fix_baker_disappear", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Bugfixes", + "modIdentifier": "o_fix_moat_digging_unit_disappearing", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_fix_moat_digging_unit_disappearing", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_housing", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "build_housing", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 100, + "interval": 1, + "default": 0, + "suggested": 5 + } + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "campfire_housing", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 25, + "interval": 1, + "default": 5, + "suggested": 10 + } + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "delete_housing", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_recruitstate_initialtimer", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_recruitstate_initialtimer", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 30, + "interval": 1, + "default": 6, + "suggested": 0 + } + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_attacklimit", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_attacklimit", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 3000, + "interval": 50, + "default": 200, + "suggested": 500 + } + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_attackwave", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_attackwave", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_attacktarget", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_attackwave", + "defaultValue": "false", + "description": {}, + "selectionType": "radio", + "selectionParameters": { + "options": [ "ai_attacktarget_nearest", "ai_attacktarget_richest", "ai_attacktarget_weakest" ] + } + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_nosleep", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_nosleep", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_demolish", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_demolish_walls", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_demolish_trapped", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_demolish_eco", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_addattack", + "modDescription": {}, + "modSelectionRule": "1|2", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_addattack", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 250, + "interval": 1, + "default": 5, + "suggested": 12 + } + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_addattack_alt", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 3, + "interval": 0.1, + "default": 0, + "suggested": 0.3 + } + } + ] + }, + { + "modType": "AILords", + "modIdentifier": "ai_recruitinterval", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "ai_recruitinterval", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Units", + "modIdentifier": "u_laddermen", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_laddermen", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Units", + "modIdentifier": "u_arabxbow", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_arabxbow", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Units", + "modIdentifier": "u_arabwall", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_arabwall", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Units", + "modIdentifier": "u_spearmen", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_spearmen", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Units", + "modIdentifier": "o_restore_arabian_engineer_speech", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_restore_arabian_engineer_speech", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Units", + "modIdentifier": "u_spearmen_run", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "u_spearmen_run", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_firecooldown", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_firecooldown", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 0, + "maximum": 20000, + "interval": 500, + "default": 2000, + "suggested": 4000 + } + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_xtreme", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_xtreme", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_playercolor", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_playercolor", + "defaultValue": "false", + "description": {}, + "selectionType": "radio", + "selectionParameters": { + "options": [ "red", "blue", "yellow", "orange", "green", "cyan", "black", "purple" ] + } + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_keys", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_keys", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_override_identity_menu", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_override_identity_menu", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_healer", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_healer", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_freetrader", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_freetrader", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_engineertent", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_engineertent", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_moatvisibility", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_moatvisibility", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_gamespeed", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_gamespeed", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_responsivegates", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_responsivegates", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_onlyai", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_onlyai", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_armory_marketplace_weapon_order_fix", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_armory_marketplace_weapon_order_fix", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_increase_path_update_tick_rate", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_increase_path_update_tick_rate", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_default_multiplayer_speed", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_default_multiplayer_speed", + "defaultValue": "true", + "description": {}, + "selectionType": "slider", + "selectionParameters": { + "minimum": 20, + "maximum": 90, + "interval": 1, + "default": 40, + "suggested": 50 + } + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_shfy", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_shfy_beer", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_shfy_religion", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_shfy_peasantspawnrate", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_shfy_resourcequantity", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "fix_apple_orchard_build_size", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "fix_apple_orchard_build_size", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_seed_modification_possibility_title", + "modDescription": {}, + "modSelectionRule": "1|2", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_seed_modification_possibility_only_set", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + }, + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_seed_modification_possibility", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_change_siege_engine_spawn_position_catapult", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_change_siege_engine_spawn_position_catapult", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + }, + { + "modType": "Other", + "modIdentifier": "o_stop_player_keep_rotation", + "modDescription": {}, + "modSelectionRule": "*", + "changes": [ + { + "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], + "identifier": "o_stop_player_keep_rotation", + "defaultValue": "true", + "description": {}, + "selectionType": "checkbox", + "selectionParameters": {} + } + ] + } +] \ No newline at end of file diff --git a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj index f5df8071..f1335038 100644 --- a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj +++ b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj @@ -332,6 +332,7 @@ + diff --git a/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs b/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs index 6ce83cde..f004ab93 100644 --- a/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs +++ b/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs @@ -77,7 +77,7 @@ static StartResourceEnumerator() { Load(); } - catch (ArgumentException e) + catch (ArgumentException) { startResourceConfig = null; } From 2ec5bdfd5d9e47267b7729e60eea9e18cc295e62 Mon Sep 17 00:00:00 2001 From: patel-nikhil Date: Sun, 15 Aug 2021 16:54:15 -0400 Subject: [PATCH 4/7] Add UnofficialCrusaderPatchPyGUI project to solution --- .gitignore | 7 +- UnofficialCrusaderPatch.sln | 36 ++++ .../UnofficialCrusaderPatchPyGUI.pyproj | 99 +++++++++++ UnofficialCrusaderPatchPyGUI/app.py | 42 +++++ UnofficialCrusaderPatchPyGUI/requirements.txt | 2 + .../static/css/bootstrap.min.css | 7 + .../static/css/bootstrap.min.css.map | 1 + .../static/css/index.css | 78 ++++++++ .../static/img/wallpaper.jpg | Bin 0 -> 82679 bytes .../static/js/bootstrap.min.js | 7 + .../static/js/index.js | 3 + .../static/js/jquery-3.2.1.slim.min.js | 4 + .../static/js/popper.min.js | 6 + .../templates/index-1.html | 111 ++++++++++++ .../templates/index.html | 167 ++++++++++++++++++ 15 files changed, 569 insertions(+), 1 deletion(-) create mode 100644 UnofficialCrusaderPatchPyGUI/UnofficialCrusaderPatchPyGUI.pyproj create mode 100644 UnofficialCrusaderPatchPyGUI/app.py create mode 100644 UnofficialCrusaderPatchPyGUI/requirements.txt create mode 100644 UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css create mode 100644 UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css.map create mode 100644 UnofficialCrusaderPatchPyGUI/static/css/index.css create mode 100644 UnofficialCrusaderPatchPyGUI/static/img/wallpaper.jpg create mode 100644 UnofficialCrusaderPatchPyGUI/static/js/bootstrap.min.js create mode 100644 UnofficialCrusaderPatchPyGUI/static/js/index.js create mode 100644 UnofficialCrusaderPatchPyGUI/static/js/jquery-3.2.1.slim.min.js create mode 100644 UnofficialCrusaderPatchPyGUI/static/js/popper.min.js create mode 100644 UnofficialCrusaderPatchPyGUI/templates/index-1.html create mode 100644 UnofficialCrusaderPatchPyGUI/templates/index.html diff --git a/.gitignore b/.gitignore index 3c4efe20..06c65600 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +UnofficialCrusaderPatchPyGUI/*.dll +UnofficialCrusaderPatchPyGUI/*.xml +UnofficialCrusaderPatchPyGUI/*.config +UnofficialCrusaderPatchPyGUI/resources + # User-specific files *.suo *.user @@ -258,4 +263,4 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc diff --git a/UnofficialCrusaderPatch.sln b/UnofficialCrusaderPatch.sln index 3928f7fb..506b8a54 100644 --- a/UnofficialCrusaderPatch.sln +++ b/UnofficialCrusaderPatch.sln @@ -15,36 +15,72 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnofficialCrusaderPatchGUI" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnofficialCrusaderPatchConsole", "UnofficialCrusaderPatchConsole\UnofficialCrusaderPatchConsole.csproj", "{743F77E0-AD5A-42FE-B928-535AAF40AC4D}" EndProject +Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "UnofficialCrusaderPatchPyGUI", "UnofficialCrusaderPatchPyGUI\UnofficialCrusaderPatchPyGUI.pyproj", "{500A7837-8D87-42F8-928A-31648E29D762}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {53FFBF10-68B1-474F-BD93-903195B2A14C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53FFBF10-68B1-474F-BD93-903195B2A14C}.Debug|Any CPU.Build.0 = Debug|Any CPU {53FFBF10-68B1-474F-BD93-903195B2A14C}.Debug|x86.ActiveCfg = Debug|x86 {53FFBF10-68B1-474F-BD93-903195B2A14C}.Debug|x86.Build.0 = Debug|x86 + {53FFBF10-68B1-474F-BD93-903195B2A14C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53FFBF10-68B1-474F-BD93-903195B2A14C}.Release|Any CPU.Build.0 = Release|Any CPU {53FFBF10-68B1-474F-BD93-903195B2A14C}.Release|x86.ActiveCfg = Release|Any CPU {53FFBF10-68B1-474F-BD93-903195B2A14C}.Release|x86.Build.0 = Release|Any CPU + {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Debug|x86.ActiveCfg = Debug|x86 {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Debug|x86.Build.0 = Debug|x86 + {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Release|Any CPU.Build.0 = Release|Any CPU {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Release|x86.ActiveCfg = Release|Any CPU {7DEF41CF-C827-4E8F-8243-E600AF1651C0}.Release|x86.Build.0 = Release|Any CPU + {0A526306-B374-43C4-BC10-102CD6A242E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A526306-B374-43C4-BC10-102CD6A242E1}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A526306-B374-43C4-BC10-102CD6A242E1}.Debug|x86.ActiveCfg = Debug|x86 {0A526306-B374-43C4-BC10-102CD6A242E1}.Debug|x86.Build.0 = Debug|x86 + {0A526306-B374-43C4-BC10-102CD6A242E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A526306-B374-43C4-BC10-102CD6A242E1}.Release|Any CPU.Build.0 = Release|Any CPU {0A526306-B374-43C4-BC10-102CD6A242E1}.Release|x86.ActiveCfg = Release|Any CPU {0A526306-B374-43C4-BC10-102CD6A242E1}.Release|x86.Build.0 = Release|Any CPU + {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Debug|x86.ActiveCfg = Debug|x86 {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Debug|x86.Build.0 = Debug|x86 + {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|Any CPU.Build.0 = Release|Any CPU {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|x86.ActiveCfg = Release|Any CPU {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|x86.Build.0 = Release|Any CPU + {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|Any CPU.Build.0 = Debug|Any CPU {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|x86.ActiveCfg = Debug|x86 {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|x86.Build.0 = Debug|x86 + {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|Any CPU.Build.0 = Release|Any CPU {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|x86.ActiveCfg = Release|Any CPU {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|x86.Build.0 = Release|Any CPU + {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|Any CPU.Build.0 = Debug|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|x86.ActiveCfg = Debug|x86 {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|x86.Build.0 = Debug|x86 + {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|Any CPU.Build.0 = Release|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|x86.ActiveCfg = Release|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|x86.Build.0 = Release|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Debug|Any CPU.Build.0 = Debug|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Debug|x86.ActiveCfg = Debug|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Debug|x86.Build.0 = Debug|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Release|Any CPU.ActiveCfg = Release|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Release|Any CPU.Build.0 = Release|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Release|x86.ActiveCfg = Release|Any CPU + {500A7837-8D87-42F8-928A-31648E29D762}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UnofficialCrusaderPatchPyGUI/UnofficialCrusaderPatchPyGUI.pyproj b/UnofficialCrusaderPatchPyGUI/UnofficialCrusaderPatchPyGUI.pyproj new file mode 100644 index 00000000..2534df79 --- /dev/null +++ b/UnofficialCrusaderPatchPyGUI/UnofficialCrusaderPatchPyGUI.pyproj @@ -0,0 +1,99 @@ + + + 10.0 + Debug + 2.0 + 500a7837-8d87-42f8-928a-31648e29d762 + . + {789894c7-04a9-4a11-a6b5-3f4435165112};{1b580a1a-fdb3-4b32-83e1-6407eb2722e6};{349c5851-65df-11da-9384-00065b846f21};{888888a0-9f3d-457c-b088-3a5042f75d52} + app.py + + + . + Web launcher + http://localhost + . + true + UnofficialCrusaderPatchPyGUI + UnofficialCrusaderPatchPyGUI + True + + + true + false + + + true + false + + + + + + + + + + + + + + + + + + + + UnofficialCrusaderPatch + {53ffbf10-68b1-474f-bd93-903195b2a14c} + True + + + + + + + + + + + + + + + + + + + + True + True + http://localhost + False + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + False + False + + + + + \ No newline at end of file diff --git a/UnofficialCrusaderPatchPyGUI/app.py b/UnofficialCrusaderPatchPyGUI/app.py new file mode 100644 index 00000000..a3102388 --- /dev/null +++ b/UnofficialCrusaderPatchPyGUI/app.py @@ -0,0 +1,42 @@ +from flask import Flask, jsonify, make_response, render_template, request, flash, redirect +# from flaskwebgui import FlaskUI + +import webview +import sys +import threading + +import clr +clr.AddReference("UnofficialCrusaderPatch") +from UCP.API import ModAPIContract +# for aic in : +# print(aic.Identifier) +# print(list(aic.CharacterList)) +# print(list(aic.CustomCharacterList)) +# print(aic.Description["English"]) + +app = Flask(__name__) +app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 +# ui = FlaskUI(app, width=600, height=400) +# app.config['SECRET_KEY'] = b'\xb1\xa5\x12\xf7>\xb3b\x96\xb0\r*B|i\xd2[' + +@app.route('/') +def start(): + ucp_configuration = ModAPIContract.GetUCPConfiguration() + aic_list = ModAPIContract.ListAICConfigurations() + aiv_list = ModAPIContract.ListAIVConfigurations() + starttroop_list = ModAPIContract.ListStartTroopConfigurations() + startresource_list = ModAPIContract.ListStartResourceConfigurations() + return render_template("index.html", ucp_config=ucp_configuration, aiv_list=aiv_list, aic_list=aic_list, starttroop_list=starttroop_list, startresource_list=startresource_list) + +def start_server(): + app.run() + +if __name__ == '__main__': + # ui.run() + t = threading.Thread(target=start_server) + t.daemon = True + t.start() + + webview.create_window("Unofficial Crusader Patch", "http://127.0.0.1:5000/", width=600, height=400, min_size=(600, 400)) + webview.start(debug=True) + sys.exit() \ No newline at end of file diff --git a/UnofficialCrusaderPatchPyGUI/requirements.txt b/UnofficialCrusaderPatchPyGUI/requirements.txt new file mode 100644 index 00000000..0d4aa89d --- /dev/null +++ b/UnofficialCrusaderPatchPyGUI/requirements.txt @@ -0,0 +1,2 @@ +flask +pywebview \ No newline at end of file diff --git a/UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css b/UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css new file mode 100644 index 00000000..33edb059 --- /dev/null +++ b/UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css @@ -0,0 +1,7 @@ +@charset "UTF-8";/*! + * Bootstrap v5.0.0-beta2 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0))}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-font-sans-serif);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x)/ -2);margin-left:calc(var(--bs-gutter-x)/ -2)}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x)/ 2);padding-left:calc(var(--bs-gutter-x)/ 2);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.3333333333%}.col-2{flex:0 0 auto;width:16.6666666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.3333333333%}.col-5{flex:0 0 auto;width:41.6666666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.3333333333%}.col-8{flex:0 0 auto;width:66.6666666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.3333333333%}.col-11{flex:0 0 auto;width:91.6666666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.3333333333%}.col-sm-2{flex:0 0 auto;width:16.6666666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.3333333333%}.col-sm-5{flex:0 0 auto;width:41.6666666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.3333333333%}.col-sm-8{flex:0 0 auto;width:66.6666666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.3333333333%}.col-sm-11{flex:0 0 auto;width:91.6666666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.3333333333%}.col-md-2{flex:0 0 auto;width:16.6666666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.3333333333%}.col-md-5{flex:0 0 auto;width:41.6666666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.3333333333%}.col-md-8{flex:0 0 auto;width:66.6666666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.3333333333%}.col-md-11{flex:0 0 auto;width:91.6666666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.3333333333%}.col-lg-2{flex:0 0 auto;width:16.6666666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.3333333333%}.col-lg-5{flex:0 0 auto;width:41.6666666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.3333333333%}.col-lg-8{flex:0 0 auto;width:66.6666666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.3333333333%}.col-lg-11{flex:0 0 auto;width:91.6666666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.3333333333%}.col-xl-2{flex:0 0 auto;width:16.6666666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.3333333333%}.col-xl-5{flex:0 0 auto;width:41.6666666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.3333333333%}.col-xl-8{flex:0 0 auto;width:66.6666666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.3333333333%}.col-xl-11{flex:0 0 auto;width:91.6666666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.3333333333%}.col-xxl-2{flex:0 0 auto;width:16.6666666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.3333333333%}.col-xxl-5{flex:0 0 auto;width:41.6666666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.3333333333%}.col-xxl-8{flex:0 0 auto;width:66.6666666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.3333333333%}.col-xxl-11{flex:0 0 auto;width:91.6666666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.3333333333%}.offset-xxl-2{margin-left:16.6666666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.3333333333%}.offset-xxl-5{margin-left:41.6666666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.3333333333%}.offset-xxl-8{margin-left:66.6666666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.3333333333%}.offset-xxl-11{margin-left:91.6666666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:last-child)>:last-child>*{border-bottom-color:currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-striped>tbody>tr:nth-of-type(odd){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#cfe2ff;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:#000;border-color:#bacbe6}.table-secondary{--bs-table-bg:#e2e3e5;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:#000;border-color:#cbccce}.table-success{--bs-table-bg:#d1e7dd;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:#000;border-color:#bcd0c7}.table-info{--bs-table-bg:#cff4fc;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:#000;border-color:#badce3}.table-warning{--bs-table-bg:#fff3cd;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:#000;border-color:#e6dbb9}.table-danger{--bs-table-bg:#f8d7da;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:#000;border-color:#dfc2c4}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg:#212529;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:#fff;border-color:#373b3e}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{max-width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{color:#6c757d;background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);padding:1rem .75rem}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control::-webkit-input-placeholder{color:transparent}.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(25,135,84,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#198754;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754;padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545;padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#0b5ed7;border-color:#0a58ca}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#0b5ed7;border-color:#0a58ca;box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-check:active+.btn-primary,.btn-check:checked+.btn-primary,.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0a58ca;border-color:#0a53be}.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary:focus,.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:active+.btn-secondary,.btn-check:checked+.btn-secondary,.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#198754;border-color:#198754}.btn-success:hover{color:#fff;background-color:#157347;border-color:#146c43}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#157347;border-color:#146c43;box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-check:active+.btn-success,.btn-check:checked+.btn-success,.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#146c43;border-color:#13653f}.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success:focus,.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#198754;border-color:#198754}.btn-info{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-info:hover{color:#000;background-color:#31d2f2;border-color:#25cff2}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#31d2f2;border-color:#25cff2;box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-check:active+.btn-info,.btn-check:checked+.btn-info,.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#3dd5f3;border-color:#25cff2}.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info:focus,.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-info.disabled,.btn-info:disabled{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#000;background-color:#ffca2c;border-color:#ffc720}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#ffca2c;border-color:#ffc720;box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-check:active+.btn-warning,.btn-check:checked+.btn-warning,.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#ffcd39;border-color:#ffc720}.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning:focus,.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#bb2d3b;border-color:#b02a37}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#bb2d3b;border-color:#b02a37;box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-check:active+.btn-danger,.btn-check:checked+.btn-danger,.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b02a37;border-color:#a52834}.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger:focus,.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:active+.btn-light,.btn-check:checked+.btn-light,.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light:focus,.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light.disabled,.btn-light:disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#212529;border-color:#212529}.btn-dark:hover{color:#fff;background-color:#1c1f23;border-color:#1a1e21}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#1c1f23;border-color:#1a1e21;box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-check:active+.btn-dark,.btn-check:checked+.btn-dark,.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1a1e21;border-color:#191c1f}.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark:focus,.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#198754;border-color:#198754}.btn-outline-success:hover{color:#fff;background-color:#198754;border-color:#198754}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#198754;border-color:#198754}.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#198754;background-color:transparent}.btn-outline-info{color:#0dcaf0;border-color:#0dcaf0}.btn-outline-info:hover{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#0dcaf0;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-dark{color:#212529;border-color:#212529}.btn-outline-dark:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#212529;border-color:#212529}.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#212529;background-color:transparent}.btn-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#0a58ca}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropend,.dropstart,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%}.dropup .dropdown-menu[data-bs-popper]{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu{top:0;right:auto;left:100%}.dropend .dropdown-menu[data-bs-popper]{margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu{top:0;right:100%;left:auto}.dropstart .dropdown-menu[data-bs-popper]{margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:focus,.dropdown-menu-dark .dropdown-item:hover{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#0d6efd}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:0 0;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#0d6efd}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:transparent;border:1px solid rgba(0,0,0,.125);border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button.collapsed{border-bottom-width:0}.accordion-button:not(.collapsed){color:#0c63e4;background-color:#e7f1ff}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.accordion-header{margin-bottom:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-width:1px;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-collapse{border-bottom-width:1px;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-collapse{border:solid rgba(0,0,0,.125);border-width:0 1px}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-button{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item:first-of-type .accordion-button{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.accordion-flush .accordion-item:last-of-type .accordion-button.collapsed{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#0a58ca;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#0a58ca;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{color:#084298;background-color:#cfe2ff;border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0f5132;background-color:#d1e7dd;border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{color:#055160;background-color:#cff4fc;border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{color:#664d03;background-color:#fff3cd;border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{color:#842029;background-color:#f8d7da;border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{color:#636464;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{color:#141619;background-color:#d3d3d4;border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#0d6efd;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#084298;background-color:#cfe2ff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#084298;background-color:#bacbe6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#084298;border-color:#084298}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0f5132;background-color:#d1e7dd}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#0f5132;background-color:#bcd0c7}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0f5132;border-color:#0f5132}.list-group-item-info{color:#055160;background-color:#cff4fc}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#055160;background-color:#badce3}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#055160;border-color:#055160}.list-group-item-warning{color:#664d03;background-color:#fff3cd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#664d03;background-color:#e6dbb9}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#664d03;border-color:#664d03}.list-group-item-danger{color:#842029;background-color:#f8d7da}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#842029;background-color:#dfc2c4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#842029;border-color:#842029}.list-group-item-light{color:#636464;background-color:#fefefe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#636464;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#636464;border-color:#636464}.list-group-item-dark{color:#141619;background-color:#d3d3d4}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#141619;background-color:#bebebf}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#141619;border-color:#141619}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast:not(.showing):not(.show){opacity:0}.toast.hide{display:none}.toast-container{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-header .btn-close{margin-right:-.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[data-popper-placement^=right],.bs-tooltip-end{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[data-popper-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[data-popper-placement^=left],.bs-tooltip-start{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid #d8d8d8;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#0a58ca}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#565e64}.link-success{color:#198754}.link-success:focus,.link-success:hover{color:#146c43}.link-info{color:#0dcaf0}.link-info:focus,.link-info:hover{color:#3dd5f3}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ffcd39}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#b02a37}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#f9fafb}.link-dark{color:#212529}.link-dark:focus,.link-dark:hover{color:#1a1e21}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio:calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio:calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-end{border-right:1px solid #dee2e6!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:1px solid #dee2e6!important}.border-start-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#198754!important}.border-info{border-color:#0dcaf0!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#212529!important}.border-white{border-color:#fff!important}.border-0{border-width:0!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-primary{color:#0d6efd!important}.text-secondary{color:#6c757d!important}.text-success{color:#198754!important}.text-info{color:#0dcaf0!important}.text-warning{color:#ffc107!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#212529!important}.text-white{color:#fff!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-reset{color:inherit!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.bg-primary{background-color:#0d6efd!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:#198754!important}.bg-info{background-color:#0dcaf0!important}.bg-warning{background-color:#ffc107!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#212529!important}.bg-body{background-color:#fff!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.bg-gradient{background-image:var(--bs-gradient)!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:.2rem!important}.rounded-2{border-radius:.25rem!important}.rounded-3{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-end{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-start{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css.map b/UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css.map new file mode 100644 index 00000000..8305eb4f --- /dev/null +++ b/UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","../../scss/mixins/_border-radius.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/_tables.scss","../../scss/mixins/_table-variants.scss","../../scss/forms/_labels.scss","../../scss/forms/_form-text.scss","../../scss/forms/_form-control.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_gradients.scss","../../scss/forms/_form-select.scss","../../scss/forms/_form-check.scss","../../scss/forms/_form-range.scss","../../scss/forms/_floating-labels.scss","../../scss/forms/_input-group.scss","../../scss/mixins/_forms.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/_button-group.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_accordion.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/helpers/_colored-links.scss","../../scss/helpers/_ratio.scss","../../scss/helpers/_position.scss","../../scss/helpers/_visually-hidden.scss","../../scss/mixins/_visually-hidden.scss","../../scss/helpers/_stretched-link.scss","../../scss/helpers/_text-truncation.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v5.0.0-beta2 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n// scss-docs-start import-stack\n// Configuration\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"utilities\";\n\n// Layout & components\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"containers\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"accordion\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"alert\";\n@import \"progress\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n\n// Helpers\n@import \"helpers\";\n\n// Utilities\n@import \"utilities/api\";\n// scss-docs-end import-stack\n",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$variable-prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$variable-prefix}#{$color}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)};\n --#{$variable-prefix}gradient: #{$gradient};\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n font-size: $font-size-root;\n\n @if $enable-smooth-scroll {\n @media (prefers-reduced-motion: no-preference) {\n scroll-behavior: smooth;\n }\n }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: $body-text-align;\n background-color: $body-bg; // 2\n -webkit-text-size-adjust: 100%; // 3\n -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n\n\n// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline\n// on elements that programmatically receive focus but wouldn't normally show a visible\n// focus outline. In general, this would mean that the outline is only applied if the\n// interaction that led to the element receiving programmatic focus was a keyboard interaction,\n// or the browser has somehow determined that the user is primarily a keyboard user and/or\n// wants focus outlines to always be presented.\n// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible\n// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/\n\n[tabindex=\"-1\"]:focus:not(:focus-visible) {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field\n\nhr {\n margin: $hr-margin-y 0;\n color: $hr-color; // 1\n background-color: currentColor;\n border: 0;\n opacity: $hr-opacity;\n}\n\nhr:not([size]) {\n height: $hr-height; // 2\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n margin-top: 0; // 1\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-style: $headings-font-style;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1 {\n @extend %heading;\n @include font-size($h1-font-size);\n}\n\nh2 {\n @extend %heading;\n @include font-size($h2-font-size);\n}\n\nh3 {\n @extend %heading;\n @include font-size($h3-font-size);\n}\n\nh4 {\n @extend %heading;\n @include font-size($h4-font-size);\n}\n\nh5 {\n @extend %heading;\n @include font-size($h5-font-size);\n}\n\nh6 {\n @extend %heading;\n @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-bs-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-bs-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n text-decoration-skip-ink: none; // 4\n}\n\n\n// Address\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n position: relative;\n @include font-size($sub-sup-font-size);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n\n &:hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n &,\n &:hover {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-code;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n direction: ltr #{\"/* rtl:ignore */\"};\n unicode-bidi: bidi-override;\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n display: block;\n margin-top: 0; // 1\n margin-bottom: 1rem; // 2\n overflow: auto; // 3\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n\n kbd {\n padding: 0;\n @include font-size(1em);\n font-weight: $nested-kbd-font-weight;\n }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: $table-cell-padding-y;\n padding-bottom: $table-cell-padding-y;\n color: $table-caption-color;\n text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // 1\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\n\nbutton,\nselect {\n text-transform: none;\n}\n\n// Set the cursor for non-` +

+ +
+ +
+
+ {% for aiv in aiv_list %} +
+ +
+
+
+
+ {{aiv.Value.Description["English"]}} +
+
+
+ {% endfor %} +
+
+
+
+ {% for aic in aic_list %} +
+ +
+
+ {{aic.Description["English"]}} +
+
+
+ {% endfor %} +
+
+
+
Start Troop
+
+
+ Start Resource +
+
+ + + \ No newline at end of file diff --git a/UnofficialCrusaderPatchPyGUI/templates/index.html b/UnofficialCrusaderPatchPyGUI/templates/index.html new file mode 100644 index 00000000..72a52fee --- /dev/null +++ b/UnofficialCrusaderPatchPyGUI/templates/index.html @@ -0,0 +1,167 @@ + + + + + + Unofficial Crusader Patch + + + + + + + + + +
+

Welcome to the Unofficial Crusader Patch

+ +
+ + +
+ {% for modType in ucp_config|map(attribute='modType')|unique|list %} +
+ {% for config in ucp_config if config.modType == modType %} + {% if modType != "AIC" and modType != "AIV" %} +
+ + + +
+
+ {{config.modDescription["English"]}} + {% if modType != "troop" and modType != "resource" and config.changes|length > 0 %} + {% if config.changes|length > 1 or config.changes[0].selectionType != "checkbox" %} + {% for change in config.changes %} +
+ + +
+ {% endfor %} + {% endif %} + {% endif %} +
+ {% endif %} + {% endfor %} +
+ {% endfor %} + +
+ Bugfix +
+
+ AI Lords +
+
+ Other +
+ +
+ {% for aiv in aiv_list %} +
+ + + +
+
+ {{aiv.Value.Description["English"]}} +
+ {% endfor %} + +
+
+ {% for aic in aic_list %} +
+ + + +
+
+ {{aic.Description["English"]}} +
+ {% endfor %} + +
+ +
+ {% for config in startresource_list %} +
+ + + +
+
+ {{config.Value.Description["English"]}} +
+ {% endfor %} +
+
+
+ + \ No newline at end of file From 3a1e0cadb0d5aa0c3e765b9152557d34353f15a2 Mon Sep 17 00:00:00 2001 From: patel-nikhil Date: Fri, 24 Dec 2021 00:28:26 -0500 Subject: [PATCH 5/7] Update PyGUI implementation --- .../API/{ModAPIContract.cs => Startup.cs} | 105 +- UnofficialCrusaderPatch/App.config | 2 +- .../Localization/Chinese.txt | 1072 ++++++++++++++++ .../Localization/English.txt | 1071 ++++++++++++++++ .../Localization/German.txt | 1075 ++++++++++++++++ .../Localization/Hungarian.txt | 1061 ++++++++++++++++ .../Localization/Localization.cs | 244 ++++ .../Localization/Polish.txt | 1102 ++++++++++++++++ .../Localization/Russian.txt | 1072 ++++++++++++++++ .../Localization/TextReferencer.cs | 72 ++ .../Properties/Resources.Designer.cs | 26 +- .../Properties/Settings.Designer.cs | 10 +- .../Resources/modConfig.json | 1124 +++++++++++++++-- .../UnofficialCrusaderPatch.csproj | 26 +- .../Enumerators/StartResourceEnumerator.cs | 16 + UnofficialCrusaderPatch/packages.config | 2 +- UnofficialCrusaderPatchGUI/MainWindow.xaml.cs | 6 +- UnofficialCrusaderPatchPyGUI/app.py | 5 +- .../static/css/index.css | 148 ++- .../templates/index.html | 213 +--- 20 files changed, 8100 insertions(+), 352 deletions(-) rename UnofficialCrusaderPatch/API/{ModAPIContract.cs => Startup.cs} (85%) create mode 100644 UnofficialCrusaderPatch/Localization/Chinese.txt create mode 100644 UnofficialCrusaderPatch/Localization/English.txt create mode 100644 UnofficialCrusaderPatch/Localization/German.txt create mode 100644 UnofficialCrusaderPatch/Localization/Hungarian.txt create mode 100644 UnofficialCrusaderPatch/Localization/Localization.cs create mode 100644 UnofficialCrusaderPatch/Localization/Polish.txt create mode 100644 UnofficialCrusaderPatch/Localization/Russian.txt create mode 100644 UnofficialCrusaderPatch/Localization/TextReferencer.cs diff --git a/UnofficialCrusaderPatch/API/ModAPIContract.cs b/UnofficialCrusaderPatch/API/Startup.cs similarity index 85% rename from UnofficialCrusaderPatch/API/ModAPIContract.cs rename to UnofficialCrusaderPatch/API/Startup.cs index d819609c..64927569 100644 --- a/UnofficialCrusaderPatch/API/ModAPIContract.cs +++ b/UnofficialCrusaderPatch/API/Startup.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using System.Text; +using System.Threading.Tasks; using System.Web.Script.Serialization; using UCP.AIC; using UCP.AIV; @@ -14,11 +15,21 @@ namespace UCP.API { - public static class ModAPIContract + public class Startup { #region Configuration - public static object GetUCPConfiguration() + /** + * Func> delegate to expose method to external callers (ie NodeJS) + */ + public async Task Invoke (object input) { + return GetUCPConfiguration(input.ToString()); + } + + public static object GetUCPConfiguration(string language) + { + Localization.Load(language); + StreamReader reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("UCP.Resources.modConfig.json"), Encoding.UTF8); string configText = reader.ReadToEnd(); reader.Close(); @@ -29,8 +40,16 @@ public static object GetUCPConfiguration() List modules = new List(); foreach (var mod in config) { - dynamic transformedMod = ConstructMod(mod); - modules.Add(transformedMod); + try + { + dynamic transformedMod = ConstructMod(mod, language); + modules.Add(transformedMod); + } catch (Exception e) + { + throw new Exception("Mod that failed is" + ((dynamic) mod)["modIdentifier"].ToString() + e.Message); + } + + } Dictionary aivConfiguration = AIVEnumerator.GetAIVConfiguration(); @@ -39,7 +58,7 @@ public static object GetUCPConfiguration() Dictionary modConfig = new Dictionary(); modConfig["modIdentifier"] = aivPair.Key; modConfig["modType"] = "AIV"; - modConfig["modDescription"] = aivPair.Value.Description; + modConfig["modDescription"] = aivPair.Value.Description[language]; modConfig["modSelectionRule"] = "*"; //IEnumerable castles = keyValuePair.Value.Description.Values.AsEnumerable(); //keyValuePair.Value.Castles: { filename/id, description, image } @@ -53,7 +72,7 @@ public static object GetUCPConfiguration() Dictionary modConfig = new Dictionary(); modConfig["modIdentifier"] = aic.Identifier; modConfig["modType"] = "AIC"; - modConfig["modDescription"] = aic.Description; + modConfig["modDescription"] = aic.Description[language]; modConfig["modChanges"] = aic.CustomCharacterList; modConfig["modSelectionRule"] = "*"; modules.Add(modConfig); @@ -65,7 +84,7 @@ public static object GetUCPConfiguration() Dictionary modConfig = new Dictionary(); modConfig["modIdentifier"] = troop.Key; modConfig["modType"] = "troop"; - modConfig["modDescription"] = troop.Value.Description; + modConfig["modDescription"] = troop.Value.Description[language]; modConfig["modSelectionRule"] = "*"; modules.Add(modConfig); } @@ -76,27 +95,37 @@ public static object GetUCPConfiguration() Dictionary modConfig = new Dictionary(); modConfig["modIdentifier"] = res.Key; modConfig["modType"] = "resource"; - modConfig["modDescription"] = res.Value.Description; + modConfig["modDescription"] = res.Value.Description[language]; modConfig["modSelectionRule"] = "*"; modules.Add(modConfig); } return modules; } - static object ConstructMod(dynamic mod) + static object ConstructMod(dynamic mod, string language) { JavaScriptSerializer serializer = new JavaScriptSerializer(); dynamic transformedMod = serializer.Deserialize(serializer.Serialize(mod)); try { - transformedMod["modDescription"] = GetTranslations(mod["modIdentifier"]); - } + transformedMod["modDescription"] = mod["modDescription"][language]; + } catch (KeyNotFoundException) {} catch (Exception) { throw new Exception("Invalid modIdentifier present in mod"); } + try + { + transformedMod["detailedDescription"] = mod["detailedDescription"][language]; + } + catch (KeyNotFoundException) { } + catch (Exception) + { + transformedMod["detailedDescription"] = ""; + } + List changes = new List(); foreach (var change in mod["changes"]) { @@ -105,7 +134,40 @@ static object ConstructMod(dynamic mod) throw new Exception("Invalid change configuration for mod: " + mod["modIdentifier"]); } dynamic changeCopy = serializer.Deserialize(serializer.Serialize(change)); - changeCopy["description"] = GetTranslations(changeCopy["identifier"]); + + try + { + changeCopy["description"] = changeCopy["description"][language]; + } + catch (KeyNotFoundException) { + changeCopy["description"] = ""; + } + + try + { + changeCopy["detailedDescription"] = changeCopy["detailedDescription"][language]; + } catch (KeyNotFoundException) { + changeCopy["detailedDescription"] = ""; + } + + try + { + for (int i = 0; i < changeCopy["selectionParameters"]["options"].Length; i++) + { + try + { + changeCopy["selectionParameters"]["options"][i]["description"] = changeCopy["selectionParameters"]["options"][i]["description"][language]; + } + catch (KeyNotFoundException) { } + + try + { + changeCopy["selectionParameters"]["options"][i]["detailedDescription"] = changeCopy["selectionParameters"]["options"][i]["detailedDescription"][language]; + } + catch (KeyNotFoundException) { } + } + } catch (KeyNotFoundException) { } + changes.Add(changeCopy); } transformedMod["changes"] = changes; @@ -232,12 +294,9 @@ static bool IsValidChange(dynamic change) return true; } - static Dictionary GetTranslations(string identifier) + static string GetTranslations(string identifier) { - return new Dictionary - { - { "English", "English" } - }; + return Localization.Get(identifier); } @@ -461,12 +520,12 @@ public static void SetModExtremeValues(IEnumerable modValue #region Installation public static bool Install(UCPConfig config, bool overwrite = false, bool graphical = false) { - ModAPIContract.SetAICConfiguration(config.AIC); - ModAPIContract.SetAIVConfiguration(config.AIV); - ModAPIContract.SetStartResourceConfiguration(config.StartResource); - ModAPIContract.SetStartTroopConfiguration(config.StartTroop); - ModAPIContract.SetModValues(config.GenericMods); - ModAPIContract.SetModExtremeValues(config.GenericMods); + Startup.SetAICConfiguration(config.AIC); + Startup.SetAIVConfiguration(config.AIV); + Startup.SetStartResourceConfiguration(config.StartResource); + Startup.SetStartTroopConfiguration(config.StartTroop); + Startup.SetModValues(config.GenericMods); + Startup.SetModExtremeValues(config.GenericMods); AIVEnumerator.Install(config.Path, overwrite, graphical); diff --git a/UnofficialCrusaderPatch/App.config b/UnofficialCrusaderPatch/App.config index 74ade9db..d1428ad7 100644 --- a/UnofficialCrusaderPatch/App.config +++ b/UnofficialCrusaderPatch/App.config @@ -1,6 +1,6 @@ - + diff --git a/UnofficialCrusaderPatch/Localization/Chinese.txt b/UnofficialCrusaderPatch/Localization/Chinese.txt new file mode 100644 index 00000000..7397e6fc --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/Chinese.txt @@ -0,0 +1,1072 @@ +// ====================== +// 2.15 +// ====================== +u_spearmen_run +{ +"矛兵默认为奔跑状态而不是步行" +} + +u_spearmen_run_descr +{ +"矛兵在默认状态下将使用奔跑作为移动方式,而不是步行。" +} + +o_seed_modification_possibility_title +{ +"游戏种子" +} + +o_seed_modification_possibility_only_set +{ +"启用固定游戏随机种子" +} + +o_seed_modification_possibility_only_set_descr +{ +"如果使用相同的地图设置,设置游戏种子可以使只有AI的游戏对局每次都以相同的过程进行。对于既有玩家也有AI的游戏对局,设置游戏种子可以确保每次游戏的开始条件是相同的(例如相同的AIV)。若要设置游戏种子,请启用此选项并在game install/gameseeds目录中创建一个名为“live”的txt文件,并手动写上6位数字。注意:启动此功能后需要重新启动游戏!" +} + +o_seed_modification_possibility +{ +"启用或保存游戏随机种子" +} + +o_seed_modification_possibility_descr +{ +"这个选项可以保存你当前的游戏种子,前提是你当前没有设定游戏种子,你可以将保存的游戏种子重命名为“live”使其应用在之后的游戏中。" +} + +ai_recruitstate_initialtimer +{ +"AI在初期阶段只招募防御士兵" +} + +ai_recruitstate_initialtimervalue_descr +{ +"AI在游戏开始起的以下时间内只会招募防御士兵,除非防御士兵数量已达上限。" +} + +ai_defense +{ +"修复ai不会补充防守兵种" +} + +ai_defense_descr +{ +"当ai城墙防守部队出现减员时,如果城外防守部队仍然存在,那么ai将& +不会补充城墙防守部队。" +} + +ai_housing +{ +"AI建造民房更加智能" +} + +build_housing_descr +{ +"你可以设定AI的民房数量的浮动值,AI建造民房时,会额外建造该数值的民房,这样直到下次人口不足之前,AI都不需要建造民房;同样的,当AI工作人口减少时,AI也会最多保留该数值的超出工作人口部分的民房。这使得AI无需频繁的拆建民房,浪费木材资源,尤其是人口频繁波动时。" +} + +campfire_housing_descr +{ +"此处设置AI篝火处的空闲农民数量,当空闲农民数量多于此数值时,AI会停止建造民房。这个功能同时会禁止AI拆除民房。" +} + +delete_housing +{ +"禁止AI拆除民房" +} + +delete_housing_descr +{ +"打开这个功能,AI将不会拆除民房。" +} + +aiv_prompt +{ +"检测到自定义AIV。你希望创建一个备份吗?" +} + +aiv_cli_prompt +{ +"检测到自定义AIV。输入“delete”删除此AIV或者输入文件夹的名字将AIV复制进此文件夹。" +} + +install_abort_io +{ +"安装中止。该文件夹下已存在相同名称的文件,请再次尝试并选择一个不同的文件夹。" +} + +install_abort +{ +"安装中止" +} + +backup_aiv_select +{ +"选择备份AIV文件夹" +} + +o_change_siege_engine_spawn_position_catapult +{ +"器械建造完成时将位于帐篷中央" +} + +o_change_siege_engine_spawn_position_catapult_descr +{ +"器械建造完成时将不再位于帐篷的右上角,而是位于帐篷的中央。" +} + +o_stop_player_keep_rotation +{ +"玩家的大本营会根据所处地图方位进行旋转" +} + +o_stop_player_keep_rotation_descr +{ +"玩家的大本营将可以和AI一样,会根据所处地图方位进行旋转,使篝火处永远背向地图中央。" +} + +o_restore_arabian_engineer_speech +{ +"工程师切换为阿拉伯语音" +} + +o_restore_arabian_engineer_speech_descr +{ +"当玩家使用阿拉伯领主时,工程师的语音将会切换为阿拉伯语。" +} + +u_fix_lord_animation_stuck_movement +{ +"修正领主摧毁建筑物后的人物动画" +} + +u_fix_lord_animation_stuck_movement_descr +{ +"修正了领主的姿势,当领主停止移动或者摧毁一个建筑物后,他将会站立,而不是被卡在地上。" +} + +fix_apple_orchard_build_size +{ +"修正苹果园建造时的面积" +} + +fix_apple_orchard_build_size_descr +{ +"将建造时苹果园需求的面积修正为苹果园的实际面积,这也可以让AI正确的放置苹果园。" +} + +u_fix_applefarm_blocking +{ +"修复苹果园工人被堵路" +} + +u_fix_applefarm_blocking_descr +{ +"当农场的左上方被建筑堵住时,将不再阻止苹果园工人进入苹果园。" +} + +o_increase_path_update_tick_rate +{ +"寻路检测频率增加" +} + +o_increase_path_update_tick_rate_descr +{ +"在原版,每200游戏刻会检测一次可行通路,经常导致ai的单位在摧毁了敌人的城门或者塔楼时不能立刻进入城堡。 + +打开后,每50个游戏刻就会进行一次检测,使得单位的反应速度加快。" +} + +o_fix_ladderclimb +{ +"修复士兵爬上云梯后遗失目的地bug" +} + +o_fix_ladderclimb_descr +{ +"士兵现在爬上云梯后将会记住目的地,而不会被困在云梯上。" +} + +u_tanner_fix +{ +"修复所有皮革工人获取同一头牛" +} + +u_tanner_fix_descr +{ +"现在皮革工人到达牧场后,若发现想要牵走的牛已被其他工人牵去,会转而去牵另外一头牛,而不是直接回到作坊。极大提高皮革作坊的效率。" +} + +o_fix_fletcher_bug +{ +"修复弓弩工人的路线" +} + +o_fix_fletcher_bug_descr +{ +"现在弓弩工人在武器库放下弓弩后会直接去储存区拿原料,而不是先返回作坊。" +} + +ai_fix_crusader_archers_pitch +{ +"修复AI的欧洲弓箭手不会点燃沥青" +} + +ai_fix_crusader_archers_pitch_descr +{ +"AI的欧洲弓箭手可以和阿拉伯弓箭手一样点燃沥青。" +} + +o_fix_baker_disappear +{ +"修复面包工人消失" +} + +o_fix_baker_disappear_descr +{ +"当面包工人到达储存区却没有面粉时,不再会消失。" +} + +o_fix_moat_digging_unit_disappearing +{ +"修复挖河士兵消失" +} + +o_fix_moat_digging_unit_disappearing_descr +{ +"挖河士兵在挖护城河时不再会随机消失。注意的是,当挖河士兵正好位于无通路地区时,如果你对其下达命令,他仍会消失!" +} + +ui_welcometext +{ +"这是要塞十字军东征的非官方补丁编辑器。 +该项目在github上开源: +[GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). + +通常来说,这个编辑器支持所有游戏版本。但是该编辑器是基于steam上1.41版本制作的,使用更低版本可能会出错。 +安装补丁时若出现问题,会弹出错误信息。 +安装补丁时的UCP版本会显示在游戏主菜单界面的左下角,游戏版本号的右边。 +在安装补丁之前,编辑器会自动备份原始文件。你可以通过'复原'按钮来取消更改,也可以手动更改备份文件的后缀名来复原。 + +UCP制作团队 + +作者 +[Sh0wdown](https://github.com/Sh0wdown) + +项目负责 +[Kimberly Azula](https://github.com/ByBurton/) +[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) + +协力制作 +[LordHansCapon](https://github.com/LordHansCapon) +[np123](https://github.com/patel-nikhil) +[J-T-de](https://github.com/J-T-de) +[gynt](https://github.com/gynt) +[Le spec](https://github.com/LeSpec) +[Chaf1812](https://github.com/Chaf1812) + +翻译提供者 +[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (波兰语) +[Lolasik011](https://github.com/Lolasik011) (俄语) +[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (中文) +[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (匈牙利) + +内容创建者 +[Evrey](https://github.com/Evrey) (aiv) +[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) +[PitchNeeded](https://github.com/PitchNeeded) (aiv) +[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) + +特别鸣谢 +[Firefly Studios](https://fireflyworlds.com/) +for the creation of the Stronghold series + +其他 +[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) +[PodeCaradox](https://github.com/PodeCaradox) +[GRhin](https://www.twitch.tv/grhin) +[Heroesflorian](https://github.com/Heroesflorian)" +} + +// ====================== +// 2.14 +// ====================== + +ui_StartTroops +{ + "起始部队" +} + +ui_Resource +{ + "起始资金" +} + +ui_aicconflict +{ + "AIC存在ai冲突,第二个AIC的冲突ai会被忽略" +} + +o_shfy +{ + "要塞修改" +} + +o_shfy_beer +{ + "从啤酒中获取的声望" +} + +o_shfy_beer_descr +{ + " " +} + +o_shfy_religion +{ + "从宗教中获取的声望" +} + +o_shfy_religion_descr +{ + " " +} + +o_shfy_peasantspawnrate +{ + "农民产生速度" +} + +o_shfy_peasantspawnrate_descr +{ + " " +} + +o_shfy_resourcequantity +{ + "交付资源数量" +} + +o_shfy_resourcequantity_descr +{ + "将这些方面调整为要塞1的数值。注意:任何改变都会影响ai领主,最坏的情况是失效!" +} + +o_armory_marketplace_weapon_order_fix +{ + "调整武器库和市场中武器的顺序" +} + +o_armory_marketplace_weapon_order_fix_descr +{ + "调整了武器在武器库和市场中的排序,同时将皮甲移至链锤和弩之间,将铁甲移至戟和剑之间,使得在浏览时更方便。" +} + +ai_fix_laddermen_with_enclosed_keep +{ + "修复了ai在城堡无通路时不使用云梯兵的错误" +} + +ai_fix_laddermen_with_enclosed_keep_descr +{ + "当ai(尤其是蛇)在自己城堡无通路到外界时,不再会停止使用云梯兵。" +} + +o_override_identity_menu +{ + "在设置菜单里添加一些新的选择" +} + +o_override_identity_menu_descr +{ + "增加了玩家初始兵种的选择的功能,只在普通模式下生效。" +} + +o_default_multiplayer_speed +{ + "设置多人游戏中的默认游戏速度" +} + +o_default_multiplayer_speed_descr +{ + " " +} + +u_fireballistafix +{ + "巨火弩正确攻击僧侣和隧道工" +} + +u_fireballistafix_descr +{ + "巨火弩将会自动攻击敌人的僧侣和隧道工。" +} + + +ui_browsepath +{ + "请选择你的要塞十字军东征安装路径" +} + +ui_aicoldversion +{ + "检测到旧版本AIC文件,点击转化为新版本。" +} + +ui_aicofferconvert +{ + "确定将AIC文件转化为新版本吗?" +} + +ui_aicconvertprompt +{ + "AIC转化完成" +} + +ui_aicselect +{ + "请先选择AIC文件,以下aic文件可供选择: " +} + +// ====================== +// 2.13 +// ====================== + +o_firecooldown +{ + "调整刚灭火建筑的免疫火灾时间" +} + +o_firecooldown_descr +{ + "着火的建筑在火被扑灭后,会有一段免疫着火的时间,此处可修改时间长短。" +} + +u_ballistamonk +{ + "巨火弩攻击僧侣" +} + +u_ballistamonk_descr +{ + "打开后,巨火弩将会自动攻击僧侣。" +} + + +// ====================== +// 2.12 +// ====================== + +ui_AIC +{ + "AIC" +} + +ui_aicExport +{ + "导出" +} + +ui_aicExport_success +{ + "导出成功。" +} + +ui_aicHint +{ + "将.aic文件从安装程序导出到crusader文件夹中。" +} + + +// ====================== +// 1.00 +// ====================== + +Name +{ + "非官方要塞十字军东征补丁" +} + +u_ArabXBow +{ + "增强了阿拉伯剑士抵抗弩箭的能力" +} + +u_arabxbow_descr +{ + " -阿拉伯剑士在中3发弩箭后死亡改为6发弩箭后死亡。" +} + +u_ArabWall +{ + "阿拉伯剑士破坏城墙速度加快" +} + +u_ArabWall_descr +{ + "在原版,阿拉伯剑士破坏城墙的速度比其他任何单位都要更慢,& +打开这个选项后,破坏速度将会提升为原来的两倍,稍快于长矛手。" +} + +u_spearmen +{ + "增强长矛手抵抗箭矢的能力" +} + +u_spearmen_descr +{ + " - 长矛手在中3发箭后死亡改为5发箭后死亡, + - 长矛手承受1发弩箭后还可以刚好存活。" +} + +ai_buy +{ + "提升ai的市场使用" +} + +ai_buy_descr +{ + "在原版,部分ai不会正确使用市场,下列改动包含在此项中: + - 皇帝和元帅会购买武器装备 + - 修道院长和埃米尔会购买弓 + - 维奇尔会购买苹果。" +} + +ui_error +{ + "错误" +} + +ui_SearchPath +{ + " 请选择你的游戏安装路径" +} + +ui_search +{ + "浏览" +} + +ui_continue +{ + "继续" +} + +ui_wrongpath +{ + "该路径中未发现要塞十字军东征游戏程序!" +} + +ui_back +{ + "返回" +} + +ui_install +{ + "安装" +} + +ui_finished +{ + "完成" +} + +ui_chooseLangTitle +{ + "选择语言" +} + +ui_chooseLang +{ + "请在下列选项中选择一门语言" +} + +ui_accept +{ + "确定" +} + +ui_cancel +{ + "取消" +} + +ui_uninstall +{ + "复原" +} + +ui_uninstalldone +{ + "所有改动已复原。" +} + +ai_recruitinterval +{ + "加快所有ai的训练士兵速度" +} + +ai_recruitinterval_descr +{ + "将所有ai的训练时间间隔降低至最低(老鼠和狮心王的程度)" +} + +ai_recruitsleep +{ + "取消ai的训练暂停" +} + +ai_attacklimit +{ + "调整ai的进攻部队数量限制" +} + +ai_attacklimit_descr +{ + "ai的进攻部队的数量会随时间而增加,额外增加的部队数量上限& +在原版是200。你可以在此处修改这个值。" +} + +o_gamespeed +{ + "拓宽游戏速度限制" +} + +o_gamespeed_descr +{ + "游戏速度的限制更改为如下所示: + - 在10到90之间以5为间隔 + - 在90到200之间以10为间隔 + - 在200到1000之间以100为间隔 +新的游戏速度范围仅可通过键盘上的+ -号来改变,菜单中的游戏速度& +调整不到新的范围。" +} + +ui_bugfix +{ + "bug修复" +} + +ui_ailords +{ + "AI领主" +} + +ui_troops +{ + "单位" +} + +ui_other +{ + "其他" +} + +o_responsivegates +{ + "城门快速反应" +} + +o_responsivegates_descr +{ + "敌人在靠近城门一定距离时城门将会关闭,该距离由200调整至140。& +敌人在远离城门一定距离时城门将会打开,该距离由1200调整至100。" +} + +ai_addattack +{ + "调整ai每波进攻额外增加的兵力" +} + +ai_addattack_descr +{ + "在原版,ai每波进攻都会额外增加5的兵力,这个同时生效于& +所有ai的数值可以在此处改变。" +} + +ai_addattack_alt_descr +{ + "或者,每波额外增加的兵力可以和ai初次进攻的兵力有关,对于不同ai来说,& +初次进攻兵力可以是不同的,因此这个选项可以使不同ai的进攻士兵增速不同。 +举例: 倍率 = 0.5 +苏丹从第一波开始的进攻士兵数量 = 10, 15, 20, 25, ... +萨拉丁从第一波开始的进攻士兵数量 = 50, 75, 100, 125, ..." +} + +u_laddermen +{ + "增强云梯兵对于箭矢的抗性" +} + +u_laddermen_descr +{ + " - 云梯兵在中5发箭后死亡改为中12发箭后死亡 + - 云梯兵在中2发弩箭后死亡改为中5发弩箭后死亡 + - 云梯兵价钱从4提升为20" +} + +o_playercolor +{ + "改变玩家1号的颜色" +} + +o_playercolor_descr +{ + " " +} + +o_trooplimit +{ + "调整部队数量上限" +} + +o_trooplimit_descr +{ + "在原版,每位玩家最多可有2400名士兵,这个值可在此处改变" +} + +ai_demolish +{ + "停用ai拆毁以下类型建筑来获取资金" +} + +ai_demolish_walls +{ + "城堡建筑" +} + +ai_demolish_eco +{ + "经济建筑" +} + +ai_demolish_walls_descr +{ + " " +} + +ai_demolish_eco_descr +{ + "如果ai感受到了压力,他会通过拆毁城堡建筑或者经济建筑的方式来快速获取资金& +这在有时是没有必要的,你可以在此处取消这个行为。." +} + +ai_tethers +{ + "防止ai牛栏堆积" +} + +ai_tethers_descr +{ + "通常,ai会为每个新的采石场建筑一个新的牛栏,而不管已经存在多少牛栏。& +当采石场被反复摧毁时,会导致牛栏数量很多。打开此选项可以避免这种现象。" +} + +// ======================= +// 2.06 +// ======================= + +ai_nosleep +{ + "资源不足时ai不再休眠建筑" +} + +ai_nosleep_descr +{ + "ai通常会将正在生产中的建筑休眠,因为有部分建筑缺乏原料,哪怕原料& +正在运回的路上,打开此选项可以防止ai将建筑休眠。" +} + + +// ======================= +// 5.12.2018 +// ======================= + +o_onlyai +{ + "打开观察者模式" +} + +o_onlyai_descr +{ + "移除了玩家1使得玩家只能以观察的视角观看游戏,这使得8个ai同时出场成为了可能。该模式下保存的游戏可以被正常读取。偶尔可能会出现物体随机遍布在整个地图的bug,这只是视觉上的bug并不影响游戏本身,保存游戏,退出游戏,再读取游戏可以清除该bug。" +} + +o_moatvisibility +{ + "一直显示规划中的护城河" +} + +o_moatvisibility_descr +{ + "你将可以一直看到规划中的护城河,而不需要点选单位。" +} + +o_engineertent +{ + "无需重复选择工程师帐篷类型" +} + +o_engineertent_descr +{ + "打开这个选择之后,选择一次工程师帐篷类型后即可一直放置该类型的工程师& +帐篷,而不需要每次都再选择一次。" +} + + + + + + + + + + +// ================================ +// 2.07 +// ================================ + + +ai_demolish_trapped +{ + "城堡与外界隔绝" +} + +ai_demolish_trapped_descr +{ + " " +} + +o_freetrader +{ + "免费市场" +} + +o_freetrader_descr +{ + "有时ai的市场被拆除且没有木头时,ai将会彻底瘫痪。使市场免费可以避免此问题。" +} + +ai_towerengines +{ + "解除ai的器械数量限制" +} + +ai_towerengines_descr +{ + "在原版,每种器械ai最多只能放置3个,打开此选项可以解除此限制。" +} + +ai_buywood +{ + "购买足够木头" +} + +ai_buywood_descr +{ + "ai购买木头用于建筑时,将会购买2根额外的木头,防止刚购买的木头被& +工人拿走使得木头不足以建造目标建筑。" +} + +o_keys +{ + "WASD键移动以及Ctrl+S/L键保存读取" +} + +o_keys_descr +{ + "打开此选项后,可以使用WASD键移动屏幕,以及Ctrl+S键打开保存界面,& +Ctrl+L键打开读取界面。" +} + + + + + + + + + + + + + + + + + + + + + +// =========== +// 2.07a +// =========== + + + +ai_attacktarget +{ + "设置ai的目标敌人" +} + +ai_attacktarget_nearest +{ + "最近的敌人" +} + +ai_attacktarget_nearest_descr +{ + " " +} + +ai_attacktarget_richest +{ + "最富有的敌人" +} + +ai_attacktarget_richest_descr +{ + " " +} + +ai_attacktarget_weakest +{ + "最弱的敌人" +} + +ai_attacktarget_weakest_descr +{ + "该选项可以给所有ai设置相同的目标选择。" +} + + + + + + + + + +// ==================== +// 2.08 +// ==================== + + + + + +ai_assaultswitch +{ + "进攻时不改变目标" +} + +ai_assaultswitch_descr +{ + "当ai进攻时,如果目标发生改变,将会改变已派出部队的目标,比如ai目标若是最弱的敌人,当ai已派出进攻部队时,如果最弱的敌人改变了,将会改变进攻部队的路径转而攻击新目标。打开这个选项可以防止这种现象的发生。已派出的部队不会中途改变目标。" +} + + + +ai_rebuild +{ + "增强ai修复和建筑能力" +} + +ai_rebuild_descr +{ + "打开后,ai将会在废墟中重建塔楼,修复微小损坏的城墙。工程师协会,隧道工协会,油锅被摧毁后,如果后半截仍然存在,打开后ai将可以正确重建。采石场被摧毁后,如果存放石头点仍然存在,打开后ai可以无视存放石头点放置建筑。" +} + + + + + +// ==================== +// 2.09 +// ==================== + +o_healer +{ + "医生会治愈伤员" +} + +o_healer_descr +{ + "药房的医生现在会积极寻找兵治疗受伤的士兵,平民或者动物。 & +优先治疗最近的目标。每次治疗动画中,可恢复长矛兵血量的1/3。 游览& +花园和治疗瘟疫的功能依旧存在! 只有游览城堡的行为会被跳过,直到该& +地区不再有受伤的目标." +} + + + + + + +// ==================== +// 2.10 +// ==================== + + + +o_xtreme +{ + "移除增强版的技能条" +} + +o_xtreme_descr +{ + "移除要塞十字军东征增强版中的技能条。" +} + + +// ====================== +// 2.11 +// ====================== + + +ui_AIV +{ + "AIV" +} + +ai_access +{ + "不拆除无通路建筑" +} + +ai_access_descr +{ + "ai会反复建造又拆除无通路但需要通路的建筑,打开此选项可以避免此问题。" +} + +ai_moredef +{ + "老鼠,菲利普,狮心王将会有更多的防守部队" +} + +ai_moredef_descr +{ + "在原版,这三个ai只有很少的防守部队,打开此选项后可以增多他们的& +防守部队数量,如下: + +老鼠: 20 -> 40 +狮心王: 20 -> 40 +菲利普: 4 -> 32 + +需要注意的是,打开此选项后,会导致这三个ai的初次进攻时间延后。" +} + +ai_attackwave +{ + "提升ai的进攻" +} + +ai_attackwave_descr +{ + "在原版中,ai在进攻时,只会派出能够得着城墙的数量的士兵,比如说一圈城堡有50格城墙,那么只有50个人可以在不重叠的情况下砍城墙,此时哪怕有100名士兵集结在敌人城堡附近,也只会派出50人前去攻击城堡,打开此选项后将可以避免此现象。并且,打开此选项后,ai的士兵将会主动攻击城堡建筑和经济建筑。此外,ai将会派出更多的士兵去攻击敌人的领主。" +} diff --git a/UnofficialCrusaderPatch/Localization/English.txt b/UnofficialCrusaderPatch/Localization/English.txt new file mode 100644 index 00000000..5dd881c2 --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/English.txt @@ -0,0 +1,1071 @@ +// ====================== +// 2.15 +// ====================== +u_spearmen_run +{ +"Spearmen run by default instead of walking" +} + +u_spearmen_run_descr +{ +"Makes spearmen run by default like slaves and macemen." +} + +o_seed_modification_possibility_title +{ +"Manipulate random number generator" +} + +o_seed_modification_possibility_only_set +{ +"Enable fixed game randomseed" +} + +o_seed_modification_possibility_only_set_descr +{ +"Setting the Game seed will allow AI-only games to play out the same way if the same map settings are used. For games involving human players, it will ensure the same starting conditions in the map (e.g. AIV selection). To set the game seed, enable this option and create a file called 'live' containing an integer in the [game install]/gameseeds directory. CAUTION: This feature only works after also restarting the game!" +} + +o_seed_modification_possibility +{ +"Enable & Save game randomseeds" +} + +o_seed_modification_possibility_descr +{ +"This option will save the seed from games that do not have a live seed set, so you can rename them to 'live' in order to recreate the match afterwards." +} + +ai_recruitstate_initialtimer +{ +"Set AIs initial time until they recruit by the AIC parameters" +} + +ai_recruitstate_initialtimervalue_descr +{ +"Set this value to number of months for which the AI will exclusively recruit defence troops, unless it has already filled up its defence total" +} + +ai_defense +{ +"Fix reinforcement of defense troops" +} + +ai_defense_descr +{ + "Fixes a bug which stopped the AI from reinforcing missing troops & +on walls and towers, as long as defensive patrols were still around." +} + +ai_housing +{ +"Let the AI build houses smarter" +} + +build_housing_descr +{ +"Difference between current and maximum population, above which the AI stops building houses. This is 0 in vanilla. This also disables deleting of houses for the AI." +} + +campfire_housing_descr +{ +"Number of idle peasants at the campfire before the AI stops building houses. This also disables deleting of houses for the AI." +} + +delete_housing +{ +"Disable the AI's ability to delete houses." +} + +delete_housing_descr +{ +"When this option is selected the AI will never delete houses." +} + +aiv_prompt +{ +"Custom AIVs detected. Do you want to create a backup Milord?" +} + +aiv_cli_prompt +{ +"Custom AIVs detected. Enter 'delete' to erase or enter folder name to copy files to." +} + +install_abort_io +{ +"Installation aborted. Files with the same name already exist in this folder. Please try again and select a different folder." +} + +install_abort +{ +"Installation aborted" +} + +backup_aiv_select +{ +"Select Backup AIV folder" +} + +o_change_siege_engine_spawn_position_catapult +{ +"Spawn siege engines in the center of their tent" +} + +o_change_siege_engine_spawn_position_catapult_descr +{ +"Siege engines are spawning in the middle of their construction tent, instead of the top right corner." +} + +o_stop_player_keep_rotation +{ +"Rotate player keeps same as AI's" +} + +o_stop_player_keep_rotation_descr +{ +"Player keeps now get rotated the same way, that AI keeps rotate on a map, facing with their campfire outwards towards the map edge." +} + +o_restore_arabian_engineer_speech +{ +"Restore engineer arabian speech" +} + +o_restore_arabian_engineer_speech_descr +{ +"Allows engineers to speak the originally recorded arabian voicelines when the player uses the Arabian lord." +} + +u_fix_lord_animation_stuck_movement +{ +"Reset lord animation after destroying buildings" +} + +u_fix_lord_animation_stuck_movement_descr +{ +"Reset the pose of the lord after it stops moving or destroys a building into the upright position. Usually it would get stuck bend down to the ground." +} + +fix_apple_orchard_build_size +{ +"Shrink apple orchard's build size" +} + +fix_apple_orchard_build_size_descr +{ +"Changes the apple orchard's build size to the size it occupies after the farm is placed down. This saves some space when building the farms and increases the rate with which the AI is able to put these farms down." +} + +u_fix_applefarm_blocking +{ +"Fix apple farm worker getting blocked" +} + +u_fix_applefarm_blocking_descr +{ +"Apple farmers can no longer be blocked by placing buildings at the top left side of the farm." +} + +o_increase_path_update_tick_rate +{ +"Check more often for available paths" +} + +o_increase_path_update_tick_rate_descr +{ +"In vanilla, it took 200 game ticks to check for new paths, often stopping units to move into the castle after destroying a gate or tower immediately. + +Availability is calculated every 50 gameticks now, allowing the units to 'realize' new paths more quickly." +} + +o_fix_ladderclimb +{ +"Fix ladder climbing destination bug" +} + +o_fix_ladderclimb_descr +{ +"Units will now remember their original destination after climbing a ladder, not getting stuck on the ladder." +} + +u_tanner_fix +{ +"Fix tanners getting all the same cow" +} + +u_tanner_fix_descr +{ +"Tanners will no longer return without a cow when another tanner took their target cow. They will now instead stand around a bit and then get another one." +} + +o_fix_fletcher_bug +{ +"Fix fletcher pathing" +} + +o_fix_fletcher_bug_descr +{ +"Fixes the behaviour where fletchers go back to the workplace after depositing the bow/crossbow instead of going straight to the stockpile." +} + +ai_fix_crusader_archers_pitch +{ +"Fix AI's crusader archers not lighting pitch" +} + +ai_fix_crusader_archers_pitch_descr +{ +"AI's European archers light pitch the same way arabian archers do, defending against enemy units." +} + +o_fix_baker_disappear +{ +"Fix bakers despawning" +} + +o_fix_baker_disappear_descr +{ +"Bakers no longer disappear when they don't find flour at their targeted stockpile." +} + +o_fix_moat_digging_unit_disappearing +{ +"Fix despawning of digging units" +} + +o_fix_moat_digging_unit_disappearing_descr +{ +"Fixes the bug where moat digging units would disappear while digging. Note that they can still disappear if you order them to move while standing on unwalkable terrain!" +} + +ui_welcometext +{ +"This is an unofficial patch for Stronghold Crusader. +The project ist available as open-source on [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). + +Any Crusader version is potentially supported, but since the changes were derived from the 1.41 Steam-Version, incompatibilities may appear. +The setup will then show error messages. The installed patch version is shown in the bottom left corner of the main menu of the game. +Before any changes, backup files will be created. These can be restored via the 'Uninstall'-button or manually. + +The team behind the UCP + +Creator of the UCP +[Sh0wdown](https://github.com/Sh0wdown) + +Project Management +[Kimberly Azula](https://github.com/ByBurton/) +[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) + +Developers +[LordHansCapon](https://github.com/LordHansCapon) +[np123](https://github.com/patel-nikhil) +[J-T-de](https://github.com/J-T-de) +[gynt](https://github.com/gynt) +[Le spec](https://github.com/LeSpec) +[Chaf1812](https://github.com/Chaf1812) + +Translators +[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polish) +[Lolasik011](https://github.com/Lolasik011) (Russian) +[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chinese) +[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Hungarian) + +Content Creators +[Evrey](https://github.com/Evrey) (aiv) +[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) +[PitchNeeded](https://github.com/PitchNeeded) (aiv) +[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) + +Special thanks of course go to +[Firefly Studios](https://fireflyworlds.com/) +for the creation of the Stronghold series + +And many more +[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) +[PodeCaradox](https://github.com/PodeCaradox) +[GRhin](https://www.twitch.tv/grhin) +[Heroesflorian](https://github.com/Heroesflorian)" +} + +// ====================== +// 2.14 +// ====================== + +ui_StartTroops +{ + "StartTroops" +} + +ui_Resource +{ + "StartGoods" +} + +ui_aicconflict +{ + "conflict and will be ignored" +} + +o_shfy +{ + "Strongholdify" +} + +o_shfy_beer +{ + "Popularity bonus from beer" +} + +o_shfy_beer_descr +{ + " " +} + +o_shfy_religion +{ + "Popularity bonus from cathedral and church" +} + +o_shfy_religion_descr +{ + " " +} + +o_shfy_peasantspawnrate +{ + "Spawnrate peasants" +} + +o_shfy_peasantspawnrate_descr +{ + " " +} + +o_shfy_resourcequantity +{ + "Quantity of delivered resources" +} + +o_shfy_resourcequantity_descr +{ + "Adapts listed aspects to match Stronghold 1. Attention: Every change influences the AI lords, in the worst case renders them useless!" +} + +o_armory_marketplace_weapon_order_fix +{ + "Fix armory/marketplace weapon orders to match" +} + +o_armory_marketplace_weapon_order_fix_descr +{ + "Reorders Weapon icons in Armory and Marketplace to have the same order. Also moves Leather Armor between Mace and Crossbow, and moves Metal Armor between Polearm and Sword for easier access while in Marketplace scrolling through items." +} + +ai_fix_laddermen_with_enclosed_keep +{ + "Fix AI not using laddermen if they are enclosed" +} + +ai_fix_laddermen_with_enclosed_keep_descr +{ + "AI (notably Snake) no longer stops using Laddermen with their sieging units if their keep is enclosed." +} + +o_override_identity_menu +{ + "Override the Set-up Identity menu adding new features" +} + +o_override_identity_menu_descr +{ + "Adds Ranged and Melee unit selection to Set-up Identity menu. ONLY FOR NORMAL GAME MODE!" +} + +o_default_multiplayer_speed +{ + "Set default multiplayer speed." +} + +o_default_multiplayer_speed_descr +{ + " " +} + +u_fireballistafix +{ + "Fire ballistae shoot monks and tunnelers" +} + +u_fireballistafix_descr +{ + "Fire ballistae automatically shoot at monks and tunnelers." +} + +ui_browsepath +{ + "Please choose your Stronghold Crusader installation directory." +} + +ui_aicoldversion +{ + "Old version detected. Click to convert" +} + +ui_aicofferconvert +{ + "Convert aic file to newer version?" +} + +ui_aicconvertprompt +{ + "AIC Conversion" +} + +ui_aicselect +{ + "Please deselect other AIC file(s) first. The following aic characters are already selected: " +} + +// ====================== +// 2.13 +// ====================== + +o_firecooldown +{ + "Extend fireproof duration of extinguished buildings" +} + +o_firecooldown_descr +{ + "The duration in which extinguished buildings cannot catch fire again can be extended here." +} + +u_ballistamonk +{ + "Fire ballistas shoot monks" +} + +u_ballistamonk_descr +{ + "Fire ballistas shoot automatically at monks with this setting." +} + + +// ====================== +// 2.12 +// ====================== + +ui_AIC +{ + "AIC" +} + +ui_aicExport +{ + "Export" +} + +ui_aicExport_success +{ + "Exported successfully." +} + +ui_aicHint +{ + "Exports the .aic-file from the installer into the crusader folder." +} + +// ====================== +// 1.00 +// ====================== + +Name +{ + "Unofficial Crusader Patcher" +} + +u_ArabXBow +{ + "Increased armor of Arabic Swordsmen against crossbows" +} + +u_arabxbow_descr +{ + " - Arabic Swordsmen only die after 6 crossbow hits intead of 3" +} + +u_ArabWall +{ + "Arabic Swordsmen destroy walls faster" +} + +u_ArabWall_descr +{ + "In Vanilla, arabic swordsmen destroy walls slower than any other melee unit. & +With this option, the tear down speed against walls is about doubled for them, & +putting them slightly above Spearmen." +} + +u_spearmen +{ + "Increased armor of spearmen against ranged units" +} + +u_spearmen_descr +{ + " - Spearmen only die after 5 arrow hits instead of 3 + - Spearmen barely survive one crossbow hit, instead of getting one-shot" +} + +ui_error +{ + "Error" +} + +ui_SearchPath +{ + " Please select your installation folder:" +} + +ui_search +{ + "Browse" +} + +ui_continue +{ + "Continue" +} + +ui_wrongpath +{ + "Stronghold Crusader could not be found in the specified path!" +} + +ui_back +{ + "Back" +} + +ui_install +{ + "Install" +} + +ui_finished +{ + "Finished" +} + +ui_chooseLangTitle +{ + "Setup language" +} + +ui_chooseLang +{ + "Please choose a language for this setup from the list below." +} + +ui_accept +{ + "OK" +} + +ui_cancel +{ + "Cancel" +} + +ui_uninstall +{ + "Uninstall" +} + +ui_uninstalldone +{ + "Uninstall completed." +} + +ai_recruitinterval +{ + "Increased recruitment speed" +} + +ai_recruitinterval_descr +{ + "Sets the recruitment interval of all AIs to the lowest value (Rat/Richard niveau)" +} + +ai_attacklimit +{ + "Increase of the attacking troops limit of the AIs" +} + +ai_attacklimit_descr +{ + "The number of additional units which are added after the first attack is & +limited to 200 in Vanilla. Here you can change this limit." +} + +o_gamespeed +{ + "Extended game speed limits" +} + +o_gamespeed_descr +{ + "The game speed can now be changed as follows: + - From 10 to 90 in intervals of 5 + - From 90 to 200 in intervals of 10 + - From 200 to 1000 in intervals of 100 +The new values are only available ingame via the +- keys, the slider in the & +game menu remains unchanged." +} + +ui_bugfix +{ + "Bugfixes" +} + +ui_ailords +{ + "AI lords" +} + +ui_troops +{ + "Units" +} + +ui_other +{ + "Other" +} + +o_responsivegates +{ + "Quicker responsiveness of gates towards enemies" +} + +o_responsivegates_descr +{ + "Gates close themselves later if enemies get into range and open faster & +when the danger is gone. The distance of an enemy for which the gates close & +will be reduced from 200 to 140. The time after which the gates open, after & +all enemies left will be reduced from 1200 to 100." +} + +ai_addattack +{ + "Increase of the rate of additional attack troops" +} + +ai_addattack_descr +{ + "In Vanilla the attack troop number is increased after each attack by 5 & +units on average. This value is the same for all AI lords and can be changed & +here." +} + +ai_addattack_alt_descr +{ + "Alternatively, the additional troop count can be made dependent on the & +troop count of the first attack. Since this value is different for each AI, & +the following attacks will also scale, instead of increasing by the same value & +for each AI lord. +Example: Scale factor = 0.5 +Sultan's attack troops = 10, 15, 20, 25, ... +Saladin's attack troops = 50, 75, 100, 125, ..." +} + +u_laddermen +{ + "Increased armor of laddermen against ranged units" +} + +u_laddermen_descr +{ + " - Laddermen die after 12 arrow hits instead of 5 + - Laddermen die after 5 crossbow or slinger hits instead of 2 + - Laddermen cost 20 gold instead of 4" +} + +o_playercolor +{ + "Change the color of player 1" +} + +o_playercolor_descr +{ + " " +} + +ai_demolish +{ + "Deactivate demolishing for money of the AI lords" +} + +ai_demolish_walls +{ + "fortification buildings" +} + +ai_demolish_eco +{ + "econonmy buildings" +} + +ai_demolish_walls_descr +{ + " " +} + +ai_demolish_eco_descr +{ + "If the AI feels pressured, it likes to demolishes its economy or & +fortification buildings to get quick money for troops. This feature sometimes & +seems to be triggered without any visible reason and thus can be disabled here." +} + +ai_tethers +{ + "Disable ox tether spam" +} + +ai_tethers_descr +{ + "Usually, the AI builds for each new stone quarry a new ox tether, & +independent of how many tether already exist. This can be disabled here, since & +it leads to ox tether spam if the AIs' quarries get destroyed repeatedly." +} + + + + + + + + + + +// ======================= +// 2.06 +// ======================= + +ai_nosleep +{ + "Disable sleeping mode for lack of resources" +} + +ai_nosleep_descr +{ + "The AI usually puts its processing buildings to sleep, as soon & +as the needed resource is missing. This is done without the regard for & +losing products which are just on the way f.e. to the weapon chamber. +This feature can be completely disabled here." +} + + + + + + + + +// 5.12.2018 + +o_onlyai +{ + "Activate Spectator-mode [bug possible]" +} + +o_onlyai_descr +{ + "Removes player 1 so that you can only spectate and makes 8 AIs in one & +round possible. Savegames now load properly in this mode. Sometimes a bug & +appears in which random objects spawn all over the map. This is just visually & +and can be removed by saving the game, ending the mission and reloading the & +save file." +} + +o_moatvisibility +{ + "Always show planned moat" +} + +o_moatvisibility_descr +{ + "Your own placed but not digged out moat will always be shown with this & +setting, even if you deselect the moat placing." +} + +o_engineertent +{ + "No siege tent deselection" +} + +o_engineertent_descr +{ + "With this setting, the game will not deselect your chosen siege equipment & +after placing one tent anymore. This way you can create several tents after another & +without having to reselect the same siege equipment every time." +} + + + + + + + + + + +// ================================ +// 2.07 +// ================================ + + +ai_demolish_trapped +{ + "If enclosed" +} + +ai_demolish_trapped_descr +{ + " " +} + +o_freetrader +{ + "Free trader post" +} + +o_freetrader_descr +{ + "Since the AI sometimes plays itself, when they're out of wood and their trader post & +is destroyed. With this setting, the trader post will become free of cost to prevent this." +} + +ai_towerengines +{ + "No limit for siege engines on towers" +} + +ai_towerengines_descr +{ + "Usually the AI only builds up to three mangonels and ballistae each on its towers. & +This limit can be lifted here." +} + +ai_buywood +{ + "Buy enough wood" +} + +ai_buywood_descr +{ + "To prevent thievish fletchers from stealing wood which the AI just bought for & +buildings, 2 extra wood will now be bought for each building." +} + +o_keys +{ + "WASD-Keys and quicksaves" +} + +o_keys_descr +{ + "The WASD-keys can be used to move around with this setting as well as & +CTRL-S and CTRL-L to quicksave and load respectively." +} + + + + + + + + + + + + + + + + + + + + + +// =========== +// 2.07a +// =========== + + + +ai_attacktarget +{ + "Set AI attack target" +} + +ai_attacktarget_nearest +{ + "Nearest enemy" +} + +ai_attacktarget_nearest_descr +{ + " " +} + +ai_attacktarget_richest +{ + "Richest Enemy" +} + +ai_attacktarget_richest_descr +{ + " " +} + +ai_attacktarget_weakest +{ + "Weakest Enemy" +} + +ai_attacktarget_weakest_descr +{ + "With this setting, all AI lords will chose their next attack target in & +the same way. This prevents troops switching targets during a castle assault & +as well as sending them past other enemies' castles to gather." +} + + + + + + + + + +// ==================== +// 2.08 +// ==================== + + + + + +ai_assaultswitch +{ + "No AI target change during sieges" +} + +ai_assaultswitch_descr +{ + "AI lords which attack the mightiest oder weakest enemy sometimes & +switch their target in the middle of an ongoing assault and send their & +troops to a different castle. This is prevented with this setting, as soon & +as the assault has started, i.e. during the troop gathering phase in front of & +a castle a change can still happen." +} + + + +ai_rebuild +{ + "Improved AI repairs" +} + +ai_rebuild_descr +{ + "The AI will repair tower ruins, slightly damaged walls, as well as & +destroyed engineer's and tunneler's guilds and oil smelters, of which the gathering place & +still exists. Furthermore, the AI can now build over the collection platform & +of quarries." +} + + + + + +// ==================== +// 2.09 +// ==================== + +o_healer +{ + "Healer heals casualties" +} + +o_healer_descr +{ + "The healer of the apothecary building now actively seeks out injured soldiers, & +civilists and animals to heal them. The nearest targets are treated first. With each & +healing animation ca. 1/3 of a spearman's health is recovered. The strolling through & +gardens and investigation of plague clouds is not replaced! Only the strolling through & +the castle is skipped until no more wounded targets are in the area." +} + + + + + + +// ==================== +// 2.10 +// ==================== + + + +o_xtreme +{ + "Remove the magic bar in Extreme" +} + +o_xtreme_descr +{ + "Removes the magic bar in Crusader Extreme." +} + + +// ====================== +// 2.11 +// ====================== + + +ui_AIV +{ + "AIV" +} + +ai_access +{ + "No demolishing of inaccessible buildings" +} + +ai_access_descr +{ + "Prevents the AI from demolishing buildings without access. This should & +stop the AI from continuously demolishing and rebuilding buildings where no & +access is available." +} + +ai_attackwave +{ + "Improve attack waves" +} + +ai_attackwave_descr +{ + "The AI in an attack in vanilla only sends as many troops at once as & +there are wall parts reachable. This causes units to drop in in small waves & +when the target castle has a lot of buildings directly at its walls. +This option makes units also attack civil and fortification buildings, as & +well as wall parts which are already being attacked by one unit. Moreover, +the AI sends more troops to the enemy lord as soon as it detects a breach." +} diff --git a/UnofficialCrusaderPatch/Localization/German.txt b/UnofficialCrusaderPatch/Localization/German.txt new file mode 100644 index 00000000..15ae5079 --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/German.txt @@ -0,0 +1,1075 @@ +// ====================== +// 2.15 +// ====================== + +u_spearmen_run +{ +"Speerträger rennen standardmäßig" +} + +u_spearmen_run_descr +{ +"Speerträger rennen standardmäßig so schnell wie Sklaven und Streitkolbenkämpfer." +} + +o_seed_modification_possibility_title +{ +"Manipuliere Zufallszahlengenerator" +} + +o_seed_modification_possibility_only_set +{ +"Ermögliche Festlegung eines Zufallsstartwertes" +} + +o_seed_modification_possibility_only_set_descr +{ +"Das Setzen eines Startwertes für den Zufallszahlen Generator ermöglicht es für KI Spiele immer den gleichen Verlauf zu nehmen. Für Spiele mit menschlichen Spielern und KI können feste Startbedingungen ermöglicht werden (z.B. die gleiche Auswahl von AIV Dateien für die KI). Um den Zufallsstartwert zu setzen, erstelle eine Datei mit dem Namen 'live', welche eine ganze Zahl enthält im Ordner Installationsverzeichnis/gameseeds. ACHTUNG: Vor Beginn eines wiederholbaren Scharmützels muss das Spiel neu gestartet werden!" +} + +o_seed_modification_possibility +{ +"Ermögliche & Speichere Zufallsstartwerte" +} + +o_seed_modification_possibility_descr +{ +"Mit dieser Option werden Zufallsstartwerte von Spielen gespeichert, für die keiner im gameseeds Ordner gesetzt wurde. So können diese nachträglich in 'live' umbenannt werden um das Spiel zu wiederholen." +} + +ai_recruitstate_initialtimer +{ +"Setzt den Zeitpunkt, ab dem KIs anhand der AIC rekrutieren" +} + +ai_recruitstate_initialtimervalue_descr +{ +"Anzahl an Monaten, ab der die KI anhand der in der AIC festgelegten Rekrutierungswahrscheinlichkeiten rekrutiert. Bis dahin rekrutiert sie ausschließlich Defensivtruppen bis diese vollständig sind und daraufhin Angriffstruppen." +} + +ai_defense +{ +"Verstärkung der Burgverteidigung fixen" +} + +ai_defense_descr +{ +"Fixt den Bug, der die KI davon abhielt, fehlende Truppen auf Wällen und Türmen zu verstärken solange noch Defensivpatrouillien vorhanden waren." +} + +ai_housing +{ +"Intelligenteres Errichten und Abreißen von Häusern" +} + +build_housing_descr +{ +"Die Differenz aus aktueller und maximal möglicher Bevölkerung, ab der KIs keine Häuser mehr bauen. In Vanilla ist diese 0. Zudem deaktiviert diese Option das Abreißen von Häusern für KIs." +} + +campfire_housing_descr +{ +"Wenn mehr als diese Anzahl an freien Bauern am Lagerfeuer sitzen, baut die KI keine Häuser mehr. Zudem deaktiviert diese Option das Abreißen von Häusern für KIs." +} + +delete_housing +{ +"Kein Abreißen von Häusern der KIs" +} + +delete_housing_descr +{ +"Mit dieser Option reißen KIs keine Häuser mehr ab." +} + +aiv_prompt +{ +"Modifizierte AIVs erkannt. Wollen Eure Lordschaft jetzt ein Backup anlegen?" +} + +aiv_cli_prompt +{ +"Modifizierte AIVs erkannt. Schreibe 'delete', um sie zu löschen oder einen Ordnernamen, um ein Backup zu erstellen." +} + +install_abort_io +{ +"Installation abgebrochen. Dateien mit dem selben Namen waren bereits im gewählten Ordner vorhanden. Bitte wählen Eure Lordschaft einen anderen Ordner aus." +} + +install_abort +{ +"Installation abgebrochen" +} + +backup_aiv_select +{ +"Backup AIV Ordner auswählen" +} + +o_change_siege_engine_spawn_position_catapult +{ +"Belagerungsgeräte in der Mitte des Zelts aufbauen" +} + +o_change_siege_engine_spawn_position_catapult_descr +{ +"Belagerungsgeräte erscheinen nun nach dem Aufbauen am Punkt der Zeltmitte, statt wie bisher in der oberen rechten Ecke des Zelts." +} + +o_stop_player_keep_rotation +{ +"Drehe Spielerbergfriede wie die der KIs" +} + +o_stop_player_keep_rotation_descr +{ +"Die Bergfriede der Spieler richten sich nun so aus wie die der KI; sie drehen sich so, dass das Lagerfeuer in Richtung des Kartenrands zeigt." +} + +o_restore_arabian_engineer_speech +{ +"Baumeister arabischer Lords sprechen Arabisch" +} + +o_restore_arabian_engineer_speech_descr +{ +"Falls der Spieler den arabischen Lord auswählt nutzen Baumeister nun ihre arabischen Sprachdateien." +} + +u_fix_lord_animation_stuck_movement +{ +"Setzt die Lordanimation nach Zerstörung von Gebäuden zurück" +} + +u_fix_lord_animation_stuck_movement_descr +{ +"Der Lord wechselt mit dieser Änderung nach dem Zerstören eines Gebäudes in seine Ausgangsposition. Bisher blieb er in der Zerstöranimation stecken." +} + +fix_apple_orchard_build_size +{ +"Reduziert die Baugröße von Apfelfarmen" +} + +fix_apple_orchard_build_size_descr +{ +"Ändert die Bauvorschau von Apfelfarmen auf die Größe, die sie nach der Platzierung der Farm haben." +} + +u_fix_applefarm_blocking +{ +"Behebt das Blockieren des Apfelfarmers" +} + +u_fix_applefarm_blocking_descr +{ +"Apfelfarmer werden nicht länger inaktiv, wenn der Pfad links oben direkt neben der Farm blockiert wird." +} + +o_increase_path_update_tick_rate +{ +"Suche öfter nach verfügbaren Wegen" +} + +o_increase_path_update_tick_rate_descr +{ +"Das Spiel überprüft nun viermal so häufig, welche Bereiche der Karte verbunden sind. Dadurch können beispielsweise nach der Zerstörung eines Torhauses oder eines Turmes die Truppen schneller ins Innere einer zuvor unzugänglichen Burg beordert werden." +} + +o_fix_ladderclimb +{ +"Behebt Befehlsverlust beim Klettern auf Leitern" +} + +o_fix_ladderclimb_descr +{ +"Einheiten klettern nicht mehr direkt zurück und vergessen auch nicht mehr ihr Ziel, nachdem sie eine Leiter erklommen haben." +} + +u_tanner_fix +{ +"Gerberinnen holen sich unterschiedliche Kühe" +} + +u_tanner_fix_descr +{ +"Gerberinnen kehren nicht länger ohne Kuh zurück, falls ihre anvisierte Kuh bereits weg ist. Sie warten nun, bis sie eine andere Kuh mitnehmen können." +} + +o_fix_fletcher_bug +{ +"Entfernt den Extraweg des Pfeilmachers zur Werkstatt" +} + +o_fix_fletcher_bug_descr +{ +"Passt das Verhalten des Pfeilmachers an andere Waffenproduzenten an. Nach Abgabe seines Gutes geht er nun direkt zum Vorratslager, statt erneut zur Werkstatt zurückzukehren." +} + +ai_fix_crusader_archers_pitch +{ +"Europäische Bogenschützen der KI entzünden Pech." +} + +ai_fix_crusader_archers_pitch_descr +{ +"Bisher waren nur Arabische Bogenschützen der KIs in der Lage Pechgraben mit Feuerpfeilen zu entzünden; nun können dies auch Europäischen Bogenschützen." +} + +o_fix_baker_disappear +{ +"Behebt das Verschwinden von Bäckern" +} + +o_fix_baker_disappear_descr +{ +"Behebt den Fehler, der Bäcker verschwinden ließ, wenn sie kein Mehl am angestrebten Platz im Vorratslager vorfinden konnten." +} + +o_fix_moat_digging_unit_disappearing +{ +"Behebt das Verschwinden von Buddeleinheiten." +} + +o_fix_moat_digging_unit_disappearing_descr +{ +"Behebt das Verschwinden von Truppen, die mit dem Ausheben von Burggräben beschäftigt sind. Diese verschwinden allerdings weiterhin, falls diese neue Befehle bekommen und zeitgleich auf unbegehbarem Terrain stehen." +} + +ui_welcometext +{ +"Dies ist ein inoffizieller Patch für Stronghold Crusader. +Das Projekt ist Open-Source auf [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch) zu finden. + +Potenziell wird jede Crusader-Version unterstützt, die Änderungen wurden allerdings anhand der 1.41 Steam-Version hergeleitet. +Im Falle von Versionsinkompatibilität wird der Setup Fehlermeldungen zeigen. Die installierte Patchversion wird unten links im Hauptmenü angezeigt. +Vor jeglichen Änderungen werden Backup-Dateien erstellt, die über den 'Deinstallieren'-Button oder manuell wiederhergestellt werden können. + +Das Team hinter dem inoffiziellen Patch + +Erschaffer des UCP +[Sh0wdown](https://github.com/Sh0wdown) + +Projektleitung +[Kimberly Azula](https://github.com/ByBurton/) +[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) + +Entwickler +[LordHansCapon](https://github.com/LordHansCapon) +[np123](https://github.com/patel-nikhil) +[J-T-de](https://github.com/J-T-de) +[gynt](https://github.com/gynt) +[Le spec](https://github.com/LeSpec) +[Chaf1812](https://github.com/Chaf1812) + +Übersetzer +[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polnisch) +[Lolasik011](https://github.com/Lolasik011) (Russisch) +[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chinesisch) +[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Ungarisch) + +Inhaltliche Beiträge +[Evrey](https://github.com/Evrey) (aiv) +[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) +[PitchNeeded](https://github.com/PitchNeeded) (aiv) +[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) + +Besonderer Dank geht an +[Firefly Studios](https://fireflyworlds.com/) +für die Erstellung der Stronghold Serie + +Und viele mehr +[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) +[PodeCaradox](https://github.com/PodeCaradox) +[GRhin](https://www.twitch.tv/grhin) +[Heroesflorian](https://github.com/Heroesflorian)" +} + +// ====================== +// 2.14 +// ====================== + +ui_StartTroops +{ + "Starttruppen" +} + +ui_Resource +{ + "Startgüter" +} + +ui_aicconflict +{ + "Konflikt und wird ignoriert" +} + +o_shfy +{ + "Strongholdify" +} + +o_shfy_beer +{ + "Beliebtheitsbonus durch Bier" +} + +o_shfy_beer_descr +{ + " " +} + +o_shfy_religion +{ + "Beliebtheitsbonus Kathedrale und Kirche" +} + +o_shfy_religion_descr +{ + " " +} + +o_shfy_peasantspawnrate +{ + "Spawngeschwindigkeit Bauern" +} + +o_shfy_peasantspawnrate_descr +{ + " " +} + +o_shfy_resourcequantity +{ + "Anzahl der gelieferten Resourcen" +} + +o_shfy_resourcequantity_descr +{ + "Passt aufgelistete Aspekte an Stronghold 1 an. Achtung: Jede Annpassung nimmt Einfluss auf die KI Lords, schlimmstenfalls werden diese nutzlos!" +} + +o_armory_marketplace_weapon_order_fix +{ + "Vereinheitlicht Waffenreihenfolge" +} + +o_armory_marketplace_weapon_order_fix_descr +{ + "Vereinheitlicht Waffenreihenfolge in Waffenkammer und Marktplatz. Es befinden sich nun Lederrüstungen zwischen Streitkolben und Armbrüste, und Rüstungen zwischen Piken und Schwertern für einfacheres Scrollen im Marktplatz." +} + +ai_fix_laddermen_with_enclosed_keep +{ + "Korrigiert Leiternutzung" +} + +ai_fix_laddermen_with_enclosed_keep_descr +{ + "Mit diesem Fix können Belagerungseinheiten von KIs, deren Bergfried abgeschlossen ist, weiterhin die Leitern der Leiterträger nutzen (betrifft vanilla nur die Schlange)." +} + +o_override_identity_menu +{ + "Fügt neue Optionen zum Menüpunkt 'Identität zulegen' hinzu" +} + +o_override_identity_menu_descr +{ + "Im Menüpunkt 'Identität zulegen' kann man nun die Starteinheiten für 'Normales Spiel' ändern" +} + +o_default_multiplayer_speed +{ + "Setzt Mehrspieler Standardgeschwindigkeit" +} + +o_default_multiplayer_speed_descr +{ + " " +} + +u_fireballistafix +{ + "Feuerballisten schießen auf Mönche und Tunnelgräber" +} + +u_fireballistafix_descr +{ + "Feuerballisten erkennen nun Mönche und Tunnelgräber als Feinde und schießen auf diese." +} + +ui_browsepath +{ + "Bitte wähle dein Stronghold Crusader - Installationsverzeichnis." +} + +ui_aicoldversion +{ + "Alte Version erkannt. Klicken Sie zum Konvertieren" +} + +ui_aicofferconvert +{ + "AIC-Datei in neuere Version konvertieren?" +} + +ui_aicconvertprompt +{ + "AIC-Konvertierung" +} + +ui_aicselect +{ + "Bitte deaktivieren Sie zuerst andere AIC-Dateien. Die folgenden aic-Zeichen sind bereits ausgewählt: " +} + + +// ====================== +// 2.13 +// ====================== + +o_firecooldown +{ + "Feuerfeste Zeit gelöschter Gebäude verlängern" +} + +o_firecooldown_descr +{ + "Der Zeitraum in dem gelöschte Häuser nicht wieder brennen können kann hier verlängert werden." +} + +u_ballistamonk +{ + "Feuerballisten schießen auf Mönche" +} + +u_ballistamonk_descr +{ + "Lässt Feuerballisten automatisch auch auf Mönche schießen." +} + + +// ====================== +// 2.12 +// ====================== + +ui_AIC +{ + "AIC" +} + +ui_aicExport +{ + "Export" +} + +ui_aicExport_success +{ + "Erfolgreich exportiert." +} + +ui_aicHint +{ + "Exportiert die .aic-Datei aus dem Installer in das Crusader-Verzeichnis." +} + +// ====================== +// 1.00 +// ====================== + +Name +{ + "Inoffizieller Crusader Patcher" +} + +u_ArabXBow +{ + "Erhöhter Schutz von Arab. Schwertkämpfer vor Armbrüsten" +} + +u_arabxbow_descr +{ + " - Arabische Schwertkämpfer sterben erst nach 6 Armbrusttreffern statt 3" +} + +u_ArabWall +{ + "Arab. Schwertkämpfer reißen Mauern schneller ein" +} + +u_ArabWall_descr +{ + "In Vanilla reißen Arabische Schwertkämpfer Mauern am langsamsten ein unter & +den Nahkämpfern. Die Einreißgeschwindigkeit wird hiermit für sie ca. & +verdoppelt, sodass sie dabei knapp über Lanzenträgern sind." +} + +u_spearmen +{ + "Erhöhter Schutz von Lanzenträger gegen Fernkämpfer" +} + +u_spearmen_descr +{ + " - Lanzenträger sterben erst nach 5 Pfeiltreffern statt 3 + - Lanzenträger überleben knapp einen Armbrusttreffer" +} + +ui_error +{ + "Fehler" +} + +ui_SearchPath +{ + " Bitte wähle dein Installationverzeichnis:" +} + +ui_search +{ + "Suchen" +} + +ui_continue +{ + "Weiter" +} + +ui_wrongpath +{ + "Stronghold Crusader konnte nicht im angegebenen Pfad gefunden werden!" +} + +ui_back +{ + "Zurück" +} + +ui_install +{ + "Installieren" +} + +ui_finished +{ + "Fertig" +} + +ui_chooseLangTitle +{ + "Setup-Sprache" +} + +ui_chooseLang +{ + "Bitte wählen Sie eine Sprache für die Installation aus der unten & +aufgeführten Liste." +} + +ui_accept +{ + "OK" +} + +ui_cancel +{ + "Abbrechen" +} + +ui_uninstall +{ + "Deinstallieren" +} + +ui_uninstalldone +{ + "Deinstallation abgeschlossen." +} + +ai_recruitinterval +{ + "Erhöhtes Rekrutierungstempo" +} + +ai_recruitinterval_descr +{ + "Setzt das Rekrutierungsintervall aller KIs auf den niedrigsten Wert. & +(Ratte/Richard-Niveau)" +} + +ai_attacklimit +{ + "Erhöhung des Angriffstruppenlimits der KIs" +} + +ai_attacklimit_descr +{ + "In Vanilla is das Limit der zusätzlichen Truppen, die nach dem ersten & +Angriff dazukommen auf 200 begrenzt. Hier kann diese Grenze verändert werden." +} + +o_gamespeed +{ + "Erweiterte Spielgeschwindigkeitsgrenzen" +} + +o_gamespeed_descr +{ + "Die Spielgeschwindigkeit kann nun wie folgt geändert werden: + - Von 10 bis 90 in 5er Schritten + - Von 90 bis 200 in 10er Schritten + - Von 200 bis 1000 in 100er Schritten +Die neuen Werte sind nur im Spiel über die +- Tasten erreichbar, der Regler im & +Spielmenü bleibt ungeändert." +} + +ui_bugfix +{ + "Bugfixes" +} + +ui_ailords +{ + "KI-Lords" +} + +ui_troops +{ + "Einheiten" +} + +ui_other +{ + "Sonstiges" +} + +o_responsivegates +{ + "Torhäuser schneller auf Gegner reagieren lassen" +} + +o_responsivegates_descr +{ + "Torhäuser schließen sich jetzt später bei Gegnernähe und öffnen wieder & +schneller automatisch, sobald die Gefahr vorüber ist. Die Distanz die ein & +Gegner haben muss, damit sich das Tor automatisch schließt, wird von 200 auf & +140 gesenkt. Die Zeit nach der sich das Tor wieder öffnet, sofern kein Gegner & +mehr in der Nähe ist, wird von 1200 auf 100 reduziert." +} + +ai_addattack +{ + "Erhöhung der Rate von zusätzlichen Angriffstruppen" +} + +ai_addattack_descr +{ + "In Vanilla wird nach jedem Angriff die Truppenzahl für den nächsten & +Angriff durchschnittlich um 5 Einheiten erhöht. Dieser Wert ist für alle & +KI-Lords gleich und kann hier geändert werden." +} + +ai_addattack_alt_descr +{ + "Alternativ kann hier die hinzukommende Truppenanzahl von der Truppenstärke & +des ersten Angriffs abhängig gemacht werden. Da jede KI unterschiedliche & +Anzahlen für den Erstangriff hat, werden somit auch folgende Angriffe & +skalieren, anstatt für jede KI gleich anzusteigen. +Beispiel: Skalierungsfaktor = 0,5 +Sultans Angriffszahlen = 10, 15, 20, 25, ... +Saladins Angriffszahlen = 50, 75, 100, 125, ..." +} + +u_laddermen +{ + "Erhöhter Schutz für Leiterträger gegen Fernkämpfer" +} + +u_laddermen_descr +{ + " - Leiterträger sterben erst nach 12 Pfeiltreffern statt 5 + - Leiterträger sterben erst nach 5 Armbrust- oder Schleudertreffern statt 2 + - Leiterträger kosten 20 Gold statt 4" +} + +o_playercolor +{ + "Farbe von Spieler 1 wechseln" +} + +o_playercolor_descr +{ + " " +} + +ai_demolish +{ + "Einreißen für Geld der KI-Lords deaktivieren" +} + +ai_demolish_walls +{ + "Befestigungsanlagen" +} + +ai_demolish_eco +{ + "Wirtschaftsgebäude" +} + +ai_demolish_walls_descr +{ + " " +} + +ai_demolish_eco_descr +{ + "Wenn die KI sich bedrängt fühlt und schnell an Geld für Truppen kommen & +will, reißt sie gerne mal ihre komplette Wirtschaft oder Befestigungsanlagen & +ein. Manchmal wird dieses Feature aber auch völlig ohne scheinbaren Grund & +ausgelöst und kann darum hier ausgestellt werden." +} + +ai_tethers +{ + "Ochsenjoch-Spam deaktivieren" +} + +ai_tethers_descr +{ + "Die KI baut normalerweise mit jedem neuen Steinbruch auch ein neues & +Ochsenjoch, unabhängig davon wie viele sie schon hat. Dies kann hier & +deaktiviert werden, da es zu Ochsenjoch-Spam führt, wenn die Steinbrüche & +der AI immer wieder zerstört werden." +} + + + + + + + + +// ======================= +// 2.06 +// ======================= + + + +ai_nosleep +{ + "Schlafenlegen bei Rohstoffmangel deaktivieren" +} + +ai_nosleep_descr +{ + "Normalerweise legt die KI ihre Verarbeitungsgebäude schlafen, & +sobald der nötige Rohstoff nicht mehr im Lager vorhanden ist. Dabei & +wird keine Rücksicht genommen ob Produkte verloren gehen die & +z.B. gerade zur Waffenkammer gebracht werden. Diese Funktion kann hier & +komplett deaktiviert werden." +} + + + + + + + +// 5.12.2018 + +o_onlyai +{ + "Zuschauer-Modus aktivieren [bug möglich]" +} + +o_onlyai_descr +{ + "Entfernt Spieler 1 sodass man nur noch zugucken kann und 8 KIs in einem & +Kreuzzug möglich sind. Gespeicherte Spiele laden jetzt auch ordnungsgemäß in & +diesem Modus. Ab und zu tritt ein Bug auf, bei dem überall auf der Karte zufällige & +Objekte auftauchen. Diese sind jedoch nur visuell und können durch einfaches & +Spiel speichern -> Mission beenden -> Spiel laden behoben werden." +} + +o_moatvisibility +{ + "Geplanten Burggraben immer zeigen" +} + +o_moatvisibility_descr +{ + "Mit dieser Einstellung wird der gesetzte, aber noch nicht ausgehobene & +Burggraben immer angezeigt, auch wenn man die Burggrabenplatzierung abwählt." +} + + +o_engineertent +{ + "Belagerungsgeräte nicht automatisch abwählen" +} + +o_engineertent_descr +{ + "Mit dieser Einstellung wird das zuletzt zum Bau ausgewählte Belagerungsgerät & +bei Baumeistern nicht abgewählt, sodass man mehrere Zelte nacheinander bauen kann, & +ohne jedes mal neu wählen zu müssen." +} + + + + + + + +// ================================ +// 2.07 +// ================================ + + +ai_demolish_trapped +{ + "Falls eingeschlossen" +} + +ai_demolish_trapped_descr +{ + " " +} + + +o_freetrader +{ + "Kostenloser Marktplatz" +} + +o_freetrader_descr +{ + "Da die KI sich manchmal selbst Schachmatt setzt, wenn sie kein Holz hat und der & +Marktplatz zerstört wurde, kann hier der Bau des Marktplatzes kostenlos gemacht werden." +} + +ai_towerengines +{ + "Keine Grenze für Geräte auf Türmen" +} + +ai_towerengines_descr +{ + "Normalerweise baut die KI maximal je drei Ballisten und Mangen. & +Dieses Limit wird hiermit aufgehoben." +} + +ai_buywood +{ + "Genügend Holz kaufen" +} + +ai_buywood_descr +{ + "Damit Bogenmacher etc. nicht ständig gekauftes Bauholz wegschnappen, & +kauft die KI mit dieser Einstellung immer 2 Holz mehr als nötig für Gebäude." +} + +o_keys +{ + "WASD-Tasten und Quicksaves" +} + +o_keys_descr +{ + "Mit dieser Einstellung werden die WASD-Tasten für die Kamera aktiviert. +Außerdem kann mit STRG-S und STRG-L ein Quicksave erstellt und geladen werden." +} + + + + + + + + + + + + + +// =========== +// 2.07a +// =========== + + + +ai_attacktarget +{ + "AI-Angriffsziel einstellen" +} + +ai_attacktarget_nearest +{ + "Nahegelegenster Gegner" +} + +ai_attacktarget_nearest_descr +{ + " " +} + +ai_attacktarget_richest +{ + "Reichster Gegner" +} + +ai_attacktarget_richest_descr +{ + " " +} + +ai_attacktarget_weakest +{ + "Schwächster Gegner" +} + +ai_attacktarget_weakest_descr +{ + "Mit dieser Einstellung suchen sich die KI-Lords alle auf die selbe Weise, +das Ziel für ihren nächsten Angriff. Dies verhindert, dass die Truppen mittem & +im laufenden Angriff umschwenken oder an Gegnerburgen vorbeigeschickt werden & +zum Sammeln." +} + + + + + + + + + + + +// ================ +// 2.08 +// ================ + + +ai_assaultswitch +{ + "Kein KI-Angriffszielwechsel während Belagerung" +} + +ai_assaultswitch_descr +{ + "KI-Lords die den mächtigsten oder schwächsten Gegner angreifen, & +hatten manchmal die Tendenz mitten in einem Angriff das Ziel zu wechseln, & +und ihre Truppen zu einer anderen Burg schicken. Mit dieser Einstellung, & +passiert das nicht mehr, sobald der Angriff begonnen hat, d.h. während & +des Sammelns vor der Burg kann ein Wechsel noch passieren." +} + + + +ai_rebuild +{ + "Verbessertes KI-Reparieren" +} + +ai_rebuild_descr +{ + "Mit dieser Einstellung reparieren KI-Lords auch Turmruinen, leicht & +angeschlagene Mauern, sowie Baumeister-, Tunnelgilden und Ölkessel bei denen & +der Sammelplatz übergeblieben ist. Weiterhin kann die KI nun auch die Sammelstelle & +von Steinbrüchen überbauen." +} + + + + + + +// ==================== +// 2.09 +// ==================== + +o_healer +{ + "Heiler verarztet Verwundete" +} + +o_healer_descr +{ + "Der Heiler des Apothekengebäudes sucht nun verletzte Soldaten, Zivilisten & +und Tiere auf und heilt diese. Nahe Ziele werden dabei bevorzugt. Mit jeder Heilungs-Animation & +wird ca. 1/3 des Lebens eines Lanzenträgers geheilt. Das Schlendern durch die Gärten und & +Aufsuchen von Pestwolken wird dadurch nicht ersetzt! Nur das Schlendern durch die Burg & +wird ausgelassen, bis keine Verwundeten mehr in Reichweite sind." +} + + + + + + + +// ==================== +// 2.10 +// ==================== + + + +o_xtreme +{ + "Magie-Leiste in Extreme entfernen." +} + +o_xtreme_descr +{ + "Entfernt die Magie-Leiste in Crusader Extreme." +} + + + + + + + +// ====================== +// 2.11 +// ====================== + + +ui_AIV +{ + "AIV" +} + +ai_access +{ + "Kein Abreißen von unzugänglichen Gebäuden" +} + +ai_access_descr +{ + "Verhindert, dass die KI Gebäude abreißt zu denen es keinen Zuweg gibt. & +Damit soll der Bug verhindert werden, bei dem manche KIs in ihren Burgen & +andauernd Gebäude abreißen und wieder aufbauen zu denen es keinen Weg gibt." +} + +ai_attackwave +{ + "Angriffswellen verbessern" +} + +ai_attackwave_descr +{ + "In Vanilla schickt die KI bei einem Angriff immer nur & +so viele Einheiten auf einmal los wie Mauernstücke erreichbar & +sind. Bei Burgen die mit Gebäuden umbaut sind greifen die Einheiten & +dadurch nur tröpfchenweise an. +Durch die Aktivierung dieser Option greifen Einheiten auch Gebäude und & +Befestigungsanlagen an, sowie Mauerstücke die bereits von einem Angreifer & +besetzt sind. Außerdem schickt die KI jetzt auch mehr Truppen auf den & +gegnerischen Bergfried, sobald sie eine Bresche erkennt." +} diff --git a/UnofficialCrusaderPatch/Localization/Hungarian.txt b/UnofficialCrusaderPatch/Localization/Hungarian.txt new file mode 100644 index 00000000..2cd2fda0 --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/Hungarian.txt @@ -0,0 +1,1061 @@ +// ====================== +// 2.15 +// ====================== + +u_spearmen_run +{ +"A lándzsás egység sétálás helyett alapból fut" +} + +u_spearmen_run_descr +{ +"A lándzsás egység lassú sétálás helyett alapból futni fog. A lándzsás olyan gyorsan fut, mint egy rabszolga vagy buzogányos." +} + +o_seed_modification_possibility_title +{ +"Random játék seed" +} + +o_seed_modification_possibility_only_set +{ +"Megadott Random játék seed engedélyezése" +} + +o_seed_modification_possibility_only_set_descr +{ +"A játék seed megadásával az MI harcoknak a kimenetele ugyanaz lesz, azonos pályabeállítások esetén. Játékos-MI harc esetén, ugyanazon kezdési feltételeket biztosítja a pályán (mint pl. az AIV kiválasztás). A játék seed megadásához, engedélyezd ezt a beállítást és hozz létre egy 6 darab számot tartalmazó 'live' nevű szöveges fájlt a játék könyvtár/gameseeds mappában. FIGYELEM: Ez a beállítás csak a játék újraindítása után működik!" +} + +o_seed_modification_possibility +{ +"Random játék seed-ek engedélyezése és mentése" +} + +o_seed_modification_possibility_descr +{ +"Ez a beállítás elmenti a seed-et azon játékokból amikhez nem lett megadva live seed érték, nevezd át a kívánt seed-et tartalmazó szöveges fájlt 'live'-ra hogy a későbbiekben újra rekonstruálhasd a harcot." +} + +ai_recruitstate_initialtimer +{ +"Az MI a megadott ideig az AIC paraméterek alapján toborozzon" +} + +ai_recruitstate_initialtimervalue_descr +{ +"Az értéknek add meg azon hónapok számát, amikor az MI az AIC fájlban megadott toborzási sebeséggel toboroz kizárólag védekező egységeket, ha már teljesen megerősítette a védelmét, akkor támadó egységeket fog toborozni" +} + +ai_defense +{ +"Várvédő egységek megerősítése kijavítva" +} + +ai_defense_descr +{ +"Kijavítja azt a hibát, ami megakadályozza az MI-t abban, hogy a hiányzó egységekkel megerősítse a várfalat és a tornyot, ameddig rendelkezik még védekező-járőröző egységekkel." +} + +ai_housing +{ +"Házak okosabb építése" +} + +build_housing_descr +{ +"A jelenlegi és a maximális népességszám közötti különbség, amely felett az MI nem épít több házat. Az eredeti játékban ez a szám 0. Ha ez a beállítás be van jelölve, akkor az MI nem rombolja le a házakat." +} + +campfire_housing_descr +{ +"Parasztok száma a tábortűznél, mielőtt az MI nem épít több házat. Ha ez a beállítás be van jelölve, akkor az MI nem rombolja le a házakat." +} + +delete_housing +{ +"Az MI ne rombolja le a házakat." +} + +delete_housing_descr +{ +"Ha ez a beállítás be van jelölve, akkor az MI soha nem rombolja le a házakat." +} + +aiv_prompt +{ +"Módosított AIV fájlok észlelve. Szeretne egy biztonsági másolatot készíteni, uram?" +} + +aiv_cli_prompt +{ +"Módosított AIV fájlok észlelve. Írd be a 'delete' szót az eltávolításukhoz vagy adj meg egy mappa nevet, ahova a fájlok települnek." +} + +install_abort_io +{ +"Telepítés megszakítva. Már léteznek ilyen nevű fájlok ebben a mappában. Kérjük válassz egy másik mappát és próbáld meg újra." +} + +install_abort +{ +"Telepítés megszakítva" +} + +backup_aiv_select +{ +"Válaszd ki az AIV Backup mappát" +} + +o_change_siege_engine_spawn_position_catapult +{ +"Elkészült ostromgépek középre pozicionálása" +} + +o_change_siege_engine_spawn_position_catapult_descr +{ +"Az elkészült ostromgépek a sátor közepénél jelennek meg a sátor jobb felső sarka helyett." +} + +o_stop_player_keep_rotation +{ +"Játékos vártornyok elforgatása" +} + +o_stop_player_keep_rotation_descr +{ +"A játékosok vártornyai mostantól ugyanolyan módon lesznek elforgatva, mint az MI vártornyok. A tábortűz mindig a térkép legközelebbi széle felé néz." +} + +o_restore_arabian_engineer_speech +{ +"Az arab mérnök arabul beszél" +} + +o_restore_arabian_engineer_speech_descr +{ +"Ha a játékos az Arab Lord-ot választja, akkor a mérnök beszédekor az eredeti felvett arab hangfájlt használja. + +Nincs túl sok variáció ezekben a hangfájlokban, így egy idő után zavaró lehet." +} + +u_fix_lord_animation_stuck_movement +{ +"Lord animáció visszaállítása az épületek lerombolása után" +} + +u_fix_lord_animation_stuck_movement_descr +{ +"Ezzel a változtatással egy épület lerombolása után a Lord a kiindulási animációra tér vissza. Mostantól nem marad a leromboló animációban." +} + +fix_apple_orchard_build_size +{ +"Almáskert építési méretének csökkentése" +} + +fix_apple_orchard_build_size_descr +{ +"Az almáskert elhelyezése előtt az előnézeti mérete nagyobb volt, mint amekkora valójában az almáskert az elhelyezés után. Ez a hiba kijavításra került. Ezzel a beállítással több szabad hely marad az almáskertek építésekor és megnöveli az MI mezőgazdasági épületek építésének rátáját." +} + +u_fix_applefarm_blocking +{ +"Almáskert blokkolása javítás" +} + +u_fix_applefarm_blocking_descr +{ +"Az almatermesztő nem várakozik, ha az almáskert bal felső részénél lévő utat blokkolja valami." +} + +o_increase_path_update_tick_rate +{ +"Elérhető útvonalak gyakoribb ellenőrzése" +} + +o_increase_path_update_tick_rate_descr +{ +"Az eredeti játékban minden 200. játékidő tick után kerültek ellenőrzésre az új útvonalak, ami azt eredményezte, hogy az egységek nem tudtak azonnal bemenni a várba miután lerombolták a kaput vagy a tornyot. + +Az elérhető útvonalakat mostantól minden 50. játékidő tick után ellenőrzi, így lehetővé téve hogy az egységek sokkal gyorsabban 'realizálják' az elérhető új útvonalat." +} + +o_fix_ladderclimb +{ +"Létramászás hibajavítás" +} + +o_fix_ladderclimb_descr +{ +"Az egységek mászás után nem felejtik el a számukra adott parancsot, és többé nem fognak lemászni miután már felmásztak." +} + +u_tanner_fix +{ +"A tímárok ugyanazt a tehenet választják javítás" +} + +u_tanner_fix_descr +{ +"A tímárok mostantól nem fognak tehén nélkül visszatérni, ha egy másik tímár már elvitte az általuk kiválasztott tehenet. Mostantól várakoznak egy ideig és elvisznek egy másikat." +} + +o_fix_fletcher_bug +{ +"Íjkészítő hibajavítás" +} + +o_fix_fletcher_bug_descr +{ +"Kijavítja az íjkészítő azon viselkedését, miszerint visszatér a munkahelyére ha leszállított egy íjat/íjpuskát, ahelyett hogy egyenesen a raktárhoz menne." +} + +ai_fix_crusader_archers_pitch +{ +"MI keresztes íjász nem gyújtja be az olajosárkot javítás" +} + +ai_fix_crusader_archers_pitch_descr +{ +"Az MI keresztes íjász most már begyújtja az olajosárkot, úgy mint az arab íjász amikor ellenséges egység lép az olajosárokra." +} + +o_fix_baker_disappear +{ +"Eltűnő pék hibajavítás" +} + +o_fix_baker_disappear_descr +{ +"Kijavítja azt a hibát, amikor a pék eltűnik ha a raktárban nem találja meg a kiválasztott helyen a lisztet." +} + +o_fix_moat_digging_unit_disappearing +{ +"Eltűnő árokásó egység hibajavítás" +} + +o_fix_moat_digging_unit_disappearing_descr +{ +"Kijavítja azt a hibát, amikor árokásás közben véletlenszerűen eltűnik az árkot ásó egység. Megjegyzés: Az egység még mindig eltűnhet, ha árokásás közben elküldöd máshova és éppen egy nem járható helyen van!" +} + +ui_welcometext +{ +"Ez egy nem hivatalos patch a Stronghold Crusader játékhoz. +A Projekt nyílt forráskódú, ami megtalálható a [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch) weboldalon. + +Elméletben minden Crusader verzió támogatott, viszont a változtatások eredetileg a 1.41 Steames verzióhoz lettek készítve. +Azonban ha a játék verziód nem kompatibilis, a telepítő hibaüzenetet fog megjeleníteni. A telepített patch-verzió a főmenü bal alsó sarkában fog megjelenni. +Minden változtatás előtt Backup fájl készül, ami visszaállítható a 'Eltávolítás' gombra kattintva vagy manuálisan visszahelyezhető. + +Az Unofficial Crusader Patch csapat + +UCP program alkotója +[Sh0wdown](https://github.com/Sh0wdown) + +Projektvezetők +[Kimberly Azula](https://github.com/ByBurton/) +[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) + +Fejlesztők +[LordHansCapon](https://github.com/LordHansCapon) +[np123](https://github.com/patel-nikhil) +[gynt](https://github.com/gynt) +[J-T-de](https://github.com/J-T-de) +[Le spec](https://github.com/LeSpec) +[Chaf1812](https://github.com/Chaf1812) + +Fordítók +[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Lengyel) +[Lolasik011](https://github.com/Lolasik011) (Orosz) +[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Kínai) +[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Magyar) + +Tartalom készítők +[Evrey](https://github.com/Evrey) (aiv) +[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) +[PitchNeeded](https://github.com/PitchNeeded) (aiv) +[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) + +Külön köszönet nekik: +[Firefly Studios](https://fireflyworlds.com/) +a Stronghold széria létrehozásáért + +Továbbá külön köszönet: +[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) +[PodeCaradox](https://github.com/PodeCaradox) +[GRhin](https://www.twitch.tv/grhin) +[Heroesflorian](https://github.com/Heroesflorian)" +} + +// ====================== +// 2.14 +// ====================== + +ui_StartTroops +{ + "Kezdőegységek" +} + +ui_Resource +{ + "Kezdőkészlet" +} + +ui_aicconflict +{ + "A konfliktusok figyelmen kívül lesznek hagyva" +} + +o_shfy +{ + "Strongholdify" +} + +o_shfy_beer +{ + "Sör általi népszerűségi bónusz" +} + +o_shfy_beer_descr +{ + " " +} + +o_shfy_religion +{ + "Templom és katedrális általi népszerűségi bónusz" +} + +o_shfy_religion_descr +{ + " " +} + +o_shfy_peasantspawnrate +{ + "Parasztok érkezésének sebessége" +} + +o_shfy_peasantspawnrate_descr +{ + " " +} + +o_shfy_resourcequantity +{ + "Leszállított erőforrások mennyisége" +} + +o_shfy_resourcequantity_descr +{ + "A felsorolt szempontokat a Stronghold 1-hez igazítja. Vigyázat: Minden változtatás hatással van az MI Lordokra, a legrosszabb esetben haszontalanná teszi őket!" +} + +o_armory_marketplace_weapon_order_fix +{ + "Megegyező fegyver sorrend a fegyverraktár/piacban" +} + +o_armory_marketplace_weapon_order_fix_descr +{ + "Újrarendezi a fegyver ikonokat a fegyverraktárban és a piacban, hogy egyforma legyen a sorrend. A bőrpáncél a buzogány és számszeríj között lesz, míg a vaspáncél a dárda és kard között, hogy könnyebben megtalálható legyen a piacban való kereséskor." +} + +ai_fix_laddermen_with_enclosed_keep +{ + "Javított létrahasználat" +} + +ai_fix_laddermen_with_enclosed_keep_descr +{ + "Ezzel a hibajavítással azok az MI-k, akiknek a vártornyuk körül van zárva, továbbra is tudják az ostromegységeik használni a létrahordozók létráit (az eredeti játékban ez csak a Kígyót érinti)." +} + +o_override_identity_menu +{ + "Új beállítások hozzáadása a 'Játékos szerkesztése' menühöz" +} + +o_override_identity_menu_descr +{ + "Távolsági és közelharci egységek kiválasztási lehetőségét adja hozzá a 'Játékos szerkesztése' menüponthoz. CSAK NORMÁL JÁTÉK MÓDHOZ!" +} + +o_default_multiplayer_speed +{ + "Többjátékos mód alapsebességének beállítása" +} + +o_default_multiplayer_speed_descr +{ + " " +} + +u_fireballistafix +{ + "A tűzhajítógépek lőnek a szerzetesekre és az alagútásókra" +} + +u_fireballistafix_descr +{ + "A tűzhajítógépek most már ellenségként észlelik a szerzeteseket és az alagútásókat, mostantól lőnek rájuk." +} + +ui_browsepath +{ + "Kérjük adja meg a Stronghold Crusader telepítési könyvtárát." +} + +ui_aicoldversion +{ + "Régi verzió észlelve. Kattintson a konvertáláshoz" +} + +ui_aicofferconvert +{ + "AIC fájlok konvertálása az új verzióhoz?" +} + +ui_aicconvertprompt +{ + "AIC konvertálás" +} + +ui_aicselect +{ + "Kérjük először szüntesse meg a többi AIC fájl(ok) kiválasztását. Az alábbi aic karakterek vannak kijelölve: " +} + +// ====================== +// 2.13 +// ====================== + +o_firecooldown +{ + "Eloltott épületek tűzálló időtartamának megnövelése" +} + +o_firecooldown_descr +{ + "Itt meghosszabbítható az az időtartam, amely alatt az eloltott épületek nem tudnak újra kigyulladni." +} + +u_ballistamonk +{ + "A tűzhajítógépek lőnek a szerzetesekre" +} + +u_ballistamonk_descr +{ + "A tűzhajítógépek automatikusan lőnek a szerzetesekre is." +} + + +// ====================== +// 2.12 +// ====================== + +ui_AIC +{ + "AIC" +} + +ui_aicExport +{ + "Exportálás" +} + +ui_aicExport_success +{ + "Exportálás sikeresen befejezve." +} + +ui_aicHint +{ + "Exportálja az .aic fájlokat a telepítőből a Crusader mappába." +} + +// ====================== +// 1.00 +// ====================== + +Name +{ + "Unofficial Crusader Patcher" +} + +u_ArabXBow +{ + "Megnövelt védelem az arab szablyás egységnek a számszeríj nyílvessző ellen" +} + +u_arabxbow_descr +{ + " - Az arab szablyás 3 helyett 6 számszeríj nyílvessző találat után hal meg" +} + +u_ArabWall +{ + "Az arab szablyás gyorsabban rombolja le a várfalat" +} + +u_ArabWall_descr +{ + "Az eredeti játékban az arab szablyás rombolja le a várfalat a leglassabban a közelharci egységek közül. A lerombolás sebessége ezentúl kb. megkétszereződik, így épphogy jobb lesz a lándzsás egységnél." +} + +u_spearmen +{ + "Megnövelt védelem a lándzsás egységnek a távolsági egységek ellen" +} + +u_spearmen_descr +{ + " - A lándzsás egység 3 helyett 5 nyíl találat után hal meg + - A lándzsás egység épphogy túlél egy számszeríj nyílvessző találatot" +} + +ai_buy +{ + "Javított piac elhelyezés az MI Lordoknak" +} + +ai_buy_descr +{ + "Az eredeti játékban egyes új MI Lordok nem helyezik jól el a piacot. +Az alábbi javítások lesznek ezentúl érvényesek: + - Frigyes és a Tábornok ezentúl vásárolnak fegyvert és páncélt + - Az Apát és az Emír ezentúl vásárolnak íjat + - Wazir ezentúl vásárol almát, mint Nizar és Emír" +} + +ui_error +{ + "Hiba" +} + +ui_SearchPath +{ + " Kérjük adja meg a telepítési útvonalat:" +} + +ui_search +{ + "Keresés" +} + +ui_continue +{ + "Tovább" +} + +ui_wrongpath +{ + "A Stronghold Crusader nem található a megadott elérési útvonalon!" +} + +ui_back +{ + "Vissza" +} + +ui_install +{ + "Telepítés" +} + +ui_finished +{ + "Kész" +} + +ui_chooseLangTitle +{ + "Telepítő nyelve" +} + +ui_chooseLang +{ + "Kérjük válasszon ki egy nyelvet a telepítéshez a lent megjelenített listából." +} + +ui_accept +{ + "OK" +} + +ui_cancel +{ + "Mégsem" +} + +ui_uninstall +{ + "Eltávolítás" +} + +ui_uninstalldone +{ + "Eltávolítás befejezve." +} + +ai_recruitinterval +{ + "Megnövelt toborzási sebesség" +} + +ai_recruitinterval_descr +{ + "Átállítja minden MI Lordnak a toborzási intervallumát a legkisebb értékre. (Patkány/Richárd szint)" +} + +ai_recruitsleep +{ + "Deaktiválja minden MI Lordnak a toborzási szünetét" +} + +ai_attacklimit +{ + "Megnövelt támadó egység limit az MI Lordoknak" +} + +ai_attacklimit_descr +{ + "Az eredeti játékban a további egységek limitje, akik az első támadás után csatlakoznak 200-ra van korlátozva. Itt tudod megváltoztatni ezt a korlátozást." +} + +o_gamespeed +{ + "Bővített játéksebesség limit" +} + +o_gamespeed_descr +{ + "A játéksebességet mostantól a következőképpen lehet megváltoztatni: + - 10-től 90-ig 5 lépésben + - 90-től 200-ig 10 lépésben + - 200-tól 1000-ig 100 lépésben +Az új értékek elérhetők a játékban a +- billentyűk segítségével, a csúszka a játékmenüben változatlanul maradt." +} + +ui_bugfix +{ + "Hibajavítások" +} + +ui_ailords +{ + "MI Lordok" +} + +ui_troops +{ + "Egységek" +} + +ui_other +{ + "Egyéb" +} + +o_responsivegates +{ + "A várkapuk gyorsabban reagálnak az ellenséges egységekre" +} + +o_responsivegates_descr +{ + "A várkapuk mostantól később záródnak be ha ellenség van a közelben és automatikusan gyorsabban kinyílnak, ha már nincs közelben ellenség. A távolság ami szükséges az ellenségnek, hogy a várkapu automatikusan bezáródjon, 200-ról 140-re lett csökkentve. Az idő amikor a várkapu ismét kinyílik, mihelyst nincs ellenség a közelben, 1200-ról 100-ra lett csökkentve." +} + +ai_addattack +{ + "Megnövelt további támadó egységek mértéke" +} + +ai_addattack_descr +{ + "Az eredeti játékban minden egyes támadás után az egységek száma a következő támadáskor átlagosan 5 egységgel lesz megnövelve. Ez az érték minden MI Lordnak ugyanannyi és itt tudod megváltoztatni." +} + +ai_addattack_alt_descr +{ + "Alternatív megoldásként, a további csatlakozó egységek számát az első támadás erősségétől függetlenné lehet tenni. De mivel minden MI Lord különböző számú egységet használ az első támadásnál, ezzel együtt a következő támadások is skálázódnak ahelyett, hogy minden MI Lordnak ugyanaz az értéke lenne. +Például: Skálázási faktor = 0,5 +Szultán támadásainak száma = 10, 15, 20, 25, ... +Szaladin támadásainak száma = 50, 75, 100, 125, ..." +} + +u_laddermen +{ + "Megnövelt védelem a létrás egységnek a távolsági egységek ellen" +} + +u_laddermen_descr +{ + " - A létrás egység 5 helyett 12 nyíl találat után hal meg + - A létrás egység 2 helyett 5 számszeríj nyílvessző találat vagy parittyakő találat után hal meg + - A létrás egység 4 helyett 20 aranyba kerül" +} + +o_playercolor +{ + "Játékos 1 színcsere" +} + +o_playercolor_descr +{ + " " +} + +o_trooplimit +{ + "Megnövelt egység limit" +} + +o_trooplimit_descr +{ + "Az eredeti játékban az egységek száma egy játékosnak +2400/játékosszám. Itt tudod megváltoztatni ezt a számot." +} + +ai_demolish +{ + "Az MI Lord lerombol mindent hogy pénzhez jusson deaktiválása" +} + +ai_demolish_walls +{ + "Várépületek" +} + +ai_demolish_eco +{ + "Ipari épületek" +} + +ai_demolish_walls_descr +{ + " " +} + +ai_demolish_eco_descr +{ + "Ha az MI Lord sarokba szorítva érzi magát és gyorsan pénzt akar szerezni az egységekhez, előszeretettel rombolja le a teljes iparát vagy várépületeit. Néha ez az esemény láthatólag minden indok nélkül megtörténik és emiatt itt ki tudod kapcsolni." +} + +ai_tethers +{ + "Ökör karám spam deaktiválása" +} + +ai_tethers_descr +{ + "Az MI általában minden új kőfejtő építésekor épít egy új ökör karámot is attól függetlenül, hogy mennyi van neki. Ezt itt tudod deaktiválni, mert különben spammelni fogja az ökör karámokat, ha az MI kőfejtőjét mindig lerombolják." +} + + + + + + + + +// ======================= +// 2.06 +// ======================= + + + +ai_nosleep +{ + "Ha nincs elég erőforrás, szünetel a munka deaktiválása" +} + +ai_nosleep_descr +{ + "Általában az MI szünetelteti a munkát az ipari épületeinél, ha a szükséges erőforrás már nem áll rendelkezésére a raktárban. Eközben a termék kárba veszik amit pl. éppen a fegyverraktárba visznek. Ezt a funkciót itt teljesen ki lehet kapcsolni." +} + + +// 5.12.2018 + +o_onlyai +{ + "Nézői mód aktiválása [hiba előfordulhat]" +} + +o_onlyai_descr +{ + "Eltávolítja az 1.játékost a nézői módhoz és így 8 MI harcolhat egymással az Egyedi játék módban. Az elmentett játék most már rendesen működik ebben a módban is. Néha előfordulhat olyan hiba, hogy az egész térképen véletlenszerűen feltűnhetnek tárgyak. De ezek csak vizuálisan jelennek meg és egyszerűen megoldható a Játék mentése -> Küldetés befejezése -> Játék betöltésével." +} + +o_moatvisibility +{ + "Mindig mutassa a tervezett várárkot" +} + +o_moatvisibility_descr +{ + "Ezzel a beállítással a lehelyezett, de a még nem felásott várárok mindig látható, még akkor is ha nincs kiválasztva a várárokásás." +} + + +o_engineertent +{ + "Ostromgépek kijelölve maradnak" +} + +o_engineertent_descr +{ + "Ezzel a beállítással az utoljára építésre kiválasztott ostromgép marad kijelölve ha több mérnököt kiválasztottál, így több ostromsátrat is lehet egymás után építeni." +} + + + + + + + +// ================================ +// 2.07 +// ================================ + + +ai_demolish_trapped +{ + "Ha bezárva" +} + +ai_demolish_trapped_descr +{ + " Ha az MI be van zárva és nem jutnak ki az egységei, lerombol mindent. Ezt itt tudod kikapcsolni. (pl. a játékos lerak egy épületet a várkapuja elé és nincs másik bejárata a várnak)" +} + + +o_freetrader +{ + "Ingyen piac" +} + +o_freetrader_descr +{ + "Mivel néha az MI magának add sakk-mattot, ha nincs elég fája és a piacát lerombolták. Itt tudod beállítani hogy a piac építése ingyenes legyen." +} + +ai_towerengines +{ + "Ne legyen korlátozás a tornyokon lévő szerkezeteknek" +} + +ai_towerengines_descr +{ + "Általában az MI maximálisan 3 hajítógépet és kővetőgépet épít minden tornyára. Ezen beállítással ez a korlátozás megszűnik." +} + +ai_buywood +{ + "Elegendő fa vásárlása" +} + +ai_buywood_descr +{ + "Ahhoz hogy az íjkészítők stb. ne vigyék el mindig a megvásárolt fát. Az MI ezzel a beállítással mindig 2 fával többet vesz, mint ami szükséges az épületek építéséhez." +} + +o_keys +{ + "WASD billentyűk és gyorsmentés" +} + +o_keys_descr +{ + "Ezzel a beállítással aktiválva lesznek a WASD billentyűk a kamerához. +Ezenkívül a CTRL-S és a CTRL-L billentyűkkel lehet gyorsmentést létrehozni és betölteni." +} + + + + + + + + + + + + + +// =========== +// 2.07a +// =========== + + + +ai_attacktarget +{ + "MI támadási-célpont beállítása" +} + +ai_attacktarget_nearest +{ + "A legközelebbi ellenség" +} + +ai_attacktarget_nearest_descr +{ + " " +} + +ai_attacktarget_richest +{ + "A leggazdagabb ellenség" +} + +ai_attacktarget_richest_descr +{ + " " +} + +ai_attacktarget_weakest +{ + "A leggyengébb ellenség" +} + +ai_attacktarget_weakest_descr +{ + "Ezzel a beállítással az MI Lordok a saját módjukon keresik meg a célpontot a következő támadásukhoz. Ez megakadályozza azt, hogy az egységek támadás közben célpontot változtassanak vagy az MI ne a másik ellenséges várhoz küldje gyülekezni a seregét." +} + + + + + + + + + + + +// ================ +// 2.08 +// ================ + + +ai_assaultswitch +{ + "Ostrom közben ne változtasson az MI támadási-célpontot" +} + +ai_assaultswitch_descr +{ + "Azok az MI Lordok akik a legerősebbet vagy a leggyengébbet támadták meg, néha hajlamosak voltak a támadás közepén célpontot változtatni, és az egységeiket elküldeni a másik várhoz. Ezzel a beállítással, ez már nem fordul elő, mihelyst a támadást megkezdte, viszont a vár előtti egységek gyülekezésekor még előfordulhat, hogy célpontot vált." +} + + + +ai_rebuild +{ + "Kijavított MI javítások" +} + +ai_rebuild_descr +{ + "Ezzel a beállítással az MI Lordok megjavítják a toronyromokat is, enyhén megrongált várfalakat, továbbá mérnökök-, alagútásók céhet és olajfőző kunyhót ha a helyük megmaradt. Továbbá az MI most már képes építeni a kőfejtők helye felett is." +} + + + + + + +// ==================== +// 2.09 +// ==================== + +o_healer +{ + "A gyógyító ellátja a sérülteket" +} + +o_healer_descr +{ + "A gyógyszertár gyógyítója mostantól megkeresi a sérült harcosokat, civileket, állatokat és meggyógyítja őket. A hozzá legközelebb lévő célpontokat gyógyítja először. Minden gyógyító animációval kb. egy lándzsás 1/3 életerejét állítja helyre. A kertekben való mászkálás és a pestisfelhő felkeresése ez által nem lesz lecserélve! Csak a várban való mászkálása lesz kihagyva, ha van sebesült a hatótávolságán belül." +} + + + + + + + +// ==================== +// 2.10 +// ==================== + + + +o_xtreme +{ + "Varázserő-sáv eltávolítása az Extreme kiegészítőből." +} + +o_xtreme_descr +{ + "Eltávolítja a Varázserő-sávot a Crusader Extreme kiegészítőben." +} + + + + + + + +// ====================== +// 2.11 +// ====================== + + +ui_AIV +{ + "AIV" +} + +ai_access +{ + "Az elérhetetlen épületek ne kerüljenek lerombolásra" +} + +ai_access_descr +{ + "Megakadályozza azt, hogy az MI lerombolja azt az épületet amihez nem lehet hozzáférni. Ezáltal kijavítható az a hiba, hogy az MI ne építse meg és rombolja le újra és újra mindig azt az épületet amihez nem tudnak eljutni." +} + +ai_moredef +{ + "Még több védekező egység Richárd, Patkány és Fülöp hercegnek" +} + +ai_moredef_descr +{ + "Az eredeti játékban Richárd, Patkány de leginkább Fülöpnek nagyon kevés védekező egysége volt a várfalakon, tornyokon. Ezzel a beállítással a távolsági harcosok száma a következőképpen változik meg: + +Patkány: 20 -> 40 +Richárd: 20 -> 40 +Fülöp: 4 -> 32 + +Viszont figyelembe kell venni, hogy ezáltal a legelső támadásuk egy kicsivel később következik be." +} + +ai_attackwave +{ + "Támadási hullámok feljavítása" +} + +ai_attackwave_descr +{ + "Az eredeti játékban az MI mindig csak annyi egységet küld el egyszerre amennyi elérhető várfal van. Azok a várak amik épületekkel vannak körülépítve, azokat az egységek csak elvétve támadják meg. Ezzel a beállítással az egységek az épületeket és az ostromsátrakat is megtámadják illetve azt a várfalat is amit már egy másik támadó egység rombol. Továbbá az MI mostantól több egységet küld az ellenséges vártoronyra, amint észrevesz egy oda vezető utat." +} diff --git a/UnofficialCrusaderPatch/Localization/Localization.cs b/UnofficialCrusaderPatch/Localization/Localization.cs new file mode 100644 index 00000000..b3ed6353 --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/Localization.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; + +namespace UCP +{ + public static class Localization + { + public class Language + { + string name; + public string Name => name; + + string ident; + public string Ident => ident; + + string culture; + public string Culture => culture; + + public Language(string name, string ident, string culture) + { + this.name = name; + this.ident = ident; + this.culture = culture; + } + } + + static int[] loadOrder = { 1, 0, 2, 3, 4}; + public static IEnumerable IndexLoadOrder => loadOrder; + + static List translations = new List() + { + new Language("Deutsch", "German", "de"), + new Language("English", "English", "en"), + new Language("Polski", "Polish", "pl"), + new Language("Русский", "Russian", "ru"), + new Language("中文", "Chinese", "ch"), + new Language("Magyar", "Hungarian", "hu") + }; + public static IEnumerable Translations => translations; + public static int GetLangByCulture(string culture) + { + return translations.FindIndex(l => l.Culture == culture); + } + + + static Dictionary localStrs = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public static void Add(string identifier, string text) + { + if (localStrs.ContainsKey(identifier)) + { + localStrs[identifier] = text; + } + else + { + localStrs.Add(identifier, text); + } + } + + public static void Remove(string identifier) + { + if (localStrs.ContainsKey(identifier)) + { + localStrs.Remove(identifier); + } + } + + public static string Get(string identifier) + { + if (localStrs.TryGetValue(identifier, out string text)) + { + return text; + } + return string.Format("{{Unknown Identifier: {0}}}", identifier); + + } + + class Reader : IDisposable + { + StreamReader sr; + int lineNum = 0; + public int LineNumber { get { return this.lineNum; } } + + public Reader(Stream stream) + { + sr = new StreamReader(stream); + } + + public void Dispose() + { + sr.Dispose(); + } + + public bool ReadLine(out string line) + { + while (true) + { + line = sr.ReadLine(); lineNum++; + if (line == null) + break; + + line = line.Trim(); + if (line.Length == 0) + continue; + + if (!line.StartsWith("//")) + return true; + } + line = null; + return false; + } + + StringBuilder chars = new StringBuilder(100); + public bool ReadString(out string text) + { + int c; + int oldLineNum = lineNum; + + while (true) + { + if ((c = sr.Read()) < 0) + throw new Exception("ReadString: End of file after line " + oldLineNum); + + if (c == '\n') + lineNum++; + + if (char.IsWhiteSpace((char)c)) + continue; + + if (c != '\"') + { + sr.ReadLine(); + lineNum++; + text = null; + return false; + } + else + { + break; + } + } + + oldLineNum = lineNum; + while (true) + { + if ((c = sr.Read()) < 0) + throw new Exception("Could not find string closing after line " + oldLineNum); + + if (c == '&') + { + int peek = sr.Peek(); + if (peek == '\r') + { + sr.Read(); + sr.Read(); + lineNum++; + continue; + } + } + + if (c == '\n') + { + lineNum++; + } + + if (c == '\"') + break; + + chars.Append((char)c); + } + + sr.ReadLine(); lineNum++; + if (chars.Length > 0) + { + text = chars.ToString(); + chars.Clear(); + return true; + } + else + { + text = null; + return false; + } + } + } + + static int langIndex; + public static int LanguageIndex => langIndex; + + public static void Load(string language) + { + int index = 0; + for (int i = 0; i < translations.Count; i++) + { + if (translations[i].Ident.Equals(language)) + { + index = i; + break; + } + } + Load(index); + } + + public static void Load(int index) + { + try + { + langIndex = index; + + string path = string.Format("UCP.Localization.{0}.txt", translations[index].Ident); + + Assembly asm = Assembly.GetExecutingAssembly(); + using (var s = asm.GetManifestResourceStream(path)) + using (Reader r = new Reader(s)) + { + localStrs.Clear(); + while (r.ReadLine(out string line)) + { + string ident = line; + + if (!r.ReadLine(out line) || !line.StartsWith("{")) + throw new Exception(ident + " Missing opening bracket at line " + r.LineNumber); + + if (!r.ReadString(out string text)) + throw new Exception(ident + " Missing string at " + r.LineNumber); + + if (!r.ReadLine(out line) || !line.StartsWith("}")) + throw new Exception(ident + " Missing closing bracket at line " + r.LineNumber); + + localStrs.Add(ident, text); + } + } + } + + catch (Exception e) + { + throw new Exception(e.Message); + } + } + } +} diff --git a/UnofficialCrusaderPatch/Localization/Polish.txt b/UnofficialCrusaderPatch/Localization/Polish.txt new file mode 100644 index 00000000..a1df384e --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/Polish.txt @@ -0,0 +1,1102 @@ +// ====================== +// 2.15 +// ====================== + +u_spearmen_run +{ +"Biegający włócznicy" +} + +u_spearmen_run_descr +{ +"Włócznicy będą cały czas biegać." +} + +o_seed_modification_possibility_title +{ +"Generowane ziarno gry" +} + +o_seed_modification_possibility_only_set +{ +"Włącza generowane ziarno gry" +} + +o_seed_modification_possibility_only_set_descr +{ +"Ta opcja pozwala na wygenerowanie ziarna gry (działa tylko na rozgrywki samych botów), aby rozgrywka była za każdym razem taka sama, jeśli wybrało się takie same ustawienia mapy. Aby to zrobić, włącz tę opcję i stwórz plik o nazwie 'live' z 6 cyframi w folderze z zainstalowaną grą/podfolderze z ziarnami (gameseed). UWAGA: Ta opcja działa po zrestartowaniu gry!" +} + +o_seed_modification_possibility +{ +"Włącz i zapisuj generowane ziarna gry" +} + +o_seed_modification_possibility_descr +{ +"This option will save the seed from games that do not have a live seed set, so you can rename them to 'live' in order to recreate the match afterwards." +} + +ai_recruitstate_initialtimer +{ +"Ustaw botom czas do rekrutacji jednostek zgodnie z parametrami AIC" +} + +ai_recruitstate_initialtimervalue_descr +{ +"Można tu ustawić liczbę miesięcy, do której boty będą rekrutować wyłącznie jednostki do obrony, chyba że wypełnili już limit żołnierzy na zamku" +} + +ai_defense +{ +"Usprawnione wysyłanie posiłków do obrony" +} + +ai_defense_descr +{ +"Naprawniono błąd, który uniemożliwiał SI dosyłanie brakujących jednostek & +na mury i wieże w momencie, gdy patrole defensywne były ciągle obecne." +} + +ai_housing +{ +"Mądrzejsze budowanie domów przez boty" +} + +build_housing_descr +{ +"Różnica między obecną a maksymalną populacją, po której bot przestaje stawiać domy. W oryginale jest to 0. Ta opcja wyłącza również usuwanie domów przez bota." +} + +campfire_housing_descr +{ +"Ilość wolnych chłopów przy ognisku, zanim bot przestanie stawiać domy. Ta opcja wyłącza również usuwanie domów przez bota." +} + +delete_housing +{ +"Wyłącz usuwanie domów." +} + +delete_housing_descr +{ +"Kiedy ta opcja jest zaznaczona, boty nie będą usuwać domów." +} + +aiv_prompt +{ +"Wykryto własne pliki AIV. Czy chcesz stworzyć kopię zapasową, mój Panie?" +} + +aiv_cli_prompt +{ +"Wykryto własne pliki AIV. Wpisz 'delete', aby usunąć lub podaj nazwę folderu w celu przekopiowania plików." +} + +install_abort_io +{ +"Instalacja przerwana. Pliki z taką samą nazwą znajdują się już w tym folderze. Wybierz inny folder i spróbuj ponownie." +} + +install_abort +{ +"Instalacja przerwana" +} + +backup_aiv_select +{ +"Wybierz zapasowy folder dla plików AIV" +} + +o_change_siege_engine_spawn_position_catapult +{ +"Wyśrodkuj pozycję pojawiania się machin oblężniczych" +} + +o_change_siege_engine_spawn_position_catapult_descr +{ +"Machiny oblężnicze będą pojawiać się na środku miejsca, w którym stał namiot oblężniczy." +} + +o_stop_player_keep_rotation +{ +"Odwróć siedziby graczy" +} + +o_stop_player_keep_rotation_descr +{ +"Siedziby graczy będą odwracać się ogniskiem (wejściem) w stronę krańca mapy." +} + +o_restore_arabian_engineer_speech +{ +"Przywróć arabskie teksty inżynierów" +} + +o_restore_arabian_engineer_speech_descr +{ +"Ta opcja pozwala inżynierom na korzystanie z nagranych arabskich tekstów, gdy gracz gra jako arabski lord. + +Tekstów nie ma zbyt wielu, więc mogą być irytujące po dłuższej chwili." +} + +u_fix_lord_animation_stuck_movement +{ +"Zresetuj animację lorda po zniszczeniu budynku" +} + +u_fix_lord_animation_stuck_movement_descr +{ +"Opcja pozwala zresetować animację lorda, gdy każemu mu zniszczyć budynek. Zazwyczaj po wykonaniu zadania stał w dziwnej pozie." +} + +fix_apple_orchard_build_size +{ +"Zmniejsz rozmiar budowy sadów jabłoni" +} + +fix_apple_orchard_build_size_descr +{ +"Opcja zmniejsza rozmiar budowy sadów jabłoni, aby był taki sam, jak rzeczywisty rozmiar całego budynku. Zaoszczędzi to miejsce na trawie i pomoże botom na lepszy rozwój." +} + +u_fix_applefarm_blocking +{ +"Napraw blokowanie sadów jabłoni" +} + +u_fix_applefarm_blocking_descr +{ +"Farmerzy nie będą już blokowani, gdy postawi się budynek w lewej, górnej stronie farmy." +} + +o_increase_path_update_tick_rate +{ +"Zwiększ częstotliwość odświeżania możliwych ścieżek" +} + +o_increase_path_update_tick_rate_descr +{ +"W oryginale jednostki potrzebowały dużo czasu, zanim mogły zrozumieć, że można wejść do zamku po zniszczeniu bramy lub wieży.. + +Ta opcja zwiększa czterokrotnie częstotliwość odświeżania możliwych ścieżek wykrywanych przez jednostki, dzięki czemu szybciej zrozumieją, że można już wejść do zamku." +} + +o_fix_ladderclimb +{ +"Napraw błąd związany z wchodzeniem po drabinie" +} + +o_fix_ladderclimb_descr +{ +"Jednostki nie będą już gubić się po wejściu na mury po drabinie i nie będą schodzić od razu na dół." +} + +u_tanner_fix +{ +"Zwiększ wydajność garbarzy" +} + +u_tanner_fix_descr +{ +"Garbarze nie będą już wracać do budynku, gdy ktoś inny zabrał krowę, po którą szli. Zamiast tego postoją chwilę w miejscu i wyruszą po kolejną krowę." +} + +o_fix_fletcher_bug +{ +"Napraw błąd łuczarza" +} + +o_fix_fletcher_bug_descr +{ +"Naprawia błąd, który powoduje, że łuczarz idzie do swojego budynku po odniesieniu broni do zbrojowni. Zamiast tego będzie teraz szedł od razu do składu zapasów po deski." +} + +ai_fix_crusader_archers_pitch +{ +"Napraw błąd z brakiem podpalania smoły przez łuczników europejskich" +} + +ai_fix_crusader_archers_pitch_descr +{ +"Łucznicy europejscy zarządzani przez SI nie podpalali smoły. Ta opcja naprawia ten błąd." +} + +o_fix_baker_disappear +{ +"Napraw błąd ze znikającym piekarzem" +} + +o_fix_baker_disappear_descr +{ +"Piekarze nie będą znikać, gdy dojdą do składu zapasów, w którym nie ma już mąki." +} + +o_fix_moat_digging_unit_disappearing +{ +"Napraw błąd ze znikającymi jednostkami kopiącymi fosę" +} + +o_fix_moat_digging_unit_disappearing_descr +{ +"Naprawia błąd, który powodował losowe znikanie jednostek kopiących fosę. Uwaga: jednostki mogą dalej znikać, jeśli każesz im przemieścić się w momencie, gdy stoją w miejscu, z którego nie da się normalnie ruszyć!" +} + +ui_welcometext +{ +"Jest to nieoficjalna łatka do Twierdzy Krzyżowiec. +Projekt jest dostępny jako otwarte oprogramowanie przez [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). + +Każda wersja Krzyżowca jest potencjalnie obsługiwana, ale wprowadzone zmiany pochodzą z wersji 1.41 Steam, dlatego mogą pojawić się problemy. +Instalator wyświetli wtedy komunikat o błędzie. Wersja tej łatki jest pokazana w lewym dolnym rogu głównego menu gry. +Przed zmianami zostaną utworzone pliki. kopii zapasowej. Można je przywrócić za pomocą przycisku 'Odinstaluj' lub ręcznie. + +Zespół odpowiedzialny za UCP + +Oryginalny twórca UCP +[Sh0wdown](https://github.com/Sh0wdown) + +Zarządzanie projektem +[Kimberly Azula](https://github.com/ByBurton/) +[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) + +Twórcy +[LordHansCapon](https://github.com/LordHansCapon) +[np123](https://github.com/patel-nikhil) +[J-T-de](https://github.com/J-T-de) +[gynt](https://github.com/gynt) +[Le spec](https://github.com/LeSpec) +[Chaf1812](https://github.com/Chaf1812) + +Tłumacze +[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polski) +[Lolasik011](https://github.com/Lolasik011) (Rosyjski) +[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chiński) +[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (język węgierski) + +Twórcy dodatkowych funkcji +[Evrey](https://github.com/Evrey) (aiv) +[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) +[PitchNeeded](https://github.com/PitchNeeded) (aiv) +[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) + +Specjalne podziękowania dla +[Firefly Studios](https://fireflyworlds.com/) +za stworzenie serii Twierdza. + +Oraz dla +[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) +[PodeCaradox](https://github.com/PodeCaradox) +[GRhin](https://www.twitch.tv/grhin) +[Heroesflorian](https://github.com/Heroesflorian)" +} + +// ====================== +// 2.14 +// ====================== + +ui_StartTroops +{ + "JednostkiPoczątkowe" +} + +ui_Resource +{ + "ZasobyPoczątkowe" +} + +ui_aicconflict +{ + "Konflikty zostaną zignorowane" +} + +o_shfy +{ + "Strongholdify" +} + +o_shfy_beer +{ + "Bonus do popularności za piwo" +} + +o_shfy_beer_descr +{ + " " +} + +o_shfy_religion +{ + "Bonus do popularności za katedrę i kościół" +} + +o_shfy_religion_descr +{ + " " +} + +o_shfy_peasantspawnrate +{ + "Szybkość pojawiania się wieśniaków" +} + +o_shfy_peasantspawnrate_descr +{ + " " +} + +o_shfy_resourcequantity +{ + "Ilośc otrzymywanych surowców" +} + +o_shfy_resourcequantity_descr +{ + "Podane aspekty są zbliżone do tych z pierwszej Twierdzy. Uwaga: Każda zmiana wpływa na przeciwników komputerowych. W najgorszym wypadku mogą stać się bezużyteczni!" +} + +o_armory_marketplace_weapon_order_fix +{ + "Ustaw broń na targowisku i w zbrojowni w tej samej kolejności" +} + +o_armory_marketplace_weapon_order_fix_descr +{ + "Ustawia broń na targowisku i w zbrojowni w tej samej kolejności. Zbroja skórzana na targowisku zostaje przesunięta między wekiery i kusze, natomiast zbroja metalowa między piki i miecze." +} + +ai_fix_laddermen_with_enclosed_keep +{ + "Napraw błąd, który powoduje, że komputer nie korzysta z drabiniarzy, gdy ma otoczoną siedzibę" +} + +ai_fix_laddermen_with_enclosed_keep_descr +{ + "Komputer (głównie Wąż) będzie od teraz korzystał z drabiniarzy, gdy jego siedziba zostanie otoczona." +} + +o_override_identity_menu +{ + "Dodaje nowe funkcje do opcji ustawień tożsamości" +} + +o_override_identity_menu_descr +{ + "Dodaje jednostki do własnego ustawienia w opcji dostosowania tożsamości. TYLKO W NORMALNYM TRYBIE GRY!" +} + +o_default_multiplayer_speed +{ + "Ustaw domyślną prędkość gry multiplayer." +} + +o_default_multiplayer_speed_descr +{ + " " +} + +u_fireballistafix +{ + "Balista ogniowa strzela do mnichów i kopaczy" +} + +u_fireballistafix_descr +{ + "Balista ogniowa automatycznie strzela w mnichów i kopaczy." +} + +ui_browsepath +{ + "Wybierz katalog instalacyjny Stronghold Crusader." +} + +ui_aicoldversion +{ + "Wykryto starą wersję. Kliknij, aby przekonwertować" +} + +ui_aicofferconvert +{ + "Konwertuj plik AIC do nowszej wersji?" +} + +ui_aicconvertprompt +{ + "Konwersja AIC" +} + +ui_aicselect +{ + "Najpierw usuń zaznaczenie innych plików AIC. Następujące znaki AIC są już wybrane: " +} + +// ====================== +// 2.13 +// ====================== + +o_firecooldown +{ + "Wydłuż czas, po którym budynek może ponownie się zapalić" +} + +o_firecooldown_descr +{ + "Można tutaj wydłużyć czas, po którym budynek może ponownie się zapalić po ugaszeniu." +} + +u_ballistamonk +{ + "Balista ogniowa strzela do mnichów" +} + +u_ballistamonk_descr +{ + "Balisty ogniowe strzelają automatycznie do mnichów." +} + + +// ====================== +// 2.12 +// ====================== + +ui_AIC +{ + "AIC" +} + +ui_aicExport +{ + "Eksport" +} + +ui_aicExport_success +{ + "Eksportowanie powiodło się." +} + +ui_aicHint +{ + "Eksportuje plik .aic z instalatora do folderu z grą." +} + +// ====================== +// 1.00 +// ====================== + + + +Name +{ + "Nieoficjalna aktualizacja do Krzyżowca" +} + +u_ArabXBow +{ + "Zwiększona obrona arabskich zbrojnych przeciwko kusznikom" +} + +u_arabxbow_descr +{ + " - Arabscy zbrojni umierają po 6 strzałach z kuszy zamiast 3" +} + +u_ArabWall +{ + "Arabscy zbrojni szybciej niszczą mury" +} + +u_ArabWall_descr +{ + "W oryginalnej grze arabscy zbrojni niszczą mury najwolniej ze wszystkich jednostek walczących wręcz. & +Dzięki tej opcji prędkość niszczenia murów przez arabskich zbrojnych jest dwukrotnie większa, & +nieco powyżej prędkości włóczników." +} + +u_spearmen +{ + "Zwiększona obrona włóczników przeciwko jednostkom strzelającym" +} + +u_spearmen_descr +{ + " - Włócznicy giną po 5 strzałach z łuku zamiast 3 + - Włócznicy ledwie przeżywają jeden strzał z kuszy, zamiast od razu ginąć" +} + +ui_error +{ + "Błąd" +} + +ui_SearchPath +{ + "Wybierz folder instalacyjny gry Twierdza Krzyżowiec:" +} + +ui_search +{ + "Wyszukaj" +} + +ui_continue +{ + "Kontynuuj" +} + +ui_wrongpath +{ + "Nie można znaleźć gry Twierdza Krzyżowiec w podanej ścieżce!" +} + +ui_back +{ + "Wróć" +} + +ui_install +{ + "Instalacja" +} + +ui_finished +{ + "Ukończono" +} + +ui_chooseLangTitle +{ + "Wybierz język" +} + +ui_chooseLang +{ + "Wybierz język instalatora z poniższej listy." +} + +ui_accept +{ + "Akceptuj" +} + +ui_cancel +{ + "Anuluj" +} + +ui_uninstall +{ + "Odinstaluj" +} + +ui_uninstalldone +{ + "Odinstalowywanie patcha zakończone prawidłowo." +} + +ai_recruitinterval +{ + "Zwiększona prędkość rekrutacji" +} + +ai_recruitinterval_descr +{ + "Ustawia odstęp między rekrutacją jednostek przez wszystkich przeciwników komputerowych na najniższą wartość & + (poziom Szczura/Ryszarda)" +} + +ai_attacklimit +{ + "Zwiększenie limitu ataku przeciwników komputerowych" +} + +ai_attacklimit_descr +{ + "Liczba dodatkowych jednostek dodawanych po pierwszym ataku jest & +ograniczona do 200 w oryginalnej grze. Tutaj możesz zmienić ten limit." +} + +o_gamespeed +{ + "Jeszcze większa prędkość gry" +} + +o_gamespeed_descr +{ + "Szybkość gry można teraz zmienić w następujący sposób: + - Od 10 do 90 w odstępach 5 + - Od 90 do 200 w odstępach 10 + - Od 200 do 1000 w odstępach 100 +Nowe wartości są dostępne w grze wyłącznie za pomocą klawiszy + i -, suwak w menu & +gry pozostaje niezmieniony." +} + +ui_bugfix +{ + "Naprawione błędy" +} + +ui_ailords +{ + "Przeciwnicy komputerowi" +} + +ui_troops +{ + "Jednostki" +} + +ui_other +{ + "Pozostałe" +} + +o_responsivegates +{ + "Szybsza reakcja bram" +} + +o_responsivegates_descr +{ + "Bramy zamykają się później, gdy wrogowie znajdą się w zasięgu i otworzą się szybciej, & +kiedy niebezpieczeństwo zniknie. Odległość wroga od bramy, która wpływa na jej automatyczne zamykanie się & +zostanie zmniejszona z 200 do 140. Czas, po którym otwierają się bramy, gdy & +wszyscy wrogowie znikną, zostaje zmniejszony z 1200 do 100." +} + +ai_addattack +{ + "Zwiększenie liczby dodatkowych jednostek w kolejnych atakach SI" +} + +ai_addattack_descr +{ + "W oryginalnej grze liczba żołnierzy wzrasta po każdym ataku średnio o 5 & +jednostek. Ta wartość jest taka sama dla wszystkich przeciwników komputerowych i można ją zmienić & +tutaj." +} + +ai_addattack_alt_descr +{ + "Ewentualnie dodatkowa liczba żołnierzy może być uzależniona od & +liczby jednostek z pierwszego ataku. Ponieważ ta wartość jest inna dla każdego przeciwnika komputerowego, & +następne ataki będą zmieniać rozmiar zależnie od tej początkowej wartości. +Przykład: współczynnik zmiany rozmiaru = 0,5 +Ataki wysyłane przez Sułtana = 10, 15, 20, 25, ... +Ataki wysyłane przez Saladyna = 50, 75, 100, 125, ..." +} + +u_laddermen +{ + "Zwiększona obrona drabiniarzy przeciwko jednostkom strzelającym" +} + +u_laddermen_descr +{ + " - Drabiniarz ginie po 12 strzałach z łuku zamiast po 5 + - Drabiniarz ginie po 5 trafieniach z kuszy lub procy zamiast 2 + - Drabiniarz kosztuje 20 złota zamiast 4" +} + +o_playercolor +{ + "Zmiana koloru pierwszego gracza" +} + +o_playercolor_descr +{ + " " +} + +ai_demolish +{ + "Dezaktywuj burzenie budynków dla pieniędzy przez przeciwników komputerowych" +} + +ai_demolish_walls +{ + "fortyfikacje obronne" +} + +ai_demolish_eco +{ + "budynki ekonomiczne" +} + +ai_demolish_walls_descr +{ + " " +} + +ai_demolish_eco_descr +{ + "Jeśli przeciwnik komputerowy czuje presję, lubi burzyć gospodarkę lub & +budynki fortyfikacyjne, aby uzyskać pieniądze w celu rekrutacji żołnierzy. Ta funkcja czasami & +wydaje się być uruchamiana bez widocznego powodu i dlatego można to tutaj wyłączyć." +} + +ai_tethers +{ + "Wyłącz niepotrzebne stawianie wołów pociągowych przez przeciwników komputerowych" +} + +ai_tethers_descr +{ + "Zazwyczaj sztuczna inteligencja buduje dla każdego nowego kamieniołomu kolejne & +woły, niezależnie od tego, ile już postawiła wcześniej. Można to wyłączyć tutaj, ponieważ & +prowadzi to do spamu wołami pociągowymi, gdy kamieniołomy sztucznej inteligencji są wielokrotnie niszczone." +} + + + + + + + + + + +// ======================= +// 2.06 +// ======================= + +ai_nosleep +{ + "Wyłącz usypianie budynków z powodu braku zasobów" +} + +ai_nosleep_descr +{ + "Sztuczna inteligencja zwykle usypia budynki produkcyjne, gdy tylko & +brakuje wymaganego zasobu. Odbywa się to bez względu na to, & +czy straci produkty, które są już w drodze, np. do zbrojowni. +Tę funkcję można tutaj całkowicie wyłączyć." +} + + + + + + + + + +// 5.12.2018 + +o_onlyai +{ + "Aktywuj tryb Obserwatora [możliwy błąd]" +} + +o_onlyai_descr +{ + "Usuwa głównego gracza, dzięki czemu możesz tylko obserwować i tworzyć & +pojedynki między ośmioma botami. Zapisy gry ładują się teraz poprawnie w tym & +trybie. Czasami pojawia się błąd, w którym losowe obiekty pojawiają się na całej mapie. & +Jest to tylko wizualny błąd i można go usunąć zapisując grę, kończąc misję i & +ponownie wczytując zapis." +} + +o_moatvisibility +{ + "Zawsze pokazuj zaplanowaną fosę" +} + +o_moatvisibility_descr +{ + "Zaplanowana, ale jeszcze nie wykopana fosa będzie zawsze pokazywana z tym & +ustawieniem, nawet jeśli odznaczysz opcję rozmieszczania fosy." +} + +o_engineertent +{ + "Brak anulowania wybranego namiotu oblężniczego" +} + +o_engineertent_descr +{ + "Przy tym ustawieniu gra nie odznacza wybranej machiny oblężniczej & +po umieszczeniu już jednego namiotu. W ten sposób możesz stworzyć kilka namiotów & +bez konieczności ponownego wybierania tego samego sprzętu oblężniczego za każdym razem." +} + + + + + + + + + + + +// ================================ +// 2.07 +// ================================ + + +ai_demolish_trapped +{ + "Jeśli siedziba jest otoczona" +} + +ai_demolish_trapped_descr +{ + " " +} + + +ai_attacknearest +{ + "Zawsze atakuj najbliższego wroga" +} + +ai_attacknearest_descr +{ + "Przy tym ustawieniu przeciwnicy komputerowi zawsze atakują najbliższych wrogów. & +Dzięki temu oddziały nie rozchodzą się podczas oblężenia zamku, ani nie giną z powodu przechodzenia obok & +zamku wroga, którego nie atakują w danej chwili." +} + + +o_freetrader +{ + "Darmowe targowisko" +} + +o_freetrader_descr +{ + "Czasami sztuczna inteligencja może nic nie robić, gdy nie ma drewna, a targowisko & +zostało zniszczone. Aby temu zapobiec, można włączyć tę opcję, dzięki czemu targowisko będzie darmowe." +} + +ai_towerengines +{ + "Brak ograniczeń dla machin oblężniczych na wieżach" +} + +ai_towerengines_descr +{ + "Zazwyczaj sztuczna inteligencja buduje maksymalnie trzy mangonele i balisty na swoich wieżach. & +Ten limit można tutaj znieść." +} + +ai_buywood +{ + "Kupuj wystarczającą ilość drewna" +} + +ai_buywood_descr +{ + "Aby uniemożliwić złodziejskim rzemieślnikom kradzież drewna, które gracz komputerowy właśnie kupił, aby postawić & +budynki, boty będą kupować o 2 deski więcej za każdym razem." +} + +o_keys +{ + "Klawisze WASD i szybki zapis" +} + +o_keys_descr +{ + "Klawisze WASD mogą być używane do poruszania kamerą. Dodatkowo & +kombinacja klawiszy CTRL-S i CTRL-L służy do szybkiego zapisania i wczytania gry." +} + + + + + + + + + + + + + + + + + + + + + +// =========== +// 2.07a +// =========== + + + +ai_attacktarget +{ + "Ustaw cel ataku graczy komputerowych" +} + +ai_attacktarget_nearest +{ + "Najbliższy przeciwnik" +} + +ai_attacktarget_nearest_descr +{ + " " +} + +ai_attacktarget_richest +{ + "Najbogatszy przeciwnik" +} + +ai_attacktarget_richest_descr +{ + " " +} + +ai_attacktarget_weakest +{ + "Najsłabszy przeciwnik" +} + +ai_attacktarget_weakest_descr +{ + "Dzięki tej opcji gracze komputerowi będą zawsze wybierać ten sam cel & +ataku. Dzięki temu oddziały nie rozchodzą się podczas oblężenia zamku, & +ani nie giną z powodu przechodzenia obok zamku wroga, którego nie atakują w danej chwili." +} + + + + + +// ================= +// 2.08 +// ================= + + + + +ai_assaultswitch +{ + "Brak zmiany celu podczas oblężenia" +} + +ai_assaultswitch_descr +{ + "Przeciwnicy komputerowi, którzy atakują najlepszego albo najsłabszego wroga, & +czasami wysyłają swoich żołnierzy w trakcie oblężenia do innego & +zamku. Ta opcja to uniemożliwia, & +gdy atak już się rozpocznie. Jeżeli atak jeszcze się nie rozpoczął, np. w momencie & +zbierania armii przed zamkiem, zmiana może nastąpić." +} + + + +ai_rebuild +{ + "Ulepszona naprawa budynków przez graczy komputerowych" +} + +ai_rebuild_descr +{ + "Gracze komputerowi będą naprawiać ruiny wież, trochę zniszczone mury oraz & +zniszczone cechy inżynierów i kopaczy, a także kotły z olejem, których punkt zbiórki & +dalej istnieje. Dodatkowo gracze komputerowi mogą teraz budować na składach kamienia & +z kamieniołomów." +} + + + + + + +// ==================== +// 2.09 +// ==================== + +o_healer +{ + "Zielarz leczy rannych" +} + +o_healer_descr +{ + "Zielarz będzie teraz szukał rannych żołnierzy, & +zwierzęta i mieszkańców, aby ich uleczyć. Zielarz zaczyna leczyć od najbliższego celu. Każda & +animacja leczenia leczy 1/3 życia włócznika. Chodzenie po ogrodach & +i pozbywanie się zarazy nie zostało zastąpione! Zielarz pomija jedynie chodzenie & +po zamku, dopóki nie wyleczy wszystkich rannych." +} + + + + + + + + +// ==================== +// 2.10 +// ==================== + + + +o_xtreme +{ + "Usuń pasek mocy w wersji Extreme" +} + +o_xtreme_descr +{ + "Usuwa pasek umiejętności w Twierdzy Krzyżowiec Extreme." +} + + + + + + + + + + + + + + +// ====================== +// 2.11 +// ====================== + + +ui_AIV +{ + "AIV" +} + +ai_access +{ + "Brak niszczenia niedostępnych budynków" +} + +ai_access_descr +{ + "Ta opcja zapobiega niszczeniu budynków, do których nie ma dojścia. Dzięki temu & +Sztuczna Inteligencja przestanie ciągle niszczyć i odbudowywać budynki, do których & +nie da się dojść." +} + +ai_attackwave +{ + "Popraw fale ataków" +} + +ai_attackwave_descr +{ + "W oryginalnej grze sztuczna inteligencja wysyła tylko tyle żołnierzy za jednym razem, ile jest wolnych & +kawałków murów. Powoduje to, że jednostki poruszają się w małych grupach, & +gdy atakowany zamek ma wiele budynków bezpośrednio przy murach. +Ta opcja sprawia, że żołnierze atakują również budynki cywilne i fortyfikacyjne, a także & +te części murów, które są już atakowane przez inną jednostkę. Dodatkowo +SI wysyła więcej jednostek do wrogiego lorda, gdy przełamie mury." +} diff --git a/UnofficialCrusaderPatch/Localization/Russian.txt b/UnofficialCrusaderPatch/Localization/Russian.txt new file mode 100644 index 00000000..c34191a1 --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/Russian.txt @@ -0,0 +1,1072 @@ +// ====================== +// 2.15 +// ====================== + +u_spearmen_run +{ +"Копейщики бегут по умолчанию вместо того, чтобы ходить пешком." +} + +u_spearmen_run_descr +{ +"Вместо медленной ходьбы копейщики бегут медленно." +} + +o_seed_modification_possibility_title +{ +"Игровой случайный сид" +} + +o_seed_modification_possibility_only_set +{ +"Включить фиксированную игру случайным сидом" +} + +o_seed_modification_possibility_only_set_descr +{ +"Установка игрового сида позволит играм только с AI играть точно так же, если используются те же настройки карты. Для игр с AI, он обеспечит такие же условия запуска на карте (например, выбор AIV). Для установки игрового сида, включите эту опцию и создайте файл под названием (live) с 6-значным номером в каталоге установки игры/игр. +ВНИМАНИЕ: Эта функция работает только после перезапуска игры!" +} + +o_seed_modification_possibility +{ +"Включить и сохранить игру случайных сидов" +} + +o_seed_modification_possibility_descr +{ +"Эта опция сохранит сид от игр, которые не имеют "live" сида, так что вы можете переименовать их в "live", чтобы потом воссоздать матч." +} + +ai_recruitstate_initialtimer +{ +"Настройка первоначального времени вербовки AI в защиту" +} + +ai_recruitstate_initialtimervalue_descr +{ +"Установите это значение на количество месяцев, в течение которых AI будет вербовать исключительно войска обороны, если только он уже не заполнил всю оборону." +} + +ai_defense +{ +"Исправляет подкрепление войск обороны AI" +} + +ai_defense_descr +{ +"Исправлен баг, из-за которого AI не усиливал недостающие войска на стенах и башнях, пока оборонительные патрули все еще были вокруг." +} + +ai_housing +{ +"Настройка решения AI о строительстве и удалении домов" +} + +build_housing_descr +{ +"Количество дополнительного доступного жилья до того, как AI прекратит строительство домов" +} + +campfire_housing_descr +{ +"Количество крестьян у костра перед тем, как AI остановит строительство домов." +} + +delete_housing +{ +"Отключает способность AI удалять дома." +} + +delete_housing_descr +{ +"Когда эта опция выбрана, AI никогда не будет удалять дома" +} + +aiv_prompt +{ +"Обнаружены пользовательские AIV. Вы хотите создать резервную копию Милорд?" +} + +aiv_cli_prompt +{ +"Обнаружены пользовательские AIV. Введите 'delete' для удаления или введите имя папки для копирования файлов." +} + +install_abort_io +{ +"Установка отменена. В этой папке уже существуют файлы с таким же именем. Попробуйте еще раз и выберите другую папку." +} + +install_abort +{ +"Установка отменена" +} + +backup_aiv_select +{ +"Выберите резервную папку AIV" +} + +o_change_siege_engine_spawn_position_catapult +{ +"Положение спавна осадных механизмов посредине" +} + +o_change_siege_engine_spawn_position_catapult_descr +{ +"Осадные механизмы теперь появляется по центру , вместо появления в верхнем углу палатки." +} + +o_stop_player_keep_rotation +{ +"Поворот крепости игрока" +} + +o_stop_player_keep_rotation_descr +{ +"Крепость игрока вращяется таким же образом как и крепости AI. Точней стоит лицом к костру AI , а другой стороной к краю карты" +} + +o_restore_arabian_engineer_speech +{ +"Восстановление арабской речи инженера" +} + +o_restore_arabian_engineer_speech_descr +{ +"Позволяет инженерам говорить на изначально записанных арабских голосовых дорожках, когда игрок использует арабского лорда. + +Голосовые линии не сильно отличаются друг от друга, так что через некоторое время они могут стать раздражающими." +} + +u_fix_lord_animation_stuck_movement +{ +"Исправляет анимацию замирания Лорда" +} + +u_fix_lord_animation_stuck_movement_descr +{ +"Исправляет анимацию замирания Лорда когда тот стоит, либо когда разрушает здание." +} + +fix_apple_orchard_build_size +{ +"Размер площади яблоневой фермы" +} + +fix_apple_orchard_build_size_descr +{ +"Изменяет размер постройки яблоневого сада на размер который он занимает после расположение фермы. Это экономит место при строительстве ферм и увеличивает скорость, с которой AI может располагать эти фермы." +} + +u_fix_applefarm_blocking +{ +"Исправить блокировку яблочных ферм" +} + +u_fix_applefarm_blocking_descr +{ +"Яблочные фермеры больше нельзя блокировать, размещая здания в верхней левой части фермы." +} + +o_increase_path_update_tick_rate +{ +"Более частая проверка доступного пути" +} + +o_increase_path_update_tick_rate_descr +{ +"В ваниле, это заняло 200 игровых тиков, чтобы проверить новые пути, часто останавливая юнитов, чтобы перейти в замок после уничтожения ворот или башни немедленно. + Доступность рассчитывается теперь каждые 50 игровых тиков, что позволяет юнитам реализовывать новые пути быстрее." +} + +o_fix_ladderclimb +{ +"Исправить ошибку подъёма по лестнице" +} + +o_fix_ladderclimb_descr +{ +"Отряды больше не забывают о своем предназначении после восхождения на стену, и они больше не начнут подниматься или спускаться вниз сразу же после того, как они только что поднялись." +} + +u_tanner_fix +{ +"Исправляет кожевников которые получают одну и ту же корову" +} + +u_tanner_fix_descr +{ +"Кожевники больше не вернутся без коровы, когда другой кожевник забрал их целевую корову. Вместо этого они немного подождут, а потом возьмут еще одну корову." +} + +o_fix_fletcher_bug +{ +"Исправляет баг стрельника" +} + +o_fix_fletcher_bug_descr +{ +"Исправление поведения, при котором стрельник возвращается на рабочее место после сдачи на хранение лука/арбалета вместо того, чтобы идти прямо на склад." +} + +ai_fix_crusader_archers_pitch +{ +"Исправляет европейских лучников которые не стреляют в нефтяной ров" +} + +ai_fix_crusader_archers_pitch_descr +{ +"Исправляет, что (AI) европейские лучники не зажигают рвы, как арабские лучники, когда на них попадают вражеские юниты." +} + +o_fix_baker_disappear +{ +"Исправить ошибку исчезновения пекаря" +} + +o_fix_baker_disappear_descr +{ +"Исправляет ошибку, при которой пекарни исчезали бы, если бы пекари не нашли муку на складе запасов." +} + +o_fix_moat_digging_unit_disappearing +{ +"Исправляет исчезания юнитов при копании рва" +} + +o_fix_moat_digging_unit_disappearing_descr +{ +"Исправлена ошибка, при которой копатели рва исчезали случайно во время раскопок. Обратите внимание, что они все равно могут исчезнуть, если вы прикажете им двигаться во время раскопок, и они случайно встанут на непешеходную плитку!" +} + +ui_welcometext +{ +"Это неофициальный патч для Stronghold Crusader. +Проект доступен в виде открытого исходного кода по адресу [GitHub](https://github.com/UnofficialCrusaderPatch/UnofficialCrusaderPatch). + +Любая версия Crusader потенциально поддерживается, но так как изменения были получены из версии 1.41 Steam-Version, могут появиться несовместимости. +После этого в настройках появятся сообщения об ошибках. Установленная версия патча отображается в левом нижнем углу главного меню игры. +Перед любыми изменениями будут созданы резервные файлы. Их можно восстановить с помощью кнопки 'Удалить' или вручную. + +Команда, стоящая за UCP + +Создатель UCP +[Sh0wdown](https://github.com/Sh0wdown) + +Управление проектами +[Kimberly Azula](https://github.com/ByBurton/) +[Krarilotus (Youtube)](https://www.youtube.com/channel/UCMXHqa2vmclSoSkuCu_q5rw) + +Разработчики +[LordHansCapon](https://github.com/LordHansCapon) +[np123](https://github.com/patel-nikhil) +[J-T-de](https://github.com/J-T-de) +[gynt](https://github.com/gynt) +[Le spec](https://github.com/LeSpec) +[Chaf1812](https://github.com/Chaf1812) + +Переводчики +[Lutel (YouTube)](https://www.youtube.com/user/MrLutel05) (Polish) +[Lolasik011](https://steamcommunity.com/profiles/76561198399248341) (Russian) +[Skysoul (e-mail)](mailto:theskysoul@vip.qq.com) (Chinese) +[Liegav (YouTube)](https://www.youtube.com/channel/UCFqQMKfYgGb7iFKJagQl_wA) (Hungarian) + +Создатели контента +[Evrey](https://github.com/Evrey) (aiv) +[Tatha](https://www.youtube.com/channel/UC4BrhBzHp1ymnczlkdKcSkg) (aiv,aic) +[PitchNeeded](https://github.com/PitchNeeded) (aiv) +[Xander10alpha (YouTube)](https://www.youtube.com/channel/UCYlyixfoKPcz-Ixi6Nc383Q) (aic) + +Особая благодарность, конечно же, выражается +[Firefly Studios](https://fireflyworlds.com/) +за создания серии игр Stronghold + +И многие другие +[Udwin (YouTube)](https://www.youtube.com/user/UdwinLP) +[PodeCaradox](https://github.com/PodeCaradox) +[GRhin](https://www.twitch.tv/grhin) +[Heroesflorian](https://github.com/Heroesflorian)" +} + +// ====================== +// 2.14 +// ====================== + +ui_StartTroops +{ + "Стартовые войска" +} + +ui_Resource +{ + "Стартовые товары" +} + +ui_aicconflict +{ + "конфликт AI будет игнорироваться" +} + +o_shfy +{ + "Strongholdify" +} + +o_shfy_beer +{ + "Бонус за популярность от пива" +} + +o_shfy_beer_descr +{ + " " +} + +o_shfy_religion +{ + "Бонус за популярность от собора налогов и церкви" +} + +o_shfy_religion_descr +{ + " " +} + +o_shfy_peasantspawnrate +{ + "Скорость появления крестьян (спавн)" +} + +o_shfy_peasantspawnrate_descr +{ + " " +} + +o_shfy_resourcequantity +{ + "Количество предоставленных ресурсов" +} + +o_shfy_resourcequantity_descr +{ + "Адаптирует перечисленные аспекты в соответствии с Stronghold 1. Внимание: Каждое изменение влияет на повелителей AI, в худшем случае делает их бесполезными!" +} + +o_armory_marketplace_weapon_order_fix +{ + "Исправить оружейный склад/рыночное оружие, чтобы соответствовать порядку" +} + +o_armory_marketplace_weapon_order_fix_descr +{ + "Изменение порядка иконок оружия в Оружейной и на Рынке, чтобы они располагались в одинаковом порядке. Также перемещает кожаную броню между булавой и арбалетом, а металлическую броню - между пиками и мечом для более легкого доступа во время прокрутки предметов на Рынке." +} + +ai_fix_laddermen_with_enclosed_keep +{ + "Исправить AI, не использующий лестниц, если они есть в наличии." +} + +ai_fix_laddermen_with_enclosed_keep_descr +{ + "AI (в частности, Змея) больше не прекращает использование Лестниц с Осадными орудиями, если они находится в замкнутом пространстве." +} + +o_override_identity_menu +{ + "Переопределить меню "Set-up Identity", добавляя новые функции." +} + +o_override_identity_menu_descr +{ + "Добавляет выбор юнитов дальнего и ближнего боя в меню Set-up Identity". ТОЛЬКО ДЛЯ ОБЫЧНОГО ИГРОВОГО РЕЖИМА!" +} + +o_default_multiplayer_speed +{ + "Установить скорость мультиплеера по умолчанию." +} + +o_default_multiplayer_speed_descr +{ + " " +} + +u_fireballistafix +{ + "Огненные баллисты стреляют в монахов и тунелекопателей" +} + +u_fireballistafix_descr +{ + "Огненные баллисты автоматически стреляют в монахов и тунелекопателей." +} + +ui_browsepath +{ + "Пожалуйста, выберите каталог установки Stronghold Crusader." +} + +ui_aicoldversion +{ + "Обнаружена старая версия. Нажмите чтобы конвертировать" +} + +ui_aicofferconvert +{ + "Конвертировать файл в новую версию?" +} + +ui_aicconvertprompt +{ + "Преобразование AIC" +} + +ui_aicselect +{ + "Сначала отмените выбор других файлов AIC. Следующие символы aic уже выбраны: " +} + +// ====================== +// 2.13 +// ====================== + +o_firecooldown +{ + "Увеличить пожаробезопасную продолжительность потушенных зданий" +} + +o_firecooldown_descr +{ + "Здесь можно продлить срок, в течение которого потухшие здания больше не смогут загореться." +} + +u_ballistamonk +{ + "Огненные баллисты стреляют в монахов." +} + +u_ballistamonk_descr +{ + "Огненные баллисты стреляют автоматически в монахов с этой настройкой." +} + + +// ====================== +// 2.12 +// ====================== + + +ui_AIC +{ + "AIC" +} + +ui_aicExport +{ + "Экспорт" +} + +ui_aicExport_success +{ + "Экспортирование успешно." +} + +ui_aicHint +{ + "Экспортирует .aic-файл из установщика в папку Stronghold Crusader." +} + +// ====================== +// 1.00 +// ====================== + + +Name +{ + "Неофициальный Stronghold Crusader Патч" +} + +u_ArabXBow +{ + "Увеличенная броня арабского мечника против стрел арбалетчика" +} + +u_arabxbow_descr +{ + " - Арабские мечники умирают после 6 стрел из арбалета вместо 3" +} + +u_ArabWall +{ + "Арабские мечники разрушают стены быстрее" +} + +u_ArabWall_descr +{ + "В Ваниле арабские мечники разрушают стены медленнее любого другого подразделения ближнего боя. +С этой опцией скорость удара (анимации) против стен удваивается для них,поставив их немного выше копейщиков. (по скорости анимации атаки)" +} + +u_spearmen +{ + "Увеличенная броня копейщиков против урона дальних юнитов" +} + +u_spearmen_descr +{ + " - Копейщики умирают после 5 попаданий стрел из лука, вместо 3 +  - Копейщики едва выдерживали один выстрел из арбалета, вместо того чтобы умереть от одного выстрела" +} + +ui_error +{ + "Ошибка" +} + +ui_SearchPath +{ + "Выберите папку установки:" +} + +ui_search +{ + "Просматривать" +} + +ui_continue +{ + "Продолжить" +} + +ui_wrongpath +{ + "Stronghold Crusader не может быть найден по указанному пути!" +} + +ui_back +{ + "Назад" +} + +ui_install +{ + "Установить" +} + +ui_finished +{ + "Завершение" +} + +ui_chooseLangTitle +{ + "Язык установки" +} + +ui_chooseLang +{ + "Пожалуйста, выберите язык для этой настройки из списка ниже." +} + +ui_accept +{ + "ОК" +} + +ui_cancel +{ + "Отмена" +} + +ui_uninstall +{ + "Удаление" +} + +ui_uninstalldone +{ + "Удаление завершено." +} + +ai_recruitinterval +{ + "Увеличенная скорость набора рекрутов" +} + +ai_recruitinterval_descr +{ + "Устанавливает интервал набора всех AI до самого низкого значения (Крыса/Ричард)" +} + +ai_attacklimit +{ + "Увеличение предела атакующих войск AI" +} + +ai_attacklimit_descr +{ + "Количество дополнительных единиц, которые добавляются после первой атаки & +в Ваниле - до 200. Здесь вы можете изменить этот предел." +} + +o_gamespeed +{ + "Расширенные ограничения скорости игры" +} + +o_gamespeed_descr +{ + "Теперь скорость игры можно изменить следующим образом: + - От 10 до 90 с интервалом 5 +  - от 90 до 200 с интервалом 10 +  - от 200 до 1000 с интервалом в 100 + - от 1100 - 9000 (Но после 1100 уже не происходит увеличение) +Новые значения доступны только с помощью клавиш + -, ползунка в & +меню игры остается неизменным." +} + +ui_bugfix +{ + "Исправления ошибок" +} + +ui_ailords +{ + "AI Лорды" +} + +ui_troops +{ + "Юниты" +} + +ui_other +{ + "Другое" +} + +o_responsivegates +{ + "Быстрая реакция юнитов на врагов" +} + +o_responsivegates_descr +{ + "Ворота закрывается позже & +когда опасность исчезнет. Расстояние врага, для которого закрываются ворота & +будет уменьшено с 200 до 140. Время, после которого ворота открываются, & +будет уменьшены с 1200 до 100." +} + +ai_addattack +{ + "Увеличение скорости дополнительных атакующих войск" +} + +ai_addattack_descr +{ + "В Ваниле количество единиц атаки увеличивается на 5 & +единиц в среднем. Это значение для всех здесь." + +} + +ai_addattack_alt_descr +{ + "В качестве альтернативы, дополнительное количество войск может быть выполнено в зависимости от & +число войск первой атаки. Поскольку это значение отличается для каждого AI & +следующие атаки будут масштабироваться, а не на одну и ту же величину & +для каждого лорда AI. +Пример: Масштабный коэффициент = 0,5 +Войска Султана атакуют = 10, 15, 20, 25, ... +Атакующие войска Саладина = 50, 75, 100, 125, ... " +} + +u_laddermen +{ + "Увеличенная броня Крестьян с лесницами против дальних войск" +} + +u_laddermen_descr +{ + " - Крестияне с лестницами умирают после 12 стрел вместо 5 +  - Крестияне с лестницами умирают после 5 выстрелов арбалетов или пращников вместо 2 +  - Крестияне с лестницами стоят 20 золотых вместо 4" +} + +o_playercolor +{ + "Изменить цвет Игрока 1" +} + +o_playercolor_descr +{ + " " +} + +ai_demolish +{ + "Деактивировать снос за деньги AI Лордов" +} + +ai_demolish_walls +{ + "фортификационные сооружения" +} + +ai_demolish_eco +{ + "экономические сооружения" +} + +ai_demolish_walls_descr +{ + " " +} + +ai_demolish_eco_descr +{ + "Если AI чуствует прессинг, он начинает разрушать свою экономику или & +фортификационные здания, чтобы получить быстрые деньги для сбора войск." +} + +ai_tethers +{ + "Отключит спам привязей" +} + +ai_tethers_descr +{ + "Как правило, AI строит для каждой новой каменоломни новую привязь & +независимо от того сколько привязей уже существует. Здесь это можно отключить, так как & +это приводит к спаму если карьеры AI будут уничтожены повторно." +} + + + + + + + + + + +// ======================= +// 2.06 +// ======================= + +ai_nosleep +{ + "Отключить спящий режим из-за нехватки ресурсов" +} + +ai_nosleep_descr +{ + "AI обычно ставит свои обрабатывающие здания в сон поскольку необходимый ресурс отсутствует. +Это делается без учета потери продуктов, и оружия которые находятся на пути в Оружейную. +Эта функция может быть полностью отключена здесь." +} + + + + + + + + + + +// 5.12.2018 + +o_onlyai +{ + "Активировать Режим - Зрителя (Только AI) [Возможны баги]" +} + +o_onlyai_descr +{ + "Убирает игрока 1, чтобы вы могли видеть только 8 AI в одном и том же режиме. & +Сохранения игры теперь правильно загружаются в этом режиме. Иногда ошибка & +появляется, когда случайные объекты появляются на всей карте. Это просто визуальный баг & +и его можно убрать сохранив игру, завершая миссию и перезагружая & +сохранить файл." +} + +o_moatvisibility +{ + "Всегда показывать планированый ров" +} + +o_moatvisibility_descr +{ + "Ваш собственный,но не выкопанный ров всегда будет показан с этой опцией, даже если вы отмените выбор размещения рва." +} + +o_engineertent +{ + "Нету выбора осадной палатки" +} + +o_engineertent_descr +{ + "С помощью этой настройки игра не отменяет выбранное вами осадное оборудование после размещения больше одной палатки +Таким образом вы можете создать несколько палаток одну за другим,без необходимости повторного выбора одного и того же осадного оборудования." +} + + + + + + + + + + + +// ================================ +// 2.07 +// ================================ + + +ai_demolish_trapped +{ + "Если приложено" +} + +ai_demolish_trapped_descr +{ + " " +} + +o_freetrader +{ + "Бесплатный рынок" +} + +o_freetrader_descr +{ + "Поскольку АI иногда играет сам, когда он находится далеко от леса и его рынок уничтожен. & + С этим параметром рынок станет бесплатным, чтобы предотвратить это." +} + +ai_towerengines +{ + "Нет лимита на осадные машины на башнях" +} + +ai_towerengines_descr +{ + "Обычно АI строит на своих башнях до трех мангонелей и баллист. & +Этот лимит можно снять здесь." +} + +ai_buywood +{ + "Купить достаточно древесины" +} + +ai_buywood_descr +{ + "Чтобы воры стрельники не могли украсть древесину которую АI только что купил для здания. + 2 единицы дополнительной деревесины AI теперь будет покупать для каждого здания." +} + +o_keys +{ + "WASD-Кнопки и быстрые сохранения" +} + +o_keys_descr +{ + "Клавиши WASD можно использовать для перемещения с этой настройкой, а также & +CTRL-S и CTRL-L для быстрого сохранения и загрузки соответственно." +} + + + + + + + + + + + + + + + + + + + + + +// =========== +// 2.07a +// =========== + + + +ai_attacktarget +{ + "Установить цель атаки AI" +} + +ai_attacktarget_nearest +{ + "Ближайший враг" +} + +ai_attacktarget_nearest_descr +{ + " " +} + +ai_attacktarget_richest +{ + "Богатый враг" +} + +ai_attacktarget_richest_descr +{ + " " +} + +ai_attacktarget_weakest +{ + "Слабый враг" +} + +ai_attacktarget_weakest_descr +{ + "С этим параметром все лорды AI выберут свою следующую цель атаки. & +Это предотвращает переключение войск во время штурма замка, а также отправку & +их мимо замков других врагов." +} + + + +// ===================== +// 2.08 +// ===================== + + +ai_assaultswitch +{ + "Нет изменения цели AI во время осады" +} + +ai_assaultswitch_descr +{ + "Лорды AI, которые иногда нападают на самого могущественного или самого слабого врага & +они переключают свою цель в середине продолжающегося нападения и отправляют свои войска & +в другой замок. Это предотвращается с помощью этой настройки, как только начался штурм, & +т. е. на этапе сбора войск перед замком, изменения все еще могут произойти." +} + + + +ai_rebuild +{ + "Улучшенный ремонт AI" +} + +ai_rebuild_descr +{ + "AI будет ремонтировать руины башни, слегка поврежденные стены, а также & +уничтожит инженерные и туннельные гильдии и нефтеперерабатывающие платформы, место сбора которых & +все еще существует. Кроме того, AI теперь может строить на платформе сбора & +карьеров." +} + + + + + + +// ==================== +// 2.09 +// ==================== + +o_healer +{ + "Целитель лечит раненых солдат" +} + +o_healer_descr +{ + "Целитель здания аптеки теперь активно ищет раненых солдат,жителей и жывотных чтобы исцелить их. Ближайшие цели он лечит первыми. +Проигрывается анимация ,и он исцеляет за 1/3 секунды здоровье копейщика. Когда Целитель прогуливается он может разсеять облако чумы которое он заметит. +Он будет лечить в одной области замка всех пока не вылечет до конца, а только потом он перейдет к другому участку замка. +Также он не начнет разсеивать облака чумы пока он не сходит в сады." +} + + + + + + + + + + +// ==================== +// 2.10 +// ==================== + + + +o_xtreme +{ + "Убраны значки магии в Stronghold Crusader Extreme" +} + +o_xtreme_descr +{ + "Убирает значки магии в Stronghold Crusader Extreme." +} + + + + + + + + + + +// ====================== +// 2.11 +// ====================== + + +ui_AIV +{ + "AIV" +} + +ai_access +{ + "Нет сноса недоступных зданий" +} + +ai_access_descr +{ + "Предотвращает AI от разрушения зданий без доступа. Это должно остановить AI +непрерывного разрушения и восстановления зданий где нет доступа к ним." +} + +ai_attackwave +{ + "Улучшение волны атаки" +} + +ai_attackwave_descr +{ + "AI в атаке в ванили посылает сразу столько же войск, как и тогда когда стены целые. Это заставляет единицы умирать в маленьких волнах +когда у целевого замка много зданий прямо у его стен. Этот вариант позволяет подразделениям атаковать гражданские и фортификационные здания, а также +стены которые уже атакованы одной единицей. Более того AI посылает больше войск к вражескому лорду, как только обнаруживает что стена разрушена." +} diff --git a/UnofficialCrusaderPatch/Localization/TextReferencer.cs b/UnofficialCrusaderPatch/Localization/TextReferencer.cs new file mode 100644 index 00000000..1e49e00b --- /dev/null +++ b/UnofficialCrusaderPatch/Localization/TextReferencer.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Diagnostics; + +namespace UCP +{ + public static class TextReferencer + { + struct TextRef + { + string keyword; + public string Keyword { get { return this.keyword; } } + + string reference; + public string Reference { get { return this.reference; } } + + public TextRef(string keyword, string reference) + { + this.keyword = keyword; + this.reference = reference; + } + } + + public static void SetText(TextBlock tb, string text) + { + int last = 0, index = 0; + while (index < text.Length) + { + if (text[index] == '[') + { + int start1 = index + 1; + int end1 = text.IndexOf(']', start1); + if (end1 >= 0 && end1 < text.Length - 2 && text[end1 + 1] == '(') + { + int start2 = end1 + 2; + int end2 = text.IndexOf(')', start2); + if (end2 >= 0) + { + string url = text.Substring(start2, end2 - start2); + string urltext = text.Substring(start1, end1 - start1); + + if (index > last) + { + tb.Inlines.Add(text.Substring(last, index - last)); + } + + Hyperlink hyperlink = new Hyperlink(new Run(urltext)); + hyperlink.RequestNavigate += (s, e) => Process.Start(url); + hyperlink.NavigateUri = new Uri(url); + hyperlink.ToolTip = url; + tb.Inlines.Add(hyperlink); + + last = end2 + 1; + index = end2; + } + } + } + + index++; + } + + if (index > last) + { + tb.Inlines.Add(text.Substring(last, index - last)); + } + } + } +} diff --git a/UnofficialCrusaderPatch/Properties/Resources.Designer.cs b/UnofficialCrusaderPatch/Properties/Resources.Designer.cs index 1d161a1f..5ea9abe2 100644 --- a/UnofficialCrusaderPatch/Properties/Resources.Designer.cs +++ b/UnofficialCrusaderPatch/Properties/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -13,13 +13,13 @@ namespace UCP.Properties { /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// A strongly-typed resource class, for looking up localized strings, etc. /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -33,7 +33,7 @@ internal Resources() { } /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +47,8 @@ internal Resources() { } /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { diff --git a/UnofficialCrusaderPatch/Properties/Settings.Designer.cs b/UnofficialCrusaderPatch/Properties/Settings.Designer.cs index 3bac7c37..d54e7b77 100644 --- a/UnofficialCrusaderPatch/Properties/Settings.Designer.cs +++ b/UnofficialCrusaderPatch/Properties/Settings.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -12,7 +12,7 @@ namespace UCP.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/UnofficialCrusaderPatch/Resources/modConfig.json b/UnofficialCrusaderPatch/Resources/modConfig.json index 0277f371..74216122 100644 --- a/UnofficialCrusaderPatch/Resources/modConfig.json +++ b/UnofficialCrusaderPatch/Resources/modConfig.json @@ -2,14 +2,28 @@ { "modType": "Bugfixes", "modIdentifier": "o_fix_ladderclimb", - "modDescription": {}, + "modDescription": { + "Chinese": "修复士兵爬上云梯后遗失目的地bug", + "English": "Fix ladder climbing destination bug", + "German": "Behebt Befehlsverlust beim Klettern auf Leitern", + "Hungarian": "Létramászás hibajavítás", + "Polish": "Napraw błąd związany z wchodzeniem po drabinie", + "Russian": "Исправить ошибку подъёма по лестнице" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_fix_ladderclimb", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "士兵现在爬上云梯后将会记住目的地,而不会被困在云梯上。", + "English": "Units will now remember their original destination after climbing a ladder, not getting stuck on the ladder.", + "German": "Einheiten klettern nicht mehr direkt zurück und vergessen auch nicht mehr ihr Ziel, nachdem sie eine Leiter erklommen haben.", + "Hungarian": "Az egységek mászás után nem felejtik el a számukra adott parancsot, és többé nem fognak lemászni miután már felmásztak.", + "Polish": "Jednostki nie będą już gubić się po wejściu na mury po drabinie i nie będą schodzić od razu na dół.", + "Russian": "Отряды больше не забывают о своем предназначении после восхождения на стену, и они больше не начнут подниматься или спускаться вниз сразу же после того, как они только что поднялись." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -18,14 +32,28 @@ { "modType": "Bugfixes", "modIdentifier": "u_fireballistafix", - "modDescription": {}, + "modDescription": { + "Chinese": "巨火弩正确攻击僧侣和隧道工", + "English": "Fire ballistae shoot monks and tunnelers", + "German": "Feuerballisten schießen auf Mönche und Tunnelgräber", + "Hungarian": "A tűzhajítógépek lőnek a szerzetesekre és az alagútásókra", + "Polish": "Balista ogniowa strzela do mnichów i kopaczy", + "Russian": "Огненные баллисты стреляют в монахов и тунелекопателей" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_fireballistafix", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "巨火弩将会自动攻击敌人的僧侣和隧道工。", + "English": "Fire ballistae automatically shoot at monks and tunnelers.", + "German": "Feuerballisten erkennen nun Mönche und Tunnelgräber als Feinde und schießen auf diese.", + "Hungarian": "A tűzhajítógépek most már ellenségként észlelik a szerzeteseket és az alagútásókat, mostantól lőnek rájuk.", + "Polish": "Balista ogniowa automatycznie strzela w mnichów i kopaczy.", + "Russian": "Огненные баллисты автоматически стреляют в монахов и тунелекопателей." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -34,14 +62,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_access", - "modDescription": {}, + "modDescription": { + "Chinese": "不拆除无通路建筑", + "English": "No demolishing of inaccessible buildings", + "German": "Kein Abreißen von unzugänglichen Gebäuden", + "Hungarian": "Az elérhetetlen épületek ne kerüljenek lerombolásra", + "Polish": "Brak niszczenia niedostępnych budynków", + "Russian": "Нет сноса недоступных зданий" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_access", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "ai会反复建造又拆除无通路但需要通路的建筑,打开此选项可以避免此问题。", + "English": "Prevents the AI from demolishing buildings without access. This should stop the AI from continuously demolishing and rebuilding buildings where no access is available.", + "German": "Verhindert, dass die KI Gebäude abreißt zu denen es keinen Zuweg gibt. Damit soll der Bug verhindert werden, bei dem manche KIs in ihren Burgen andauernd Gebäude abreißen und wieder aufbauen zu denen es keinen Weg gibt.", + "Hungarian": "Megakadályozza azt, hogy az MI lerombolja azt az épületet amihez nem lehet hozzáférni. Ezáltal kijavítható az a hiba, hogy az MI ne építse meg és rombolja le újra és újra mindig azt az épületet amihez nem tudnak eljutni.", + "Polish": "Ta opcja zapobiega niszczeniu budynków, do których nie ma dojścia. Dzięki temu Sztuczna Inteligencja przestanie ciągle niszczyć i odbudowywać budynki, do których nie da się dojść.", + "Russian": "Предотвращает AI от разрушения зданий без доступа. Это должно остановить AI непрерывного разрушения и восстановления зданий где нет доступа к ним." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -50,14 +92,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_defense", - "modDescription": {}, + "modDescription": { + "Chinese": "修复ai不会补充防守兵种", + "English": "Fix reinforcement of defense troops", + "German": "Verstärkung der Burgverteidigung fixen", + "Hungarian": "Várvédő egységek megerősítése kijavítva", + "Polish": "Usprawnione wysyłanie posiłków do obrony", + "Russian": "Исправляет подкрепление войск обороны AI" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_defense", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "当ai城墙防守部队出现减员时,如果城外防守部队仍然存在,那么ai将不会补充城墙防守部队。", + "English": "Fixes a bug which stopped the AI from reinforcing missing troops on walls and towers, as long as defensive patrols were still around.", + "German": "Fixt den Bug, der die KI davon abhielt, fehlende Truppen auf Wällen und Türmen zu verstärken solange noch Defensivpatrouillien vorhanden waren.", + "Hungarian": "Kijavítja azt a hibát, ami megakadályozza az MI-t abban, hogy a hiányzó egységekkel megerősítse a várfalat és a tornyot, ameddig rendelkezik még védekező-járőröző egységekkel.", + "Polish": "Naprawniono błąd, który uniemożliwiał SI dosyłanie brakujących jednostek na mury i wieże w momencie, gdy patrole defensywne były ciągle obecne.", + "Russian": "Исправлен баг, из-за которого AI не усиливал недостающие войска на стенах и башнях, пока оборонительные патрули все еще были вокруг." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -66,14 +122,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_tethers", - "modDescription": {}, + "modDescription": { + "Chinese": "防止ai牛栏堆积", + "English": "Disable ox tether spam", + "German": "Ochsenjoch-Spam deaktivieren", + "Hungarian": "Ökör karám spam deaktiválása", + "Polish": "Wyłącz niepotrzebne stawianie wołów pociągowych przez przeciwników komputerowych", + "Russian": "Отключит спам привязей" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_tethers", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "通常,ai会为每个新的采石场建筑一个新的牛栏,而不管已经存在多少牛栏。当采石场被反复摧毁时,会导致牛栏数量很多。打开此选项可以避免这种现象。", + "English": "Usually, the AI builds for each new stone quarry a new ox tether, independent of how many tether already exist. This can be disabled here, since it leads to ox tether spam if the AIs' quarries get destroyed repeatedly.", + "German": "Die KI baut normalerweise mit jedem neuen Steinbruch auch ein neues Ochsenjoch, unabhängig davon wie viele sie schon hat. Dies kann hier deaktiviert werden, da es zu Ochsenjoch-Spam führt, wenn die Steinbrüche der AI immer wieder zerstört werden.", + "Hungarian": "Az MI általában minden új kőfejtő építésekor épít egy új ökör karámot is attól függetlenül, hogy mennyi van neki. Ezt itt tudod deaktiválni, mert különben spammelni fogja az ökör karámokat, ha az MI kőfejtőjét mindig lerombolják.", + "Polish": "Zazwyczaj sztuczna inteligencja buduje dla każdego nowego kamieniołomu kolejne woły, niezależnie od tego, ile już postawiła wcześniej. Można to wyłączyć tutaj, ponieważ prowadzi to do spamu wołami pociągowymi, gdy kamieniołomy sztucznej inteligencji są wielokrotnie niszczone.", + "Russian": "Как правило, AI строит для каждой новой каменоломни новую привязь независимо от того сколько привязей уже существует. Здесь это можно отключить, так как это приводит к спаму если карьеры AI будут уничтожены повторно." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -82,14 +152,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_buywood", - "modDescription": {}, + "modDescription": { + "Chinese": "购买足够木头", + "English": "Buy enough wood", + "German": "Genügend Holz kaufen", + "Hungarian": "Elegendő fa vásárlása", + "Polish": "Kupuj wystarczającą ilość drewna", + "Russian": "Купить достаточно древесины" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_buywood", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "ai购买木头用于建筑时,将会购买2根额外的木头,防止刚购买的木头被工人拿走使得木头不足以建造目标建筑。", + "English": "To prevent thievish fletchers from stealing wood which the AI just bought for buildings, 2 extra wood will now be bought for each building.", + "German": "Damit Bogenmacher etc. nicht ständig gekauftes Bauholz wegschnappen, kauft die KI mit dieser Einstellung immer 2 Holz mehr als nötig für Gebäude.", + "Hungarian": "Ahhoz hogy az íjkészítők stb. ne vigyék el mindig a megvásárolt fát. Az MI ezzel a beállítással mindig 2 fával többet vesz, mint ami szükséges az épületek építéséhez.", + "Polish": "Aby uniemożliwić złodziejskim rzemieślnikom kradzież drewna, które gracz komputerowy właśnie kupił, aby postawić budynki, boty będą kupować o 2 deski więcej za każdym razem.", + "Russian": "Чтобы воры стрельники не могли украсть древесину которую АI только что купил для здания. 2 единицы дополнительной деревесины AI теперь будет покупать для каждого здания." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -98,14 +182,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_towerengines", - "modDescription": {}, + "modDescription": { + "Chinese": "解除ai的器械数量限制", + "English": "No limit for siege engines on towers", + "German": "Keine Grenze für Geräte auf Türmen", + "Hungarian": "Ne legyen korlátozás a tornyokon lévő szerkezeteknek", + "Polish": "Brak ograniczeń dla machin oblężniczych na wieżach", + "Russian": "Нет лимита на осадные машины на башнях" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_towerengines", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "在原版,每种器械ai最多只能放置3个,打开此选项可以解除此限制。", + "English": "Usually the AI only builds up to three mangonels and ballistae each on its towers. This limit can be lifted here.", + "German": "Normalerweise baut die KI maximal je drei Ballisten und Mangen. Dieses Limit wird hiermit aufgehoben.", + "Hungarian": "Általában az MI maximálisan 3 hajítógépet és kővetőgépet épít minden tornyára. Ezen beállítással ez a korlátozás megszűnik.", + "Polish": "Zazwyczaj sztuczna inteligencja buduje maksymalnie trzy mangonele i balisty na swoich wieżach. Ten limit można tutaj znieść.", + "Russian": "Обычно АI строит на своих башнях до трех мангонелей и баллист. Этот лимит можно снять здесь." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -114,14 +212,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_assaultswitch", - "modDescription": {}, + "modDescription": { + "Chinese": "进攻时不改变目标", + "English": "No AI target change during sieges", + "German": "Kein KI-Angriffszielwechsel während Belagerung", + "Hungarian": "Ostrom közben ne változtasson az MI támadási-célpontot", + "Polish": "Brak zmiany celu podczas oblężenia", + "Russian": "Нет изменения цели AI во время осады" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_assaultswitch", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "当ai进攻时,如果目标发生改变,将会改变已派出部队的目标,比如ai目标若是最弱的敌人,当ai已派出进攻部队时,如果最弱的敌人改变了,将会改变进攻部队的路径转而攻击新目标。打开这个选项可以防止这种现象的发生。已派出的部队不会中途改变目标。", + "English": "AI lords which attack the mightiest oder weakest enemy sometimes switch their target in the middle of an ongoing assault and send their troops to a different castle. This is prevented with this setting, as soon as the assault has started, i.e. during the troop gathering phase in front of a castle a change can still happen.", + "German": "KI-Lords die den mächtigsten oder schwächsten Gegner angreifen, hatten manchmal die Tendenz mitten in einem Angriff das Ziel zu wechseln, und ihre Truppen zu einer anderen Burg schicken. Mit dieser Einstellung, passiert das nicht mehr, sobald der Angriff begonnen hat, d.h. während des Sammelns vor der Burg kann ein Wechsel noch passieren.", + "Hungarian": "Azok az MI Lordok akik a legerősebbet vagy a leggyengébbet támadták meg, néha hajlamosak voltak a támadás közepén célpontot változtatni, és az egységeiket elküldeni a másik várhoz. Ezzel a beállítással, ez már nem fordul elő, mihelyst a támadást megkezdte, viszont a vár előtti egységek gyülekezésekor még előfordulhat, hogy célpontot vált.", + "Polish": "Przeciwnicy komputerowi, którzy atakują najlepszego albo najsłabszego wroga, czasami wysyłają swoich żołnierzy w trakcie oblężenia do innego zamku. Ta opcja to uniemożliwia, gdy atak już się rozpocznie. Jeżeli atak jeszcze się nie rozpoczął, np. w momencie zbierania armii przed zamkiem, zmiana może nastąpić.", + "Russian": "Лорды AI, которые иногда нападают на самого могущественного или самого слабого врага они переключают свою цель в середине продолжающегося нападения и отправляют свои войска в другой замок. Это предотвращается с помощью этой настройки, как только начался штурм, т. е. на этапе сбора войск перед замком, изменения все еще могут произойти." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -130,14 +242,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_rebuild", - "modDescription": {}, + "modDescription": { + "Chinese": "增强ai修复和建筑能力", + "English": "Improved AI repairs", + "German": "Verbessertes KI-Reparieren", + "Hungarian": "Kijavított MI javítások", + "Polish": "Ulepszona naprawa budynków przez graczy komputerowych", + "Russian": "Улучшенный ремонт AI" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_rebuild", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "打开后,ai将会在废墟中重建塔楼,修复微小损坏的城墙。工程师协会,隧道工协会,油锅被摧毁后,如果后半截仍然存在,打开后ai将可以正确重建。采石场被摧毁后,如果存放石头点仍然存在,打开后ai可以无视存放石头点放置建筑。", + "English": "The AI will repair tower ruins, slightly damaged walls, as well as destroyed engineer's and tunneler's guilds and oil smelters, of which the gathering place still exists. Furthermore, the AI can now build over the collection platform of quarries.", + "German": "Mit dieser Einstellung reparieren KI-Lords auch Turmruinen, leicht angeschlagene Mauern, sowie Baumeister-, Tunnelgilden und Ölkessel bei denen der Sammelplatz übergeblieben ist. Weiterhin kann die KI nun auch die Sammelstelle von Steinbrüchen überbauen.", + "Hungarian": "Ezzel a beállítással az MI Lordok megjavítják a toronyromokat is, enyhén megrongált várfalakat, továbbá mérnökök-, alagútásók céhet és olajfőző kunyhót ha a helyük megmaradt. Továbbá az MI most már képes építeni a kőfejtők helye felett is.", + "Polish": "Gracze komputerowi będą naprawiać ruiny wież, trochę zniszczone mury oraz zniszczone cechy inżynierów i kopaczy, a także kotły z olejem, których punkt zbiórki dalej istnieje. Dodatkowo gracze komputerowi mogą teraz budować na składach kamienia z kamieniołomów.", + "Russian": "AI будет ремонтировать руины башни, слегка поврежденные стены, а также уничтожит инженерные и туннельные гильдии и нефтеперерабатывающие платформы, место сбора которых все еще существует. Кроме того, AI теперь может строить на платформе сбора карьеров." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -146,14 +272,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_fix_laddermen_with_enclosed_keep", - "modDescription": {}, + "modDescription": { + "Chinese": "修复了ai在城堡无通路时不使用云梯兵的错误", + "English": "Fix AI not using laddermen if they are enclosed", + "German": "Korrigiert Leiternutzung", + "Hungarian": "Javított létrahasználat", + "Polish": "Napraw błąd, który powoduje, że komputer nie korzysta z drabiniarzy, gdy ma otoczoną siedzibę", + "Russian": "Исправить AI, не использующий лестниц, если они есть в наличии." + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_fix_laddermen_with_enclosed_keep", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "当ai(尤其是蛇)在自己城堡无通路到外界时,不再会停止使用云梯兵。", + "English": "AI (notably Snake) no longer stops using Laddermen with their sieging units if their keep is enclosed.", + "German": "Mit diesem Fix können Belagerungseinheiten von KIs, deren Bergfried abgeschlossen ist, weiterhin die Leitern der Leiterträger nutzen (betrifft vanilla nur die Schlange).", + "Hungarian": "Ezzel a hibajavítással azok az MI-k, akiknek a vártornyuk körül van zárva, továbbra is tudják az ostromegységeik használni a létrahordozók létráit (az eredeti játékban ez csak a Kígyót érinti).", + "Polish": "Komputer (głównie Wąż) będzie od teraz korzystał z drabiniarzy, gdy jego siedziba zostanie otoczona.", + "Russian": "AI (в частности, Змея) больше не прекращает использование Лестниц с Осадными орудиями, если они находится в замкнутом пространстве." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -162,14 +302,28 @@ { "modType": "Bugfixes", "modIdentifier": "u_fix_lord_animation_stuck_movement", - "modDescription": {}, + "modDescription": { + "Chinese": "修正领主摧毁建筑物后的人物动画", + "English": "Reset lord animation after destroying buildings", + "German": "Setzt die Lordanimation nach Zerstörung von Gebäuden zurück", + "Hungarian": "Lord animáció visszaállítása az épületek lerombolása után", + "Polish": "Zresetuj animację lorda po zniszczeniu budynku", + "Russian": "Исправляет анимацию замирания Лорда" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_fix_lord_animation_stuck_movement", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "修正了领主的姿势,当领主停止移动或者摧毁一个建筑物后,他将会站立,而不是被卡在地上。", + "English": "Reset the pose of the lord after it stops moving or destroys a building into the upright position. Usually it would get stuck bend down to the ground.", + "German": "Der Lord wechselt mit dieser Änderung nach dem Zerstören eines Gebäudes in seine Ausgangsposition. Bisher blieb er in der Zerstöranimation stecken.", + "Hungarian": "Ezzel a változtatással egy épület lerombolása után a Lord a kiindulási animációra tér vissza. Mostantól nem marad a leromboló animációban.", + "Polish": "Opcja pozwala zresetować animację lorda, gdy każemu mu zniszczyć budynek. Zazwyczaj po wykonaniu zadania stał w dziwnej pozie.", + "Russian": "Исправляет анимацию замирания Лорда когда тот стоит, либо когда разрушает здание." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -178,14 +332,28 @@ { "modType": "Bugfixes", "modIdentifier": "u_fix_applefarm_blocking", - "modDescription": {}, + "modDescription": { + "Chinese": "修复苹果园工人被堵路", + "English": "Fix apple farm worker getting blocked", + "German": "Behebt das Blockieren des Apfelfarmers", + "Hungarian": "Almáskert blokkolása javítás", + "Polish": "Napraw blokowanie sadów jabłoni", + "Russian": "Исправить блокировку яблочных ферм" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_fix_applefarm_blocking", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "当农场的左上方被建筑堵住时,将不再阻止苹果园工人进入苹果园。", + "English": "Apple farmers can no longer be blocked by placing buildings at the top left side of the farm.", + "German": "Apfelfarmer werden nicht länger inaktiv, wenn der Pfad links oben direkt neben der Farm blockiert wird.", + "Hungarian": "Az almatermesztő nem várakozik, ha az almáskert bal felső részénél lévő utat blokkolja valami.", + "Polish": "Farmerzy nie będą już blokowani, gdy postawi się budynek w lewej, górnej stronie farmy.", + "Russian": "Яблочные фермеры больше нельзя блокировать, размещая здания в верхней левой части фермы." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -194,14 +362,28 @@ { "modType": "Bugfixes", "modIdentifier": "u_tanner_fix", - "modDescription": {}, + "modDescription": { + "Chinese": "修复所有皮革工人获取同一头牛", + "English": "Fix tanners getting all the same cow", + "German": "Gerberinnen holen sich unterschiedliche Kühe", + "Hungarian": "A tímárok ugyanazt a tehenet választják javítás", + "Polish": "Zwiększ wydajność garbarzy", + "Russian": "Исправляет кожевников которые получают одну и ту же корову" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_tanner_fix", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "现在皮革工人到达牧场后,若发现想要牵走的牛已被其他工人牵去,会转而去牵另外一头牛,而不是直接回到作坊。极大提高皮革作坊的效率。", + "English": "Tanners will no longer return without a cow when another tanner took their target cow. They will now instead stand around a bit and then get another one.", + "German": "Gerberinnen kehren nicht länger ohne Kuh zurück, falls ihre anvisierte Kuh bereits weg ist. Sie warten nun, bis sie eine andere Kuh mitnehmen können.", + "Hungarian": "A tímárok mostantól nem fognak tehén nélkül visszatérni, ha egy másik tímár már elvitte az általuk kiválasztott tehenet. Mostantól várakoznak egy ideig és elvisznek egy másikat.", + "Polish": "Garbarze nie będą już wracać do budynku, gdy ktoś inny zabrał krowę, po którą szli. Zamiast tego postoją chwilę w miejscu i wyruszą po kolejną krowę.", + "Russian": "Кожевники больше не вернутся без коровы, когда другой кожевник забрал их целевую корову. Вместо этого они немного подождут, а потом возьмут еще одну корову." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -210,14 +392,28 @@ { "modType": "Bugfixes", "modIdentifier": "o_fix_fletcher_bug", - "modDescription": {}, + "modDescription": { + "Chinese": "修复弓弩工人的路线", + "English": "Fix fletcher pathing", + "German": "Entfernt den Extraweg des Pfeilmachers zur Werkstatt", + "Hungarian": "Íjkészítő hibajavítás", + "Polish": "Napraw błąd łuczarza", + "Russian": "Исправляет баг стрельника" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_fix_fletcher_bug", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "现在弓弩工人在武器库放下弓弩后会直接去储存区拿原料,而不是先返回作坊。", + "English": "Fixes the behaviour where fletchers go back to the workplace after depositing the bow/crossbow instead of going straight to the stockpile.", + "German": "Passt das Verhalten des Pfeilmachers an andere Waffenproduzenten an. Nach Abgabe seines Gutes geht er nun direkt zum Vorratslager, statt erneut zur Werkstatt zurückzukehren.", + "Hungarian": "Kijavítja az íjkészítő azon viselkedését, miszerint visszatér a munkahelyére ha leszállított egy íjat/íjpuskát, ahelyett hogy egyenesen a raktárhoz menne.", + "Polish": "Naprawia błąd, który powoduje, że łuczarz idzie do swojego budynku po odniesieniu broni do zbrojowni. Zamiast tego będzie teraz szedł od razu do składu zapasów po deski.", + "Russian": "Исправление поведения, при котором стрельник возвращается на рабочее место после сдачи на хранение лука/арбалета вместо того, чтобы идти прямо на склад." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -226,14 +422,28 @@ { "modType": "Bugfixes", "modIdentifier": "ai_fix_crusader_archers_pitch", - "modDescription": {}, + "modDescription": { + "Chinese": "修复AI的欧洲弓箭手不会点燃沥青", + "English": "Fix AI's crusader archers not lighting pitch", + "German": "Europäische Bogenschützen der KI entzünden Pech.", + "Hungarian": "MI keresztes íjász nem gyújtja be az olajosárkot javítás", + "Polish": "Napraw błąd z brakiem podpalania smoły przez łuczników europejskich", + "Russian": "Исправляет европейских лучников которые не стреляют в нефтяной ров" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_fix_crusader_archers_pitch", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "AI的欧洲弓箭手可以和阿拉伯弓箭手一样点燃沥青。", + "English": "AI's European archers light pitch the same way arabian archers do, defending against enemy units.", + "German": "Bisher waren nur Arabische Bogenschützen der KIs in der Lage Pechgraben mit Feuerpfeilen zu entzünden; nun können dies auch Europäischen Bogenschützen.", + "Hungarian": "Az MI keresztes íjász most már begyújtja az olajosárkot, úgy mint az arab íjász amikor ellenséges egység lép az olajosárokra.", + "Polish": "Łucznicy europejscy zarządzani przez SI nie podpalali smoły. Ta opcja naprawia ten błąd.", + "Russian": "Исправляет, что (AI) европейские лучники не зажигают рвы, как арабские лучники, когда на них попадают вражеские юниты." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -242,14 +452,28 @@ { "modType": "Bugfixes", "modIdentifier": "o_fix_baker_disappear", - "modDescription": {}, + "modDescription": { + "Chinese": "修复面包工人消失", + "English": "Fix bakers despawning", + "German": "Behebt das Verschwinden von Bäckern", + "Hungarian": "Eltűnő pék hibajavítás", + "Polish": "Napraw błąd ze znikającym piekarzem", + "Russian": "Исправить ошибку исчезновения пекаря" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_fix_baker_disappear", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "当面包工人到达储存区却没有面粉时,不再会消失。", + "English": "Bakers no longer disappear when they don't find flour at their targeted stockpile.", + "German": "Behebt den Fehler, der Bäcker verschwinden ließ, wenn sie kein Mehl am angestrebten Platz im Vorratslager vorfinden konnten.", + "Hungarian": "Kijavítja azt a hibát, amikor a pék eltűnik ha a raktárban nem találja meg a kiválasztott helyen a lisztet.", + "Polish": "Piekarze nie będą znikać, gdy dojdą do składu zapasów, w którym nie ma już mąki.", + "Russian": "Исправляет ошибку, при которой пекарни исчезали бы, если бы пекари не нашли муку на складе запасов." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -258,14 +482,28 @@ { "modType": "Bugfixes", "modIdentifier": "o_fix_moat_digging_unit_disappearing", - "modDescription": {}, + "modDescription": { + "Chinese": "修复挖河士兵消失", + "English": "Fix despawning of digging units", + "German": "Behebt das Verschwinden von Buddeleinheiten.", + "Hungarian": "Eltűnő árokásó egység hibajavítás", + "Polish": "Napraw błąd ze znikającymi jednostkami kopiącymi fosę", + "Russian": "Исправляет исчезания юнитов при копании рва" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_fix_moat_digging_unit_disappearing", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "挖河士兵在挖护城河时不再会随机消失。注意的是,当挖河士兵正好位于无通路地区时,如果你对其下达命令,他仍会消失!", + "English": "Fixes the bug where moat digging units would disappear while digging. Note that they can still disappear if you order them to move while standing on unwalkable terrain!", + "German": "Behebt das Verschwinden von Truppen, die mit dem Ausheben von Burggräben beschäftigt sind. Diese verschwinden allerdings weiterhin, falls diese neue Befehle bekommen und zeitgleich auf unbegehbarem Terrain stehen.", + "Hungarian": "Kijavítja azt a hibát, amikor árokásás közben véletlenszerűen eltűnik az árkot ásó egység. Megjegyzés: Az egység még mindig eltűnhet, ha árokásás közben elküldöd máshova és éppen egy nem járható helyen van!", + "Polish": "Naprawia błąd, który powodował losowe znikanie jednostek kopiących fosę. Uwaga: jednostki mogą dalej znikać, jeśli każesz im przemieścić się w momencie, gdy stoją w miejscu, z którego nie da się normalnie ruszyć!", + "Russian": "Исправлена ошибка, при которой копатели рва исчезали случайно во время раскопок. Обратите внимание, что они все равно могут исчезнуть, если вы прикажете им двигаться во время раскопок, и они случайно встанут на непешеходную плитку!" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -274,14 +512,28 @@ { "modType": "AILords", "modIdentifier": "ai_housing", - "modDescription": {}, + "modDescription": { + "Chinese": "AI建造民房更加智能", + "English": "Let the AI build houses smarter", + "German": "Intelligenteres Errichten und Abreißen von Häusern", + "Hungarian": "Házak okosabb építése", + "Polish": "Mądrzejsze budowanie domów przez boty", + "Russian": "Настройка решения AI о строительстве и удалении домов" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "build_housing", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "你可以设定AI的民房数量的浮动值,AI建造民房时,会额外建造该数值的民房,这样直到下次人口不足之前,AI都不需要建造民房;同样的,当AI工作人口减少时,AI也会最多保留该数值的超出工作人口部分的民房。这使得AI无需频繁的拆建民房,浪费木材资源,尤其是人口频繁波动时。", + "English": "Difference between current and maximum population, above which the AI stops building houses. This is 0 in vanilla. This also disables deleting of houses for the AI.", + "German": "Die Differenz aus aktueller und maximal möglicher Bevölkerung, ab der KIs keine Häuser mehr bauen. In Vanilla ist diese 0. Zudem deaktiviert diese Option das Abreißen von Häusern für KIs.", + "Hungarian": "A jelenlegi és a maximális népességszám közötti különbség, amely felett az MI nem épít több házat. Az eredeti játékban ez a szám 0. Ha ez a beállítás be van jelölve, akkor az MI nem rombolja le a házakat.", + "Polish": "Różnica między obecną a maksymalną populacją, po której bot przestaje stawiać domy. W oryginale jest to 0. Ta opcja wyłącza również usuwanie domów przez bota.", + "Russian": "Количество дополнительного доступного жилья до того, как AI прекратит строительство домов" + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -295,7 +547,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "campfire_housing", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "此处设置AI篝火处的空闲农民数量,当空闲农民数量多于此数值时,AI会停止建造民房。这个功能同时会禁止AI拆除民房。", + "English": "Number of idle peasants at the campfire before the AI stops building houses. This also disables deleting of houses for the AI.", + "German": "Wenn mehr als diese Anzahl an freien Bauern am Lagerfeuer sitzen, baut die KI keine Häuser mehr. Zudem deaktiviert diese Option das Abreißen von Häusern für KIs.", + "Hungarian": "Parasztok száma a tábortűznél, mielőtt az MI nem épít több házat. Ha ez a beállítás be van jelölve, akkor az MI nem rombolja le a házakat.", + "Polish": "Ilość wolnych chłopów przy ognisku, zanim bot przestanie stawiać domy. Ta opcja wyłącza również usuwanie domów przez bota.", + "Russian": "Количество крестьян у костра перед тем, как AI остановит строительство домов." + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -309,7 +568,22 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "delete_housing", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "禁止AI拆除民房", + "English": "Disable the AI's ability to delete houses.", + "German": "Kein Abreißen von Häusern der KIs", + "Hungarian": "Az MI ne rombolja le a házakat.", + "Polish": "Wyłącz usuwanie domów.", + "Russian": "Отключает способность AI удалять дома." + }, + "detailedDescription": { + "Chinese": "打开这个功能,AI将不会拆除民房。", + "English": "When this option is selected the AI will never delete houses.", + "German": "Mit dieser Option reißen KIs keine Häuser mehr ab.", + "Hungarian": "Ha ez a beállítás be van jelölve, akkor az MI soha nem rombolja le a házakat.", + "Polish": "Kiedy ta opcja jest zaznaczona, boty nie będą usuwać domów.", + "Russian": "Когда эта опция выбрана, AI никогда не будет удалять дома" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -318,14 +592,28 @@ { "modType": "AILords", "modIdentifier": "ai_recruitstate_initialtimer", - "modDescription": {}, + "modDescription": { + "Chinese": "AI在初期阶段只招募防御士兵", + "English": "Set AIs initial time until they recruit by the AIC parameters", + "German": "Setzt den Zeitpunkt, ab dem KIs anhand der AIC rekrutieren", + "Hungarian": "Az MI a megadott ideig az AIC paraméterek alapján toborozzon", + "Polish": "Ustaw botom czas do rekrutacji jednostek zgodnie z parametrami AIC", + "Russian": "Настройка первоначального времени вербовки AI в защиту" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], - "identifier": "ai_recruitstate_initialtimer", + "identifier": "ai_recruitstate_initialtimervalue", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "AI在游戏开始起的以下时间内只会招募防御士兵,除非防御士兵数量已达上限。", + "English": "Set this value to number of months for which the AI will exclusively recruit defence troops, unless it has already filled up its defence total", + "German": "Anzahl an Monaten, ab der die KI anhand der in der AIC festgelegten Rekrutierungswahrscheinlichkeiten rekrutiert. Bis dahin rekrutiert sie ausschließlich Defensivtruppen bis diese vollständig sind und daraufhin Angriffstruppen.", + "Hungarian": "Az értéknek add meg azon hónapok számát, amikor az MI az AIC fájlban megadott toborzási sebeséggel toboroz kizárólag védekező egységeket, ha már teljesen megerősítette a védelmét, akkor támadó egységeket fog toborozni", + "Polish": "Można tu ustawić liczbę miesięcy, do której boty będą rekrutować wyłącznie jednostki do obrony, chyba że wypełnili już limit żołnierzy na zamku", + "Russian": "Установите это значение на количество месяцев, в течение которых AI будет вербовать исключительно войска обороны, если только он уже не заполнил всю оборону." + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -340,14 +628,28 @@ { "modType": "AILords", "modIdentifier": "ai_attacklimit", - "modDescription": {}, + "modDescription": { + "Chinese": "调整ai的进攻部队数量限制", + "English": "Increase of the attacking troops limit of the AIs", + "German": "Erhöhung des Angriffstruppenlimits der KIs", + "Hungarian": "Megnövelt támadó egység limit az MI Lordoknak", + "Polish": "Zwiększenie limitu ataku przeciwników komputerowych", + "Russian": "Увеличение предела атакующих войск AI" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_attacklimit", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "ai的进攻部队的数量会随时间而增加,额外增加的部队数量上限在原版是200。你可以在此处修改这个值。", + "English": "The number of additional units which are added after the first attack is limited to 200 in Vanilla. Here you can change this limit.", + "German": "In Vanilla is das Limit der zusätzlichen Truppen, die nach dem ersten Angriff dazukommen auf 200 begrenzt. Hier kann diese Grenze verändert werden.", + "Hungarian": "Az eredeti játékban a további egységek limitje, akik az első támadás után csatlakoznak 200-ra van korlátozva. Itt tudod megváltoztatni ezt a korlátozást.", + "Polish": "Liczba dodatkowych jednostek dodawanych po pierwszym ataku jest ograniczona do 200 w oryginalnej grze. Tutaj możesz zmienić ten limit.", + "Russian": "Количество дополнительных единиц, которые добавляются после первой атаки в Ваниле - до 200. Здесь вы можете изменить этот предел." + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -362,14 +664,28 @@ { "modType": "AILords", "modIdentifier": "ai_attackwave", - "modDescription": {}, + "modDescription": { + "Chinese": "提升ai的进攻", + "English": "Improve attack waves", + "German": "Angriffswellen verbessern", + "Hungarian": "Támadási hullámok feljavítása", + "Polish": "Popraw fale ataków", + "Russian": "Улучшение волны атаки" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_attackwave", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "在原版中,ai在进攻时,只会派出能够得着城墙的数量的士兵,比如说一圈城堡有50格城墙,那么只有50个人可以在不重叠的情况下砍城墙,此时哪怕有100名士兵集结在敌人城堡附近,也只会派出50人前去攻击城堡,打开此选项后将可以避免此现象。并且,打开此选项后,ai的士兵将会主动攻击城堡建筑和经济建筑。此外,ai将会派出更多的士兵去攻击敌人的领主。", + "English": "The AI in an attack in vanilla only sends as many troops at once as there are wall parts reachable. This causes units to drop in in small waves when the target castle has a lot of buildings directly at its walls.This option makes units also attack civil and fortification buildings, as well as wall parts which are already being attacked by one unit. Moreover,the AI sends more troops to the enemy lord as soon as it detects a breach.", + "German": "In Vanilla schickt die KI bei einem Angriff immer nur so viele Einheiten auf einmal los wie Mauernstücke erreichbar sind. Bei Burgen die mit Gebäuden umbaut sind greifen die Einheiten dadurch nur tröpfchenweise an.Durch die Aktivierung dieser Option greifen Einheiten auch Gebäude und Befestigungsanlagen an, sowie Mauerstücke die bereits von einem Angreifer besetzt sind. Außerdem schickt die KI jetzt auch mehr Truppen auf den gegnerischen Bergfried, sobald sie eine Bresche erkennt.", + "Hungarian": "Az eredeti játékban az MI mindig csak annyi egységet küld el egyszerre amennyi elérhető várfal van. Azok a várak amik épületekkel vannak körülépítve, azokat az egységek csak elvétve támadják meg. Ezzel a beállítással az egységek az épületeket és az ostromsátrakat is megtámadják illetve azt a várfalat is amit már egy másik támadó egység rombol. Továbbá az MI mostantól több egységet küld az ellenséges vártoronyra, amint észrevesz egy oda vezető utat.", + "Polish": "W oryginalnej grze sztuczna inteligencja wysyła tylko tyle żołnierzy za jednym razem, ile jest wolnych kawałków murów. Powoduje to, że jednostki poruszają się w małych grupach, gdy atakowany zamek ma wiele budynków bezpośrednio przy murach.Ta opcja sprawia, że żołnierze atakują również budynki cywilne i fortyfikacyjne, a także te części murów, które są już atakowane przez inną jednostkę. DodatkowoSI wysyła więcej jednostek do wrogiego lorda, gdy przełamie mury.", + "Russian": "AI в атаке в ванили посылает сразу столько же войск, как и тогда когда стены целые. Это заставляет единицы умирать в маленьких волнахкогда у целевого замка много зданий прямо у его стен. Этот вариант позволяет подразделениям атаковать гражданские и фортификационные здания, а такжестены которые уже атакованы одной единицей. Более того AI посылает больше войск к вражескому лорду, как только обнаруживает что стена разрушена." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -378,17 +694,69 @@ { "modType": "AILords", "modIdentifier": "ai_attacktarget", - "modDescription": {}, + "modDescription": { + "Chinese": "设置ai的目标敌人", + "English": "Set AI attack target", + "German": "AI-Angriffsziel einstellen", + "Hungarian": "MI támadási-célpont beállítása", + "Polish": "Ustaw cel ataku graczy komputerowych", + "Russian": "Установить цель атаки AI" + }, + "detailedDescription": { + "Chinese": "该选项可以给所有ai设置相同的目标选择。", + "English": "With this setting, all AI lords will chose their next attack target in the same way. This prevents troops switching targets during a castle assault as well as sending them past other enemies' castles to gather.", + "German": "Mit dieser Einstellung suchen sich die KI-Lords alle auf die selbe Weise,das Ziel für ihren nächsten Angriff. Dies verhindert, dass die Truppen mittem im laufenden Angriff umschwenken oder an Gegnerburgen vorbeigeschickt werden zum Sammeln.", + "Hungarian": "Ezzel a beállítással az MI Lordok a saját módjukon keresik meg a célpontot a következő támadásukhoz. Ez megakadályozza azt, hogy az egységek támadás közben célpontot változtassanak vagy az MI ne a másik ellenséges várhoz küldje gyülekezni a seregét.", + "Polish": "Dzięki tej opcji gracze komputerowi będą zawsze wybierać ten sam cel ataku. Dzięki temu oddziały nie rozchodzą się podczas oblężenia zamku, ani nie giną z powodu przechodzenia obok zamku wroga, którego nie atakują w danej chwili.", + "Russian": "С этим параметром все лорды AI выберут свою следующую цель атаки. Это предотвращает переключение войск во время штурма замка, а также отправку их мимо замков других врагов." + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], - "identifier": "ai_attackwave", + "identifier": "ai_attacktarget", "defaultValue": "false", "description": {}, "selectionType": "radio", "selectionParameters": { - "options": [ "ai_attacktarget_nearest", "ai_attacktarget_richest", "ai_attacktarget_weakest" ] + "options": [ + { + "type": "string", + "value": "ai_attacktarget_nearest", + "description": { + "Chinese": "最近的敌人", + "English": "Nearest enemy", + "German": "Nahegelegenster Gegner", + "Hungarian": "A legközelebbi ellenség", + "Polish": "Najbliższy przeciwnik", + "Russian": "Ближайший враг" + } + }, + { + "type": "string", + "value": "ai_attacktarget_richest", + "description": { + "Chinese": "最富有的敌人", + "English": "Richest Enemy", + "German": "Reichster Gegner", + "Hungarian": "A leggazdagabb ellenség", + "Polish": "Najbogatszy przeciwnik", + "Russian": "Богатый враг" + } + }, + { + "type": "string", + "value": "ai_attacktarget_weakest", + "description": { + "Chinese": "最弱的敌人", + "English": "Weakest Enemy", + "German": "Schwächster Gegner", + "Hungarian": "A leggyengébb ellenség", + "Polish": "Najsłabszy przeciwnik", + "Russian": "Слабый враг" + } + } + ] } } ] @@ -396,14 +764,28 @@ { "modType": "AILords", "modIdentifier": "ai_nosleep", - "modDescription": {}, + "modDescription": { + "Chinese": "资源不足时ai不再休眠建筑", + "English": "Disable sleeping mode for lack of resources", + "German": "Schlafenlegen bei Rohstoffmangel deaktivieren", + "Hungarian": "Ha nincs elég erőforrás, szünetel a munka deaktiválása", + "Polish": "Wyłącz usypianie budynków z powodu braku zasobów", + "Russian": "Отключить спящий режим из-за нехватки ресурсов" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_nosleep", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "ai通常会将正在生产中的建筑休眠,因为有部分建筑缺乏原料,哪怕原料正在运回的路上,打开此选项可以防止ai将建筑休眠。", + "English": "The AI usually puts its processing buildings to sleep, as soon as the needed resource is missing. This is done without the regard for losing products which are just on the way f.e. to the weapon chamber.This feature can be completely disabled here.", + "German": "Normalerweise legt die KI ihre Verarbeitungsgebäude schlafen, sobald der nötige Rohstoff nicht mehr im Lager vorhanden ist. Dabei wird keine Rücksicht genommen ob Produkte verloren gehen die z.B. gerade zur Waffenkammer gebracht werden. Diese Funktion kann hier komplett deaktiviert werden.", + "Hungarian": "Általában az MI szünetelteti a munkát az ipari épületeinél, ha a szükséges erőforrás már nem áll rendelkezésére a raktárban. Eközben a termék kárba veszik amit pl. éppen a fegyverraktárba visznek. Ezt a funkciót itt teljesen ki lehet kapcsolni.", + "Polish": "Sztuczna inteligencja zwykle usypia budynki produkcyjne, gdy tylko brakuje wymaganego zasobu. Odbywa się to bez względu na to, czy straci produkty, które są już w drodze, np. do zbrojowni.Tę funkcję można tutaj całkowicie wyłączyć.", + "Russian": "AI обычно ставит свои обрабатывающие здания в сон поскольку необходимый ресурс отсутствует.Это делается без учета потери продуктов, и оружия которые находятся на пути в Оружейную.Эта функция может быть полностью отключена здесь." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -412,14 +794,36 @@ { "modType": "AILords", "modIdentifier": "ai_demolish", - "modDescription": {}, + "modDescription": { + "Chinese": "停用ai拆毁以下类型建筑来获取资金", + "English": "Deactivate demolishing for money of the AI lords", + "German": "Einreißen für Geld der KI-Lords deaktivieren", + "Hungarian": "Az MI Lord lerombol mindent hogy pénzhez jusson deaktiválása", + "Polish": "Dezaktywuj burzenie budynków dla pieniędzy przez przeciwników komputerowych", + "Russian": "Деактивировать снос за деньги AI Лордов" + }, + "detailedDescription": { + "Chinese": "如果ai感受到了压力,他会通过拆毁城堡建筑或者经济建筑的方式来快速获取资金这在有时是没有必要的,你可以在此处取消这个行为。.", + "English": "If the AI feels pressured, it likes to demolishes its economy or fortification buildings to get quick money for troops. This feature sometimes seems to be triggered without any visible reason and thus can be disabled here.", + "German": "Wenn die KI sich bedrängt fühlt und schnell an Geld für Truppen kommen will, reißt sie gerne mal ihre komplette Wirtschaft oder Befestigungsanlagen ein. Manchmal wird dieses Feature aber auch völlig ohne scheinbaren Grund ausgelöst und kann darum hier ausgestellt werden.", + "Hungarian": "Ha az MI Lord sarokba szorítva érzi magát és gyorsan pénzt akar szerezni az egységekhez, előszeretettel rombolja le a teljes iparát vagy várépületeit. Néha ez az esemény láthatólag minden indok nélkül megtörténik és emiatt itt ki tudod kapcsolni.", + "Polish": "Jeśli przeciwnik komputerowy czuje presję, lubi burzyć gospodarkę lub budynki fortyfikacyjne, aby uzyskać pieniądze w celu rekrutacji żołnierzy. Ta funkcja czasami wydaje się być uruchamiana bez widocznego powodu i dlatego można to tutaj wyłączyć.", + "Russian": "Если AI чуствует прессинг, он начинает разрушать свою экономику или фортификационные здания, чтобы получить быстрые деньги для сбора войск." + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_demolish_walls", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "城堡建筑", + "English": "fortification buildings", + "German": "Befestigungsanlagen", + "Hungarian": "Várépületek", + "Polish": "fortyfikacje obronne", + "Russian": "фортификационные сооружения" + }, "selectionType": "checkbox", "selectionParameters": {} }, @@ -427,7 +831,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_demolish_trapped", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "城堡与外界隔绝", + "English": "If enclosed", + "German": "Falls eingeschlossen", + "Hungarian": "Ha bezárva", + "Polish": "Jeśli siedziba jest otoczona", + "Russian": "Если приложено" + }, "selectionType": "checkbox", "selectionParameters": {} }, @@ -435,7 +846,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_demolish_eco", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "经济建筑", + "English": "econonmy buildings", + "German": "Wirtschaftsgebäude", + "Hungarian": "Ipari épületek", + "Polish": "budynki ekonomiczne", + "Russian": "экономические сооружения" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -444,14 +862,28 @@ { "modType": "AILords", "modIdentifier": "ai_addattack", - "modDescription": {}, + "modDescription": { + "Chinese": "调整ai每波进攻额外增加的兵力", + "English": "Increase of the rate of additional attack troops", + "German": "Erhöhung der Rate von zusätzlichen Angriffstruppen", + "Hungarian": "Megnövelt további támadó egységek mértéke", + "Polish": "Zwiększenie liczby dodatkowych jednostek w kolejnych atakach SI", + "Russian": "Увеличение скорости дополнительных атакующих войск" + }, "modSelectionRule": "1|2", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_addattack", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "在原版,ai每波进攻都会额外增加5的兵力,这个同时生效于所有ai的数值可以在此处改变。", + "English": "In Vanilla the attack troop number is increased after each attack by 5 units on average. This value is the same for all AI lords and can be changed here.", + "German": "In Vanilla wird nach jedem Angriff die Truppenzahl für den nächsten Angriff durchschnittlich um 5 Einheiten erhöht. Dieser Wert ist für alle KI-Lords gleich und kann hier geändert werden.", + "Hungarian": "Az eredeti játékban minden egyes támadás után az egységek száma a következő támadáskor átlagosan 5 egységgel lesz megnövelve. Ez az érték minden MI Lordnak ugyanannyi és itt tudod megváltoztatni.", + "Polish": "W oryginalnej grze liczba żołnierzy wzrasta po każdym ataku średnio o 5 jednostek. Ta wartość jest taka sama dla wszystkich przeciwników komputerowych i można ją zmienić tutaj.", + "Russian": "В Ваниле количество единиц атаки увеличивается на 5 единиц в среднем. Это значение для всех здесь." + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -465,7 +897,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_addattack_alt", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "或者,每波额外增加的兵力可以和ai初次进攻的兵力有关,对于不同ai来说,初次进攻兵力可以是不同的,因此这个选项可以使不同ai的进攻士兵增速不同。举例: 倍率 = 0.5苏丹从第一波开始的进攻士兵数量 = 10, 15, 20, 25, ...萨拉丁从第一波开始的进攻士兵数量 = 50, 75, 100, 125, ...", + "English": "Alternatively, the additional troop count can be made dependent on the troop count of the first attack. Since this value is different for each AI, the following attacks will also scale, instead of increasing by the same value for each AI lord.Example: Scale factor = 0.5Sultan's attack troops = 10, 15, 20, 25, ...Saladin's attack troops = 50, 75, 100, 125, ...", + "German": "Alternativ kann hier die hinzukommende Truppenanzahl von der Truppenstärke des ersten Angriffs abhängig gemacht werden. Da jede KI unterschiedliche Anzahlen für den Erstangriff hat, werden somit auch folgende Angriffe skalieren, anstatt für jede KI gleich anzusteigen.Beispiel: Skalierungsfaktor = 0,5Sultans Angriffszahlen = 10, 15, 20, 25, ...Saladins Angriffszahlen = 50, 75, 100, 125, ...", + "Hungarian": "Alternatív megoldásként, a további csatlakozó egységek számát az első támadás erősségétől függetlenné lehet tenni. De mivel minden MI Lord különböző számú egységet használ az első támadásnál, ezzel együtt a következő támadások is skálázódnak ahelyett, hogy minden MI Lordnak ugyanaz az értéke lenne.Például: Skálázási faktor = 0,5Szultán támadásainak száma = 10, 15, 20, 25, ...Szaladin támadásainak száma = 50, 75, 100, 125, ...", + "Polish": "Ewentualnie dodatkowa liczba żołnierzy może być uzależniona od liczby jednostek z pierwszego ataku. Ponieważ ta wartość jest inna dla każdego przeciwnika komputerowego, następne ataki będą zmieniać rozmiar zależnie od tej początkowej wartości.Przykład: współczynnik zmiany rozmiaru = 0,5Ataki wysyłane przez Sułtana = 10, 15, 20, 25, ...Ataki wysyłane przez Saladyna = 50, 75, 100, 125, ...", + "Russian": "В качестве альтернативы, дополнительное количество войск может быть выполнено в зависимости от число войск первой атаки. Поскольку это значение отличается для каждого AI следующие атаки будут масштабироваться, а не на одну и ту же величину для каждого лорда AI.Пример: Масштабный коэффициент = 0,5Войска Султана атакуют = 10, 15, 20, 25, ...Атакующие войска Саладина = 50, 75, 100, 125, ..." + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -480,14 +919,28 @@ { "modType": "AILords", "modIdentifier": "ai_recruitinterval", - "modDescription": {}, + "modDescription": { + "Chinese": "加快所有ai的训练士兵速度", + "English": "Increased recruitment speed", + "German": "Erhöhtes Rekrutierungstempo", + "Hungarian": "Megnövelt toborzási sebesség", + "Polish": "Zwiększona prędkość rekrutacji", + "Russian": "Увеличенная скорость набора рекрутов" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "ai_recruitinterval", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "将所有ai的训练时间间隔降低至最低(老鼠和狮心王的程度)", + "English": "Sets the recruitment interval of all AIs to the lowest value (Rat/Richard niveau)", + "German": "Setzt das Rekrutierungsintervall aller KIs auf den niedrigsten Wert. (Ratte/Richard-Niveau)", + "Hungarian": "Átállítja minden MI Lordnak a toborzási intervallumát a legkisebb értékre. (Patkány/Richárd szint)", + "Polish": "Ustawia odstęp między rekrutacją jednostek przez wszystkich przeciwników komputerowych na najniższą wartość (poziom Szczura/Ryszarda)", + "Russian": "Устанавливает интервал набора всех AI до самого низкого значения (Крыса/Ричард)" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -496,14 +949,28 @@ { "modType": "Units", "modIdentifier": "u_laddermen", - "modDescription": {}, + "modDescription": { + "Chinese": "增强云梯兵对于箭矢的抗性", + "English": "Increased armor of laddermen against ranged units", + "German": "Erhöhter Schutz für Leiterträger gegen Fernkämpfer", + "Hungarian": "Megnövelt védelem a létrás egységnek a távolsági egységek ellen", + "Polish": "Zwiększona obrona drabiniarzy przeciwko jednostkom strzelającym", + "Russian": "Увеличенная броня Крестьян с лесницами против дальних войск" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_laddermen", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "- 云梯兵在中5发箭后死亡改为中12发箭后死亡\r\n - 云梯兵在中2发弩箭后死亡改为中5发弩箭后死亡\r\n - 云梯兵价钱从4提升为20", + "English": "- Laddermen die after 12 arrow hits instead of 5\r\n - Laddermen die after 5 crossbow or slinger hits instead of 2\r\n - Laddermen cost 20 gold instead of 4", + "German": "- Leiterträger sterben erst nach 12 Pfeiltreffern statt 5\r\n - Leiterträger sterben erst nach 5 Armbrust- oder Schleudertreffern statt 2\r\n - Leiterträger kosten 20 Gold statt 4", + "Hungarian": "- A létrás egység 5 helyett 12 nyíl találat után hal meg\r\n - A létrás egység 2 helyett 5 számszeríj nyílvessző találat vagy parittyakő találat után hal meg\r\n - A létrás egység 4 helyett 20 aranyba kerül", + "Polish": "- Drabiniarz ginie po 12 strzałach z łuku zamiast po 5\r\n - Drabiniarz ginie po 5 trafieniach z kuszy lub procy zamiast 2\r\n - Drabiniarz kosztuje 20 złota zamiast 4", + "Russian": "- Крестияне с лестницами умирают после 12 стрел вместо 5\r\n  - Крестияне с лестницами умирают после 5 выстрелов арбалетов или пращников вместо 2\r\n  - Крестияне с лестницами стоят 20 золотых вместо 4" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -512,14 +979,28 @@ { "modType": "Units", "modIdentifier": "u_arabxbow", - "modDescription": {}, + "modDescription": { + "Chinese": "增强了阿拉伯剑士抵抗弩箭的能力", + "English": "Increased armor of Arabic Swordsmen against crossbows", + "German": "Erhöhter Schutz von Arab. Schwertkämpfer vor Armbrüsten", + "Hungarian": "Megnövelt védelem az arab szablyás egységnek a számszeríj nyílvessző ellen", + "Polish": "Zwiększona obrona arabskich zbrojnych przeciwko kusznikom", + "Russian": "Увеличенная броня арабского мечника против стрел арбалетчика" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_arabxbow", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "-阿拉伯剑士在中3发弩箭后死亡改为6发弩箭后死亡。", + "English": "- Arabic Swordsmen only die after 6 crossbow hits intead of 3", + "German": "- Arabische Schwertkämpfer sterben erst nach 6 Armbrusttreffern statt 3", + "Hungarian": "- Az arab szablyás 3 helyett 6 számszeríj nyílvessző találat után hal meg", + "Polish": "- Arabscy zbrojni umierają po 6 strzałach z kuszy zamiast 3", + "Russian": "- Арабские мечники умирают после 6 стрел из арбалета вместо 3" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -528,14 +1009,28 @@ { "modType": "Units", "modIdentifier": "u_arabwall", - "modDescription": {}, + "modDescription": { + "Chinese": "阿拉伯剑士破坏城墙速度加快", + "English": "Arabic Swordsmen destroy walls faster", + "German": "Arab. Schwertkämpfer reißen Mauern schneller ein", + "Hungarian": "Az arab szablyás gyorsabban rombolja le a várfalat", + "Polish": "Arabscy zbrojni szybciej niszczą mury", + "Russian": "Арабские мечники разрушают стены быстрее" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_arabwall", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "在原版,阿拉伯剑士破坏城墙的速度比其他任何单位都要更慢,打开这个选项后,破坏速度将会提升为原来的两倍,稍快于长矛手。", + "English": "In Vanilla, arabic swordsmen destroy walls slower than any other melee unit. With this option, the tear down speed against walls is about doubled for them, putting them slightly above Spearmen.", + "German": "In Vanilla reißen Arabische Schwertkämpfer Mauern am langsamsten ein unter den Nahkämpfern. Die Einreißgeschwindigkeit wird hiermit für sie ca. verdoppelt, sodass sie dabei knapp über Lanzenträgern sind.", + "Hungarian": "Az eredeti játékban az arab szablyás rombolja le a várfalat a leglassabban a közelharci egységek közül. A lerombolás sebessége ezentúl kb. megkétszereződik, így épphogy jobb lesz a lándzsás egységnél.", + "Polish": "W oryginalnej grze arabscy zbrojni niszczą mury najwolniej ze wszystkich jednostek walczących wręcz. Dzięki tej opcji prędkość niszczenia murów przez arabskich zbrojnych jest dwukrotnie większa, nieco powyżej prędkości włóczników.", + "Russian": "В Ваниле арабские мечники разрушают стены медленнее любого другого подразделения ближнего боя.С этой опцией скорость удара (анимации) против стен удваивается для них,поставив их немного выше копейщиков. (по скорости анимации атаки)" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -544,14 +1039,28 @@ { "modType": "Units", "modIdentifier": "u_spearmen", - "modDescription": {}, + "modDescription": { + "Chinese": "增强长矛手抵抗箭矢的能力", + "English": "Increased armor of spearmen against ranged units", + "German": "Erhöhter Schutz von Lanzenträger gegen Fernkämpfer", + "Hungarian": "Megnövelt védelem a lándzsás egységnek a távolsági egységek ellen", + "Polish": "Zwiększona obrona włóczników przeciwko jednostkom strzelającym", + "Russian": "Увеличенная броня копейщиков против урона дальних юнитов" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_spearmen", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "- 长矛手在中3发箭后死亡改为5发箭后死亡,\r\n - 长矛手承受1发弩箭后还可以刚好存活。", + "English": "- Spearmen only die after 5 arrow hits instead of 3\r\n - Spearmen barely survive one crossbow hit, instead of getting one-shot", + "German": "- Lanzenträger sterben erst nach 5 Pfeiltreffern statt 3\r\n - Lanzenträger überleben knapp einen Armbrusttreffer", + "Hungarian": "- A lándzsás egység 3 helyett 5 nyíl találat után hal meg\r\n - A lándzsás egység épphogy túlél egy számszeríj nyílvessző találatot", + "Polish": "- Włócznicy giną po 5 strzałach z łuku zamiast 3\r\n - Włócznicy ledwie przeżywają jeden strzał z kuszy, zamiast od razu ginąć", + "Russian": "- Копейщики умирают после 5 попаданий стрел из лука, вместо 3\r\n  - Копейщики едва выдерживали один выстрел из арбалета, вместо того чтобы умереть от одного выстрела" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -560,14 +1069,28 @@ { "modType": "Units", "modIdentifier": "o_restore_arabian_engineer_speech", - "modDescription": {}, + "modDescription": { + "Chinese": "工程师切换为阿拉伯语音", + "English": "Restore engineer arabian speech", + "German": "Baumeister arabischer Lords sprechen Arabisch", + "Hungarian": "Az arab mérnök arabul beszél", + "Polish": "Przywróć arabskie teksty inżynierów", + "Russian": "Восстановление арабской речи инженера" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_restore_arabian_engineer_speech", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "当玩家使用阿拉伯领主时,工程师的语音将会切换为阿拉伯语。", + "English": "Allows engineers to speak the originally recorded arabian voicelines when the player uses the Arabian lord.", + "German": "Falls der Spieler den arabischen Lord auswählt nutzen Baumeister nun ihre arabischen Sprachdateien.", + "Hungarian": "Ha a játékos az Arab Lord-ot választja, akkor a mérnök beszédekor az eredeti felvett arab hangfájlt használja.Nincs túl sok variáció ezekben a hangfájlokban, így egy idő után zavaró lehet.", + "Polish": "Ta opcja pozwala inżynierom na korzystanie z nagranych arabskich tekstów, gdy gracz gra jako arabski lord.Tekstów nie ma zbyt wielu, więc mogą być irytujące po dłuższej chwili.", + "Russian": "Позволяет инженерам говорить на изначально записанных арабских голосовых дорожках, когда игрок использует арабского лорда.Голосовые линии не сильно отличаются друг от друга, так что через некоторое время они могут стать раздражающими." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -576,14 +1099,28 @@ { "modType": "Units", "modIdentifier": "u_spearmen_run", - "modDescription": {}, + "modDescription": { + "Chinese": "矛兵默认为奔跑状态而不是步行", + "English": "Spearmen run by default instead of walking", + "German": "Speerträger rennen standardmäßig", + "Hungarian": "A lándzsás egység sétálás helyett alapból fut", + "Polish": "Biegający włócznicy", + "Russian": "Копейщики бегут по умолчанию вместо того, чтобы ходить пешком." + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "u_spearmen_run", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "矛兵在默认状态下将使用奔跑作为移动方式,而不是步行。", + "English": "Makes spearmen run by default like slaves and macemen.", + "German": "Speerträger rennen standardmäßig so schnell wie Sklaven und Streitkolbenkämpfer.", + "Hungarian": "A lándzsás egység lassú sétálás helyett alapból futni fog. A lándzsás olyan gyorsan fut, mint egy rabszolga vagy buzogányos.", + "Polish": "Włócznicy będą cały czas biegać.", + "Russian": "Вместо медленной ходьбы копейщики бегут медленно." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -592,14 +1129,28 @@ { "modType": "Other", "modIdentifier": "o_firecooldown", - "modDescription": {}, + "modDescription": { + "Chinese": "调整刚灭火建筑的免疫火灾时间", + "English": "Extend fireproof duration of extinguished buildings", + "German": "Feuerfeste Zeit gelöschter Gebäude verlängern", + "Hungarian": "Eloltott épületek tűzálló időtartamának megnövelése", + "Polish": "Wydłuż czas, po którym budynek może ponownie się zapalić", + "Russian": "Увеличить пожаробезопасную продолжительность потушенных зданий" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_firecooldown", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "着火的建筑在火被扑灭后,会有一段免疫着火的时间,此处可修改时间长短。", + "English": "The duration in which extinguished buildings cannot catch fire again can be extended here.", + "German": "Der Zeitraum in dem gelöschte Häuser nicht wieder brennen können kann hier verlängert werden.", + "Hungarian": "Itt meghosszabbítható az az időtartam, amely alatt az eloltott épületek nem tudnak újra kigyulladni.", + "Polish": "Można tutaj wydłużyć czas, po którym budynek może ponownie się zapalić po ugaszeniu.", + "Russian": "Здесь можно продлить срок, в течение которого потухшие здания больше не смогут загореться." + }, "selectionType": "slider", "selectionParameters": { "minimum": 0, @@ -614,14 +1165,28 @@ { "modType": "Other", "modIdentifier": "o_xtreme", - "modDescription": {}, + "modDescription": { + "Chinese": "移除增强版的技能条", + "English": "Remove the magic bar in Extreme", + "German": "Magie-Leiste in Extreme entfernen.", + "Hungarian": "Varázserő-sáv eltávolítása az Extreme kiegészítőből.", + "Polish": "Usuń pasek mocy w wersji Extreme", + "Russian": "Убраны значки магии в Stronghold Crusader Extreme" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_xtreme", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "移除要塞十字军东征增强版中的技能条。", + "English": "Removes the magic bar in Crusader Extreme.", + "German": "Entfernt die Magie-Leiste in Crusader Extreme.", + "Hungarian": "Eltávolítja a Varázserő-sávot a Crusader Extreme kiegészítőben.", + "Polish": "Usuwa pasek umiejętności w Twierdzy Krzyżowiec Extreme.", + "Russian": "Убирает значки магии в Stronghold Crusader Extreme." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -630,7 +1195,14 @@ { "modType": "Other", "modIdentifier": "o_playercolor", - "modDescription": {}, + "modDescription": { + "Chinese": "改变玩家1号的颜色", + "English": "Change the color of player 1", + "German": "Farbe von Spieler 1 wechseln", + "Hungarian": "Játékos 1 színcsere", + "Polish": "Zmiana koloru pierwszego gracza", + "Russian": "Изменить цвет Игрока 1" + }, "modSelectionRule": "*", "changes": [ { @@ -640,7 +1212,40 @@ "description": {}, "selectionType": "radio", "selectionParameters": { - "options": [ "red", "blue", "yellow", "orange", "green", "cyan", "black", "purple" ] + "options": [ + { + "type": "color", + "value": "red" + }, + { + "type": "color", + "value": "blue" + }, + { + "type": "color", + "value": "yellow" + }, + { + "type": "color", + "value": "orange" + }, + { + "type": "color", + "value": "green" + }, + { + "type": "color", + "value": "cyan" + }, + { + "type": "color", + "value": "black" + }, + { + "type": "color", + "value": "purple" + } + ] } } ] @@ -648,14 +1253,28 @@ { "modType": "Other", "modIdentifier": "o_keys", - "modDescription": {}, + "modDescription": { + "Chinese": "WASD键移动以及Ctrl+S/L键保存读取", + "English": "WASD-Keys and quicksaves", + "German": "WASD-Tasten und Quicksaves", + "Hungarian": "WASD billentyűk és gyorsmentés", + "Polish": "Klawisze WASD i szybki zapis", + "Russian": "WASD-Кнопки и быстрые сохранения" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_keys", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "打开此选项后,可以使用WASD键移动屏幕,以及Ctrl+S键打开保存界面,Ctrl+L键打开读取界面。", + "English": "The WASD-keys can be used to move around with this setting as well as CTRL-S and CTRL-L to quicksave and load respectively.", + "German": "Mit dieser Einstellung werden die WASD-Tasten für die Kamera aktiviert.Außerdem kann mit STRG-S und STRG-L ein Quicksave erstellt und geladen werden.", + "Hungarian": "Ezzel a beállítással aktiválva lesznek a WASD billentyűk a kamerához.Ezenkívül a CTRL-S és a CTRL-L billentyűkkel lehet gyorsmentést létrehozni és betölteni.", + "Polish": "Klawisze WASD mogą być używane do poruszania kamerą. Dodatkowo kombinacja klawiszy CTRL-S i CTRL-L służy do szybkiego zapisania i wczytania gry.", + "Russian": "Клавиши WASD можно использовать для перемещения с этой настройкой, а также CTRL-S и CTRL-L для быстрого сохранения и загрузки соответственно." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -664,14 +1283,28 @@ { "modType": "Other", "modIdentifier": "o_override_identity_menu", - "modDescription": {}, + "modDescription": { + "Chinese": "在设置菜单里添加一些新的选择", + "English": "Override the Set-up Identity menu adding new features", + "German": "Fügt neue Optionen zum Menüpunkt 'Identität zulegen' hinzu", + "Hungarian": "Új beállítások hozzáadása a 'Játékos szerkesztése' menühöz", + "Polish": "Dodaje nowe funkcje do opcji ustawień tożsamości", + "Russian": "Переопределить меню Set-up Identity, добавляя новые функции." + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_override_identity_menu", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "增加了玩家初始兵种的选择的功能,只在普通模式下生效。", + "English": "Adds Ranged and Melee unit selection to Set-up Identity menu. ONLY FOR NORMAL GAME MODE!", + "German": "Im Menüpunkt 'Identität zulegen' kann man nun die Starteinheiten für 'Normales Spiel' ändern", + "Hungarian": "Távolsági és közelharci egységek kiválasztási lehetőségét adja hozzá a 'Játékos szerkesztése' menüponthoz. CSAK NORMÁL JÁTÉK MÓDHOZ!", + "Polish": "Dodaje jednostki do własnego ustawienia w opcji dostosowania tożsamości. TYLKO W NORMALNYM TRYBIE GRY!", + "Russian": "Добавляет выбор юнитов дальнего и ближнего боя в меню Set-up Identity. ТОЛЬКО ДЛЯ ОБЫЧНОГО ИГРОВОГО РЕЖИМА!" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -680,14 +1313,28 @@ { "modType": "Other", "modIdentifier": "o_healer", - "modDescription": {}, + "modDescription": { + "Chinese": "医生会治愈伤员", + "English": "Healer heals casualties", + "German": "Heiler verarztet Verwundete", + "Hungarian": "A gyógyító ellátja a sérülteket", + "Polish": "Zielarz leczy rannych", + "Russian": "Целитель лечит раненых солдат" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_healer", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "药房的医生现在会积极寻找兵治疗受伤的士兵,平民或者动物。 优先治疗最近的目标。每次治疗动画中,可恢复长矛兵血量的1/3。 游览&花园和治疗瘟疫的功能依旧存在! 只有游览城堡的行为会被跳过,直到该地区不再有受伤的目标.", + "English": "The healer of the apothecary building now actively seeks out injured soldiers, civilists and animals to heal them. The nearest targets are treated first. With each healing animation ca. 1/3 of a spearman's health is recovered. The strolling through gardens and investigation of plague clouds is not replaced! Only the strolling through the castle is skipped until no more wounded targets are in the area.", + "German": "Der Heiler des Apothekengebäudes sucht nun verletzte Soldaten, Zivilisten und Tiere auf und heilt diese. Nahe Ziele werden dabei bevorzugt. Mit jeder Heilungs-Animation wird ca. 1/3 des Lebens eines Lanzenträgers geheilt. Das Schlendern durch die Gärten und Aufsuchen von Pestwolken wird dadurch nicht ersetzt! Nur das Schlendern durch die Burg wird ausgelassen, bis keine Verwundeten mehr in Reichweite sind.", + "Hungarian": "A gyógyszertár gyógyítója mostantól megkeresi a sérült harcosokat, civileket, állatokat és meggyógyítja őket. A hozzá legközelebb lévő célpontokat gyógyítja először. Minden gyógyító animációval kb. egy lándzsás 1/3 életerejét állítja helyre. A kertekben való mászkálás és a pestisfelhő felkeresése ez által nem lesz lecserélve! Csak a várban való mászkálása lesz kihagyva, ha van sebesült a hatótávolságán belül.", + "Polish": "Zielarz będzie teraz szukał rannych żołnierzy, zwierzęta i mieszkańców, aby ich uleczyć. Zielarz zaczyna leczyć od najbliższego celu. Każda animacja leczenia leczy 1/3 życia włócznika. Chodzenie po ogrodach i pozbywanie się zarazy nie zostało zastąpione! Zielarz pomija jedynie chodzenie po zamku, dopóki nie wyleczy wszystkich rannych.", + "Russian": "Целитель здания аптеки теперь активно ищет раненых солдат,жителей и жывотных чтобы исцелить их. Ближайшие цели он лечит первыми.Проигрывается анимация ,и он исцеляет за 1/3 секунды здоровье копейщика. Когда Целитель прогуливается он может разсеять облако чумы которое он заметит.Он будет лечить в одной области замка всех пока не вылечет до конца, а только потом он перейдет к другому участку замка.Также он не начнет разсеивать облака чумы пока он не сходит в сады." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -696,14 +1343,28 @@ { "modType": "Other", "modIdentifier": "o_freetrader", - "modDescription": {}, + "modDescription": { + "Chinese": "免费市场", + "English": "Free trader post", + "German": "Kostenloser Marktplatz", + "Hungarian": "Ingyen piac", + "Polish": "Darmowe targowisko", + "Russian": "Бесплатный рынок" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_freetrader", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "有时ai的市场被拆除且没有木头时,ai将会彻底瘫痪。使市场免费可以避免此问题。", + "English": "Since the AI sometimes plays itself, when they're out of wood and their trader post is destroyed. With this setting, the trader post will become free of cost to prevent this.", + "German": "Da die KI sich manchmal selbst Schachmatt setzt, wenn sie kein Holz hat und der Marktplatz zerstört wurde, kann hier der Bau des Marktplatzes kostenlos gemacht werden.", + "Hungarian": "Mivel néha az MI magának add sakk-mattot, ha nincs elég fája és a piacát lerombolták. Itt tudod beállítani hogy a piac építése ingyenes legyen.", + "Polish": "Czasami sztuczna inteligencja może nic nie robić, gdy nie ma drewna, a targowisko zostało zniszczone. Aby temu zapobiec, można włączyć tę opcję, dzięki czemu targowisko będzie darmowe.", + "Russian": "Поскольку АI иногда играет сам, когда он находится далеко от леса и его рынок уничтожен. С этим параметром рынок станет бесплатным, чтобы предотвратить это." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -712,14 +1373,28 @@ { "modType": "Other", "modIdentifier": "o_engineertent", - "modDescription": {}, + "modDescription": { + "Chinese": "无需重复选择工程师帐篷类型", + "English": "No siege tent deselection", + "German": "Belagerungsgeräte nicht automatisch abwählen", + "Hungarian": "Ostromgépek kijelölve maradnak", + "Polish": "Brak anulowania wybranego namiotu oblężniczego", + "Russian": "Нету выбора осадной палатки" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_engineertent", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "打开这个选择之后,选择一次工程师帐篷类型后即可一直放置该类型的工程师帐篷,而不需要每次都再选择一次。", + "English": "With this setting, the game will not deselect your chosen siege equipment after placing one tent anymore. This way you can create several tents after another without having to reselect the same siege equipment every time.", + "German": "Mit dieser Einstellung wird das zuletzt zum Bau ausgewählte Belagerungsgerät bei Baumeistern nicht abgewählt, sodass man mehrere Zelte nacheinander bauen kann, ohne jedes mal neu wählen zu müssen.", + "Hungarian": "Ezzel a beállítással az utoljára építésre kiválasztott ostromgép marad kijelölve ha több mérnököt kiválasztottál, így több ostromsátrat is lehet egymás után építeni.", + "Polish": "Przy tym ustawieniu gra nie odznacza wybranej machiny oblężniczej po umieszczeniu już jednego namiotu. W ten sposób możesz stworzyć kilka namiotów bez konieczności ponownego wybierania tego samego sprzętu oblężniczego za każdym razem.", + "Russian": "С помощью этой настройки игра не отменяет выбранное вами осадное оборудование после размещения больше одной палаткиТаким образом вы можете создать несколько палаток одну за другим,без необходимости повторного выбора одного и того же осадного оборудования." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -728,14 +1403,28 @@ { "modType": "Other", "modIdentifier": "o_moatvisibility", - "modDescription": {}, + "modDescription": { + "Chinese": "一直显示规划中的护城河", + "English": "Always show planned moat", + "German": "Geplanten Burggraben immer zeigen", + "Hungarian": "Mindig mutassa a tervezett várárkot", + "Polish": "Zawsze pokazuj zaplanowaną fosę", + "Russian": "Всегда показывать планированый ров" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_moatvisibility", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "你将可以一直看到规划中的护城河,而不需要点选单位。", + "English": "Your own placed but not digged out moat will always be shown with this setting, even if you deselect the moat placing.", + "German": "Mit dieser Einstellung wird der gesetzte, aber noch nicht ausgehobene Burggraben immer angezeigt, auch wenn man die Burggrabenplatzierung abwählt.", + "Hungarian": "Ezzel a beállítással a lehelyezett, de a még nem felásott várárok mindig látható, még akkor is ha nincs kiválasztva a várárokásás.", + "Polish": "Zaplanowana, ale jeszcze nie wykopana fosa będzie zawsze pokazywana z tym ustawieniem, nawet jeśli odznaczysz opcję rozmieszczania fosy.", + "Russian": "Ваш собственный,но не выкопанный ров всегда будет показан с этой опцией, даже если вы отмените выбор размещения рва." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -744,14 +1433,28 @@ { "modType": "Other", "modIdentifier": "o_gamespeed", - "modDescription": {}, + "modDescription": { + "Chinese": "拓宽游戏速度限制", + "English": "Extended game speed limits", + "German": "Erweiterte Spielgeschwindigkeitsgrenzen", + "Hungarian": "Bővített játéksebesség limit", + "Polish": "Jeszcze większa prędkość gry", + "Russian": "Расширенные ограничения скорости игры" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_gamespeed", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "游戏速度的限制更改为如下所示:\r\n - 在10到90之间以5为间隔\r\n - 在90到200之间以10为间隔\r\n - 在200到1000之间以100为间隔\r\n新的游戏速度范围仅可通过键盘上的+ -号来改变,菜单中的游戏速度\r\n调整不到新的范围。", + "English": "The game speed can now be changed as follows:\r\n - From 10 to 90 in intervals of 5\r\n - From 90 to 200 in intervals of 10\r\n - From 200 to 1000 in intervals of 100\r\nThe new values are only available ingame via the +- keys, the slider in the \r\ngame menu remains unchanged.", + "German": "Die Spielgeschwindigkeit kann nun wie folgt geändert werden:\r\n - Von 10 bis 90 in 5er Schritten\r\n - Von 90 bis 200 in 10er Schritten\r\n - Von 200 bis 1000 in 100er Schritten\r\nDie neuen Werte sind nur im Spiel über die +- Tasten erreichbar, der Regler im \r\nSpielmenü bleibt ungeändert.", + "Hungarian": "A játéksebességet mostantól a következőképpen lehet megváltoztatni:\r\n - 10-től 90-ig 5 lépésben\r\n - 90-től 200-ig 10 lépésben\r\n - 200-tól 1000-ig 100 lépésben\r\nAz új értékek elérhetők a játékban a +- billentyűk segítségével, a csúszka a játékmenüben változatlanul maradt.", + "Polish": "Szybkość gry można teraz zmienić w następujący sposób:\r\n - Od 10 do 90 w odstępach 5\r\n - Od 90 do 200 w odstępach 10\r\n - Od 200 do 1000 w odstępach 100\r\nNowe wartości są dostępne w grze wyłącznie za pomocą klawiszy + i -, suwak w menu \r\ngry pozostaje niezmieniony.", + "Russian": "Теперь скорость игры можно изменить следующим образом:\r\n - От 10 до 90 с интервалом 5\r\n  - от 90 до 200 с интервалом 10\r\n  - от 200 до 1000 с интервалом в 100\r\n - от 1100 - 9000 (Но после 1100 уже не происходит увеличение) \r\nНовые значения доступны только с помощью клавиш + -, ползунка в \r\nменю игры остается неизменным." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -760,14 +1463,28 @@ { "modType": "Other", "modIdentifier": "o_responsivegates", - "modDescription": {}, + "modDescription": { + "Chinese": "城门快速反应", + "English": "Quicker responsiveness of gates towards enemies", + "German": "Torhäuser schneller auf Gegner reagieren lassen", + "Hungarian": "A várkapuk gyorsabban reagálnak az ellenséges egységekre", + "Polish": "Szybsza reakcja bram", + "Russian": "Быстрая реакция юнитов на врагов" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_responsivegates", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "敌人在靠近城门一定距离时城门将会关闭,该距离由200调整至140。敌人在远离城门一定距离时城门将会打开,该距离由1200调整至100。", + "English": "Gates close themselves later if enemies get into range and open faster when the danger is gone. The distance of an enemy for which the gates close will be reduced from 200 to 140. The time after which the gates open, after & all enemies left will be reduced from 1200 to 100.", + "German": "Torhäuser schließen sich jetzt später bei Gegnernähe und öffnen wieder schneller automatisch, sobald die Gefahr vorüber ist. Die Distanz die ein Gegner haben muss, damit sich das Tor automatisch schließt, wird von 200 auf 140 gesenkt. Die Zeit nach der sich das Tor wieder öffnet, sofern kein Gegner mehr in der Nähe ist, wird von 1200 auf 100 reduziert.", + "Hungarian": "A várkapuk mostantól később záródnak be ha ellenség van a közelben és automatikusan gyorsabban kinyílnak, ha már nincs közelben ellenség. A távolság ami szükséges az ellenségnek, hogy a várkapu automatikusan bezáródjon, 200-ról 140-re lett csökkentve. Az idő amikor a várkapu ismét kinyílik, mihelyst nincs ellenség a közelben, 1200-ról 100-ra lett csökkentve.", + "Polish": "Bramy zamykają się później, gdy wrogowie znajdą się w zasięgu i otworzą się szybciej, kiedy niebezpieczeństwo zniknie. Odległość wroga od bramy, która wpływa na jej automatyczne zamykanie się zostanie zmniejszona z 200 do 140. Czas, po którym otwierają się bramy, gdy wszyscy wrogowie znikną, zostaje zmniejszony z 1200 do 100.", + "Russian": "Ворота закрывается позже когда опасность исчезнет. Расстояние врага, для которого закрываются ворота будет уменьшено с 200 до 140. Время, после которого ворота открываются, будет уменьшены с 1200 до 100." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -776,14 +1493,28 @@ { "modType": "Other", "modIdentifier": "o_onlyai", - "modDescription": {}, + "modDescription": { + "Chinese": "打开观察者模式", + "English": "Activate Spectator-mode [bug possible]", + "German": "Zuschauer-Modus aktivieren [bug möglich]", + "Hungarian": "Nézői mód aktiválása [hiba előfordulhat]", + "Polish": "Aktywuj tryb Obserwatora [możliwy błąd]", + "Russian": "Активировать Режим - Зрителя (Только AI) [Возможны баги]" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_onlyai", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "移除了玩家1使得玩家只能以观察的视角观看游戏,这使得8个ai同时出场成为了可能。该模式下保存的游戏可以被正常读取。偶尔可能会出现物体随机遍布在整个地图的bug,这只是视觉上的bug并不影响游戏本身,保存游戏,退出游戏,再读取游戏可以清除该bug。", + "English": "Removes player 1 so that you can only spectate and makes 8 AIs in one round possible. Savegames now load properly in this mode. Sometimes a bug appears in which random objects spawn all over the map. This is just visually and can be removed by saving the game, ending the mission and reloading the save file.", + "German": "Entfernt Spieler 1 sodass man nur noch zugucken kann und 8 KIs in einem Kreuzzug möglich sind. Gespeicherte Spiele laden jetzt auch ordnungsgemäß in diesem Modus. Ab und zu tritt ein Bug auf, bei dem überall auf der Karte zufällige Objekte auftauchen. Diese sind jedoch nur visuell und können durch einfaches Spiel speichern -> Mission beenden -> Spiel laden behoben werden.", + "Hungarian": "Eltávolítja az 1.játékost a nézői módhoz és így 8 MI harcolhat egymással az Egyedi játék módban. Az elmentett játék most már rendesen működik ebben a módban is. Néha előfordulhat olyan hiba, hogy az egész térképen véletlenszerűen feltűnhetnek tárgyak. De ezek csak vizuálisan jelennek meg és egyszerűen megoldható a Játék mentése -> Küldetés befejezése -> Játék betöltésével.", + "Polish": "Usuwa głównego gracza, dzięki czemu możesz tylko obserwować i tworzyć pojedynki między ośmioma botami. Zapisy gry ładują się teraz poprawnie w tym trybie. Czasami pojawia się błąd, w którym losowe obiekty pojawiają się na całej mapie. Jest to tylko wizualny błąd i można go usunąć zapisując grę, kończąc misję i ponownie wczytując zapis.", + "Russian": "Убирает игрока 1, чтобы вы могли видеть только 8 AI в одном и том же режиме. Сохранения игры теперь правильно загружаются в этом режиме. Иногда ошибка появляется, когда случайные объекты появляются на всей карте. Это просто визуальный баг и его можно убрать сохранив игру, завершая миссию и перезагружая сохранить файл." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -792,14 +1523,27 @@ { "modType": "Other", "modIdentifier": "o_armory_marketplace_weapon_order_fix", - "modDescription": {}, + "modDescription": { + "Chinese": "调整武器库和市场中武器的顺序", + "English": "Fix armory/marketplace weapon orders to match", + "German": "Vereinheitlicht Waffenreihenfolge", + "Hungarian": "Megegyező fegyver sorrend a fegyverraktár/piacban", + "Polish": "Ustaw broń na targowisku i w zbrojowni w tej samej kolejności", + "Russian": "Исправить оружейный склад/рыночное оружие, чтобы соответствовать порядку" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_armory_marketplace_weapon_order_fix", "defaultValue": "true", - "description": {}, + "description": { + "English": "Reorders Weapon icons in Armory and Marketplace to have the same order. Also moves Leather Armor between Mace and Crossbow, and moves Metal Armor between Polearm and Sword for easier access while in Marketplace scrolling through items.", + "German": "Vereinheitlicht Waffenreihenfolge in Waffenkammer und Marktplatz. Es befinden sich nun Lederrüstungen zwischen Streitkolben und Armbrüste, und Rüstungen zwischen Piken und Schwertern für einfacheres Scrollen im Marktplatz.", + "Hungarian": "Újrarendezi a fegyver ikonokat a fegyverraktárban és a piacban, hogy egyforma legyen a sorrend. A bőrpáncél a buzogány és számszeríj között lesz, míg a vaspáncél a dárda és kard között, hogy könnyebben megtalálható legyen a piacban való kereséskor.", + "Polish": "Ustawia broń na targowisku i w zbrojowni w tej samej kolejności. Zbroja skórzana na targowisku zostaje przesunięta między wekiery i kusze, natomiast zbroja metalowa między piki i miecze.", + "Russian": "Изменение порядка иконок оружия в Оружейной и на Рынке, чтобы они располагались в одинаковом порядке. Также перемещает кожаную броню между булавой и арбалетом, а металлическую броню - между пиками и мечом для более легкого доступа во время прокрутки предметов на Рынке." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -808,14 +1552,28 @@ { "modType": "Other", "modIdentifier": "o_increase_path_update_tick_rate", - "modDescription": {}, + "modDescription": { + "Chinese": "寻路检测频率增加", + "English": "Check more often for available paths", + "German": "Suche öfter nach verfügbaren Wegen", + "Hungarian": "Elérhető útvonalak gyakoribb ellenőrzése", + "Polish": "Zwiększ częstotliwość odświeżania możliwych ścieżek", + "Russian": "Более частая проверка доступного пути" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_increase_path_update_tick_rate", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "在原版,每200游戏刻会检测一次可行通路,经常导致ai的单位在摧毁了敌人的城门或者塔楼时不能立刻进入城堡。打开后,每50个游戏刻就会进行一次检测,使得单位的反应速度加快。", + "English": "In vanilla, it took 200 game ticks to check for new paths, often stopping units to move into the castle after destroying a gate or tower immediately.Availability is calculated every 50 gameticks now, allowing the units to 'realize' new paths more quickly.", + "German": "Das Spiel überprüft nun viermal so häufig, welche Bereiche der Karte verbunden sind. Dadurch können beispielsweise nach der Zerstörung eines Torhauses oder eines Turmes die Truppen schneller ins Innere einer zuvor unzugänglichen Burg beordert werden.", + "Hungarian": "Az eredeti játékban minden 200. játékidő tick után kerültek ellenőrzésre az új útvonalak, ami azt eredményezte, hogy az egységek nem tudtak azonnal bemenni a várba miután lerombolták a kaput vagy a tornyot.Az elérhető útvonalakat mostantól minden 50. játékidő tick után ellenőrzi, így lehetővé téve hogy az egységek sokkal gyorsabban 'realizálják' az elérhető új útvonalat.", + "Polish": "W oryginale jednostki potrzebowały dużo czasu, zanim mogły zrozumieć, że można wejść do zamku po zniszczeniu bramy lub wieży..Ta opcja zwiększa czterokrotnie częstotliwość odświeżania możliwych ścieżek wykrywanych przez jednostki, dzięki czemu szybciej zrozumieją, że można już wejść do zamku.", + "Russian": "В ваниле, это заняло 200 игровых тиков, чтобы проверить новые пути, часто останавливая юнитов, чтобы перейти в замок после уничтожения ворот или башни немедленно. Доступность рассчитывается теперь каждые 50 игровых тиков, что позволяет юнитам реализовывать новые пути быстрее." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -824,14 +1582,28 @@ { "modType": "Other", "modIdentifier": "o_default_multiplayer_speed", - "modDescription": {}, + "modDescription": { + "Chinese": "设置多人游戏中的默认游戏速度", + "English": "Set default multiplayer speed.", + "German": "Setzt Mehrspieler Standardgeschwindigkeit", + "Hungarian": "Többjátékos mód alapsebességének beállítása", + "Polish": "Ustaw domyślną prędkość gry multiplayer.", + "Russian": "Установить скорость мультиплеера по умолчанию." + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_default_multiplayer_speed", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "", + "English": "", + "German": "", + "Hungarian": "", + "Polish": "", + "Russian": "" + }, "selectionType": "slider", "selectionParameters": { "minimum": 20, @@ -846,14 +1618,36 @@ { "modType": "Other", "modIdentifier": "o_shfy", - "modDescription": {}, + "modDescription": { + "Chinese": "要塞修改", + "English": "Strongholdify", + "German": "Strongholdify", + "Hungarian": "Strongholdify", + "Polish": "Strongholdify", + "Russian": "Strongholdify" + }, + "detailedDescription": { + "Chinese": "将这些方面调整为要塞1的数值。注意:任何改变都会影响ai领主,最坏的情况是失效!", + "English": "Adapts listed aspects to match Stronghold 1. Attention: Every change influences the AI lords, in the worst case renders them useless!", + "German": "Passt aufgelistete Aspekte an Stronghold 1 an. Achtung: Jede Annpassung nimmt Einfluss auf die KI Lords, schlimmstenfalls werden diese nutzlos!", + "Hungarian": "A felsorolt szempontokat a Stronghold 1-hez igazítja. Vigyázat: Minden változtatás hatással van az MI Lordokra, a legrosszabb esetben haszontalanná teszi őket!", + "Polish": "Podane aspekty są zbliżone do tych z pierwszej Twierdzy. Uwaga: Każda zmiana wpływa na przeciwników komputerowych. W najgorszym wypadku mogą stać się bezużyteczni!", + "Russian": "Адаптирует перечисленные аспекты в соответствии с Stronghold 1. Внимание: Каждое изменение влияет на повелителей AI, в худшем случае делает их бесполезными!" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_shfy_beer", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "从啤酒中获取的声望", + "English": "Popularity bonus from beer", + "German": "Beliebtheitsbonus durch Bier", + "Hungarian": "Sör általi népszerűségi bónusz", + "Polish": "Bonus do popularności za piwo", + "Russian": "Бонус за популярность от пива" + }, "selectionType": "checkbox", "selectionParameters": {} }, @@ -861,7 +1655,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_shfy_religion", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "从宗教中获取的声望", + "English": "Popularity bonus from cathedral and church", + "German": "Beliebtheitsbonus Kathedrale und Kirche", + "Hungarian": "Templom és katedrális általi népszerűségi bónusz", + "Polish": "Bonus do popularności za katedrę i kościół", + "Russian": "Бонус за популярность от собора налогов и церкви" + }, "selectionType": "checkbox", "selectionParameters": {} }, @@ -869,7 +1670,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_shfy_peasantspawnrate", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "农民产生速度", + "English": "Spawnrate peasants", + "German": "Spawngeschwindigkeit Bauern", + "Hungarian": "Parasztok érkezésének sebessége", + "Polish": "Szybkość pojawiania się wieśniaków", + "Russian": "Скорость появления крестьян (спавн)" + }, "selectionType": "checkbox", "selectionParameters": {} }, @@ -877,7 +1685,14 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_shfy_resourcequantity", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "交付资源数量", + "English": "Quantity of delivered resources", + "German": "Anzahl der gelieferten Resourcen", + "Hungarian": "Leszállított erőforrások mennyisége", + "Polish": "Ilośc otrzymywanych surowców", + "Russian": "Количество предоставленных ресурсов" + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -886,14 +1701,28 @@ { "modType": "Other", "modIdentifier": "fix_apple_orchard_build_size", - "modDescription": {}, + "modDescription": { + "Chinese": "修正苹果园建造时的面积", + "English": "Shrink apple orchard's build size", + "German": "Reduziert die Baugröße von Apfelfarmen", + "Hungarian": "Almáskert építési méretének csökkentése", + "Polish": "Zmniejsz rozmiar budowy sadów jabłoni", + "Russian": "Размер площади яблоневой фермы" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "fix_apple_orchard_build_size", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "将建造时苹果园需求的面积修正为苹果园的实际面积,这也可以让AI正确的放置苹果园。", + "English": "Changes the apple orchard's build size to the size it occupies after the farm is placed down. This saves some space when building the farms and increases the rate with which the AI is able to put these farms down.", + "German": "Ändert die Bauvorschau von Apfelfarmen auf die Größe, die sie nach der Platzierung der Farm haben.", + "Hungarian": "Az almáskert elhelyezése előtt az előnézeti mérete nagyobb volt, mint amekkora valójában az almáskert az elhelyezés után. Ez a hiba kijavításra került. Ezzel a beállítással több szabad hely marad az almáskertek építésekor és megnöveli az MI mezőgazdasági épületek építésének rátáját.", + "Polish": "Opcja zmniejsza rozmiar budowy sadów jabłoni, aby był taki sam, jak rzeczywisty rozmiar całego budynku. Zaoszczędzi to miejsce na trawie i pomoże botom na lepszy rozwój.", + "Russian": "Изменяет размер постройки яблоневого сада на размер который он занимает после расположение фермы. Это экономит место при строительстве ферм и увеличивает скорость, с которой AI может располагать эти фермы." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -902,14 +1731,36 @@ { "modType": "Other", "modIdentifier": "o_seed_modification_possibility_title", - "modDescription": {}, + "modDescription": { + "Chinese": "游戏种子", + "English": "Manipulate random number generator", + "German": "Manipuliere Zufallszahlengenerator", + "Hungarian": "Random játék seed", + "Polish": "Generowane ziarno gry", + "Russian": "Игровой случайный сид" + }, "modSelectionRule": "1|2", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_seed_modification_possibility_only_set", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "启用固定游戏随机种子", + "English": "Enable fixed game randomseed", + "German": "Ermögliche Festlegung eines Zufallsstartwertes", + "Hungarian": "Megadott Random játék seed engedélyezése", + "Polish": "Włącza generowane ziarno gry", + "Russian": "Включить фиксированную игру случайным сидом" + }, + "detailedDescription": { + "Chinese": "如果使用相同的地图设置,设置游戏种子可以使只有AI的游戏对局每次都以相同的过程进行。对于既有玩家也有AI的游戏对局,设置游戏种子可以确保每次游戏的开始条件是相同的(例如相同的AIV)。若要设置游戏种子,请启用此选项并在game install/gameseeds目录中创建一个名为“live”的txt文件,并手动写上6位数字。注意:启动此功能后需要重新启动游戏!", + "English": "Setting the Game seed will allow AI-only games to play out the same way if the same map settings are used. For games involving human players, it will ensure the same starting conditions in the map (e.g. AIV selection). To set the game seed, enable this option and create a file called 'live' containing an integer in the [game install]/gameseeds directory. CAUTION: This feature only works after also restarting the game!", + "German": "Das Setzen eines Startwertes für den Zufallszahlen Generator ermöglicht es für KI Spiele immer den gleichen Verlauf zu nehmen. Für Spiele mit menschlichen Spielern und KI können feste Startbedingungen ermöglicht werden (z.B. die gleiche Auswahl von AIV Dateien für die KI). Um den Zufallsstartwert zu setzen, erstelle eine Datei mit dem Namen 'live', welche eine ganze Zahl enthält im Ordner Installationsverzeichnis/gameseeds. ACHTUNG: Vor Beginn eines wiederholbaren Scharmützels muss das Spiel neu gestartet werden!", + "Hungarian": "A játék seed megadásával az MI harcoknak a kimenetele ugyanaz lesz, azonos pályabeállítások esetén. Játékos-MI harc esetén, ugyanazon kezdési feltételeket biztosítja a pályán (mint pl. az AIV kiválasztás). A játék seed megadásához, engedélyezd ezt a beállítást és hozz létre egy 6 darab számot tartalmazó 'live' nevű szöveges fájlt a játék könyvtár/gameseeds mappában. FIGYELEM: Ez a beállítás csak a játék újraindítása után működik!", + "Polish": "Ta opcja pozwala na wygenerowanie ziarna gry (działa tylko na rozgrywki samych botów), aby rozgrywka była za każdym razem taka sama, jeśli wybrało się takie same ustawienia mapy. Aby to zrobić, włącz tę opcję i stwórz plik o nazwie 'live' z 6 cyframi w folderze z zainstalowaną grą/podfolderze z ziarnami (gameseed). UWAGA: Ta opcja działa po zrestartowaniu gry!", + "Russian": "Установка игрового сида позволит играм только с AI играть точно так же, если используются те же настройки карты. Для игр с AI, он обеспечит такие же условия запуска на карте (например, выбор AIV). Для установки игрового сида, включите эту опцию и создайте файл под названием (live) с 6-значным номером в каталоге установки игры/игр. ВНИМАНИЕ: Эта функция работает только после перезапуска игры!" + }, "selectionType": "checkbox", "selectionParameters": {} }, @@ -917,7 +1768,22 @@ "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_seed_modification_possibility", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "启用或保存游戏随机种子", + "English": "Enable & Save game randomseeds", + "German": "Ermögliche & Speichere Zufallsstartwerte", + "Hungarian": "Random játék seed-ek engedélyezése és mentése", + "Polish": "Włącz i zapisuj generowane ziarna gry", + "Russian": "Включить и сохранить игру случайных сидов" + }, + "detailedDescription": { + "Chinese": "这个选项可以保存你当前的游戏种子,前提是你当前没有设定游戏种子,你可以将保存的游戏种子重命名为“live”使其应用在之后的游戏中。", + "English": "This option will save the seed from games that do not have a live seed set, so you can rename them to 'live' in order to recreate the match afterwards.", + "German": "Mit dieser Option werden Zufallsstartwerte von Spielen gespeichert, für die keiner im gameseeds Ordner gesetzt wurde. So können diese nachträglich in 'live' umbenannt werden um das Spiel zu wiederholen.", + "Hungarian": "Ez a beállítás elmenti a seed-et azon játékokból amikhez nem lett megadva live seed érték, nevezd át a kívánt seed-et tartalmazó szöveges fájlt 'live'-ra hogy a későbbiekben újra rekonstruálhasd a harcot.", + "Polish": "This option will save the seed from games that do not have a live seed set, so you can rename them to 'live' in order to recreate the match afterwards.", + "Russian": "Эта опция сохранит сид от игр, которые не имеют live сида, так что вы можете переименовать их в live, чтобы потом воссоздать матч." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -926,14 +1792,28 @@ { "modType": "Other", "modIdentifier": "o_change_siege_engine_spawn_position_catapult", - "modDescription": {}, + "modDescription": { + "Chinese": "器械建造完成时将位于帐篷中央", + "English": "Spawn siege engines in the center of their tent", + "German": "Belagerungsgeräte in der Mitte des Zelts aufbauen", + "Hungarian": "Elkészült ostromgépek középre pozicionálása", + "Polish": "Wyśrodkuj pozycję pojawiania się machin oblężniczych", + "Russian": "Положение спавна осадных механизмов посредине" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_change_siege_engine_spawn_position_catapult", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "器械建造完成时将不再位于帐篷的右上角,而是位于帐篷的中央。", + "English": "Siege engines are spawning in the middle of their construction tent, instead of the top right corner.", + "German": "Belagerungsgeräte erscheinen nun nach dem Aufbauen am Punkt der Zeltmitte, statt wie bisher in der oberen rechten Ecke des Zelts.", + "Hungarian": "Az elkészült ostromgépek a sátor közepénél jelennek meg a sátor jobb felső sarka helyett.", + "Polish": "Machiny oblężnicze będą pojawiać się na środku miejsca, w którym stał namiot oblężniczy.", + "Russian": "Осадные механизмы теперь появляется по центру , вместо появления в верхнем углу палатки." + }, "selectionType": "checkbox", "selectionParameters": {} } @@ -942,14 +1822,28 @@ { "modType": "Other", "modIdentifier": "o_stop_player_keep_rotation", - "modDescription": {}, + "modDescription": { + "Chinese": "玩家的大本营会根据所处地图方位进行旋转", + "English": "Rotate player keeps same as AI's", + "German": "Drehe Spielerbergfriede wie die der KIs", + "Hungarian": "Játékos vártornyok elforgatása", + "Polish": "Odwróć siedziby graczy", + "Russian": "Поворот крепости игрока" + }, "modSelectionRule": "*", "changes": [ { "compatibility": [ "crusader", "extreme", "singleplayer", "multiplayer" ], "identifier": "o_stop_player_keep_rotation", "defaultValue": "true", - "description": {}, + "description": { + "Chinese": "玩家的大本营将可以和AI一样,会根据所处地图方位进行旋转,使篝火处永远背向地图中央。", + "English": "Player keeps now get rotated the same way, that AI keeps rotate on a map, facing with their campfire outwards towards the map edge.", + "German": "Die Bergfriede der Spieler richten sich nun so aus wie die der KI; sie drehen sich so, dass das Lagerfeuer in Richtung des Kartenrands zeigt.", + "Hungarian": "A játékosok vártornyai mostantól ugyanolyan módon lesznek elforgatva, mint az MI vártornyok. A tábortűz mindig a térkép legközelebbi széle felé néz.", + "Polish": "Siedziby graczy będą odwracać się ogniskiem (wejściem) w stronę krańca mapy.", + "Russian": "Крепость игрока вращяется таким же образом как и крепости AI. Точней стоит лицом к костру AI , а другой стороной к краю карты" + }, "selectionType": "checkbox", "selectionParameters": {} } diff --git a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj index f1335038..19688b9c 100644 --- a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj +++ b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj @@ -8,7 +8,7 @@ Library UCP UnofficialCrusaderPatch - v4.0 + v4.5 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 @@ -46,17 +46,19 @@ x86 bin\Debug\ + false x86 bin\Release\ + false OnBuildSuccess - ..\packages\Newtonsoft.Json.13.0.1\lib\net40\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll @@ -79,9 +81,11 @@ CodeBlocks\CodeBlock.cs + + - + @@ -158,6 +162,11 @@ + + + + + @@ -363,13 +372,16 @@ + + + + + + - - - - + diff --git a/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs b/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs index f004ab93..f574432f 100644 --- a/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs +++ b/UnofficialCrusaderPatch/Util/Enumerators/StartResourceEnumerator.cs @@ -31,6 +31,22 @@ class StartResourceEnumerator private static byte[] resourceBlock; private static byte[] goldBlock; + // to be deprecated + internal static List GetStartResourceChanges() + { + _changes.Clear(); + startResourceConfig.Clear(); + Load(); + ResetStartResourceConfiguration(); + return _changes; + } + + // to be deprecated + internal static Change GetActiveChange() + { + return activeChange; + } + internal static Dictionary GetStartResourceConfigurations() { _changes.Clear(); diff --git a/UnofficialCrusaderPatch/packages.config b/UnofficialCrusaderPatch/packages.config index d9261b81..093dcd23 100644 --- a/UnofficialCrusaderPatch/packages.config +++ b/UnofficialCrusaderPatch/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/UnofficialCrusaderPatchGUI/MainWindow.xaml.cs b/UnofficialCrusaderPatchGUI/MainWindow.xaml.cs index a4db87c3..ae580869 100644 --- a/UnofficialCrusaderPatchGUI/MainWindow.xaml.cs +++ b/UnofficialCrusaderPatchGUI/MainWindow.xaml.cs @@ -18,6 +18,8 @@ using UCP.AIC; using System.Diagnostics; using System.Windows.Input; +using UCP.Model; +using UCP.Views; namespace UCP { @@ -279,9 +281,9 @@ void FillTreeView(IEnumerable changes) }; tabControl.Items.Add(tab); - if (type == ChangeType.Resource) + if (type == ChangeType.StartResource) { - new ResourceView().InitUI(grid, View_SelectedItemChanged); + new StartResourceView().InitUI(grid, View_SelectedItemChanged); continue; } else if (type == ChangeType.AIV) diff --git a/UnofficialCrusaderPatchPyGUI/app.py b/UnofficialCrusaderPatchPyGUI/app.py index a3102388..d924a9e0 100644 --- a/UnofficialCrusaderPatchPyGUI/app.py +++ b/UnofficialCrusaderPatchPyGUI/app.py @@ -21,7 +21,8 @@ @app.route('/') def start(): - ucp_configuration = ModAPIContract.GetUCPConfiguration() + language = "English" + ucp_configuration = ModAPIContract.GetUCPConfiguration(language) aic_list = ModAPIContract.ListAICConfigurations() aiv_list = ModAPIContract.ListAIVConfigurations() starttroop_list = ModAPIContract.ListStartTroopConfigurations() @@ -38,5 +39,5 @@ def start_server(): t.start() webview.create_window("Unofficial Crusader Patch", "http://127.0.0.1:5000/", width=600, height=400, min_size=(600, 400)) - webview.start(debug=True) + webview.start(debug=True, gui='mshtml') sys.exit() \ No newline at end of file diff --git a/UnofficialCrusaderPatchPyGUI/static/css/index.css b/UnofficialCrusaderPatchPyGUI/static/css/index.css index 0bcc8194..902682e1 100644 --- a/UnofficialCrusaderPatchPyGUI/static/css/index.css +++ b/UnofficialCrusaderPatchPyGUI/static/css/index.css @@ -1,78 +1,158 @@ html { - overflow: hidden; + overflow: hidden; } body { - /* background-color: maroon; */ - background-image: url("/static/img/wallpaper.jpg"); - background-repeat: no-repeat; - background-size: cover; - font-size: medium; - color: white; + /* background-color: maroon; */ + background-image: url("/static/img/wallpaper.jpg"); + background-repeat: no-repeat; + background-size: cover; + font-size: medium; + color: white; } #ucp-title { - color: gold; - text-align: center; + color: gold; + text-align: center; } .ucp-select { - margin-right: 10px; - z-index: 100; + margin-right: 10px; + z-index: 100; } .ucp-select-text { - color: goldenrod; - font-weight: bold; - text-decoration: none; + color: goldenrod; + font-weight: bold; + text-decoration: none; } .ucp-select-info { - float: right; - cursor: pointer; + float: right; + cursor: pointer; } .ucp-select-header { - width: 98%; + width: 98%; } .nav-tabs .nav-item .nav-link { - width: max-content; - font-size: small; - padding: 5px; + width: max-content; + font-size: small; + padding: 5px; } -#myTabContent, label { - color: white; +#myTabContent, +label { + color: white; } .tab-pane { - overflow-y: scroll; - height: 230px; - background: rgba(255, 255, 255, 0.25); - border-radius: 10px; - padding: 10px; + overflow-y: scroll; + height: 230px; + background: rgba(255, 255, 255, 0.25); + border-radius: 10px; + padding: 10px; } .description { - padding-left: 32px; - padding-right: 32px; - overflow-wrap: break-word; + padding-left: 32px; + padding-right: 32px; + overflow-wrap: break-word; +} + +input[type="range"] { + -webkit-appearance: none; + background-color: transparent; } -::-webkit-scrollbar { - width: 12px; +input:focus { + outline: none; } -::-webkit-scrollbar-track { +/*::-webkit-scrollbar-track { + -webkit-appearance: none; + background-color: transparent; -webkit-box-shadow: inset 0 0 5px rgba(200,200,200,1); box-shadow: inset 0 0 5px rgba(200,200,200,1); border-radius: 10px; } ::-webkit-scrollbar-thumb { + -webkit-appearance: none; border-radius: 10px; background-color: gold; -webkit-box-shadow: inset 0 0 10px rgba(90,90,90,0.7); box-shadow: inset 0 0 10px rgba(90,90,90,0.7); -} \ No newline at end of file + transform: translateY(-5px); +}*/ + +.ucp-slider { + -webkit-appearance: none; + min-width: 300px; + display: block; +} + +.ucp-slider::-webkit-slider-runnable-track { + -webkit-appearance: none; + background-color: transparent; + background-color: gray; + border-radius: 5px; + height: 5px; + opacity: 0.7; + margin: 5px; +} + +.ucp-slider::-moz-range-track { + -webkit-appearance: none; + background-color: transparent; + background-color: gray; + border-radius: 5px; + height: 5px; + opacity: 0.7; + margin: 5px; +} + +.ucp-slider::-ms-track { + -webkit-appearance: none; + background-color: transparent; + background-color: gray; + border-radius: 5px; + height: 5px; + opacity: 0.7; + margin: 5px; +} + +.ucp-slider::-webkit-slider-thumb { + -webkit-appearance: none; + width: 15px; + height: 15px; + border-radius: 50%; + background: goldenrod; + border: 2px solid black; + cursor: pointer; + transform: translateY(-5px); +} + +.ucp-slider::-moz-range-thumb { + -webkit-appearance: none; + width: 15px; + height: 15px; + border-radius: 50%; + background: goldenrod; + border: 2px solid black; + cursor: pointer; + transform: translateY(-0px); +} + +.ucp-slider::-ms-thumb { + pointer-events: visible; + -webkit-appearance: none; + width: 15px; + height: 15px; + border-radius: 50%; + background: goldenrod; + border: 2px solid black; + cursor: pointer; + transform: translateY(0px); +} diff --git a/UnofficialCrusaderPatchPyGUI/templates/index.html b/UnofficialCrusaderPatchPyGUI/templates/index.html index 72a52fee..ec2166d4 100644 --- a/UnofficialCrusaderPatchPyGUI/templates/index.html +++ b/UnofficialCrusaderPatchPyGUI/templates/index.html @@ -1,167 +1,82 @@ - - - - Unofficial Crusader Patch - - + + + + Unofficial Crusader Patch + + - - - - - - -
-

Welcome to the Unofficial Crusader Patch

+ + + + + + +
+

Welcome to the Unofficial Crusader Patch

-
- - -
- {% for modType in ucp_config|map(attribute='modType')|unique|list %} -
- {% for config in ucp_config if config.modType == modType %} - {% if modType != "AIC" and modType != "AIV" %} -
- - - -
-
- {{config.modDescription["English"]}} - {% if modType != "troop" and modType != "resource" and config.changes|length > 0 %} - {% if config.changes|length > 1 or config.changes[0].selectionType != "checkbox" %} - {% for change in config.changes %} -
- - -
- {% endfor %} - {% endif %} - {% endif %} -
- {% endif %} - {% endfor %} -
- {% endfor %} +
+ -
- Bugfix -
-
- AI Lords -
-
- Other +
+ {% for modType in ucp_config|map(attribute='modType')|unique|list %} +
+ {% for config in ucp_config if config.modType == modType %} + {% if modType != "AIC" and modType != "AIV" %} +
+ + +
- -
- {% for aiv in aiv_list %} +
+ {% if modType != "troop" and modType != "resource" and config.changes|length > 0 %} + {% for change in config.changes %} + {% if change.selectionType == "checkbox" %} + {{change.description}} + {% if 'detailedDescription' in change %} + {{change.detailedDescription}} + {% endif %} + {% elif change.selectionType == "radio" %}
- -
-
- {{aiv.Value.Description["English"]}} -
- {% endfor %} - -
-
- {% for aic in aic_list %} -
- - -
-
- {{aic.Description["English"]}} -
- {% endfor %} - -
- -
- {% for config in startresource_list %} -
- - - -
-
- {{config.Value.Description["English"]}}
+ {% endif %} {% endfor %} + {% endif %}
+ {% endif %} + {% endfor %}
+ {% endfor %}
- +
+ \ No newline at end of file From 10a1993ad74b1486098609ac0c8797ceb7a61ccd Mon Sep 17 00:00:00 2001 From: patel-nikhil Date: Fri, 24 Dec 2021 00:31:06 -0500 Subject: [PATCH 6/7] Remove other GUI implementations --- UnofficialCrusaderPatch.sln | 20 - .../UnofficialCrusaderPatch.csproj | 9 +- UnofficialCrusaderPatchGUI/App.config | 6 - UnofficialCrusaderPatchGUI/App.xaml | 9 - UnofficialCrusaderPatchGUI/App.xaml.cs | 19 - .../Graphics/UCP-Bugfix.aic | 3060 ----------------- .../Graphics/background.jpg | Bin 30820 -> 0 bytes UnofficialCrusaderPatchGUI/Graphics/frame.jpg | Bin 59041 -> 0 bytes UnofficialCrusaderPatchGUI/Graphics/icon6.ico | Bin 2310 -> 0 bytes .../Graphics/refresh.odg | Bin 8885 -> 0 bytes .../Graphics/refresh.png | Bin 845 -> 0 bytes .../Graphics/shield.png | Bin 1287 -> 0 bytes .../LanguageWindow.xaml | 16 - .../LanguageWindow.xaml.cs | 79 - UnofficialCrusaderPatchGUI/MainWindow.xaml | 68 - UnofficialCrusaderPatchGUI/MainWindow.xaml.cs | 354 -- .../Properties/AssemblyInfo.cs | 55 - .../Properties/Resources.Designer.cs | 63 - .../Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 7 - .../UnofficialCrusaderPatchGUI.csproj | 175 - UnofficialCrusaderPatchGUI/icon6.ico | Bin 2310 -> 0 bytes UnofficialCrusaderPatchGUI/license.txt | 8 - .../UnofficialCrusaderPatchPyGUI.pyproj | 99 - UnofficialCrusaderPatchPyGUI/app.py | 43 - UnofficialCrusaderPatchPyGUI/requirements.txt | 2 - .../static/css/bootstrap.min.css | 7 - .../static/css/bootstrap.min.css.map | 1 - .../static/css/index.css | 158 - .../static/img/wallpaper.jpg | Bin 82679 -> 0 bytes .../static/js/bootstrap.min.js | 7 - .../static/js/index.js | 3 - .../static/js/jquery-3.2.1.slim.min.js | 4 - .../static/js/popper.min.js | 6 - .../templates/index-1.html | 111 - .../templates/index.html | 82 - 37 files changed, 1 insertion(+), 4613 deletions(-) delete mode 100644 UnofficialCrusaderPatchGUI/App.config delete mode 100644 UnofficialCrusaderPatchGUI/App.xaml delete mode 100644 UnofficialCrusaderPatchGUI/App.xaml.cs delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/UCP-Bugfix.aic delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/background.jpg delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/frame.jpg delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/icon6.ico delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/refresh.odg delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/refresh.png delete mode 100644 UnofficialCrusaderPatchGUI/Graphics/shield.png delete mode 100644 UnofficialCrusaderPatchGUI/LanguageWindow.xaml delete mode 100644 UnofficialCrusaderPatchGUI/LanguageWindow.xaml.cs delete mode 100644 UnofficialCrusaderPatchGUI/MainWindow.xaml delete mode 100644 UnofficialCrusaderPatchGUI/MainWindow.xaml.cs delete mode 100644 UnofficialCrusaderPatchGUI/Properties/AssemblyInfo.cs delete mode 100644 UnofficialCrusaderPatchGUI/Properties/Resources.Designer.cs delete mode 100644 UnofficialCrusaderPatchGUI/Properties/Resources.resx delete mode 100644 UnofficialCrusaderPatchGUI/Properties/Settings.Designer.cs delete mode 100644 UnofficialCrusaderPatchGUI/Properties/Settings.settings delete mode 100644 UnofficialCrusaderPatchGUI/UnofficialCrusaderPatchGUI.csproj delete mode 100644 UnofficialCrusaderPatchGUI/icon6.ico delete mode 100644 UnofficialCrusaderPatchGUI/license.txt delete mode 100644 UnofficialCrusaderPatchPyGUI/UnofficialCrusaderPatchPyGUI.pyproj delete mode 100644 UnofficialCrusaderPatchPyGUI/app.py delete mode 100644 UnofficialCrusaderPatchPyGUI/requirements.txt delete mode 100644 UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css delete mode 100644 UnofficialCrusaderPatchPyGUI/static/css/bootstrap.min.css.map delete mode 100644 UnofficialCrusaderPatchPyGUI/static/css/index.css delete mode 100644 UnofficialCrusaderPatchPyGUI/static/img/wallpaper.jpg delete mode 100644 UnofficialCrusaderPatchPyGUI/static/js/bootstrap.min.js delete mode 100644 UnofficialCrusaderPatchPyGUI/static/js/index.js delete mode 100644 UnofficialCrusaderPatchPyGUI/static/js/jquery-3.2.1.slim.min.js delete mode 100644 UnofficialCrusaderPatchPyGUI/static/js/popper.min.js delete mode 100644 UnofficialCrusaderPatchPyGUI/templates/index-1.html delete mode 100644 UnofficialCrusaderPatchPyGUI/templates/index.html diff --git a/UnofficialCrusaderPatch.sln b/UnofficialCrusaderPatch.sln index 506b8a54..89f6efb0 100644 --- a/UnofficialCrusaderPatch.sln +++ b/UnofficialCrusaderPatch.sln @@ -11,12 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IDAParser", "IDAParser\IDAP EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AICUpdater", "AICUpdater\AICUpdater.csproj", "{44C20962-0F8D-4582-95A1-0ECBA7AABF0A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnofficialCrusaderPatchGUI", "UnofficialCrusaderPatchGUI\UnofficialCrusaderPatchGUI.csproj", "{FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnofficialCrusaderPatchConsole", "UnofficialCrusaderPatchConsole\UnofficialCrusaderPatchConsole.csproj", "{743F77E0-AD5A-42FE-B928-535AAF40AC4D}" EndProject -Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "UnofficialCrusaderPatchPyGUI", "UnofficialCrusaderPatchPyGUI\UnofficialCrusaderPatchPyGUI.pyproj", "{500A7837-8D87-42F8-928A-31648E29D762}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,14 +53,6 @@ Global {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|Any CPU.Build.0 = Release|Any CPU {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|x86.ActiveCfg = Release|Any CPU {44C20962-0F8D-4582-95A1-0ECBA7AABF0A}.Release|x86.Build.0 = Release|Any CPU - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|x86.ActiveCfg = Debug|x86 - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Debug|x86.Build.0 = Debug|x86 - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|Any CPU.Build.0 = Release|Any CPU - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|x86.ActiveCfg = Release|Any CPU - {FFBFC874-6EAF-4B9C-8507-BBD5A9399CB5}.Release|x86.Build.0 = Release|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|Any CPU.Build.0 = Debug|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Debug|x86.ActiveCfg = Debug|x86 @@ -73,14 +61,6 @@ Global {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|Any CPU.Build.0 = Release|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|x86.ActiveCfg = Release|Any CPU {743F77E0-AD5A-42FE-B928-535AAF40AC4D}.Release|x86.Build.0 = Release|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Debug|Any CPU.Build.0 = Debug|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Debug|x86.ActiveCfg = Debug|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Debug|x86.Build.0 = Debug|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Release|Any CPU.ActiveCfg = Release|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Release|Any CPU.Build.0 = Release|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Release|x86.ActiveCfg = Release|Any CPU - {500A7837-8D87-42F8-928A-31648E29D762}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj index 19688b9c..3136fbaf 100644 --- a/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj +++ b/UnofficialCrusaderPatch/UnofficialCrusaderPatch.csproj @@ -162,11 +162,6 @@ - - - - - @@ -380,9 +375,7 @@ - - - + diff --git a/UnofficialCrusaderPatchGUI/App.config b/UnofficialCrusaderPatchGUI/App.config deleted file mode 100644 index 74ade9db..00000000 --- a/UnofficialCrusaderPatchGUI/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/UnofficialCrusaderPatchGUI/App.xaml b/UnofficialCrusaderPatchGUI/App.xaml deleted file mode 100644 index cf432469..00000000 --- a/UnofficialCrusaderPatchGUI/App.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/UnofficialCrusaderPatchGUI/App.xaml.cs b/UnofficialCrusaderPatchGUI/App.xaml.cs deleted file mode 100644 index c4ea9960..00000000 --- a/UnofficialCrusaderPatchGUI/App.xaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using UCP.Patching; - -namespace UCP -{ - /// - /// Interaktionslogik für "App.xaml" - /// - public partial class App : Application - { - } -} diff --git a/UnofficialCrusaderPatchGUI/Graphics/UCP-Bugfix.aic b/UnofficialCrusaderPatchGUI/Graphics/UCP-Bugfix.aic deleted file mode 100644 index 4556f93f..00000000 --- a/UnofficialCrusaderPatchGUI/Graphics/UCP-Bugfix.aic +++ /dev/null @@ -1,3060 +0,0 @@ -AIFileHeader -{ - DescrGer - { - Diese .aic behebt die folgenden Fehler und Macken der KIs: - - Die Ratte bemannt ihre Verteidigung wieder langsam - - Philipp besetzt seine Mauern auf Ratte-Niveau - - Friedrich, Marschall, Emir & Abt kaufen Ausrstung - - Wazir kauft Brot in Not - - Nizar kauft Brot statt pfel - - Sultan kauft auch Kse & Brot - - Wazir strebt immer mindestens 5 Getreide im Lager an statt 2 - - Wazir, Emir, Marschall & Philipp kaufen Nahrung & Getreide in 10er statt 20er Fuhren - - } - DescrEng - { - This .aic fixes the following bugs and quirks of the AI: - - The Rat reinforces its defense again slowly - - Philipp has wall defenses on the niveau of The Rat - - Frederick, Marshal, Emir & The Abbot buy equipment - - Wazir buys bread in need - - Nizar buys bread instead of apples - - Sultan also buys Cheese & Bread - - Wazir always aims at at least 5 wheat in stock instead of 2 - - Wazir, Emir, Marshal & Philipp buy food & wheat in stocks of 10 instead of 20 - - } - DescrPol = - DescrRus = -} - -/* -AICharacter -{ - Index: Int32 - Name: String - Personality: AIPersonality - { - Unknown000: Int32 - Unknown001: Int32 - Unknown002: Int32 - Unknown003: Int32 - Unknown004: Int32 - Unknown005: Int32 - CriticalPopularity: Int32, Values range from 0 to 10000, where 100 popularity equals 10000. Below this value, the AI sells more stuff than usual to get money. - LowestPopularity: Int32, Below this value the AI sets taxes to zero until it reaches 'HighestPopularity' again. - HighestPopularity: Int32, Above this value the AI sets taxes back up - Unknown009: Int32 - Unknown010: Int32 - Unknown011: Int32 - Farm1: FarmBuilding, An array of farm slots, which the AI builds in the given sequence. - Farm2: FarmBuilding - Farm3: FarmBuilding - Farm4: FarmBuilding - Farm5: FarmBuilding - Farm6: FarmBuilding - Farm7: FarmBuilding - Farm8: FarmBuilding - PopulationPerFarm: Int32, The AI builds one farm for each amount of this population value. (Also check MaxFarms) - PopulationPerWoodcutter: Int32 - PopulationPerQuarry: Int32 - PopulationPerIronmine: Int32 - PopulationPerPitchrig: Int32 - MaxQuarries: Int32 - MaxIronmines: Int32 - MaxWoodcutters: Int32 - MaxPitchrigs: Int32 - MaxFarms: Int32, The maximum amount of farms the AI builds. (Also check PopulationPerFarm) - BuildInterval: Int32, This is only considered <= 5000 gold - ResourceRebuildDelay: Int32, The delay before the AI rebuilds destroyed buildings. - MaxFood: Int32, includes flour? - MinimumApples: Int32 - MinimumCheese: Int32 - MinimumBread: Int32 - MinimumWheat: Int32 - MinimumHop: Int32, unclear - TradeAmountFood: Int32 - TradeAmountEquipment: Int32 - Unknown040: Int32 - Unknown041: Int32 - Unknown042: Int32 - MaxWood: Int32 - MaxStone: Int32 - MaxResourceOther: Int32 - MaxEquipment: Int32 - MaxBeer: Int32 - MaxResourceVariance: Int32, added to all max resource values? - Unknown049: Int32 - BlacksmithSetting: BlacksmithSetting - FletcherSetting: FletcherSetting - PoleturnerSetting: PoleturnerSetting - SellResource01: Resource - SellResource02: Resource - SellResource03: Resource - SellResource04: Resource - SellResource05: Resource - SellResource06: Resource - SellResource07: Resource - SellResource08: Resource - SellResource09: Resource - SellResource10: Resource - SellResource11: Resource - SellResource12: Resource - SellResource13: Resource - SellResource14: Resource - SellResource15: Resource - Unknown068: Int32 - Unknown069: Int32 - DefSiegeEngineGoldThreshold: Int32, This one makes no sense. In code: [if (Gold + Threshold > 30) then RecruitEngineer()], maybe it was supposed to be minus... - DefSiegeEngineBuildDelay: Int32, The delay before the AI builds its first defensive siege engine. - Unknown072: Int32 - Unknown073: Int32 - RecruitProbDefDefault: Int32, The probability with which this AI reinforces missing defense troops. - RecruitProbDefWeak: Int32 - RecruitProbDefStrong: Int32 - RecruitProbRaidDefault: Int32 - RecruitProbRaidWeak: Int32 - RecruitProbRaidStrong: Int32 - RecruitProbAttackDefault: Int32 - RecruitProbAttackWeak: Int32 - RecruitProbAttackStrong: Int32 - SortieUnitRangedMax: Int32 - SortieUnitRanged: Unit, Type of ranged units that go to the last attacked farm or building, and guard it until another is attacked. - SortieUnitMeleeMax: Int32 - SortieUnitMelee: Unit, Type of melee units to attack enemy units shooting at the AI's buildings or workers. - DefDiggingUnitMax: Int32, Amount of units that dig own moat. - DefDiggingUnit: DiggingUnit, Type of unit to dig own moat. - RecruitInterval: Int32 - RecruitIntervalWeak: Int32, The 'weak' state sets in if the AI is completely trashed. F.e. troops < 8, gold < 200, population < 15, ... - RecruitIntervalStrong: Int32, The 'strong' state sets in if f.e. the AI has troops >= 40, gold >= 200, population >= 40, ... - DefTotal: Int32 - Unknown093: Int32 - Unknown094: Int32 - Unknown095: Int32 - DefWalls: Int32 - DefUnit1: Unit - DefUnit2: Unit - DefUnit3: Unit - DefUnit4: Unit - DefUnit5: Unit - DefUnit6: Unit - DefUnit7: Unit - DefUnit8: Unit - RaidUnitsBase: Int32, Base amount of raid troops, Special case: [unknown trigger => end result multiplied by 1.25] - RaidUnitsRandom: Int32, Maximum random addition to raid troops. Special cases: [gold > 5000 => multiplied by 2][gold < 1000 => set to 0][enemy gold < 500 => divided by -2] - RaidUnit1: Unit - RaidUnit2: Unit - RaidUnit3: Unit - RaidUnit4: Unit - RaidUnit5: Unit - RaidUnit6: Unit - RaidUnit7: Unit - RaidUnit8: Unit - Unknown115: Int32 - Unknown116: Int32 - Unknown117: Int32 - Unknown118: Int32 - Unknown119: Int32 - Unknown120: Int32 - Unknown121: Int32 - Unknown122: Int32 - Unknown123: Int32 - Unknown124: Int32 - AttForceBase: Int32, The base amount of troops with which this AI attacks - AttForceRandom: Int32, The maximum random amount of additional troops in an attack (this is not the amount by which the troops increase per attack!) - Unknown127: Int32 - Unknown128: Int32 - Unknown129: Int32 - Unknown130: Int32 - Unknown131: Int32 - Unknown132: Int32 - SiegeEngine1: SiegeEngine - SiegeEngine2: SiegeEngine - SiegeEngine3: SiegeEngine - SiegeEngine4: SiegeEngine - SiegeEngine5: SiegeEngine - SiegeEngine6: SiegeEngine - SiegeEngine7: SiegeEngine - SiegeEngine8: SiegeEngine - Unknown141: Int32 - Unknown142: Int32 - AttMaxEngineers: Int32 - AttDiggingUnit: DiggingUnit, This unit is only recruited if the target enemy has moat and used preferably to dig enemy moat. - AttDiggingUnitMax: Int32 - AttUnit2: Unit - AttUnit2Max: Int32 - AttMaxAssassins: Int32 - AttMaxLaddermen: Int32 - AttMaxTunnelers: Int32 - AttUnitRangedPush: Unit, Ranged attack unit that moves towards the enemy keep and shoots - AttUnitRangedPushMax: Int32 - Unknown153: Int32 - AttUnitBackup: Unit, Attacking unit that holds position and doesn't attack until the walls are breached. - AttUnitBackupMax: Int32 - Unknown156: Int32 - AttUnit5: Unit - AttUnit5Max: Int32 - AttUnitSiegeDef: Unit, These units patrol between siege enginees in order to protect them. - AttUnitSiegeDefMax: Int32 - Unknown161: Int32 - AttUnitMain1: Unit, The units the AI recruits as main part of the strike force - AttUnitMain2: Unit, The units the AI recruits as secondary part of the strike force - Unknown164: Int32 - Unknown165: Int32 - AttMaxDefault: Int32, This does nothing - Unknown167: Int32 - TargetChoice: TargetingType - } -} -*/ - -AICharacter -{ - Index = 1 - Name = Rat - Personality - { - Unknown000 = 12 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 0 - Unknown005 = 0 - CriticalPopularity = 4000 - LowestPopularity = 5500 - HighestPopularity = 7500 - Unknown009 = 3 - Unknown010 = 10 - Unknown011 = 20 - Farm1 = AppleFarm - Farm2 = None - Farm3 = None - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 6 - PopulationPerWoodcutter = 8 - PopulationPerQuarry = 18 - PopulationPerIronmine = 0 - PopulationPerPitchrig = 0 - MaxQuarries = 1 - MaxIronmines = 1 - MaxWoodcutters = 6 - MaxPitchrigs = 1 - MaxFarms = 6 - BuildInterval = 1 - ResourceRebuildDelay = 10 - MaxFood = 100 - MinimumApples = 10 - MinimumCheese = -1 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 2 - Unknown040 = 18 - Unknown041 = 0 - Unknown042 = 0 - MaxWood = 30 - MaxStone = 40 - MaxResourceOther = 20 - MaxEquipment = 20 - MaxBeer = 20 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = Hop - SellResource03 = Iron - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = Beer - SellResource07 = Flour - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = None - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 20 - Unknown069 = 1 - DefSiegeEngineGoldThreshold = 200 - DefSiegeEngineBuildDelay = 20 - Unknown072 = 800 - Unknown073 = 80 - RecruitProbDefDefault = 10 - RecruitProbDefWeak = 50 - RecruitProbDefStrong = 0 - RecruitProbRaidDefault = 45 - RecruitProbRaidWeak = 50 - RecruitProbRaidStrong = 0 - RecruitProbAttackDefault = 45 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 100 - SortieUnitRangedMax = 5 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 6 - SortieUnitMelee = Spearman - DefDiggingUnitMax = 0 - DefDiggingUnit = Spearman - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 1 - DefTotal = 30 - Unknown093 = 1 - Unknown094 = 0 - Unknown095 = 10 - DefWalls = 20 - DefUnit1 = Spearman - DefUnit2 = Spearman - DefUnit3 = EuropArcher - DefUnit4 = EuropArcher - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 10 - RaidUnitsRandom = 15 - RaidUnit1 = Spearman - RaidUnit2 = Spearman - RaidUnit3 = EuropArcher - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 0 - Unknown124 = 3 - AttForceBase = 20 - AttForceRandom = 10 - Unknown127 = 15 - Unknown128 = 50 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 25 - Unknown132 = 20 - SiegeEngine1 = None - SiegeEngine2 = None - SiegeEngine3 = None - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 1000 - Unknown142 = 0 - AttMaxEngineers = 0 - AttDiggingUnit = Spearman - AttDiggingUnitMax = 20 - AttUnit2 = EuropArcher - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = EuropArcher - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = EuropArcher - AttUnitBackupMax = 16 - Unknown156 = 0 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = Spearman - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = Spearman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 1 - TargetChoice = Player - } -} - -AICharacter -{ - Index = 2 - Name = Snake - Personality - { - Unknown000 = 12 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 0 - Unknown005 = 0 - CriticalPopularity = 4000 - LowestPopularity = 5000 - HighestPopularity = 8000 - Unknown009 = 3 - Unknown010 = 11 - Unknown011 = 15 - Farm1 = AppleFarm - Farm2 = None - Farm3 = None - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 5 - PopulationPerWoodcutter = 5 - PopulationPerQuarry = 15 - PopulationPerIronmine = 0 - PopulationPerPitchrig = 0 - MaxQuarries = 2 - MaxIronmines = 1 - MaxWoodcutters = 10 - MaxPitchrigs = 1 - MaxFarms = 10 - BuildInterval = 2 - ResourceRebuildDelay = 12 - MaxFood = 150 - MinimumApples = 10 - MinimumCheese = 20 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 5 - TradeAmountEquipment = 6 - Unknown040 = 12 - Unknown041 = 10 - Unknown042 = 80 - MaxWood = 48 - MaxStone = 40 - MaxResourceOther = 15 - MaxEquipment = 12 - MaxBeer = 5 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = Hop - SellResource03 = Iron - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = Beer - SellResource07 = Flour - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = None - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 2 - Unknown069 = 4 - DefSiegeEngineGoldThreshold = 500 - DefSiegeEngineBuildDelay = 20 - Unknown072 = 400 - Unknown073 = 60 - RecruitProbDefDefault = 30 - RecruitProbDefWeak = 70 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 40 - RecruitProbRaidWeak = 30 - RecruitProbRaidStrong = 40 - RecruitProbAttackDefault = 30 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 40 - SortieUnitRangedMax = 2 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 8 - SortieUnitMelee = Spearman - DefDiggingUnitMax = 20 - DefDiggingUnit = Spearman - RecruitInterval = 1 - RecruitIntervalWeak = 0 - RecruitIntervalStrong = 1 - DefTotal = 80 - Unknown093 = 3 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 50 - DefUnit1 = EuropArcher - DefUnit2 = None - DefUnit3 = None - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 30 - RaidUnitsRandom = 10 - RaidUnit1 = Slave - RaidUnit2 = Slave - RaidUnit3 = Slave - RaidUnit4 = Slinger - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 1 - Unknown124 = 3 - AttForceBase = 30 - AttForceRandom = 10 - Unknown127 = 30 - Unknown128 = 50 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 25 - Unknown132 = 40 - SiegeEngine1 = Catapult - SiegeEngine2 = None - SiegeEngine3 = None - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 1000 - Unknown142 = 0 - AttMaxEngineers = 2 - AttDiggingUnit = Spearman - AttDiggingUnitMax = 20 - AttUnit2 = EuropArcher - AttUnit2Max = 20 - AttMaxAssassins = 0 - AttMaxLaddermen = 10 - AttMaxTunnelers = 0 - AttUnitRangedPush = Slinger - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = ArabArcher - AttUnitBackupMax = 50 - Unknown156 = 1 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = EuropArcher - AttUnitSiegeDefMax = 30 - Unknown161 = 0 - AttUnitMain1 = Spearman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 1 - TargetChoice = Balanced - } -} - -AICharacter -{ - Index = 3 - Name = Pig - Personality - { - Unknown000 = 12 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 0 - Unknown005 = 0 - CriticalPopularity = 5000 - LowestPopularity = 7000 - HighestPopularity = 8500 - Unknown009 = 3 - Unknown010 = 11 - Unknown011 = 20 - Farm1 = DairyFarm - Farm2 = None - Farm3 = None - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 4 - PopulationPerWoodcutter = 6 - PopulationPerQuarry = 25 - PopulationPerIronmine = 10 - PopulationPerPitchrig = 20 - MaxQuarries = 2 - MaxIronmines = 4 - MaxWoodcutters = 8 - MaxPitchrigs = 1 - MaxFarms = 12 - BuildInterval = 3 - ResourceRebuildDelay = 50 - MaxFood = 400 - MinimumApples = 10 - MinimumCheese = 10 - MinimumBread = 10 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 5 - TradeAmountEquipment = 4 - Unknown040 = 12 - Unknown041 = 100 - Unknown042 = 60 - MaxWood = 70 - MaxStone = 40 - MaxResourceOther = 10 - MaxEquipment = 10 - MaxBeer = 5 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Maces - FletcherSetting = Crossbows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = Hop - SellResource03 = None - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = Beer - SellResource07 = Flour - SellResource08 = Bows - SellResource09 = None - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = None - SellResource13 = Swords - SellResource14 = None - SellResource15 = IronArmors - Unknown068 = 10 - Unknown069 = 4 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 20 - Unknown072 = 200 - Unknown073 = 40 - RecruitProbDefDefault = 60 - RecruitProbDefWeak = 100 - RecruitProbDefStrong = 30 - RecruitProbRaidDefault = 0 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 0 - RecruitProbAttackDefault = 40 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 70 - SortieUnitRangedMax = 4 - SortieUnitRanged = Crossbowman - SortieUnitMeleeMax = 5 - SortieUnitMelee = Maceman - DefDiggingUnitMax = 0 - DefDiggingUnit = Spearman - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 4 - DefTotal = 40 - Unknown093 = 2 - Unknown094 = 1 - Unknown095 = 20 - DefWalls = 30 - DefUnit1 = Crossbowman - DefUnit2 = Crossbowman - DefUnit3 = Crossbowman - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 10 - RaidUnitsRandom = 5 - RaidUnit1 = Maceman - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 2 - Unknown124 = 3 - AttForceBase = 10 - AttForceRandom = 10 - Unknown127 = 10 - Unknown128 = 60 - Unknown129 = 100 - Unknown130 = 5 - Unknown131 = 15 - Unknown132 = 20 - SiegeEngine1 = Catapult - SiegeEngine2 = Catapult - SiegeEngine3 = Catapult - SiegeEngine4 = BatteringRam - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 30 - Unknown142 = 0 - AttMaxEngineers = 10 - AttDiggingUnit = Maceman - AttDiggingUnitMax = 10 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = Crossbowman - AttUnitBackupMax = 5 - Unknown156 = 1 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = Maceman - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = Maceman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 2 - TargetChoice = Gold - } -} - -AICharacter -{ - Index = 4 - Name = Wolf - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4500 - LowestPopularity = 6000 - HighestPopularity = 9000 - Unknown009 = 3 - Unknown010 = 11 - Unknown011 = 12 - Farm1 = DairyFarm - Farm2 = AppleFarm - Farm3 = HopFarm - Farm4 = AppleFarm - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 5 - PopulationPerWoodcutter = 4 - PopulationPerQuarry = 9 - PopulationPerIronmine = 13 - PopulationPerPitchrig = 15 - MaxQuarries = 6 - MaxIronmines = 3 - MaxWoodcutters = 12 - MaxPitchrigs = 2 - MaxFarms = 10 - BuildInterval = 3 - ResourceRebuildDelay = 20 - MaxFood = 200 - MinimumApples = 5 - MinimumCheese = 5 - MinimumBread = 5 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 4 - Unknown040 = 20 - Unknown041 = 40 - Unknown042 = 30 - MaxWood = 60 - MaxStone = 50 - MaxResourceOther = 10 - MaxEquipment = 10 - MaxBeer = 15 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Crossbows - PoleturnerSetting = Pikes - SellResource01 = None - SellResource02 = None - SellResource03 = None - SellResource04 = None - SellResource05 = Wheat - SellResource06 = None - SellResource07 = Flour - SellResource08 = None - SellResource09 = None - SellResource10 = Spears - SellResource11 = None - SellResource12 = Maces - SellResource13 = None - SellResource14 = None - SellResource15 = None - Unknown068 = 4 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 250 - DefSiegeEngineBuildDelay = 2 - Unknown072 = 100 - Unknown073 = 20 - RecruitProbDefDefault = 60 - RecruitProbDefWeak = 90 - RecruitProbDefStrong = 30 - RecruitProbRaidDefault = 30 - RecruitProbRaidWeak = 10 - RecruitProbRaidStrong = 10 - RecruitProbAttackDefault = 10 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 60 - SortieUnitRangedMax = 8 - SortieUnitRanged = ArabArcher - SortieUnitMeleeMax = 6 - SortieUnitMelee = Pikeman - DefDiggingUnitMax = 8 - DefDiggingUnit = Pikeman - RecruitInterval = 4 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 4 - DefTotal = 100 - Unknown093 = 4 - Unknown094 = 1 - Unknown095 = 3 - DefWalls = 80 - DefUnit1 = Crossbowman - DefUnit2 = Crossbowman - DefUnit3 = EuropArcher - DefUnit4 = EuropArcher - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 5 - RaidUnitsRandom = 20 - RaidUnit1 = HorseArcher - RaidUnit2 = HorseArcher - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 4 - Unknown124 = 5 - AttForceBase = 40 - AttForceRandom = 15 - Unknown127 = 30 - Unknown128 = 80 - Unknown129 = 100 - Unknown130 = 12 - Unknown131 = 5 - Unknown132 = 50 - SiegeEngine1 = Catapult - SiegeEngine2 = Trebuchet - SiegeEngine3 = FireBallista - SiegeEngine4 = Trebuchet - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 8 - Unknown142 = 0 - AttMaxEngineers = 12 - AttDiggingUnit = Pikeman - AttDiggingUnitMax = 20 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = Crossbowman - AttUnitBackupMax = 30 - Unknown156 = 3 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = Swordsman - AttUnitSiegeDefMax = 5 - Unknown161 = 1 - AttUnitMain1 = Swordsman - AttUnitMain2 = Pikeman - Unknown164 = 25 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 3 - TargetChoice = Closest - } -} - -AICharacter -{ - Index = 5 - Name = Saladin - Personality - { - Unknown000 = 10 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 0 - Unknown005 = 0 - CriticalPopularity = 4000 - LowestPopularity = 5000 - HighestPopularity = 8000 - Unknown009 = 3 - Unknown010 = 12 - Unknown011 = 20 - Farm1 = HopFarm - Farm2 = WheatFarm - Farm3 = WheatFarm - Farm4 = AppleFarm - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 3 - PopulationPerWoodcutter = 6 - PopulationPerQuarry = 10 - PopulationPerIronmine = 12 - PopulationPerPitchrig = 20 - MaxQuarries = 4 - MaxIronmines = 4 - MaxWoodcutters = 14 - MaxPitchrigs = 1 - MaxFarms = 15 - BuildInterval = 2 - ResourceRebuildDelay = 40 - MaxFood = 50 - MinimumApples = 5 - MinimumCheese = 5 - MinimumBread = 5 - MinimumWheat = 5 - MinimumHop = 5 - TradeAmountFood = 10 - TradeAmountEquipment = 0 - Unknown040 = 40 - Unknown041 = 20 - Unknown042 = 20 - MaxWood = 60 - MaxStone = 50 - MaxResourceOther = 10 - MaxEquipment = 5 - MaxBeer = 10 - MaxResourceVariance = 2 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Crossbows - PoleturnerSetting = Pikes - SellResource01 = None - SellResource02 = None - SellResource03 = None - SellResource04 = None - SellResource05 = None - SellResource06 = None - SellResource07 = None - SellResource08 = Bows - SellResource09 = Crossbows - SellResource10 = None - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = None - SellResource14 = LeatherArmors - SellResource15 = None - Unknown068 = 3 - Unknown069 = 4 - DefSiegeEngineGoldThreshold = 20 - DefSiegeEngineBuildDelay = 8 - Unknown072 = 100 - Unknown073 = 20 - RecruitProbDefDefault = 34 - RecruitProbDefWeak = 100 - RecruitProbDefStrong = 25 - RecruitProbRaidDefault = 33 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 25 - RecruitProbAttackDefault = 33 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 50 - SortieUnitRangedMax = 10 - SortieUnitRanged = ArabArcher - SortieUnitMeleeMax = 7 - SortieUnitMelee = ArabSwordsman - DefDiggingUnitMax = 4 - DefDiggingUnit = Slave - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 1 - DefTotal = 70 - Unknown093 = 2 - Unknown094 = 1 - Unknown095 = 10 - DefWalls = 50 - DefUnit1 = ArabSwordsman - DefUnit2 = ArabArcher - DefUnit3 = ArabArcher - DefUnit4 = ArabArcher - DefUnit5 = FireThrower - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 10 - RaidUnitsRandom = 5 - RaidUnit1 = HorseArcher - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 5 - Unknown124 = 3 - AttForceBase = 50 - AttForceRandom = 10 - Unknown127 = 8 - Unknown128 = 80 - Unknown129 = 100 - Unknown130 = 4 - Unknown131 = 1 - Unknown132 = 60 - SiegeEngine1 = FireBallista - SiegeEngine2 = FireBallista - SiegeEngine3 = Catapult - SiegeEngine4 = Catapult - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 2000 - Unknown142 = 0 - AttMaxEngineers = 10 - AttDiggingUnit = Slave - AttDiggingUnitMax = 20 - AttUnit2 = HorseArcher - AttUnit2Max = 20 - AttMaxAssassins = 5 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = HorseArcher - AttUnitRangedPushMax = 20 - Unknown153 = 1 - AttUnitBackup = ArabArcher - AttUnitBackupMax = 20 - Unknown156 = 3 - AttUnit5 = FireThrower - AttUnit5Max = 0 - AttUnitSiegeDef = FireThrower - AttUnitSiegeDefMax = 6 - Unknown161 = 1 - AttUnitMain1 = ArabSwordsman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 3 - TargetChoice = Gold - } -} - -AICharacter -{ - Index = 6 - Name = Caliph - Personality - { - Unknown000 = 10 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 0 - Unknown005 = 1 - CriticalPopularity = 4000 - LowestPopularity = 5000 - HighestPopularity = 9000 - Unknown009 = 3 - Unknown010 = 12 - Unknown011 = 12 - Farm1 = AppleFarm - Farm2 = HopFarm - Farm3 = AppleFarm - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 5 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 10 - PopulationPerIronmine = 12 - PopulationPerPitchrig = 7 - MaxQuarries = 2 - MaxIronmines = 1 - MaxWoodcutters = 8 - MaxPitchrigs = 10 - MaxFarms = 10 - BuildInterval = 3 - ResourceRebuildDelay = 60 - MaxFood = 100 - MinimumApples = 10 - MinimumCheese = -1 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 0 - Unknown040 = 12 - Unknown041 = 50 - Unknown042 = 50 - MaxWood = 50 - MaxStone = 50 - MaxResourceOther = 10 - MaxEquipment = 5 - MaxBeer = 15 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Crossbows - PoleturnerSetting = Pikes - SellResource01 = None - SellResource02 = None - SellResource03 = Iron - SellResource04 = None - SellResource05 = Wheat - SellResource06 = None - SellResource07 = Flour - SellResource08 = Bows - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 5 - Unknown069 = 2 - DefSiegeEngineGoldThreshold = 120 - DefSiegeEngineBuildDelay = 8 - Unknown072 = 100 - Unknown073 = 20 - RecruitProbDefDefault = 40 - RecruitProbDefWeak = 80 - RecruitProbDefStrong = 40 - RecruitProbRaidDefault = 40 - RecruitProbRaidWeak = 20 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 20 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 30 - SortieUnitRangedMax = 7 - SortieUnitRanged = ArabArcher - SortieUnitMeleeMax = 5 - SortieUnitMelee = ArabSwordsman - DefDiggingUnitMax = 4 - DefDiggingUnit = Slave - RecruitInterval = 0 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 0 - DefTotal = 60 - Unknown093 = 2 - Unknown094 = 1 - Unknown095 = 10 - DefWalls = 60 - DefUnit1 = FireThrower - DefUnit2 = ArabArcher - DefUnit3 = ArabArcher - DefUnit4 = ArabArcher - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 30 - RaidUnitsRandom = 30 - RaidUnit1 = Slave - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 358 - Unknown116 = 190 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 2 - Unknown124 = 3 - AttForceBase = 15 - AttForceRandom = 10 - Unknown127 = 70 - Unknown128 = 100 - Unknown129 = 100 - Unknown130 = 2 - Unknown131 = 10 - Unknown132 = 50 - SiegeEngine1 = FireBallista - SiegeEngine2 = FireBallista - SiegeEngine3 = FireBallista - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 7 - Unknown142 = 0 - AttMaxEngineers = 6 - AttDiggingUnit = Slave - AttDiggingUnitMax = 20 - AttUnit2 = ArabSwordsman - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = HorseArcher - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = HorseArcher - AttUnitBackupMax = 40 - Unknown156 = 2 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = ArabArcher - AttUnitSiegeDefMax = 10 - Unknown161 = 1 - AttUnitMain1 = ArabSwordsman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 5 - TargetChoice = Balanced - } -} - -AICharacter -{ - Index = 7 - Name = Sultan - Personality - { - Unknown000 = 10 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 0 - Unknown005 = 0 - CriticalPopularity = 5000 - LowestPopularity = 6000 - HighestPopularity = 9000 - Unknown009 = 1 - Unknown010 = 8 - Unknown011 = 20 - Farm1 = None - Farm2 = None - Farm3 = None - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 100 - PopulationPerWoodcutter = 2 - PopulationPerQuarry = 5 - PopulationPerIronmine = 0 - PopulationPerPitchrig = 0 - MaxQuarries = 2 - MaxIronmines = 1 - MaxWoodcutters = 15 - MaxPitchrigs = 1 - MaxFarms = 6 - BuildInterval = 5 - ResourceRebuildDelay = 80 - MaxFood = 500 - MinimumApples = 20 - MinimumCheese = 20 - MinimumBread = 20 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 0 - Unknown040 = 30 - Unknown041 = 0 - Unknown042 = 0 - MaxWood = 30 - MaxStone = 20 - MaxResourceOther = 10 - MaxEquipment = 5 - MaxBeer = 20 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = Hop - SellResource03 = Iron - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = Beer - SellResource07 = Flour - SellResource08 = Bows - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 10 - Unknown069 = 2 - DefSiegeEngineGoldThreshold = 200 - DefSiegeEngineBuildDelay = 20 - Unknown072 = 800 - Unknown073 = 80 - RecruitProbDefDefault = 50 - RecruitProbDefWeak = 70 - RecruitProbDefStrong = 30 - RecruitProbRaidDefault = 20 - RecruitProbRaidWeak = 10 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 30 - RecruitProbAttackWeak = 20 - RecruitProbAttackStrong = 40 - SortieUnitRangedMax = 0 - SortieUnitRanged = Slinger - SortieUnitMeleeMax = 3 - SortieUnitMelee = ArabSwordsman - DefDiggingUnitMax = 2 - DefDiggingUnit = Slave - RecruitInterval = 8 - RecruitIntervalWeak = 8 - RecruitIntervalStrong = 4 - DefTotal = 50 - Unknown093 = 1 - Unknown094 = 0 - Unknown095 = 10 - DefWalls = 40 - DefUnit1 = Slinger - DefUnit2 = Slinger - DefUnit3 = ArabSwordsman - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 20 - RaidUnitsRandom = 10 - RaidUnit1 = Slinger - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 0 - Unknown124 = 3 - AttForceBase = 10 - AttForceRandom = 20 - Unknown127 = 5 - Unknown128 = 30 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 40 - Unknown132 = 20 - SiegeEngine1 = None - SiegeEngine2 = None - SiegeEngine3 = None - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 0 - AttDiggingUnit = None - AttDiggingUnitMax = 0 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = ArabArcher - AttUnitBackupMax = 120 - Unknown156 = 1 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = ArabSwordsman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 1 - TargetChoice = Closest - } -} - -AICharacter -{ - Index = 8 - Name = Richard - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 0 - CriticalPopularity = 4000 - LowestPopularity = 5000 - HighestPopularity = 8000 - Unknown009 = 3 - Unknown010 = 10 - Unknown011 = 12 - Farm1 = DairyFarm - Farm2 = AppleFarm - Farm3 = AppleFarm - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 4 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 10 - PopulationPerIronmine = 10 - PopulationPerPitchrig = 0 - MaxQuarries = 3 - MaxIronmines = 4 - MaxWoodcutters = 10 - MaxPitchrigs = 1 - MaxFarms = 15 - BuildInterval = 4 - ResourceRebuildDelay = 20 - MaxFood = 200 - MinimumApples = 5 - MinimumCheese = 5 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 5 - TradeAmountEquipment = 2 - Unknown040 = 22 - Unknown041 = 10 - Unknown042 = 40 - MaxWood = 50 - MaxStone = 60 - MaxResourceOther = 10 - MaxEquipment = 10 - MaxBeer = 10 - MaxResourceVariance = 4 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Pikes - SellResource01 = None - SellResource02 = Hop - SellResource03 = None - SellResource04 = None - SellResource05 = Wheat - SellResource06 = Beer - SellResource07 = Flour - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = None - SellResource12 = Maces - SellResource13 = None - SellResource14 = LeatherArmors - SellResource15 = None - Unknown068 = 8 - Unknown069 = 4 - DefSiegeEngineGoldThreshold = 200 - DefSiegeEngineBuildDelay = 2 - Unknown072 = 100 - Unknown073 = 20 - RecruitProbDefDefault = 30 - RecruitProbDefWeak = 90 - RecruitProbDefStrong = 10 - RecruitProbRaidDefault = 0 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 0 - RecruitProbAttackDefault = 70 - RecruitProbAttackWeak = 10 - RecruitProbAttackStrong = 90 - SortieUnitRangedMax = 6 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 6 - SortieUnitMelee = Pikeman - DefDiggingUnitMax = 0 - DefDiggingUnit = Pikeman - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 1 - DefTotal = 40 - Unknown093 = 2 - Unknown094 = 1 - Unknown095 = 5 - DefWalls = 20 - DefUnit1 = EuropArcher - DefUnit2 = EuropArcher - DefUnit3 = Pikeman - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 10 - RaidUnitsRandom = 4 - RaidUnit1 = EuropArcher - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 2 - Unknown124 = 5 - AttForceBase = 20 - AttForceRandom = 5 - Unknown127 = 10 - Unknown128 = 10 - Unknown129 = 100 - Unknown130 = 20 - Unknown131 = 2 - Unknown132 = 10 - SiegeEngine1 = Catapult - SiegeEngine2 = Catapult - SiegeEngine3 = Catapult - SiegeEngine4 = BatteringRam - SiegeEngine5 = Trebuchet - SiegeEngine6 = Trebuchet - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 16 - AttDiggingUnit = Pikeman - AttDiggingUnitMax = 6 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 3 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = EuropArcher - AttUnitBackupMax = 20 - Unknown156 = 2 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = Swordsman - AttUnitSiegeDefMax = 4 - Unknown161 = 2 - AttUnitMain1 = Swordsman - AttUnitMain2 = Pikeman - Unknown164 = 25 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 3 - TargetChoice = Closest - } -} - -AICharacter -{ - Index = 9 - Name = Frederick - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4000 - LowestPopularity = 5500 - HighestPopularity = 9000 - Unknown009 = 3 - Unknown010 = 10 - Unknown011 = 12 - Farm1 = DairyFarm - Farm2 = AppleFarm - Farm3 = HopFarm - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 4 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 12 - PopulationPerIronmine = 10 - PopulationPerPitchrig = 0 - MaxQuarries = 4 - MaxIronmines = 5 - MaxWoodcutters = 12 - MaxPitchrigs = 1 - MaxFarms = 12 - BuildInterval = 4 - ResourceRebuildDelay = 30 - MaxFood = 200 - MinimumApples = 5 - MinimumCheese = 5 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 2 - Unknown040 = 22 - Unknown041 = 10 - Unknown042 = 40 - MaxWood = 60 - MaxStone = 60 - MaxResourceOther = 15 - MaxEquipment = 20 - MaxBeer = 10 - MaxResourceVariance = 4 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Both - PoleturnerSetting = Pikes - SellResource01 = None - SellResource02 = None - SellResource03 = None - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = None - SellResource07 = Flour - SellResource08 = None - SellResource09 = None - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = None - SellResource14 = None - SellResource15 = None - Unknown068 = 8 - Unknown069 = 2 - DefSiegeEngineGoldThreshold = 200 - DefSiegeEngineBuildDelay = 2 - Unknown072 = 100 - Unknown073 = 20 - RecruitProbDefDefault = 50 - RecruitProbDefWeak = 100 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 20 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 30 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 50 - SortieUnitRangedMax = 12 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 4 - SortieUnitMelee = Swordsman - DefDiggingUnitMax = 10 - DefDiggingUnit = EuropArcher - RecruitInterval = 4 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 4 - DefTotal = 80 - Unknown093 = 2 - Unknown094 = 1 - Unknown095 = 10 - DefWalls = 50 - DefUnit1 = EuropArcher - DefUnit2 = EuropArcher - DefUnit3 = Crossbowman - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 4 - RaidUnitsRandom = 0 - RaidUnit1 = Knight - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 2 - Unknown124 = 6 - AttForceBase = 30 - AttForceRandom = 4 - Unknown127 = 20 - Unknown128 = 50 - Unknown129 = 100 - Unknown130 = 20 - Unknown131 = 5 - Unknown132 = 50 - SiegeEngine1 = Trebuchet - SiegeEngine2 = Trebuchet - SiegeEngine3 = Trebuchet - SiegeEngine4 = Trebuchet - SiegeEngine5 = Trebuchet - SiegeEngine6 = Trebuchet - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 18 - AttDiggingUnit = EuropArcher - AttDiggingUnitMax = 20 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = Crossbowman - AttUnitRangedPushMax = 20 - Unknown153 = 1 - AttUnitBackup = EuropArcher - AttUnitBackupMax = 30 - Unknown156 = 2 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = Crossbowman - AttUnitSiegeDefMax = 10 - Unknown161 = 1 - AttUnitMain1 = Swordsman - AttUnitMain2 = Swordsman - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 4 - TargetChoice = Gold - } -} - -AICharacter -{ - Index = 10 - Name = Philipp - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4000 - LowestPopularity = 5000 - HighestPopularity = 8000 - Unknown009 = 2 - Unknown010 = 10 - Unknown011 = 10 - Farm1 = AppleFarm - Farm2 = AppleFarm - Farm3 = None - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 5 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 0 - PopulationPerIronmine = 7 - PopulationPerPitchrig = 0 - MaxQuarries = 1 - MaxIronmines = 3 - MaxWoodcutters = 10 - MaxPitchrigs = 1 - MaxFarms = 8 - BuildInterval = 4 - ResourceRebuildDelay = 60 - MaxFood = 100 - MinimumApples = 10 - MinimumCheese = 10 - MinimumBread = 10 - MinimumWheat = -1 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 2 - Unknown040 = 12 - Unknown041 = 10 - Unknown042 = 50 - MaxWood = 60 - MaxStone = 60 - MaxResourceOther = 15 - MaxEquipment = 6 - MaxBeer = 10 - MaxResourceVariance = 4 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = Hop - SellResource03 = None - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = Beer - SellResource07 = Flour - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = None - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = None - SellResource14 = LeatherArmors - SellResource15 = None - Unknown068 = 2 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 20 - RecruitProbDefDefault = 40 - RecruitProbDefWeak = 70 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 40 - RecruitProbRaidWeak = 20 - RecruitProbRaidStrong = 20 - RecruitProbAttackDefault = 20 - RecruitProbAttackWeak = 10 - RecruitProbAttackStrong = 60 - SortieUnitRangedMax = 2 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 20 - SortieUnitMelee = Spearman - DefDiggingUnitMax = 4 - DefDiggingUnit = Spearman - RecruitInterval = 4 - RecruitIntervalWeak = 4 - RecruitIntervalStrong = 4 - DefTotal = 30 - Unknown093 = 4 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 20 - DefUnit1 = Knight - DefUnit2 = EuropArcher - DefUnit3 = EuropArcher - DefUnit4 = EuropArcher - DefUnit5 = EuropArcher - DefUnit6 = EuropArcher - DefUnit7 = EuropArcher - DefUnit8 = EuropArcher - RaidUnitsBase = 4 - RaidUnitsRandom = 4 - RaidUnit1 = Knight - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 1 - Unknown124 = 4 - AttForceBase = 10 - AttForceRandom = 20 - Unknown127 = 40 - Unknown128 = 40 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 5 - Unknown132 = 70 - SiegeEngine1 = None - SiegeEngine2 = None - SiegeEngine3 = None - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 0 - AttDiggingUnit = Spearman - AttDiggingUnitMax = 60 - AttUnit2 = None - AttUnit2Max = 24 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = None - AttUnitBackupMax = 0 - Unknown156 = 0 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = Spearman - AttUnitMain2 = Spearman - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 2 - TargetChoice = Balanced - } -} - -AICharacter -{ - Index = 11 - Name = Wazir - Personality - { - Unknown000 = 10 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4500 - LowestPopularity = 5000 - HighestPopularity = 8000 - Unknown009 = 2 - Unknown010 = 12 - Unknown011 = 10 - Farm1 = WheatFarm - Farm2 = None - Farm3 = None - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 5 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 6 - PopulationPerIronmine = 12 - PopulationPerPitchrig = 6 - MaxQuarries = 3 - MaxIronmines = 1 - MaxWoodcutters = 10 - MaxPitchrigs = 4 - MaxFarms = 8 - BuildInterval = 3 - ResourceRebuildDelay = 50 - MaxFood = 100 - MinimumApples = -1 - MinimumCheese = -1 - MinimumBread = 10 - MinimumWheat = 5 - MinimumHop = -1 - TradeAmountFood = 10 - TradeAmountEquipment = 0 - Unknown040 = 22 - Unknown041 = 30 - Unknown042 = 50 - MaxWood = 60 - MaxStone = 40 - MaxResourceOther = 10 - MaxEquipment = 4 - MaxBeer = 10 - MaxResourceVariance = 4 - Unknown049 = 100 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = Hop - SellResource03 = Iron - SellResource04 = None - SellResource05 = None - SellResource06 = Beer - SellResource07 = None - SellResource08 = Bows - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 2 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 20 - RecruitProbDefDefault = 30 - RecruitProbDefWeak = 70 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 20 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 20 - RecruitProbAttackDefault = 50 - RecruitProbAttackWeak = 30 - RecruitProbAttackStrong = 60 - SortieUnitRangedMax = 6 - SortieUnitRanged = HorseArcher - SortieUnitMeleeMax = 10 - SortieUnitMelee = ArabSwordsman - DefDiggingUnitMax = 4 - DefDiggingUnit = Slave - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 1 - DefTotal = 40 - Unknown093 = 1 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 40 - DefUnit1 = ArabArcher - DefUnit2 = FireThrower - DefUnit3 = None - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 30 - RaidUnitsRandom = 10 - RaidUnit1 = HorseArcher - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 358 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 4 - Unknown124 = 4 - AttForceBase = 40 - AttForceRandom = 5 - Unknown127 = 30 - Unknown128 = 80 - Unknown129 = 100 - Unknown130 = 4 - Unknown131 = 5 - Unknown132 = 90 - SiegeEngine1 = Trebuchet - SiegeEngine2 = FireBallista - SiegeEngine3 = FireBallista - SiegeEngine4 = FireBallista - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 9 - AttDiggingUnit = Slave - AttDiggingUnitMax = 15 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = HorseArcher - AttUnitBackupMax = 80 - Unknown156 = 1 - AttUnit5 = FireThrower - AttUnit5Max = 10 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = ArabSwordsman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 2 - TargetChoice = Balanced - } -} - -AICharacter -{ - Index = 12 - Name = Emir - Personality - { - Unknown000 = 10 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4500 - LowestPopularity = 5000 - HighestPopularity = 9000 - Unknown009 = 2 - Unknown010 = 12 - Unknown011 = 10 - Farm1 = WheatFarm - Farm2 = AppleFarm - Farm3 = WheatFarm - Farm4 = HopFarm - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 4 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 6 - PopulationPerIronmine = 10 - PopulationPerPitchrig = 0 - MaxQuarries = 4 - MaxIronmines = 3 - MaxWoodcutters = 10 - MaxPitchrigs = 1 - MaxFarms = 16 - BuildInterval = 2 - ResourceRebuildDelay = 40 - MaxFood = 80 - MinimumApples = 10 - MinimumCheese = -1 - MinimumBread = -1 - MinimumWheat = 2 - MinimumHop = 2 - TradeAmountFood = 10 - TradeAmountEquipment = 2 - Unknown040 = 12 - Unknown041 = 10 - Unknown042 = 40 - MaxWood = 60 - MaxStone = 60 - MaxResourceOther = 10 - MaxEquipment = 4 - MaxBeer = 10 - MaxResourceVariance = 4 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = None - SellResource03 = None - SellResource04 = None - SellResource05 = None - SellResource06 = None - SellResource07 = None - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 2 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 20 - RecruitProbDefDefault = 40 - RecruitProbDefWeak = 80 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 20 - RecruitProbRaidWeak = 10 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 40 - RecruitProbAttackWeak = 10 - RecruitProbAttackStrong = 50 - SortieUnitRangedMax = 4 - SortieUnitRanged = ArabArcher - SortieUnitMeleeMax = 20 - SortieUnitMelee = ArabSwordsman - DefDiggingUnitMax = 4 - DefDiggingUnit = EuropArcher - RecruitInterval = 0 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 0 - DefTotal = 50 - Unknown093 = 1 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 50 - DefUnit1 = EuropArcher - DefUnit2 = ArabArcher - DefUnit3 = None - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 30 - RaidUnitsRandom = 10 - RaidUnit1 = ArabSwordsman - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 190 - Unknown117 = 358 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 3 - Unknown124 = 4 - AttForceBase = 30 - AttForceRandom = 10 - Unknown127 = 20 - Unknown128 = 80 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 5 - Unknown132 = 80 - SiegeEngine1 = Catapult - SiegeEngine2 = Catapult - SiegeEngine3 = TowerBallista - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 6 - AttDiggingUnit = EuropArcher - AttDiggingUnitMax = 15 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = HorseArcher - AttUnitBackupMax = 80 - Unknown156 = 1 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = ArabSwordsman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 2 - TargetChoice = Gold - } -} - -AICharacter -{ - Index = 13 - Name = Nizar - Personality - { - Unknown000 = 10 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4500 - LowestPopularity = 5000 - HighestPopularity = 9000 - Unknown009 = 2 - Unknown010 = 12 - Unknown011 = 10 - Farm1 = WheatFarm - Farm2 = WheatFarm - Farm3 = WheatFarm - Farm4 = HopFarm - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 3 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 20 - PopulationPerIronmine = 10 - PopulationPerPitchrig = 15 - MaxQuarries = 1 - MaxIronmines = 2 - MaxWoodcutters = 12 - MaxPitchrigs = 1 - MaxFarms = 16 - BuildInterval = 1 - ResourceRebuildDelay = 20 - MaxFood = 100 - MinimumApples = -1 - MinimumCheese = -1 - MinimumBread = 10 - MinimumWheat = 5 - MinimumHop = 5 - TradeAmountFood = 10 - TradeAmountEquipment = 0 - Unknown040 = 12 - Unknown041 = 30 - Unknown042 = 30 - MaxWood = 50 - MaxStone = 40 - MaxResourceOther = 10 - MaxEquipment = 4 - MaxBeer = 10 - MaxResourceVariance = 4 - Unknown049 = 100 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = None - SellResource03 = Iron - SellResource04 = None - SellResource05 = None - SellResource06 = None - SellResource07 = None - SellResource08 = Bows - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 2 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 20 - RecruitProbDefDefault = 50 - RecruitProbDefWeak = 80 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 20 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 30 - RecruitProbAttackWeak = 20 - RecruitProbAttackStrong = 50 - SortieUnitRangedMax = 5 - SortieUnitRanged = ArabArcher - SortieUnitMeleeMax = 15 - SortieUnitMelee = ArabArcher - DefDiggingUnitMax = 60 - DefDiggingUnit = Slave - RecruitInterval = 4 - RecruitIntervalWeak = 8 - RecruitIntervalStrong = 1 - DefTotal = 80 - Unknown093 = 1 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 80 - DefUnit1 = ArabArcher - DefUnit2 = None - DefUnit3 = None - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 5 - RaidUnitsRandom = 5 - RaidUnit1 = Assassin - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 0 - Unknown124 = 4 - AttForceBase = 40 - AttForceRandom = 0 - Unknown127 = 10 - Unknown128 = 50 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 5 - Unknown132 = 50 - SiegeEngine1 = Catapult - SiegeEngine2 = None - SiegeEngine3 = None - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 0 - AttDiggingUnit = Slave - AttDiggingUnitMax = 20 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 40 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = HorseArcher - AttUnitBackupMax = 0 - Unknown156 = 0 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = Assassin - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 4 - TargetChoice = Closest - } -} - -AICharacter -{ - Index = 14 - Name = Sheriff - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4000 - LowestPopularity = 6000 - HighestPopularity = 9000 - Unknown009 = 3 - Unknown010 = 11 - Unknown011 = 10 - Farm1 = AppleFarm - Farm2 = HopFarm - Farm3 = DairyFarm - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 4 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 10 - PopulationPerIronmine = 12 - PopulationPerPitchrig = 15 - MaxQuarries = 3 - MaxIronmines = 6 - MaxWoodcutters = 10 - MaxPitchrigs = 4 - MaxFarms = 10 - BuildInterval = 3 - ResourceRebuildDelay = 8 - MaxFood = 300 - MinimumApples = 20 - MinimumCheese = 20 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = 2 - TradeAmountFood = 10 - TradeAmountEquipment = 2 - Unknown040 = 40 - Unknown041 = 40 - Unknown042 = 40 - MaxWood = 50 - MaxStone = 50 - MaxResourceOther = 10 - MaxEquipment = 10 - MaxBeer = 10 - MaxResourceVariance = 5 - Unknown049 = 200 - BlacksmithSetting = Maces - FletcherSetting = Crossbows - PoleturnerSetting = Pikes - SellResource01 = None - SellResource02 = None - SellResource03 = None - SellResource04 = None - SellResource05 = Wheat - SellResource06 = None - SellResource07 = Flour - SellResource08 = Bows - SellResource09 = None - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = None - SellResource13 = Swords - SellResource14 = None - SellResource15 = IronArmors - Unknown068 = 8 - Unknown069 = 2 - DefSiegeEngineGoldThreshold = 200 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 30 - RecruitProbDefDefault = 50 - RecruitProbDefWeak = 100 - RecruitProbDefStrong = 30 - RecruitProbRaidDefault = 30 - RecruitProbRaidWeak = 0 - RecruitProbRaidStrong = 50 - RecruitProbAttackDefault = 20 - RecruitProbAttackWeak = 0 - RecruitProbAttackStrong = 20 - SortieUnitRangedMax = 10 - SortieUnitRanged = Crossbowman - SortieUnitMeleeMax = 10 - SortieUnitMelee = Maceman - DefDiggingUnitMax = 4 - DefDiggingUnit = Maceman - RecruitInterval = 4 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 4 - DefTotal = 50 - Unknown093 = 1 - Unknown094 = 1 - Unknown095 = 5 - DefWalls = 40 - DefUnit1 = Crossbowman - DefUnit2 = Crossbowman - DefUnit3 = Crossbowman - DefUnit4 = FireThrower - DefUnit5 = Assassin - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 10 - RaidUnitsRandom = 4 - RaidUnit1 = Maceman - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 358 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 5 - Unknown124 = 4 - AttForceBase = 50 - AttForceRandom = 20 - Unknown127 = 50 - Unknown128 = 80 - Unknown129 = 100 - Unknown130 = 5 - Unknown131 = 8 - Unknown132 = 50 - SiegeEngine1 = Catapult - SiegeEngine2 = Catapult - SiegeEngine3 = FireBallista - SiegeEngine4 = FireBallista - SiegeEngine5 = FireBallista - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 6 - Unknown142 = 0 - AttMaxEngineers = 10 - AttDiggingUnit = Slave - AttDiggingUnitMax = 80 - AttUnit2 = Maceman - AttUnit2Max = 10 - AttMaxAssassins = 10 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = FireThrower - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = Crossbowman - AttUnitBackupMax = 50 - Unknown156 = 1 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = Maceman - AttUnitSiegeDefMax = 6 - Unknown161 = 1 - AttUnitMain1 = Maceman - AttUnitMain2 = Maceman - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 3 - TargetChoice = Closest - } -} - -AICharacter -{ - Index = 15 - Name = Marshal - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4000 - LowestPopularity = 5000 - HighestPopularity = 8000 - Unknown009 = 2 - Unknown010 = 10 - Unknown011 = 10 - Farm1 = DairyFarm - Farm2 = HopFarm - Farm3 = DairyFarm - Farm4 = DairyFarm - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 5 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 7 - PopulationPerIronmine = 7 - PopulationPerPitchrig = 0 - MaxQuarries = 1 - MaxIronmines = 3 - MaxWoodcutters = 8 - MaxPitchrigs = 1 - MaxFarms = 9 - BuildInterval = 3 - ResourceRebuildDelay = 40 - MaxFood = 100 - MinimumApples = 10 - MinimumCheese = 10 - MinimumBread = -1 - MinimumWheat = -1 - MinimumHop = 5 - TradeAmountFood = 10 - TradeAmountEquipment = 2 - Unknown040 = 12 - Unknown041 = 0 - Unknown042 = 80 - MaxWood = 60 - MaxStone = 50 - MaxResourceOther = 12 - MaxEquipment = 10 - MaxBeer = 6 - MaxResourceVariance = 4 - Unknown049 = 200 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = None - SellResource03 = None - SellResource04 = Pitch - SellResource05 = Wheat - SellResource06 = None - SellResource07 = Flour - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = None - SellResource14 = LeatherArmors - SellResource15 = None - Unknown068 = 2 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 20 - RecruitProbDefDefault = 30 - RecruitProbDefWeak = 50 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 40 - RecruitProbRaidWeak = 40 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 30 - RecruitProbAttackWeak = 10 - RecruitProbAttackStrong = 50 - SortieUnitRangedMax = 4 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 4 - SortieUnitMelee = Knight - DefDiggingUnitMax = 4 - DefDiggingUnit = EuropArcher - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 4 - DefTotal = 40 - Unknown093 = 1 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 30 - DefUnit1 = EuropArcher - DefUnit2 = None - DefUnit3 = None - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 16 - RaidUnitsRandom = 4 - RaidUnit1 = Knight - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 1 - Unknown124 = 4 - AttForceBase = 10 - AttForceRandom = 20 - Unknown127 = 10 - Unknown128 = 50 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 5 - Unknown132 = 70 - SiegeEngine1 = Trebuchet - SiegeEngine2 = Trebuchet - SiegeEngine3 = None - SiegeEngine4 = None - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 6 - AttDiggingUnit = EuropArcher - AttDiggingUnitMax = 20 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = EuropArcher - AttUnitBackupMax = 30 - Unknown156 = 3 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = Swordsman - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 2 - TargetChoice = Balanced - } -} - -AICharacter -{ - Index = 16 - Name = Abbot - Personality - { - Unknown000 = 13 - Unknown001 = 0 - Unknown002 = 0 - Unknown003 = 0 - Unknown004 = 1 - Unknown005 = 1 - CriticalPopularity = 4500 - LowestPopularity = 5000 - HighestPopularity = 9000 - Unknown009 = 2 - Unknown010 = 12 - Unknown011 = 10 - Farm1 = HopFarm - Farm2 = WheatFarm - Farm3 = WheatFarm - Farm4 = None - Farm5 = None - Farm6 = None - Farm7 = None - Farm8 = None - PopulationPerFarm = 4 - PopulationPerWoodcutter = 7 - PopulationPerQuarry = 6 - PopulationPerIronmine = 10 - PopulationPerPitchrig = 0 - MaxQuarries = 4 - MaxIronmines = 2 - MaxWoodcutters = 10 - MaxPitchrigs = 0 - MaxFarms = 12 - BuildInterval = 2 - ResourceRebuildDelay = 40 - MaxFood = 100 - MinimumApples = 10 - MinimumCheese = -1 - MinimumBread = -1 - MinimumWheat = 2 - MinimumHop = 2 - TradeAmountFood = 5 - TradeAmountEquipment = 2 - Unknown040 = 12 - Unknown041 = 10 - Unknown042 = 40 - MaxWood = 60 - MaxStone = 40 - MaxResourceOther = 10 - MaxEquipment = 4 - MaxBeer = 5 - MaxResourceVariance = 4 - Unknown049 = 50 - BlacksmithSetting = Swords - FletcherSetting = Bows - PoleturnerSetting = Spears - SellResource01 = None - SellResource02 = None - SellResource03 = Iron - SellResource04 = None - SellResource05 = None - SellResource06 = None - SellResource07 = None - SellResource08 = None - SellResource09 = Crossbows - SellResource10 = Spears - SellResource11 = Pikes - SellResource12 = Maces - SellResource13 = Swords - SellResource14 = LeatherArmors - SellResource15 = IronArmors - Unknown068 = 2 - Unknown069 = 3 - DefSiegeEngineGoldThreshold = 100 - DefSiegeEngineBuildDelay = 4 - Unknown072 = 200 - Unknown073 = 20 - RecruitProbDefDefault = 40 - RecruitProbDefWeak = 80 - RecruitProbDefStrong = 20 - RecruitProbRaidDefault = 20 - RecruitProbRaidWeak = 10 - RecruitProbRaidStrong = 30 - RecruitProbAttackDefault = 40 - RecruitProbAttackWeak = 10 - RecruitProbAttackStrong = 50 - SortieUnitRangedMax = 4 - SortieUnitRanged = EuropArcher - SortieUnitMeleeMax = 20 - SortieUnitMelee = Monk - DefDiggingUnitMax = 4 - DefDiggingUnit = EuropArcher - RecruitInterval = 1 - RecruitIntervalWeak = 1 - RecruitIntervalStrong = 1 - DefTotal = 30 - Unknown093 = 1 - Unknown094 = 1 - Unknown095 = 2 - DefWalls = 30 - DefUnit1 = EuropArcher - DefUnit2 = None - DefUnit3 = None - DefUnit4 = None - DefUnit5 = None - DefUnit6 = None - DefUnit7 = None - DefUnit8 = None - RaidUnitsBase = 30 - RaidUnitsRandom = 10 - RaidUnit1 = Monk - RaidUnit2 = None - RaidUnit3 = None - RaidUnit4 = None - RaidUnit5 = None - RaidUnit6 = None - RaidUnit7 = None - RaidUnit8 = None - Unknown115 = 190 - Unknown116 = 0 - Unknown117 = 0 - Unknown118 = 0 - Unknown119 = 0 - Unknown120 = 0 - Unknown121 = 0 - Unknown122 = 0 - Unknown123 = 5 - Unknown124 = 4 - AttForceBase = 50 - AttForceRandom = 10 - Unknown127 = 40 - Unknown128 = 80 - Unknown129 = 100 - Unknown130 = 0 - Unknown131 = 5 - Unknown132 = 80 - SiegeEngine1 = Catapult - SiegeEngine2 = Catapult - SiegeEngine3 = Catapult - SiegeEngine4 = Catapult - SiegeEngine5 = None - SiegeEngine6 = None - SiegeEngine7 = None - SiegeEngine8 = None - Unknown141 = 10000 - Unknown142 = 0 - AttMaxEngineers = 8 - AttDiggingUnit = EuropArcher - AttDiggingUnitMax = 10 - AttUnit2 = None - AttUnit2Max = 0 - AttMaxAssassins = 0 - AttMaxLaddermen = 0 - AttMaxTunnelers = 0 - AttUnitRangedPush = None - AttUnitRangedPushMax = 0 - Unknown153 = 0 - AttUnitBackup = EuropArcher - AttUnitBackupMax = 40 - Unknown156 = 1 - AttUnit5 = None - AttUnit5Max = 0 - AttUnitSiegeDef = None - AttUnitSiegeDefMax = 0 - Unknown161 = 0 - AttUnitMain1 = Monk - AttUnitMain2 = None - Unknown164 = 0 - Unknown165 = 0 - AttMaxDefault = 200 - Unknown167 = 2 - TargetChoice = Balanced - } -} - diff --git a/UnofficialCrusaderPatchGUI/Graphics/background.jpg b/UnofficialCrusaderPatchGUI/Graphics/background.jpg deleted file mode 100644 index d835ec215b9130653108ba7c99aad03205b4cb0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30820 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 W$;FFvrp$oEhipx8zk>hs{{I0;Q3hH7 diff --git a/UnofficialCrusaderPatchGUI/Graphics/frame.jpg b/UnofficialCrusaderPatchGUI/Graphics/frame.jpg deleted file mode 100644 index 6dccf4b97b22149136404b8d9471653c5f4db5e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59041 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 diff --git a/UnofficialCrusaderPatchGUI/Graphics/icon6.ico b/UnofficialCrusaderPatchGUI/Graphics/icon6.ico deleted file mode 100644 index a2fb379ea69403e9f76b54d04efad6185c5b2679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2310 zcmeH}zfZzY5XZk2mEx~z)oQgC;^cq9VnUeVUtuGmVP`NQj3g#P;^1Ih7}WG%fQ_ID zQAZLmf;yN!-+KiW+E*7$9JuDLNk8}Q?p=F%1tfaK4neJqo(yOJj;O|{9#dt{gT;cT zz-b-rzV6eMEvwn$cMYW*zuf9gvxbE0T34LI+t_ zRn;^_4jfZ1aBwl>z79joxsSsLyWHa->&p_AMOGh|@gnK!2|gBq1)tN&YpN4H)dN@xLsROuknt04poB>@sT2#EA9y(1_^Py}fTs1!wt z(xiz}RiqawDk5)!a)Um4ujl*zy=%Rbb&@$Vdtb9>&pwkm`_j`SBBlob$N&J*#891F zB4Dck006*WxF&!z(iwsEc0s^gT%3?_7#4{}fjm&QKr{@4!~oGQ2$U@v?(U30VS)B; zFqg|nI7V*|kc^CM4-kj(PdSULDWOqzNPBm;Jt&MQ2nL5EoDjHMv>OQS?&gL^@^W?} z0_bUy;tc>0{#5?~yKm>u#=ReQ-1qOWNN1Qm0s~S+Vx3_w7|`F9PyRvK&It{}BHaE( zi{%emE^cUhHv|S_1N%44KaGcTpZmXSG5={iw2Qk7UiDw>{F5FA3&Xnqe^`k{qn-ZW zt;B1&z)%RM->g*ktF+A~0s!zA-X{i^-JNYvFr*U(gx#+KT~PKBdOGJR$(hMpRvXZ=LAi4}GEn*Tkh~ zQu#ErK8PwQKtZXUgvb4Ic8;9XW~cYpTUY2MRr#etva!0l>bkYOM4f$Ek3CLy&hAU< zOZU=fE0`X8ZE$1LZmwb1mEf;lgK=^@Z}}6l?KUc|kehzdiC6%a#uW`RMl>{)L5+Mo z8h9#4@}Ps|g5y@1DpvM-?3tFNW3zLUh3gftHLoi7ZuxdUv0HKCMr=E-V-DorgW*sr z`6*8;hv~U*(5afv#WQU?d@q;bF_f-pic}(1apfG*tFxh-uALoj`Lq7v(-!^P6Bb|d zJ_hF>@92SAkg?lbX75~5wvdu;eFIIK_y)CdO;}%|5;8fJHGY1$rq#rh3Y;JJ{pqs} zIr*jYOkt;b+bWk}DetX#!oICUpU2r%CPOnKp%f0kui!6OE^W-v#&-X!Nvw`Ci%iTs zTpCE@x*%B*huAnR(R6 zTK*Vs|6AOWBwyiO^+83tE(7=20n}A=lc%Z& zvW4_Q=tAoWLC|X@-BXu>s?MR0W#scnT<49)+U{;sl^pMPO&Z{=l={Rbo#oBKzl~0P zNIv$UPf>y?(ukAXtHl)*yoEz=8Ux-6O+ zQYDKu3!oVLxy@8;TL<6t+*&m)W7o&rjk6Hap%h=gar@2`Gsitkfi48ymn<3oM#iXt z4Xdu3>B$B{gXu)$nmp~PxXT}!+g&y-;fn z=@5sbJ2215XRx|6JHtwz*3B|J6vk{>{zvVrY%V@S?3nfe7-`O3`i|m}XXVNylT!*; zU(R^~$<6*cp1NFK_D;Mp=xKSA3HWu-hZH8uCILbm$y{wM28D<@f> z9jlkm%g`e6k?1o@hYh)Iz{WkTwkW=Oo>C57lTZwvR91i)3vYOyL?N4K(u+>a1)1@_ zPPrQMA%%aNX_BPwZ2NRTR=Q4_e$ESZ0|sWslXZ0=I~WA<5J45v#JF8DRwiL|^W@ze z(-^{2Twtw@XAE6b+Ft8zrQF}i0ETuSH_Tc#ZV_)Yg~{*gX?PsZ8)fPJkSHxYT_eRL zI!EENViR1SD)!n=tsRqiT)DoMLcDS^xamsLIq10>56_+!;XBF%x5|!OX4N};^l0az zB$GsCwXdao{W;mT3(RntG5bf6xzQW4{`UkfBqb8fsW)7GX}r~@GUw_+VQHr^5A?ihhFKGTOvaikNzrPFpQpxm5g&e^>dHX&cq}MdLA~99PP);|ynP$OU0OVpDsClOWqPM& zQR>m_#Ku$SYnpcW2)5+3$wai<7yvN)& z&x`BuY3^Q``W)7{eGcWUUD!B2cB~w7ajf0a@Of7NdDt!i{$#erz?Ad?_t)(}0l=Nq z@F&PW9r$pa01N_)MWXC6_*30`vkRCh3F<4$<Dl9UcwIMzX1KX^z*{n=RfQw7B9EGu(cROg*8t;WctVhJfvo z+LyBTaxuQiabrcB$5W-U`v4i7BjFv&a_2RyoQL#aA?L#ZQq=vg(E$%%Zzl)98)T@wH zwlP_65fZsY`S7H8KA@pTm5qv zZ(r`O7{=|pRqF_D+Po2*cY_9GYY3PgaUg~$$t*3!&p2L;b#f?Np zW%PYchYxRdg7eHF-OOLv240e|6Ajf-oq14QfvElxP zgSqiHA}c{(>Gd37%+^sWD(~`Fn>~eWIw9Yup%Le(Lz+3;#9g!;>j_g%yZG%eu793W zjeDduk5t06XiJ-T!2~ZzFkwj%+qvPrMBRK)ssw3!m;0-F>r(TGce?R;RLkafNN5x6 zmbSq6Ag*00y0oq07v6p5+l}PE^KtldbN_T+UiI3vZp4X+ndm2}rYGc+r7GY9A<-NU zQ|K+DwZsOiNZK;iiV+C226M*~!wFV&(zPEbgrs2_w1wbBwfBtl)n7y04Y)W5idxNz z(pi^aB(1=jiINxY-0!SLcZGZ-Uri6n%$YdT#Bemn(n3Q*decKv zGx6iZOyT|H{H@~3E&)>7H+{m_z@E|%f(uzlcE$`ZiXl#3Btb2L3w7Q}3cWwYW)?PP!?;ud=R^9Q2PQ8axr3Hb)E|_ig8(Y?63xT;)dNXIU2?|7%MMe`# zBMbZ{DO<+9jh7hxxAS)-@tdIv|JvDpVgTSV=f7=+_*WPV*4qiOw-vrMf8jPQLHlU= z;=MEtlyCsIx8UOQ5^lp1rvWbyfgI@tz9R{F;U~FGICxDz(fYng9T|Pp4sDkJTqoqw zFBDz#no8$4pJUJ4R`Mje+=qS~(3N(dGykTn^~0v*We9him)56^zMapL_Soqw0o$py zvg((WPl&|bj($g*?AE3>8|Y>Qq`=G?aap@q^tmNWM<*R)67o`5Q$@lwLF)#g`J|^x z?}j)#tFyf~LGX6ufYcZEXR4e+wGXq5lS7>=5HL-Sfsy( z%CV8^t(%Gyz8cTm=XRdGo>ttd8R_YQdTbj-DCS3yaE| zx^IJZ{HVYE)G5f#4NCwxlu$)WX*Y46lIpWS`C3}*CTcpB>95L>wa>37E6`#MUt1IxAi=yU-0pZq*p?N=&S??#FfMCbc9FV z+)F1~=XfPQ4p8?`E5rmeHv_aMPZ7Sh;M1LKBYB&(wgqj8&i2rcqL7gcia68%rPb{& z=PfmV+o2%>eQVv<6`hw7X~90tDXLDxIhSaqF!FCQ#p-iz4;ViV%;6_+ju`2)xjqp& zKzgRFhn9lDwiY`?$jBG-Mz!X9EIC21Aa@9nQ8S}?9+y>GjPQ(_|9G7BrJ(AZI|!4x zd%-R|-lmt_WeY?mRq5|@Jw*u_8F+IGSVpW5Yu4U0y&?KyWfGv!qd`p(7Of9EeJb|$ zOP4|grZ||_nRpBFvTH4z35qMX^>0!|`_Lo8p(bb2l5cLDqCK@TsdCiHy9HG})lq&L zU3#5E3ii}5YW*FJJxeTyzQM%NC&dwzYvYqwQv-I+-M9o_y3a-BFSFfzXlRwbe&xjpC0| zXbOL074Wl{axXP!;5w6DIyvAPrW&Q)F_KyUcgz)&<2e?)w=9YfMW13impDb?i5|e(G@ik;MlWd={x$Lgnu-t4dqKDrHOdP)8`%G?2dS>m`k8 z6GW+svI~kgLOIS7{IJUs^yyMEYJ9Gfw*cXZkqYNDk8Vm&W`b4SK6$!NL`x+sIL7f2 z^9g;=_*>hL19nR(r5vdRK2+(bVp>9)le) zOjL0>wRpt?1#HQOl)hWlj7b?~zFd4FUxStdN=ulfZ`Yqu#Zvdv)R{&$Tz6>R%(1Je z;uK|QFe@s)!kqf4p~!WO$f9}#Vb0y8{gz9l%FZL9B!XEsLm<7PL)21SEd&YN7-_uI z>-?6$BMe(i zD**QQzqG887n`u@WcP48r`$%;9!a0caerF1^jI^mx({I_`s-AQZk|q+f1l}{{Ih1t zej73o?@}~)pA~k$8Rc_;RGCzDzv;aYFoDTbH*Rvu%Y8Q=Ah(mh+4MX@r$4hl`%I!+ za7TWzkIe?=q4??ih4^Wpbo-PW-yBa-hnpTApX zzvMp1p`L#ky8CeOlGgQ1Q!4Z;Ui*L+*ahPbPszAOC#q=*0FVfMUo4mSY zZEd`~K(6KNCkP4+{saWZM%wO#5vx)5*x1m;5xRsFgjMU6Umw)0p5ij9pGss@K)XC} zPz}{AQF5ydh&qv_&pi+{9#A{}6l_%sa%5ZG+Kf#Q5sG&+0bf1Ikd+-@>=?*jX4WCI z-V&%UQ!2bv*0-P zLi_pp(H<;8BJPNUzxH?q1Qv#WBb1fLeQ|go+%Pz1L5@oVD9puyK*75f}&-4mr$EKn_bo z_6GXV;^l-yIm&Te#$sI{Adsi0C(u(2h<39FiAYOJgZ6s4ehy^||3}Wn-OXuF$`%g7 z5g2#|1OpNQih%ZI@fQBKM&V@-o8*Gy5paNe9Lax+aaiXt78;HI$7sAiez?RJVeqnhGd&Do?`CU@Gvq%P1!uDu z$R1=1!@`6-kOt2vCgM7>N=S|?`S-`;DI*InUmBea zZ})N<77MUp$lJWr^azFy8~PfuSW_Bv@iIh>dnS+HKMja%aZ{c(6jjf6i|0np5?z{i z_Xy;cAL@+2wxcM@Mm!8Hy|XLyQol=Cl(JT-4uFX-r;#@?-zmmM(bf1>K0&uP#PPGl z=*X|$?Y69`p^A*9q|*{ybG1e+SBUw?CO)n@q2YK>PoF*HrAX{%hs}w~M=!HPWBFxI z-9-lle5#^GWz8uNFD#d`$Br}>h)NvIP=XqP3aGQxqca~IL_P`~OY{AOHZKO+F~axa#kq|G_Q)I#{rf+F9dONm zN5Qkr2jvvbpTC>*EBE|&Bs|l4Pz?WobihUb9R<%SAC#y+ptv03rvF=S-Rq%^d)s#(gAkhesqE{_cMO?~L~u diff --git a/UnofficialCrusaderPatchGUI/Graphics/refresh.png b/UnofficialCrusaderPatchGUI/Graphics/refresh.png deleted file mode 100644 index 4cefed05fe8608dcedd1d7e7a8f666f0724636a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 845 zcmV-T1G4;yP)%IW z7T(!x_U74UUaxm?@}JF8Z!Rw{zpqv+H`i{rdld`@M_l{;{^{A-*-wwhv*em*ykpJL zz(ko!r5e?0HOoB?3yH)i>Qqz>~>jGaiq(w*u=?Z!>7F*XwDnbGcl_v}QCK1^M0I-+zD^ zH8qyL*yVElaT0B*R4PajLhW=q_1mrO^?H#|C^YQ%`|qfe4d8aW9lyQ3{j>{|0?THz zRk^QJD!Juy>Dg8bI2H&5Cd1({gu|9fOFEsdJBhZ{Y9-WrA|@K4c03-xrP%a+^ZDFI zEwJ_#m^?WtDk7DZ(v4!07R+QaHQEy<)HSd|^p?wtA6IO5lS^+0g z^&M^Z^3htYmeDsxB9R__s8%>typL$GpZv#Sv5sC#FTmYyH>z)fDkzn{mY&^Lp$Gt` zkYstr_bmSCd7xO>z%_jhxb*D4215wQ&CSi{wKVGd3q`7$ou8loIA(C1o}T{Ns2>xs z3L+9>U zmW(;P&~qWq>w0rF! zfEOH35Of_Jx}cpXkW!S4kEk6%3qCwNyvO-%bKH0W;iGooQY@wc@ARk?4u=P}XD$Kf zq@cIKA%^4@CIMQC96LSknhJ@W8nxPP6ZvBlQgnz3hXtn$KqATD<$Zx?!u2qHe%H5 zVlJglH#P<3BNLhEvP94r7Xfur(j`+{6oah?Djie`uDf732c>*$xLxqvoaB9<=bYdB zzW?{h^Bh5=(fC_iTZxQ>hzMS}wY5QVvVl+lsT3A0fF(;_J;&SdND5He_|6L6ClIcfLr536vdzcUaxo9mwG%NT3TA@>FEhL*Z&Ql&lecP z)85XV>(@uJfbJp2{Tw>x50n=K(K(j z;H-yR2*Q;BB9s9s%Ru)g#76r4Q3GAN1fk;|Jo+U$8HJ)IFi58;pXqF@`8a4HW4A+g zc2|VUi+}9xoxv#3X_6b2>Kbs8>gs0N+o#*+&YinlVzF3Og1)M_ zSjLqrO~l0PM=E`YAdCl07vbU8QL7J7T--rCvw@j~3vGxmd)R|SM)Ak_9Fo?{FfTT212Kx1Y@?HaH%Pzo;8!=Dg;?}R&vuDqZ5j6lK0qM`qTeog4 zal6m2$;^C4W@exc4+;yRv{c@amX?>YZQHh=M%;;v0tBbiIqBH3!^PLGeX%wxD=>)J zOsC28*?aH4yQ)^DQZX(d05+Q~q^hd8sI2VhpgobxRb87m?_Ifkx#6-#qZ!{aAU;0+ xxkQq+$>YHfyu2@7g+h_KdiA=?!wEBx{Q+yZ%eM}#8}tAG002ovPDHLkV1hg&Zdw2U diff --git a/UnofficialCrusaderPatchGUI/LanguageWindow.xaml b/UnofficialCrusaderPatchGUI/LanguageWindow.xaml deleted file mode 100644 index 03b0bdd8..00000000 --- a/UnofficialCrusaderPatchGUI/LanguageWindow.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - -