diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..8ea9700a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Discord Server + url: https://discord.gg/dpnRn2tKT9/ + about: Please ask and answer support questions here. diff --git a/.github/ISSUE_TEMPLATE/get-help.md b/.github/ISSUE_TEMPLATE/get-help.md new file mode 100644 index 00000000..1bcac1e2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/get-help.md @@ -0,0 +1,31 @@ +--- +name: Get help +about: Get help using H2-Mod +title: '' +labels: discussion +assignees: '' + +--- + +_Do not open an issue here if you need help with modding or have a problem getting the client to run. +It is very likely your problem will be resolved by reading the [README](https://github.com/fedddddd/h2-mod#installation) carefully. +Ask in the `#help` channel on the [Discord](https://discord.gg/dpnRn2tKT9) server if you still have problems. +Before opening a new issue, please see [Issues](https://github.com/fedddddd/h2-mod/issues) and check that a similar issue does not already exist +If this does not apply, please continue by filling in the template below._ + +**What are you trying to do?** +A short, concise description of the outcome you are trying to achieve. + +**What problem are you having?** +A clear and concise description of the problem that is blocking you from your desired outcome, ex. "H2-Mod is crashing with this error message: ..." +Please walk us through the steps you have taken when you encountered this problem. +If H2-Mod is crashing, include the minidump file and the crash address in text form. Screenshots showing the message box with the crash address are not acceptable. + +**What have you tried so far?** +Describe any steps you've already taken to try to get past this issue. Have you found a workaround? + +**What version of H2-Mod are you using?** +Please make sure you are up to date with the latest build from the `main` or `develop` branch. + +**Anything else we should know?** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/request-a-feature.md b/.github/ISSUE_TEMPLATE/request-a-feature.md new file mode 100644 index 00000000..167932aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/request-a-feature.md @@ -0,0 +1,27 @@ +--- +name: Request a feature +about: Suggest a new feature or enhancement +title: '' +labels: feature +assignees: '' + +--- + +_Before opening a new feature request, please see [Issues](https://github.com/fedddddd/h2-mod/issues) and check that a similar issue does not already exist. +If this a new request, help us help you by filling in the template below. +H2-Mod is not in active development right now. Please keep in mind that if there is not a clear positive impact on the gameplay to be gained by this feature request, it may be closed at the maintainers' discretion._ + +**What problem will this solve?** +A clear and concise description of the problem this new feature is meant to solve, ex. "There is something wrong with the game" or "There is something wrong with H2-Mod's source code". +Please limit your request to a single feature; create multiple feature requests instead. + +**What might be a solution?** +A clear and concise description of what you want to happen. If you are proposing changes to H2-Mod's source code, tell us which component you want to be changed. +If you propose changes to the game, you may use images or videos to illustrate what aspect of the game should be changed. + +**What other alternatives have you already considered?** +A clear and concise description of any alternative solutions or features you've considered. +It may help others to find workarounds until the problem is resolved. + +**Anything else we should know?** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 840ec331..a5065d28 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,9 @@ on: branches: - "*" types: [opened, synchronize, reopened] +concurrency: + group: ${{ github.ref }} + cancel-in-progress: false jobs: build: name: Build binaries @@ -18,20 +21,11 @@ jobs: - Debug - Release steps: - - name: Wait for previous workflows - if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') - uses: softprops/turnstyle@v1 - with: - poll-interval-seconds: 10 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Check out files uses: actions/checkout@v3 with: submodules: true fetch-depth: 0 - # NOTE - If LFS ever starts getting used during builds, switch this to true! lfs: false - name: Add msbuild to PATH diff --git a/.gitmodules b/.gitmodules index 1c83538a..0a1dba8b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,9 +43,9 @@ [submodule "deps/curl"] path = deps/curl url = https://github.com/curl/curl.git -[submodule "deps/gsc-tool-h2"] - path = deps/gsc-tool-h2 - url = https://github.com/fedddddd/gsc-tool-h2.git [submodule "deps/json"] path = deps/json url = https://github.com/nlohmann/json.git +[submodule "deps/gsc-tool"] + path = deps/gsc-tool + url = https://github.com/xensik/gsc-tool.git diff --git a/README.md b/README.md index 09ce87b3..6c3ddd07 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ **NOTE**: You must legally own Call of Duty®: Modern Warfare® 2 Campaign Remastered to run this mod. Cracked/Pirated versions of the game are **NOT** supported. -1. Download the latest **[release](https://github.com/fedddddd/h2-mod/releases/latest/download/h2-mod.exe)** or **[develop](https://master.fed0001.xyz/data-dev/h2-mod.exe)** build +1. Download the latest **[release](https://h2-mod.fed.cat/data/h2-mod.exe)** or **[develop](https://h2-mod.fed.cat/data-dev/h2-mod.exe)** build 2. Drop the file in your **Call of Duty: Modern Warfare 2 Campaign Remastered** installation folder. 3. Run **h2-mod.exe** and make sure you press **"YES"** when asked whether to install updates. diff --git a/data/cdata/scripts/ending/achievements.gsc b/data/cdata/scripts/ending/achievements.gsc new file mode 100644 index 00000000..ecfa34b0 --- /dev/null +++ b/data/cdata/scripts/ending/achievements.gsc @@ -0,0 +1,21 @@ +main() +{ + replacefunc(maps\char_museum::ramirez_jukebox, ::ramirez_jukebox); +} + +ramirez_jukebox() +{ + common_scripts\utility::flag_wait("museum_ready"); + wait 4; + + jukebox = getent("ramirez_jukebox", "targetname"); + jukebox makeusable(); + + for (;;) + { + jukebox waittill("trigger"); + index = randomint(37); + jukebox maps\_utility::play_sound_on_entity("museum_ramirez_ee_" + index); + maps\_utility::giveachievement_wrapper("RAMIREZ"); + } +} diff --git a/data/cdata/scripts/ending/credits.gsc b/data/cdata/scripts/ending/credits.gsc index deaeff7a..eb02ab74 100644 --- a/data/cdata/scripts/ending/credits.gsc +++ b/data/cdata/scripts/ending/credits.gsc @@ -1,3 +1,5 @@ +#include maps\_endmission; + main() { replacefunc(maps\_credit_h2_autogen::_id_B775, ::initiwcredits); diff --git a/data/cdata/scripts/endmission.gsc b/data/cdata/scripts/endmission.gsc new file mode 100644 index 00000000..d0436e79 --- /dev/null +++ b/data/cdata/scripts/endmission.gsc @@ -0,0 +1,171 @@ +#include maps\_endmission; + +main() +{ + // fix credits victory screen & add wait after giving mission achievements + replacefunc(maps\_endmission::_nextmission, ::nextmission); +} + +give_mission_achievement(name) +{ + was_unlocked = achievementunlocked(name); + maps\_utility::giveachievement_wrapper(name); + + if (!was_unlocked) + { + wait 4; + } +} + +nextmission(var_0) +{ + level notify("achievements_level_complete"); + + if (level.script == "ending" && level._id_AC38 != "credits_1") + { + changelevel(""); + } + else + { + if (!isdefined(var_0)) + var_0 = 0; + + level notify("nextmission"); + level.player notify("levelComplete"); + level.nextmission = 1; + level.player enableinvulnerability(); + + if (maps\_utility::arcademode()) + { + level._id_AC81 = 1; + thread _id_D36F::_id_AF95(); + common_scripts\utility::flag_wait("arcademode_ending_complete"); + } + + var_1 = undefined; + setsaveddvar("ui_nextMission", "1"); + setdvar("ui_showPopup", "0"); + setdvar("ui_popupString", ""); + + if (level.script == "ending") + { + level.script = "af_chase"; + nextmission(1); + level.script = "ending"; + } + + game["previous_map"] = level.script; + var_1 = level.missionsettings getlevelindex(level.script); + + if (!(level.script == "af_chase" && var_0) && !maps\_utility::achievement_conditions("IMMORTAL")) + { + _func_1FC(level.script, var_1); + updategamerprofileall(); + maps\_endmission::check_immortal_achievement(); + } + + maps\_gameskill::auto_adust_zone_complete("aa_main_" + level.script); + + if (!isdefined(var_1)) + { + missionsuccess(level.script); + return; + } + + if (level.script != "ending" && !(level.script == "af_chase" && var_0)) + { + level.player thread maps\_hud_util::fade_out(1, undefined); + soundscripts\_snd::snd_message("end_mission_fade_to_black"); + wait 2; + maps\_utility::level_end_save(); + } + + if (level.script != "af_chase" || var_0) + { + level.missionsettings setlevelcompleted(var_1); + var_3 = maps\_endmission::updatesppercent(); + updategamerprofile(); + + if (level.missionsettings hasachievement(var_1)) + { + give_mission_achievement(level.missionsettings getachievement(var_1)); + } + + if (level.missionsettings haslevelveteranaward(var_1) && getlevelcompleted(var_1) == 4 && level.missionsettings check_other_haslevelveteranachievement(var_1)) + { + give_mission_achievement(level.missionsettings getlevelveteranaward(var_1)); + } + + if (level.missionsettings hasmissionhardenedaward() && level.missionsettings getlowestskill() > 2) + { + give_mission_achievement(level.missionsettings gethardenedaward()); + } + + level.missionsettings maps\_endmission::_id_D1B9(); + var_4 = level.missionsettings.levels.size; + } + + if (level.script == "af_chase" && var_0) + return; + + if (level.script == "ending" && level._id_AC38 == "credits_1") + common_scripts\utility::flag_wait("af_chase_nextmission"); + + if (level.script == "airplane" || level.script == "ending") + { + if (level.credits_active) + { + level notify("credits_ended"); + credits_end(); + } + + setsaveddvar("ui_nextMission", "0"); + return; + } + else + { + var_4 = var_1 + 1; + } + + if (getdvarint("limited_mode")) + { + setsaveddvar("ui_nextMission", "0"); + changelevel(""); + return; + } + + if (maps\_utility::arcademode()) + { + if (!getdvarint("arcademode_full")) + { + setsaveddvar("ui_nextMission", "0"); + changelevel(""); + return; + } + + if (level.script == "cargoship") + { + changelevel("blackout", level.missionsettings getkeepweapons(var_1)); + return; + } + else if (level.script == "airlift") + { + changelevel("village_assault", level.missionsettings getkeepweapons(var_1)); + return; + } + else if (level.script == "jeepride") + { + changelevel("airplane", level.missionsettings getkeepweapons(var_1)); + return; + } + } + + if (level.missionsettings skipssuccess(var_1)) + { + changelevel(level.missionsettings getlevelname(var_4), level.missionsettings getkeepweapons(var_1)); + return; + } + + missionsuccess(level.missionsettings getlevelname(var_4), level.missionsettings getkeepweapons(var_1)); + } +} diff --git a/data/cdata/scripts/gulag/achievements.gsc b/data/cdata/scripts/gulag/achievements.gsc new file mode 100644 index 00000000..52f5c139 --- /dev/null +++ b/data/cdata/scripts/gulag/achievements.gsc @@ -0,0 +1,25 @@ +main() +{ + replacefunc(maps\gulag_code::surprise, ::surprise); +} + +surprise() +{ + level endon("cancel_surprise"); + tv = getent("surprise_tv", "script_noteworthy"); + tv thread maps\gulag_code::surprise_tv(); + common_scripts\utility::flag_wait("player_nears_cell_door3"); + + maps\gulag_code::surprise_damage_trigger(); + maps\gulag_code::surprise_flag_touching(); + + tv thread maps\_utility::play_sound_on_entity("h2_zombie_easter_egg"); + tv.screen = spawn("script_model", tv.origin); + tv.screen.angles = tv.angles; + tv.screen setmodel("com_tv1_pho_zombie"); + + wait 3.3; + tv.screen delete(); + + maps\_utility::giveachievement_wrapper("BRAINS"); +} \ No newline at end of file diff --git a/data/cdata/ui_scripts/achievements/__init__.lua b/data/cdata/ui_scripts/achievements/__init__.lua new file mode 100644 index 00000000..3e0ad2bd --- /dev/null +++ b/data/cdata/ui_scripts/achievements/__init__.lua @@ -0,0 +1,2 @@ +require("toast") +require("menu") diff --git a/data/cdata/ui_scripts/achievements/menu.lua b/data/cdata/ui_scripts/achievements/menu.lua new file mode 100644 index 00000000..f04f99fa --- /dev/null +++ b/data/cdata/ui_scripts/achievements/menu.lua @@ -0,0 +1,372 @@ +LUI.MenuBuilder.registerType("achievements_menu", function(root, controller) + local menuwidth = 500 + local menu = LUI.MenuTemplate.new(root, { + menu_title = "@LUA_MENU_ACHIEVEMENTS", + exclusiveController = 0, + menu_width = menuwidth, + menu_top_indent = LUI.MenuTemplate.spMenuOffset, + showTopRightSmallBar = true, + uppercase_title = true + }) + + local black_state = CoD.CreateState(nil, nil, nil, nil, CoD.AnchorTypes.All) + black_state.red = 0 + black_state.blue = 0 + black_state.green = 0 + black_state.alpha = 0 + black_state.left = -100 + black_state.right = 100 + black_state.top = -100 + black_state.bottom = 100 + + local black = LUI.UIImage.new(black_state) + black:setPriority(-1000) + + black:registerAnimationState("BlackScreen", { + alpha = 1 + }) + + black:registerAnimationState("Faded", { + alpha = 0 + }) + + menu:addElement(black) + + local currentbackground = nil + local changebackground = function(background, isvideobg) + if (not Engine.InFrontend() or currentbackground == background) then + return + end + + currentbackground = background + + if (isvideobg) then + PersistentBackground.ChangeBackground(nil, background) + else + PersistentBackground.ChangeBackground(background, "") + PersistentBackground.ChangeBackground(background, nil) + end + + black:animateInSequence( { + { + "BlackScreen", + 0 + }, + { + "Faded", + 1000 + } + }) + end + + local itemheight = 80 + local itemwidth = menuwidth + local itemspacing = 10 + local maxrowelements = 1 + + local rowelements = 0 + local newrow = function() + local currentrow = LUI.UIElement.new({ + topAnchor = true, + leftAnchor = true, + width = itemheight * maxrowelements, + height = itemheight, + }) + + menu.list.currentrow = currentrow + menu.list:addElement(currentrow) + menu.list.currentrow:makeFocusable() + end + + newrow() + + local addelement = function(element) + local container = LUI.UIElement.new({ + topAnchor = true, + leftAnchor = true, + width = itemheight, + height = itemheight, + left = rowelements * (itemheight + itemspacing) + }) + container:addElement(element) + container:makeFocusable() + menu.list.currentrow:addElement(container) + rowelements = rowelements + 1 + if (rowelements == maxrowelements) then + newrow() + rowelements = 0 + end + end + + local achievementtable = achievements.table() + local unlockcount = 0 + for i = 0, #achievementtable do + if (achievementtable[i]) then + unlockcount = unlockcount + 1 + end + end + + for i = 0, achievements.count() - 1 do + local btnbg = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + width = itemwidth, + height = itemheight, + material = RegisterMaterial("h2_btn_unfocused") + }) + + btnbg:setup9SliceImage() + + btnbg:registerAnimationState("locked", { + material = RegisterMaterial("h2_btn_unfocused_locked") + }) + + local raritynames = { + "common", + "rare", + "legendary", + "epic", + } + + local rarityname = raritynames[achievements.getrarity(i) + 1] + + local raritystrip = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + width = 10, + height = itemheight, + material = RegisterMaterial("depot_button_rarity_strip_" .. rarityname) + }) + + raritystrip:registerAnimationState("hide", { + alpha = 0 + }) + + raritystrip:registerAnimationState("show", { + alpha = 1 + }) + + raritystrip:setup9SliceImage() + + local glow = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + width = itemwidth, + height = itemheight, + material = RegisterMaterial("depot_button_rarity_glow_" .. rarityname) + }) + + glow:registerAnimationState("hide", { + alpha = 0 + }) + + glow:registerAnimationState("show", { + alpha = 1 + }) + + local glow2 = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + width = itemwidth, + height = itemheight, + material = RegisterMaterial("depot_button_rarity_glow_" .. rarityname) + }) + + glow2:registerAnimationState("hide", { + alpha = 0 + }) + + glow2:registerAnimationState("show", { + alpha = 1 + }) + + glow:animateToState("hide") + glow2:animateToState("hide") + + local achievementcontainer = LUI.UIElement.new({ + topAnchor = true, + leftAnchor = true, + width = itemwidth, + height = itemheight, + }) + + local image = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + top = itemspacing / 2, + left = itemspacing / 2 + 10, + width = itemheight - itemspacing, + height = itemheight - itemspacing, + material = RegisterMaterial("trophy_" .. i) + }) + + image:registerAnimationState("locked", { + topAnchor = true, + leftAnchor = true, + top = itemspacing / 2 + 15, + left = itemspacing / 2 + 15 + 10, + width = itemheight - itemspacing - 30, + height = itemheight - itemspacing - 30, + material = RegisterMaterial("icon_lock_mini") + }) + + local textwidth = itemwidth - itemheight - itemspacing * 2 + local title = LUI.UIText.new({ + topAnchor = true, + leftAnchor = true, + top = itemspacing + 5, + left = itemheight + 5 + 10, + color = { + r = 0.7, + g = 0.7, + b = 0.7, + }, + width = textwidth, + font = CoD.TextSettings.Font23.Font, + height = CoD.TextSettings.Font23.Height + }) + + local desc = LUI.UIText.new({ + topAnchor = true, + leftAnchor = true, + top = itemspacing + CoD.TextSettings.Font23.Height + 10, + left = itemheight + 5 + 10, + width = textwidth, + alignment = LUI.Alignment.Left, + color = { + r = 0.7, + g = 0.7, + b = 0.7, + }, + font = CoD.TextSettings.Font21.Font, + height = CoD.TextSettings.Font21.Height + }) + + local focusedtext = { + color = {r = 1, g = 1, b = 1} + } + desc:registerAnimationState("focused", focusedtext) + title:registerAnimationState("focused", focusedtext) + + title:setText(Engine.ToUpperCase(Engine.Localize(achievements.getname(i)))) + desc:setText(Engine.Localize(achievements.getdetails(i))) + + achievementcontainer:setHandleMouse(true) + local locked = not achievementtable[i] + + if (locked) then + raritystrip:animateToState("hide") + end + + local background = achievements.getbackground(i) + achievementcontainer:registerEventHandler("mouseenter", function() + Engine.PlaySound(CoD.SFX.MouseOver) + + if (background ~= nil and achievementtable[i]) then + changebackground(background, false) + else + changebackground("sp_menus_bg_regular", true) + end + + if (locked) then + btnbg:setImage(RegisterMaterial("h2_btn_focused_locked")) + else + raritystrip:animateToState("show") + title:animateToState("focused") + desc:animateToState("focused") + glow:animateToState("show") + glow2:animateToState("show") + end + end) + achievementcontainer:registerEventHandler("mouseleave", function() + if (locked) then + btnbg:setImage(RegisterMaterial("h2_btn_unfocused_locked")) + else + title:animateToState("default") + desc:animateToState("default") + glow:animateToState("hide") + glow2:animateToState("hide") + end + end) + + achievementcontainer:addElement(btnbg) + achievementcontainer:addElement(glow) + achievementcontainer:addElement(glow2) + achievementcontainer:addElement(raritystrip) + achievementcontainer:addElement(image) + achievementcontainer:addElement(title) + achievementcontainer:addElement(desc) + + if (locked) then + btnbg:animateToState("locked") + image:animateToState("locked") + + if (achievements.issecret(i)) then + title:setText(Engine.ToUpperCase(Engine.Localize("ACHIEVEMENT_HIDDEN"))) + desc:setText(Engine.Localize("ACHIEVEMENT_HIDDEN_DESC")) + end + end + + addelement(achievementcontainer) + end + + if (rowelements == 0) then + menu.list.currentrow:close() + end + + LUI.Options.InitScrollingList(menu.list, nil, { + rows = 5 + }) + + local createprogressbar = function() + local barwidth = itemwidth + 17 + local progressbar = LUI.UIElement.new({ + bottomAnchor = true, + leftAnchor = true, + width = barwidth, + bottom = -90, + height = 15 + }) + + local bg = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + rightAnchor = true, + bottomAnchor = true, + alpha = 0.55, + color = Colors.grey_14, + }) + + local bar = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + bottomAnchor = true, + width = 0, + material = RegisterMaterial("h1_ui_progressbar_green") + }) + + progressbar.setprogress = function(fraction) + bar:registerAnimationState("progress", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = true, + width = fraction * (barwidth), + }) + + bar:animateToState("progress", 300) + end + + progressbar.setprogress(unlockcount / achievements.count()) + + progressbar:addElement(bg) + progressbar:addElement(bar) + progressbar:addElement(LUI.DecoFrame.new(nil, LUI.DecoFrame.Grey)) + + return progressbar + end + + menu:addElement(createprogressbar()) + menu:AddBackButton() + + return menu +end) diff --git a/data/cdata/ui_scripts/achievements/toast.lua b/data/cdata/ui_scripts/achievements/toast.lua new file mode 100644 index 00000000..b6a919aa --- /dev/null +++ b/data/cdata/ui_scripts/achievements/toast.lua @@ -0,0 +1,203 @@ +if (Engine.InFrontend()) then + return +end + +local hud = LUI.UIElement.new({ + topAnchor = true, + leftAnchor = true, + width = 500, + height = 500, + left = 0 +}) + +local hidetimer = LUI.UITimer.new(5000, "hide_toast") +local finishtimer = LUI.UITimer.new(6000, "notification_finished") +local animtime = 250 + +hud:setPriority(1000) + +local isshowingachievement = false +local notificationqueue = {} +local shownotificationinternal = nil + +local shownextnotification = function() + isshowingachievement = false + local data = notificationqueue[1] + if (data == nil) then + return + end + + table.remove(notificationqueue, 1) + shownotificationinternal(data) +end + +local createtoast = function() + local height = 80 + local width = 400 + local padding = 10 + local leftoffset = 10 + + local titlefont = CoD.TextSettings.Font27 + local descfont = CoD.TextSettings.Font21 + + local imagesize = height - padding * 2 + local textoffset = padding * 2 + imagesize + local textyoffset = height / 2 - (titlefont.Height + descfont.Height) / 2 + local text2yoffset = 5 + + local container = LUI.UIElement.new({ + topAnchor = true, + leftAnchor = true, + top = 100, + left = 0, + width = width, + height = height + }) + + container:registerAnimationState("hide", { + topAnchor = true, + leftAnchor = true, + top = 100, + left = -1000, + width = width, + height = height + }) + + container:registerAnimationState("show", { + topAnchor = true, + leftAnchor = true, + top = 100, + left = 0, + width = width, + height = height + }) + + container:registerAnimationState("show_right", { + topAnchor = true, + leftAnchor = true, + top = 100, + left = 40, + width = width, + height = height + }) + + local bg = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + rightAnchor = true, + bottomAnchor = true, + alpha = 0.55, + color = Colors.grey_14, + }) + + local imagebg = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + top = padding, + left = padding + leftoffset, + width = imagesize, + height = imagesize, + material = RegisterMaterial("trophy_border") + }) + + local image = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + top = padding, + left = padding + leftoffset, + width = imagesize, + height = imagesize, + }) + + local title = LUI.UIText.new({ + topAnchor = true, + leftAnchor = true, + top = textyoffset, + left = textoffset + leftoffset, + font = titlefont.Font, + height = titlefont.Height + }) + + local desc = LUI.UIText.new({ + topAnchor = true, + leftAnchor = true, + width = width - textoffset - leftoffset - padding, + alignment = LUI.Alignment.Left, + top = textyoffset + titlefont.Height + text2yoffset, + left = textoffset + leftoffset, + font = descfont.Font, + height = descfont.Height + }) + + container:addElement(bg) + container:addElement(imagebg) + container:addElement(image) + container:addElement(title) + container:addElement(desc) + container:addElement(LUI.DecoFrame.new(nil, LUI.DecoFrame.Grey)) + + container:animateToState("hide") + + container:addElement(hidetimer) + container:addElement(finishtimer) + + container:registerEventHandler("hide_toast", function() + LUI.UITimer.Stop(hidetimer) + container:animateToState("hide", animtime) + end) + + container:registerEventHandler("notification_finished", function() + LUI.UITimer.Stop(finishtimer) + shownextnotification() + end) + + hud:addElement(container) + + container.image = image + container.title = title + container.desc = desc + + return container +end + +local toast = createtoast() + +shownotificationinternal = function(data) + isshowingachievement = true + + LUI.UITimer.Reset(hidetimer) + LUI.UITimer.Reset(finishtimer) + + toast:animateToState("hide") + toast:animateToState("show", animtime) + + toast.title:setText(data.title) + toast.desc:setText(data.description) + toast.image:setImage(data.image) + + if (data.sound) then + Engine.PlaySound(data.sound) + end +end + +function addnotification(data) + table.insert(notificationqueue, data) + if (not isshowingachievement) then + shownextnotification() + end +end + +local addachievementnotification = function(id) + addnotification({ + title = Engine.Localize("ACHIEVEMENT_EARNED"), + description = Engine.ToUpperCase(Engine.Localize("ACHIEVEMENT_NAME_" .. id)), + image = RegisterMaterial("trophy_" .. id), + sound = "ui_achievement_unlocked" + }) +end + +hud:registerEventHandler("earned_achievement", function(element, event) + addachievementnotification(event.id) +end) + +LUI.roots.UIRoot0:addElement(hud) \ No newline at end of file diff --git a/data/cdata/ui_scripts/branding/__init__.lua b/data/cdata/ui_scripts/branding/__init__.lua index 169563ff..1cd95fe0 100644 --- a/data/cdata/ui_scripts/branding/__init__.lua +++ b/data/cdata/ui_scripts/branding/__init__.lua @@ -1 +1,2 @@ require("credits") +require("victoryscreen") diff --git a/data/cdata/ui_scripts/branding/victoryscreen.lua b/data/cdata/ui_scripts/branding/victoryscreen.lua new file mode 100644 index 00000000..607b970f --- /dev/null +++ b/data/cdata/ui_scripts/branding/victoryscreen.lua @@ -0,0 +1,85 @@ +local specopsmod = "mods/specops" + +function CampaignCompleteMenu() + Engine.ExecNow("profile_menuDvarsSetup") + Engine.SetDvarBool("profileMenuOption_resumeIsGameCompleted", true) + Engine.ExecNow("profile_menuDvarsFinish") + Engine.Exec("updategamerprofile") + + local victory = LUI.UIImage.new({ + material = RegisterMaterial("victory"), + top = -300, + width = 1126, + height = 563, + alpha = 0 + }) + + victory:registerAnimationState("show", { + alpha = 1 + }) + + victory:animateInSequence({ + { + "default", + 0 + }, + { + "show", + 1000 + } + }) + + local topoffset = 590 + local text = LUI.UIText.new({ + leftAnchor = true, + rightAnchor = true, + topAnchor = true, + bottomAnchor = false, + top = topoffset, + bottom = topoffset + CoD.TextSettings.BodyFont18.Height, + font = CoD.TextSettings.BodyFont18.Font, + alignment = LUI.Alignment.Center, + alpha = 0 + }) + + text:registerAnimationState("show", { + alpha = 1 + }) + + text:setText(Engine.Localize("@MENU_SP_CONTINUE_TO_SPECIAL_OPS_CAPS")) + victory:addElement(text) + victory.text = text + + victory.skipLocked = true + victory:addElement(LUI.UITimer.new(3000, "enable_quit", nil, true)) + victory:registerEventHandler("enable_quit", function (element, event) + element.text:animateToState("show", 300) + element.skipLocked = false + end) + + local buttonhandler = function (element, event) + if (element.skipLocked) then + return + else + if (mods.getinfo(specopsmod).isvalid) then + mods.load(specopsmod) + else + game:openlink("specops") + Engine.PlaySound(CoD.SFX.MenuAccept) + Engine.PopupClosed(event.controller, "accept_normal") + LUI.FlowManager.RequestCloseAllMenus(element) + end + end + end + + local bindbutton = LUI.UIBindButton.new() + bindbutton:registerEventHandler("button_start", buttonhandler) + bindbutton:registerEventHandler("button_action", buttonhandler) + bindbutton:registerEventHandler("button_secondary", buttonhandler) + bindbutton.handlePrimary = true + victory:addElement(bindbutton) + + return victory +end + +LUI.MenuBuilder.m_types_build["MENU_CAMPAIGN_COMPLETED"] = CampaignCompleteMenu diff --git a/data/cdata/ui_scripts/buttons/__init__.lua b/data/cdata/ui_scripts/buttons/__init__.lua new file mode 100644 index 00000000..2e9c4cac --- /dev/null +++ b/data/cdata/ui_scripts/buttons/__init__.lua @@ -0,0 +1,31 @@ +LUI.addmenubutton("main_campaign", { + index = 6, + text = "@MENU_MODS", + description = Engine.Localize("@MENU_MODS_DESC"), + callback = function() + LUI.FlowManager.RequestAddMenu(nil, "mods_menu") + end +}) + +LUI.addmenubutton("main_campaign", { + index = 6, + text = "@LUA_MENU_ACHIEVEMENTS", + description = Engine.Localize("@LUA_MENU_ACHIEVEMENTS_DESC"), + callback = function() + LUI.FlowManager.RequestAddMenu(nil, "achievements_menu") + end +}) + +local maincampaign = LUI.MenuBuilder.m_types_build["main_campaign"] +LUI.MenuBuilder.m_types_build["main_campaign"] = function(...) + local initlist = LUI.Options.InitScrollingList + LUI.Options.InitScrollingList = function(list) + initlist(list, nil ,{ + rows = 10 + }) + end + + local menu = maincampaign(...) + LUI.Options.InitScrollingList = initlist + return menu +end diff --git a/data/cdata/ui_scripts/mods/loading.lua b/data/cdata/ui_scripts/mods/loading.lua index dff0c811..5a01b59a 100644 --- a/data/cdata/ui_scripts/mods/loading.lua +++ b/data/cdata/ui_scripts/mods/loading.lua @@ -29,15 +29,6 @@ function string:truncate(length) return self:sub(1, length - 3) .. "..." end -LUI.addmenubutton("main_campaign", { - index = 6, - text = "@MENU_MODS", - description = Engine.Localize("@MENU_MODS_DESC"), - callback = function() - LUI.FlowManager.RequestAddMenu(nil, "mods_menu") - end -}) - function getmodname(path) local modinfo = mods.getinfo(path) diff --git a/data/cdata/ui_scripts/motd/motd.lua b/data/cdata/ui_scripts/motd/motd.lua index 0750a430..fa056ce5 100644 --- a/data/cdata/ui_scripts/motd/motd.lua +++ b/data/cdata/ui_scripts/motd/motd.lua @@ -11,6 +11,10 @@ LUI.MenuBuilder.registerPopupType("motd", function() end) LUI.onmenuopen("main_campaign", function(menu) + if (not motd.hasmotd()) then + return + end + if (not motd.hasseentoday()) then motd.sethasseentoday() LUI.FlowManager.RequestPopupMenu(nil, "motd") diff --git a/data/cdata/ui_scripts/patches/__init__.lua b/data/cdata/ui_scripts/patches/__init__.lua index da3e488b..6f6f9f6e 100644 --- a/data/cdata/ui_scripts/patches/__init__.lua +++ b/data/cdata/ui_scripts/patches/__init__.lua @@ -1 +1,2 @@ require("unlockall") +require("pausequit") diff --git a/data/cdata/ui_scripts/patches/pausequit.lua b/data/cdata/ui_scripts/patches/pausequit.lua new file mode 100644 index 00000000..ef2c6ef0 --- /dev/null +++ b/data/cdata/ui_scripts/patches/pausequit.lua @@ -0,0 +1,18 @@ +if (Engine.InFrontend()) then + return +end + +LUI.onmenuopen("sp_pause_menu", function(element) + local menu = element:getFirstChild() + + local button = menu:AddButton("@LUA_MENU_ACHIEVEMENTS", function() + LUI.FlowManager.RequestAddMenu(nil, "achievements_menu") + end) + + menu.list:removeElement(button) + menu.list:insertElement(button, 4) + + menu:AddButton("@MENU_QUIT_TO_DESKTOP", function() + LUI.FlowManager.RequestAddMenu(nil, "quit_popmenu") + end) +end) diff --git a/data/cdata/ui_scripts/settings/__init__.lua b/data/cdata/ui_scripts/settings/__init__.lua index 42ecd260..02e75c1d 100644 --- a/data/cdata/ui_scripts/settings/__init__.lua +++ b/data/cdata/ui_scripts/settings/__init__.lua @@ -1,210 +1,3 @@ +require("settings") require("language") - -function createdivider(menu, text) - local element = LUI.UIElement.new({ - leftAnchor = true, - rightAnchor = true, - left = 0, - right = 0, - topAnchor = true, - bottomAnchor = false, - top = 0, - bottom = 33.33 - }) - - element.scrollingToNext = true - element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { - title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) - })) - - menu.list:addElement(element) -end - -LUI.addmenubutton("pc_controls", { - index = 4, - text = "@MENU_GENERAL", - description = Engine.Localize("@MENU_GENERAL_DESC"), - callback = function() - LUI.FlowManager.RequestAddMenu(nil, "settings_menu") - end -}) - -LUI.MenuBuilder.m_types_build["settings_menu"] = function(a1) - local menu = LUI.MenuTemplate.new(a1, { - menu_title = "@MENU_GENERAL", - menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + H1MenuDims.spacing), - menu_width = GenericMenuDims.OptionMenuWidth - }) - - createdivider(menu, "@LUA_MENU_UPDATES") - - LUI.Options.CreateOptionButton( - menu, - "cg_auto_update", - "@LUA_MENU_AUTO_UPDATE", - "@LUA_MENU_AUTO_UPDATE_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - } - ) - - menu:AddButton("@LUA_MENU_CHECK_UPDATES", function() - LUI.tryupdating(false) - end, nil, true, nil, { - desc_text = Engine.Localize("@LUA_MENU_CHECK_UPDATES_DESC") - }) - - createdivider(menu, "@LUA_MENU_DRAWING") - - LUI.Options.CreateOptionButton( - menu, - "cg_drawFPS", - "@LUA_MENU_DRAW_FPS", - "@LUA_MENU_DRAW_FPS_DESC", - { - { - text = "@LUA_MENU_DISABLED", - value = 0 - }, - { - text = "@LUA_MENU_FPS_ONLY", - value = 1 - }, - { - text = "@LUA_MENU_FPS_AND_VIEWPOS", - value = 2 - } - } - ) - - LUI.Options.CreateOptionButton( - menu, - "cg_drawSpeed", - "@LUA_MENU_DRAW_SPEED", - "@LUA_MENU_DRAW_SPEED_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - } - ) - - LUI.Options.CreateOptionButton( - menu, - "cg_speedGraph", - "@LUA_MENU_DRAW_SPEEDGRAPH", - "@LUA_MENU_DRAW_SPEEDGRAPH_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - } - ) - - createdivider(menu, "@LUA_MENU_RENDERING") - - LUI.Options.CreateOptionButton( - menu, - "r_fullbright", - "@LUA_MENU_R_FULLBRIGHT", - "@LUA_MENU_R_FULLBRIGHT_DESC", - { - { - text = "@LUA_MENU_DISABLED", - value = 0 - }, - { - text = "@LUA_MENU_ENABLED", - value = 1 - }, - { - text = "@LUA_MENU_MODE2", - value = 2 - }, - { - text = "@LUA_MENU_MODE3", - value = 3 - } - } - ) - - createdivider(menu, "@LUA_MENU_AUDIO_OPTIONS") - - LUI.Options.CreateOptionButton( - menu, - "snd_musicDisabledForCustomSoundtrack", - "@LUA_MENU_MUSIC", - "@LUA_MENU_MUSIC_DESC", - { - { - text = "@LUA_MENU_DISABLED", - value = true - }, - { - text = "@LUA_MENU_ENABLED", - value = false - }, - } - ) - - createdivider(menu, "@MENU_GAME_BEGINNING") - - LUI.Options.CreateOptionButton( - menu, - "intro", - "@LUA_MENU_INTRO", - "@LUA_MENU_INTRO_DESC", - { - { - text = "@LUA_MENU_DISABLED", - value = false - }, - { - text = "@LUA_MENU_ENABLED", - value = true - }, - } - ) - - LUI.Options.InitScrollingList(menu.list, nil) - LUI.Options.AddOptionTextInfo(menu) - - menu:AddBackButton() - - return menu -end - -if not Engine.InFrontend() then - LUI.MenuTemplate.AddVignette = function(f36_arg0) - if not LUI.FlowManager.IsMenuTopmost(Engine.GetLuiRoot(), "advanced_video") then - local f36_local0 = CoD.CreateState(0, 0, 0, 0, CoD.AnchorTypes.All) - f36_local0.material = RegisterMaterial("h1_ui_bg_vignette") - local self = LUI.UIImage.new(f36_local0) - self:setupFullWindowElement() - f36_arg0:addElement(self) - end - end - LUI.MenuTemplate.InitInGameBkg = function(f38_arg0, f38_arg1, f38_arg2, f38_arg3) - LUI.MenuTemplate.AddDarken(f38_arg0, f38_arg1, f38_arg3, 0.55) - if not Engine.IsMultiplayer() and not LUI.FlowManager.IsMenuTopmost(Engine.GetLuiRoot(), "advanced_video") then - LUI.MenuTemplate.AddWorldBlur(f38_arg0, f38_arg1) - end - end -end +require("audio") diff --git a/data/cdata/ui_scripts/settings/audio.lua b/data/cdata/ui_scripts/settings/audio.lua new file mode 100644 index 00000000..8248a6e5 --- /dev/null +++ b/data/cdata/ui_scripts/settings/audio.lua @@ -0,0 +1,207 @@ +local function GetVolume() + return (Engine.GetProfileData("snd_volume") - SliderBounds.Volume.Min) / (SliderBounds.Volume.Max - SliderBounds.Volume.Min) +end + +local function VolumeLess(a1) + LUI.Options.ProfileDataMenuOption(a1, SliderBounds.Volume.Min, SliderBounds.Volume.Max, -SliderBounds.Volume.Step, "snd_volume") +end + +local function VolumeMore(a1) + LUI.Options.ProfileDataMenuOption(a1, SliderBounds.Volume.Min, SliderBounds.Volume.Max, SliderBounds.Volume.Step, "snd_volume") +end + +local function dvarmenuoption(name, min, max, step) + Engine.SetDvarFloat(name, math.min(max, math.max(min, Engine.GetDvarFloat(name) + step))) +end + +local function getvolumefunc(name) + return function() + return (Engine.GetDvarFloat(name) - SliderBounds.Volume.Min) / (SliderBounds.Volume.Max - SliderBounds.Volume.Min) + end +end + +local function getvolumelessfunc(name) + return function() + dvarmenuoption(name, SliderBounds.Volume.Min, SliderBounds.Volume.Max, -SliderBounds.Volume.Step) + end +end + +local function getvolumemorefunc(name) + return function() + dvarmenuoption(name, SliderBounds.Volume.Min, SliderBounds.Volume.Max, SliderBounds.Volume.Step) + end +end + +LUI.PCAudio.new = function (a1) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_AUDIO_OPTIONS")), + menu_top_indent = Engine.IsMultiplayer() and 0 or LUI.MenuTemplate.spMenuOffset, + menu_width = GenericMenuDims.OptionMenuWidth + }) + + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Slider, + "@MENU_MASTER_VOLUME", + "@MENU_MASTER_VOLUME_DESC", + GetVolume, + VolumeLess, + VolumeMore + ) + + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Slider, + "@MENU_MUSIC_VOLUME", + "@MENU_MUSIC_VOLUME_DESC", + getvolumefunc("snd_musicVolume"), + getvolumelessfunc("snd_musicVolume"), + getvolumemorefunc("snd_musicVolume") + ) + + local speakeroptions = { + { + text = "@LUA_MENU_AUTODETECT_SPEAKERS", + value = 0 + } + } + + local speakerconfig = Engine.GetDvarInt("snd_detectedSpeakerConfig") + if speakerconfig > 1 then + speakeroptions[#speakeroptions + 1] = { + text = "@LUA_MENU_STEREO", + value = 2 + } + speakeroptions[#speakeroptions + 1] = { + text = "@LUA_MENU_HEADPHONE", + value = 50 + } + end + + if speakerconfig > 2 then + speakeroptions[#speakeroptions + 1] = { + text = "@LUA_MENU_FOUR_SPEAKERS", + value = 4 + } + end + + if speakerconfig > 4 then + speakeroptions[#speakeroptions + 1] = { + text = "@LUA_MENU_FIVE_ONE_SPEAKERS", + value = 6 + } + end + + if speakerconfig > 6 then + speakeroptions[#speakeroptions + 1] = { + text = "@LUA_MENU_SEVEN_ONE_SPEAKERS", + value = 8 + } + end + + LUI.Options.CreateOptionButton( + menu, + "snd_speakerConfig", + "@LUA_MENU_SPEAKER_CONFIG", + "@LUA_MENU_SPEAKER_CONFIG_DESC", + speakeroptions + ) + + if Engine.IsMultiplayer() then + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Select, + "@LUA_MENU_MUSIC", + "@LUA_MENU_MUSIC_DESC", + LUI.Options.GetDvarEnableTextFunc("snd_musicDisabled", true), + LUI.Options.ToggleDvarFunc("snd_musicDisabled"), + LUI.Options.ToggleDvarFunc("snd_musicDisabled") + ) + + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Select, + "@LUA_MENU_ANNOUNCER", + "@LUA_MENU_ANNOUNCER_DESC", + LUI.Options.GetDvarEnableTextFunc("snd_announcerDisabled", true), + LUI.Options.ToggleDvarFunc("snd_announcerDisabled"), + LUI.Options.ToggleDvarFunc("snd_announcerDisabled") + ) + + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Select, + "@LUA_MENU_BATTLECHATTER", + "@LUA_MENU_BATTLECHATTER_DESC", + LUI.Options.GetDvarEnableTextFunc("snd_battleChatterDisabled", true), + LUI.Options.ToggleDvarFunc("snd_battleChatterDisabled"), + LUI.Options.ToggleDvarFunc("snd_battleChatterDisabled") + ) + + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Select, + "@LUA_MENU_PUSH_TO_TALK", + "@LUA_MENU_PUSH_TO_TALK_DESC", + LUI.Options.GetDvarEnableTextFunc("cl_pushToTalk", false), + LUI.Options.ToggleDvarFunc("cl_pushToTalk"), + LUI.Options.ToggleDvarFunc("cl_pushToTalk") + ) + end + + if not Engine.IsMultiplayer() and Engine.ShouldShowSubtitlesOption() then + LUI.Options.CreateControlProfileDataButton( + menu, + "subtitles", + "profile_toggleSubtitles", + nil, + "LUA_MENU_SUBTITLES", + "PLATFORM_UI_OPTIONS_SUBTITLES_DESC", + { + { + text = "@LUA_MENU_DISABLED", + value = false + }, + { + text = "@LUA_MENU_ENABLED", + value = true + } + } + ) + end + + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Select, + "@LUA_MENU_HITSOUND", + "@LUA_MENU_HITSOUND_DESC", + LUI.Options.GetDvarEnableTextFunc("snd_hitsoundDisabled", true), + LUI.Options.ToggleDvarFunc("snd_hitsoundDisabled"), + LUI.Options.ToggleDvarFunc("snd_hitsoundDisabled") + ) + + if Engine.IsPC() and Engine.GetDvarBool("snd_wasapiSampleRateConverterNeeded") then + LUI.Options.AddButtonOptionVariant( + menu, + GenericButtonSettings.Variants.Select, + "@LUA_MENU_LOWQUALITYAUDIO", + "@LUA_MENU_LOWQUALITYAUDIO_DESC", + LUI.Options.GetDvarEnableTextFunc("snd_lowQualityAudio", false), + LUI.Options.ToggleDvarFunc("snd_lowQualityAudio"), + LUI.Options.ToggleDvarFunc("snd_lowQualityAudio") + ) + end + + LUI.Options.InitScrollingList(menu.list, nil) + LUI.Options.AddOptionTextInfo(menu) + + menu:AddBackButton(function(a1, a2) + Engine.ExecNow("profile_menuDvarsFinish", a2.controller) + Engine.Exec("updategamerprofile") + LUI.FlowManager.RequestLeaveMenu(a1) + end) + + return menu +end + +LUI.MenuBuilder.m_types_build["pc_audio"] = LUI.PCAudio.new diff --git a/data/cdata/ui_scripts/settings/settings.lua b/data/cdata/ui_scripts/settings/settings.lua new file mode 100644 index 00000000..de8788bb --- /dev/null +++ b/data/cdata/ui_scripts/settings/settings.lua @@ -0,0 +1,210 @@ +function createdivider(menu, text) + local element = LUI.UIElement.new({ + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) + + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) + })) + + menu.list:addElement(element) +end + +LUI.addmenubutton("pc_controls", { + index = 4, + text = "@MENU_GENERAL", + description = Engine.Localize("@MENU_GENERAL_DESC"), + callback = function() + LUI.FlowManager.RequestAddMenu(nil, "settings_menu") + end +}) + +LUI.MenuBuilder.m_types_build["settings_menu"] = function(a1) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = "@MENU_GENERAL", + menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + H1MenuDims.spacing), + menu_width = GenericMenuDims.OptionMenuWidth + }) + + createdivider(menu, "@LUA_MENU_UPDATES") + + LUI.Options.CreateOptionButton( + menu, + "cg_auto_update", + "@LUA_MENU_AUTO_UPDATE", + "@LUA_MENU_AUTO_UPDATE_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + } + ) + + if (Engine.InFrontend()) then + menu:AddButton("@LUA_MENU_CHECK_UPDATES", function() + LUI.tryupdating(false) + end, nil, true, nil, { + desc_text = Engine.Localize("@LUA_MENU_CHECK_UPDATES_DESC") + }) + end + + createdivider(menu, "@LUA_MENU_DRAWING") + + LUI.Options.CreateOptionButton( + menu, + "cg_drawFPS", + "@LUA_MENU_DRAW_FPS", + "@LUA_MENU_DRAW_FPS_DESC", + { + { + text = "@LUA_MENU_DISABLED", + value = 0 + }, + { + text = "@LUA_MENU_FPS_ONLY", + value = 1 + }, + { + text = "@LUA_MENU_FPS_AND_VIEWPOS", + value = 2 + } + } + ) + + LUI.Options.CreateOptionButton( + menu, + "cg_drawSpeed", + "@LUA_MENU_DRAW_SPEED", + "@LUA_MENU_DRAW_SPEED_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + } + ) + + LUI.Options.CreateOptionButton( + menu, + "cg_speedGraph", + "@LUA_MENU_DRAW_SPEEDGRAPH", + "@LUA_MENU_DRAW_SPEEDGRAPH_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + } + ) + + createdivider(menu, "@LUA_MENU_RENDERING") + + LUI.Options.CreateOptionButton( + menu, + "r_fullbright", + "@LUA_MENU_R_FULLBRIGHT", + "@LUA_MENU_R_FULLBRIGHT_DESC", + { + { + text = "@LUA_MENU_DISABLED", + value = 0 + }, + { + text = "@LUA_MENU_ENABLED", + value = 1 + }, + { + text = "@LUA_MENU_MODE2", + value = 2 + }, + { + text = "@LUA_MENU_MODE3", + value = 3 + } + } + ) + + createdivider(menu, "@LUA_MENU_AUDIO_OPTIONS") + + LUI.Options.CreateOptionButton( + menu, + "snd_musicDisabledForCustomSoundtrack", + "@LUA_MENU_MUSIC", + "@LUA_MENU_MUSIC_DESC", + { + { + text = "@LUA_MENU_DISABLED", + value = true + }, + { + text = "@LUA_MENU_ENABLED", + value = false + }, + } + ) + + createdivider(menu, "@MENU_GAME_BEGINNING") + + LUI.Options.CreateOptionButton( + menu, + "intro", + "@LUA_MENU_INTRO", + "@LUA_MENU_INTRO_DESC", + { + { + text = "@LUA_MENU_DISABLED", + value = false + }, + { + text = "@LUA_MENU_ENABLED", + value = true + }, + } + ) + + LUI.Options.InitScrollingList(menu.list, nil) + LUI.Options.AddOptionTextInfo(menu) + + menu:AddBackButton() + + return menu +end + +if not Engine.InFrontend() then + LUI.MenuTemplate.AddVignette = function(f36_arg0) + if not LUI.FlowManager.IsMenuTopmost(Engine.GetLuiRoot(), "advanced_video") then + local f36_local0 = CoD.CreateState(0, 0, 0, 0, CoD.AnchorTypes.All) + f36_local0.material = RegisterMaterial("h1_ui_bg_vignette") + local self = LUI.UIImage.new(f36_local0) + self:setupFullWindowElement() + f36_arg0:addElement(self) + end + end + LUI.MenuTemplate.InitInGameBkg = function(f38_arg0, f38_arg1, f38_arg2, f38_arg3) + LUI.MenuTemplate.AddDarken(f38_arg0, f38_arg1, f38_arg3, 0.55) + if not Engine.IsMultiplayer() and not LUI.FlowManager.IsMenuTopmost(Engine.GetLuiRoot(), "advanced_video") then + LUI.MenuTemplate.AddWorldBlur(f38_arg0, f38_arg1) + end + end +end diff --git a/data/zone_source/build.txt b/data/zone_source/build.txt index 98e8990e..ee4895b0 100644 --- a/data/zone_source/build.txt +++ b/data/zone_source/build.txt @@ -33,3 +33,4 @@ sna_h2_mod_common sna_h2_mod_patch_af_caves spa_h2_mod_common tch_h2_mod_common +tur_h2_mod_common diff --git a/data/zone_source/h2_mod_patch_ending.csv b/data/zone_source/h2_mod_patch_ending.csv index ff17e8f1..8e90191f 100644 --- a/data/zone_source/h2_mod_patch_ending.csv +++ b/data/zone_source/h2_mod_patch_ending.csv @@ -1,2 +1,3 @@ +techset,,2d material,logo_h2mod localize,english diff --git a/data/zone_source/h2_mod_ui.csv b/data/zone_source/h2_mod_ui.csv index 47bd8fa7..ea72ff9d 100644 --- a/data/zone_source/h2_mod_ui.csv +++ b/data/zone_source/h2_mod_ui.csv @@ -1,3 +1,5 @@ +techset,,2d + material,h2_ui_featured_pip_focused material,h1_ui_featured_pip_unfocused material,h2_ui_btn_focused_stroke_square @@ -19,3 +21,131 @@ material,featured_panel_thumbnail_6 material,featured_panel_thumbnail_7 material,featured_panel_thumbnail_8 material,motd_image + +material,depot_button_rarity_corner_common +material,depot_button_rarity_corner_epic +material,depot_button_rarity_corner_legendary +material,depot_button_rarity_corner_rare +material,depot_button_rarity_corner_reward +material,depot_button_rarity_glow_common +material,depot_button_rarity_glow_epic +material,depot_button_rarity_glow_legendary +material,depot_button_rarity_glow_rare +material,depot_button_rarity_glow_reward +material,depot_button_rarity_strip_common +material,depot_button_rarity_strip_epic +material,depot_button_rarity_strip_legendary +material,depot_button_rarity_strip_rare +material,depot_button_rarity_strip_reward + +material,trophy_border +material,trophy_0 +material,trophy_1 +material,trophy_2 +material,trophy_3 +material,trophy_4 +material,trophy_5 +material,trophy_6 +material,trophy_7 +material,trophy_8 +material,trophy_9 +material,trophy_10 +material,trophy_11 +material,trophy_12 +material,trophy_13 +material,trophy_14 +material,trophy_15 +material,trophy_16 +material,trophy_17 +material,trophy_18 +material,trophy_19 +material,trophy_20 +material,trophy_21 +material,trophy_22 +material,trophy_23 +material,trophy_24 +material,trophy_25 +material,trophy_26 +material,trophy_27 +material,trophy_28 +material,trophy_29 +material,trophy_30 +material,trophy_31 +material,trophy_32 +material,trophy_33 +material,trophy_34 +material,trophy_35 +material,trophy_36 +material,trophy_37 +material,trophy_38 +material,trophy_39 +material,trophy_40 +material,trophy_41 +material,trophy_42 +material,trophy_43 +material,trophy_44 +material,trophy_45 +material,trophy_46 +material,trophy_47 +material,trophy_48 +material,trophy_49 +material,trophy_50 +material,trophy_51 +material,trophy_52 + +material,achievement_bg_0 +material,achievement_bg_1 +material,achievement_bg_2 +material,achievement_bg_3 +material,achievement_bg_4 +material,achievement_bg_5 +material,achievement_bg_6 +material,achievement_bg_7 +material,achievement_bg_8 +material,achievement_bg_9 +material,achievement_bg_10 +material,achievement_bg_11 +material,achievement_bg_12 +material,achievement_bg_13 +material,achievement_bg_14 +material,achievement_bg_15 +material,achievement_bg_16 +material,achievement_bg_17 +material,achievement_bg_18 +material,achievement_bg_19 +material,achievement_bg_20 +material,achievement_bg_21 +material,achievement_bg_22 +material,achievement_bg_23 +material,achievement_bg_24 +material,achievement_bg_25 +material,achievement_bg_26 +material,achievement_bg_27 +material,achievement_bg_28 +material,achievement_bg_29 +material,achievement_bg_30 +material,achievement_bg_31 +material,achievement_bg_32 +material,achievement_bg_33 +material,achievement_bg_34 +material,achievement_bg_35 +material,achievement_bg_36 +material,achievement_bg_37 +material,achievement_bg_38 +material,achievement_bg_39 +material,achievement_bg_40 +material,achievement_bg_41 +material,achievement_bg_42 +material,achievement_bg_43 +material,achievement_bg_44 +material,achievement_bg_45 +material,achievement_bg_46 +material,achievement_bg_47 +material,achievement_bg_48 +material,achievement_bg_49 +material,achievement_bg_50 +material,achievement_bg_51 +material,achievement_bg_52 + +localize,english +sound,ui_achievement_unlocked diff --git a/data/zone_source/tur_h2_mod_common.csv b/data/zone_source/tur_h2_mod_common.csv new file mode 100644 index 00000000..7219a8a6 --- /dev/null +++ b/data/zone_source/tur_h2_mod_common.csv @@ -0,0 +1,2 @@ +localize,turkish +stringtable,video/subtitles.csv diff --git a/data/zonetool/h2_mod_pre_gfx/font_zones.csv b/data/zonetool/h2_mod_pre_gfx/font_zones.csv index 04b2ad25..1bd85e97 100644 --- a/data/zonetool/h2_mod_pre_gfx/font_zones.csv +++ b/data/zonetool/h2_mod_pre_gfx/font_zones.csv @@ -9,3 +9,4 @@ russian,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold russian_partial,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold simplified_chinese,h2_mod_font_default,h2_mod_font_default_bold traditional_chinese,h2_mod_font_default,h2_mod_font_default_bold +turkish,h2_mod_font_bank,h2_mod_font_default,h2_mod_font_default_bold diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_0.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_0.dds new file mode 100644 index 00000000..6b739462 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_0.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_1.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_1.dds new file mode 100644 index 00000000..5968388f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_1.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_10.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_10.dds new file mode 100644 index 00000000..0d93a720 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_10.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_11.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_11.dds new file mode 100644 index 00000000..6e9166d1 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_11.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_12.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_12.dds new file mode 100644 index 00000000..26e5b4b5 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_12.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_13.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_13.dds new file mode 100644 index 00000000..cf50646d Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_13.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_14.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_14.dds new file mode 100644 index 00000000..3c2fb3d7 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_14.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_15.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_15.dds new file mode 100644 index 00000000..437c7b57 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_15.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_16.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_16.dds new file mode 100644 index 00000000..3c318818 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_16.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_17.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_17.dds new file mode 100644 index 00000000..125b0500 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_17.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_18.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_18.dds new file mode 100644 index 00000000..92bfdb34 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_18.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_19.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_19.dds new file mode 100644 index 00000000..5797f6f5 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_19.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_2.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_2.dds new file mode 100644 index 00000000..4e3b2bef Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_2.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_20.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_20.dds new file mode 100644 index 00000000..ac223807 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_20.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_21.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_21.dds new file mode 100644 index 00000000..243ab2d3 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_21.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_22.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_22.dds new file mode 100644 index 00000000..05818f06 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_22.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_23.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_23.dds new file mode 100644 index 00000000..39849067 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_23.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_24.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_24.dds new file mode 100644 index 00000000..c8c55fa3 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_24.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_25.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_25.dds new file mode 100644 index 00000000..0ef5dffd Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_25.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_26.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_26.dds new file mode 100644 index 00000000..ee1cf689 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_26.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_27.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_27.dds new file mode 100644 index 00000000..51f859f4 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_27.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_28.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_28.dds new file mode 100644 index 00000000..917f35fe Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_28.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_29.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_29.dds new file mode 100644 index 00000000..1261690b Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_29.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_3.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_3.dds new file mode 100644 index 00000000..0e327846 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_3.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_30.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_30.dds new file mode 100644 index 00000000..c947328b Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_30.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_31.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_31.dds new file mode 100644 index 00000000..081bb3cc Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_31.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_32.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_32.dds new file mode 100644 index 00000000..1bb95620 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_32.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_33.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_33.dds new file mode 100644 index 00000000..ec4ef66f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_33.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_34.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_34.dds new file mode 100644 index 00000000..7a04e5d0 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_34.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_35.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_35.dds new file mode 100644 index 00000000..8e439fe8 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_35.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_36.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_36.dds new file mode 100644 index 00000000..9a1dd39a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_36.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_37.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_37.dds new file mode 100644 index 00000000..f266bef4 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_37.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_38.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_38.dds new file mode 100644 index 00000000..ddc82840 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_38.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_39.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_39.dds new file mode 100644 index 00000000..6a7bfa69 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_39.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_4.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_4.dds new file mode 100644 index 00000000..bc474d5f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_4.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_40.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_40.dds new file mode 100644 index 00000000..d0ec6281 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_40.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_41.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_41.dds new file mode 100644 index 00000000..c9e67975 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_41.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_42.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_42.dds new file mode 100644 index 00000000..d6cc0043 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_42.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_43.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_43.dds new file mode 100644 index 00000000..036f4b50 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_43.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_44.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_44.dds new file mode 100644 index 00000000..5aca6990 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_44.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_45.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_45.dds new file mode 100644 index 00000000..587d6564 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_45.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_46.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_46.dds new file mode 100644 index 00000000..5293397f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_46.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_47.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_47.dds new file mode 100644 index 00000000..b78103dc Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_47.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_48.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_48.dds new file mode 100644 index 00000000..693cbb48 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_48.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_49.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_49.dds new file mode 100644 index 00000000..82eb2f55 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_49.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_5.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_5.dds new file mode 100644 index 00000000..676bde62 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_5.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_50.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_50.dds new file mode 100644 index 00000000..4f5eab97 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_50.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_51.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_51.dds new file mode 100644 index 00000000..9d92ed0d Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_51.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_52.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_52.dds new file mode 100644 index 00000000..4eca1f1a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_52.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_6.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_6.dds new file mode 100644 index 00000000..420106d8 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_6.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_7.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_7.dds new file mode 100644 index 00000000..79faacfd Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_7.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_8.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_8.dds new file mode 100644 index 00000000..fef1bf66 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_8.dds differ diff --git a/data/zonetool/h2_mod_ui/images/achievement_bg_9.dds b/data/zonetool/h2_mod_ui/images/achievement_bg_9.dds new file mode 100644 index 00000000..2e92f163 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/achievement_bg_9.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_common.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_common.dds new file mode 100644 index 00000000..7db2c5d5 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_common.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_epic.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_epic.dds new file mode 100644 index 00000000..25eaf163 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_epic.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_legendary.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_legendary.dds new file mode 100644 index 00000000..ce2027ca Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_legendary.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_rare.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_rare.dds new file mode 100644 index 00000000..8a19fdf6 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_rare.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_reward.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_reward.dds new file mode 100644 index 00000000..945e0e54 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_activecorner_reward.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_common.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_common.dds new file mode 100644 index 00000000..ca52e873 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_common.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_epic.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_epic.dds new file mode 100644 index 00000000..3cf6429d Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_epic.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_legendary.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_legendary.dds new file mode 100644 index 00000000..f4cf31cf Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_legendary.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_rare.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_rare.dds new file mode 100644 index 00000000..5b30948e Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_rare.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_reward.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_reward.dds new file mode 100644 index 00000000..85a40663 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_bggradient_reward.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_common.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_common.dds new file mode 100644 index 00000000..ff6fd92d Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_common.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_epic.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_epic.dds new file mode 100644 index 00000000..14b0f7e0 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_epic.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_legendary.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_legendary.dds new file mode 100644 index 00000000..0c8ec985 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_legendary.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_rare.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_rare.dds new file mode 100644 index 00000000..6d22233a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_rare.dds differ diff --git a/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_reward.dds b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_reward.dds new file mode 100644 index 00000000..e4d74eee Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/h1_depot_rarity_leftstrip_reward.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_0.dds b/data/zonetool/h2_mod_ui/images/trophy_0.dds new file mode 100644 index 00000000..2f223e61 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_0.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_1.dds b/data/zonetool/h2_mod_ui/images/trophy_1.dds new file mode 100644 index 00000000..0bfdc771 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_1.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_10.dds b/data/zonetool/h2_mod_ui/images/trophy_10.dds new file mode 100644 index 00000000..9ccacd8a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_10.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_11.dds b/data/zonetool/h2_mod_ui/images/trophy_11.dds new file mode 100644 index 00000000..1bd4d3c7 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_11.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_12.dds b/data/zonetool/h2_mod_ui/images/trophy_12.dds new file mode 100644 index 00000000..ea4f219f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_12.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_13.dds b/data/zonetool/h2_mod_ui/images/trophy_13.dds new file mode 100644 index 00000000..ce3c260a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_13.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_14.dds b/data/zonetool/h2_mod_ui/images/trophy_14.dds new file mode 100644 index 00000000..74f2aa19 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_14.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_15.dds b/data/zonetool/h2_mod_ui/images/trophy_15.dds new file mode 100644 index 00000000..7e132b2a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_15.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_16.dds b/data/zonetool/h2_mod_ui/images/trophy_16.dds new file mode 100644 index 00000000..b58b4089 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_16.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_17.dds b/data/zonetool/h2_mod_ui/images/trophy_17.dds new file mode 100644 index 00000000..5b66a8f9 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_17.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_18.dds b/data/zonetool/h2_mod_ui/images/trophy_18.dds new file mode 100644 index 00000000..362b5893 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_18.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_19.dds b/data/zonetool/h2_mod_ui/images/trophy_19.dds new file mode 100644 index 00000000..aed97df1 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_19.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_2.dds b/data/zonetool/h2_mod_ui/images/trophy_2.dds new file mode 100644 index 00000000..b7a2acae Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_2.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_20.dds b/data/zonetool/h2_mod_ui/images/trophy_20.dds new file mode 100644 index 00000000..f229d041 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_20.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_21.dds b/data/zonetool/h2_mod_ui/images/trophy_21.dds new file mode 100644 index 00000000..da207c20 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_21.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_22.dds b/data/zonetool/h2_mod_ui/images/trophy_22.dds new file mode 100644 index 00000000..7f0d11c5 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_22.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_23.dds b/data/zonetool/h2_mod_ui/images/trophy_23.dds new file mode 100644 index 00000000..ffb5cb9d Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_23.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_24.dds b/data/zonetool/h2_mod_ui/images/trophy_24.dds new file mode 100644 index 00000000..49b76a93 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_24.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_25.dds b/data/zonetool/h2_mod_ui/images/trophy_25.dds new file mode 100644 index 00000000..97270e16 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_25.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_26.dds b/data/zonetool/h2_mod_ui/images/trophy_26.dds new file mode 100644 index 00000000..f3cd36ea Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_26.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_27.dds b/data/zonetool/h2_mod_ui/images/trophy_27.dds new file mode 100644 index 00000000..c9d9ecf3 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_27.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_28.dds b/data/zonetool/h2_mod_ui/images/trophy_28.dds new file mode 100644 index 00000000..86771651 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_28.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_29.dds b/data/zonetool/h2_mod_ui/images/trophy_29.dds new file mode 100644 index 00000000..121300bb Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_29.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_3.dds b/data/zonetool/h2_mod_ui/images/trophy_3.dds new file mode 100644 index 00000000..312eba3b Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_3.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_30.dds b/data/zonetool/h2_mod_ui/images/trophy_30.dds new file mode 100644 index 00000000..d09f1ff1 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_30.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_31.dds b/data/zonetool/h2_mod_ui/images/trophy_31.dds new file mode 100644 index 00000000..b786c305 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_31.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_32.dds b/data/zonetool/h2_mod_ui/images/trophy_32.dds new file mode 100644 index 00000000..e454de31 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_32.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_33.dds b/data/zonetool/h2_mod_ui/images/trophy_33.dds new file mode 100644 index 00000000..79d7aed1 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_33.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_34.dds b/data/zonetool/h2_mod_ui/images/trophy_34.dds new file mode 100644 index 00000000..8632404a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_34.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_35.dds b/data/zonetool/h2_mod_ui/images/trophy_35.dds new file mode 100644 index 00000000..c9bfb76b Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_35.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_36.dds b/data/zonetool/h2_mod_ui/images/trophy_36.dds new file mode 100644 index 00000000..09761390 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_36.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_37.dds b/data/zonetool/h2_mod_ui/images/trophy_37.dds new file mode 100644 index 00000000..238f18aa Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_37.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_38.dds b/data/zonetool/h2_mod_ui/images/trophy_38.dds new file mode 100644 index 00000000..97534e23 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_38.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_39.dds b/data/zonetool/h2_mod_ui/images/trophy_39.dds new file mode 100644 index 00000000..07d91323 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_39.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_4.dds b/data/zonetool/h2_mod_ui/images/trophy_4.dds new file mode 100644 index 00000000..593b4009 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_4.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_40.dds b/data/zonetool/h2_mod_ui/images/trophy_40.dds new file mode 100644 index 00000000..6309ce6f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_40.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_41.dds b/data/zonetool/h2_mod_ui/images/trophy_41.dds new file mode 100644 index 00000000..fddfd0d4 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_41.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_42.dds b/data/zonetool/h2_mod_ui/images/trophy_42.dds new file mode 100644 index 00000000..14a4b1e1 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_42.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_43.dds b/data/zonetool/h2_mod_ui/images/trophy_43.dds new file mode 100644 index 00000000..541c0701 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_43.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_44.dds b/data/zonetool/h2_mod_ui/images/trophy_44.dds new file mode 100644 index 00000000..219d280c Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_44.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_45.dds b/data/zonetool/h2_mod_ui/images/trophy_45.dds new file mode 100644 index 00000000..3957fdb0 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_45.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_46.dds b/data/zonetool/h2_mod_ui/images/trophy_46.dds new file mode 100644 index 00000000..d6dc6b56 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_46.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_47.dds b/data/zonetool/h2_mod_ui/images/trophy_47.dds new file mode 100644 index 00000000..d4731772 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_47.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_48.dds b/data/zonetool/h2_mod_ui/images/trophy_48.dds new file mode 100644 index 00000000..a1f666e8 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_48.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_49.dds b/data/zonetool/h2_mod_ui/images/trophy_49.dds new file mode 100644 index 00000000..a919e5c2 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_49.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_5.dds b/data/zonetool/h2_mod_ui/images/trophy_5.dds new file mode 100644 index 00000000..67b12653 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_5.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_50.dds b/data/zonetool/h2_mod_ui/images/trophy_50.dds new file mode 100644 index 00000000..67940071 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_50.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_51.dds b/data/zonetool/h2_mod_ui/images/trophy_51.dds new file mode 100644 index 00000000..84cfe5f5 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_51.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_52.dds b/data/zonetool/h2_mod_ui/images/trophy_52.dds new file mode 100644 index 00000000..887cde3f Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_52.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_6.dds b/data/zonetool/h2_mod_ui/images/trophy_6.dds new file mode 100644 index 00000000..277dfa2a Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_6.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_7.dds b/data/zonetool/h2_mod_ui/images/trophy_7.dds new file mode 100644 index 00000000..ca44e124 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_7.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_8.dds b/data/zonetool/h2_mod_ui/images/trophy_8.dds new file mode 100644 index 00000000..fad6ccdf Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_8.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_9.dds b/data/zonetool/h2_mod_ui/images/trophy_9.dds new file mode 100644 index 00000000..f20a8812 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_9.dds differ diff --git a/data/zonetool/h2_mod_ui/images/trophy_border.dds b/data/zonetool/h2_mod_ui/images/trophy_border.dds new file mode 100644 index 00000000..8b5bec55 Binary files /dev/null and b/data/zonetool/h2_mod_ui/images/trophy_border.dds differ diff --git a/data/zonetool/h2_mod_ui/loaded_sound/ui/ui_achievement_unlocked.wav b/data/zonetool/h2_mod_ui/loaded_sound/ui/ui_achievement_unlocked.wav new file mode 100644 index 00000000..fd4e046c Binary files /dev/null and b/data/zonetool/h2_mod_ui/loaded_sound/ui/ui_achievement_unlocked.wav differ diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_0.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_0.json new file mode 100644 index 00000000..6889fc74 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_0.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_0", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_0", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_1.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_1.json new file mode 100644 index 00000000..08ce3e6f --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_1.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_1", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_1", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_10.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_10.json new file mode 100644 index 00000000..b869d020 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_10.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_10", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_10", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_11.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_11.json new file mode 100644 index 00000000..1187c16a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_11.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_11", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_11", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_12.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_12.json new file mode 100644 index 00000000..8a66cbd9 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_12.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_12", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_12", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_13.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_13.json new file mode 100644 index 00000000..b2226273 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_13.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_13", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_13", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_14.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_14.json new file mode 100644 index 00000000..41c73af5 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_14.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_14", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_14", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_15.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_15.json new file mode 100644 index 00000000..26f7fda2 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_15.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_15", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_15", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_16.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_16.json new file mode 100644 index 00000000..b9f8b231 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_16.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_16", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_16", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_17.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_17.json new file mode 100644 index 00000000..47a19a25 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_17.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_17", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_17", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_18.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_18.json new file mode 100644 index 00000000..ece18443 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_18.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_18", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_18", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_19.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_19.json new file mode 100644 index 00000000..fffa5564 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_19.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_19", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_19", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_2.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_2.json new file mode 100644 index 00000000..dee3b938 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_2.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_2", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_2", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_20.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_20.json new file mode 100644 index 00000000..1f235d31 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_20.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_20", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_20", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_21.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_21.json new file mode 100644 index 00000000..aa3fc118 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_21.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_21", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_21", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_22.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_22.json new file mode 100644 index 00000000..b582b7db --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_22.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_22", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_22", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_23.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_23.json new file mode 100644 index 00000000..0c671712 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_23.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_23", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_23", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_24.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_24.json new file mode 100644 index 00000000..f4fc4aef --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_24.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_24", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_24", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_25.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_25.json new file mode 100644 index 00000000..f21f82c5 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_25.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_25", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_25", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_26.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_26.json new file mode 100644 index 00000000..14dd6e39 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_26.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_26", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_26", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_27.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_27.json new file mode 100644 index 00000000..c2ce6736 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_27.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_27", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_27", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_28.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_28.json new file mode 100644 index 00000000..e7f85471 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_28.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_28", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_28", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_29.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_29.json new file mode 100644 index 00000000..ee6d8c88 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_29.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_29", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_29", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_3.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_3.json new file mode 100644 index 00000000..68653d95 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_3.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_3", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_3", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_30.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_30.json new file mode 100644 index 00000000..86bb4e8a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_30.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_30", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_30", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_31.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_31.json new file mode 100644 index 00000000..29348bda --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_31.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_31", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_31", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_32.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_32.json new file mode 100644 index 00000000..700b27b5 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_32.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_32", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_32", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_33.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_33.json new file mode 100644 index 00000000..99d030a8 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_33.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_33", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_33", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_34.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_34.json new file mode 100644 index 00000000..322d13d6 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_34.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_34", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_34", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_35.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_35.json new file mode 100644 index 00000000..674c2a95 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_35.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_35", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_35", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_36.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_36.json new file mode 100644 index 00000000..7dcd3bb2 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_36.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_36", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_36", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_37.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_37.json new file mode 100644 index 00000000..6d5dfa98 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_37.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_37", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_37", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_38.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_38.json new file mode 100644 index 00000000..1288925c --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_38.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_38", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_38", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_39.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_39.json new file mode 100644 index 00000000..64f0ac30 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_39.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_39", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_39", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_4.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_4.json new file mode 100644 index 00000000..05f09045 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_4.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_4", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_4", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_40.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_40.json new file mode 100644 index 00000000..658930d9 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_40.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_40", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_40", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_41.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_41.json new file mode 100644 index 00000000..2472089e --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_41.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_41", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_41", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_42.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_42.json new file mode 100644 index 00000000..b73f38a0 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_42.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_42", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_42", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_43.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_43.json new file mode 100644 index 00000000..979d76f1 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_43.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_43", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_43", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_44.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_44.json new file mode 100644 index 00000000..7f7e1600 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_44.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_44", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_44", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_45.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_45.json new file mode 100644 index 00000000..383fa742 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_45.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_45", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_45", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_46.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_46.json new file mode 100644 index 00000000..b55f00b7 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_46.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_46", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_46", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_47.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_47.json new file mode 100644 index 00000000..15ac49ef --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_47.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_47", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_47", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_48.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_48.json new file mode 100644 index 00000000..49e8db72 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_48.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_48", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_48", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_49.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_49.json new file mode 100644 index 00000000..ca59e010 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_49.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_49", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_49", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_5.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_5.json new file mode 100644 index 00000000..156f4cb3 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_5.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_5", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_5", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_50.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_50.json new file mode 100644 index 00000000..afc122f2 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_50.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_50", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_50", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_51.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_51.json new file mode 100644 index 00000000..18ac1772 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_51.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_51", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_51", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_52.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_52.json new file mode 100644 index 00000000..34cf49b9 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_52.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_52", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_52", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_6.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_6.json new file mode 100644 index 00000000..a39530af --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_6.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_6", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_6", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_7.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_7.json new file mode 100644 index 00000000..da80ba87 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_7.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_7", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_7", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_8.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_8.json new file mode 100644 index 00000000..5270fcc1 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_8.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_8", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_8", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/achievement_bg_9.json b/data/zonetool/h2_mod_ui/materials/achievement_bg_9.json new file mode 100644 index 00000000..91cc07c6 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/achievement_bg_9.json @@ -0,0 +1,26 @@ +{ + "name": "achievement_bg_9", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "achievement_bg_9", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_common.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_common.json new file mode 100644 index 00000000..6b77e5a9 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_common.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_corner_common", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_activecorner_common", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_epic.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_epic.json new file mode 100644 index 00000000..bb96077a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_epic.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_corner_epic", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_activecorner_epic", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_legendary.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_legendary.json new file mode 100644 index 00000000..11b1b9d4 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_legendary.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_corner_legendary", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_activecorner_legendary", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_rare.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_rare.json new file mode 100644 index 00000000..99cba84b --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_rare.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_corner_rare", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_activecorner_rare", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_reward.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_reward.json new file mode 100644 index 00000000..70d68de0 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_corner_reward.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_corner_reward", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_activecorner_reward", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_common.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_common.json new file mode 100644 index 00000000..7d4e1be4 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_common.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_glow_common", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_bggradient_common", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_epic.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_epic.json new file mode 100644 index 00000000..b7b0d3ec --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_epic.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_glow_epic", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_bggradient_epic", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_legendary.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_legendary.json new file mode 100644 index 00000000..c6565e2c --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_legendary.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_glow_legendary", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_bggradient_legendary", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_rare.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_rare.json new file mode 100644 index 00000000..e07a7986 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_rare.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_glow_rare", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_bggradient_rare", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_reward.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_reward.json new file mode 100644 index 00000000..d212cca7 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_glow_reward.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_glow_reward", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_bggradient_reward", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_common.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_common.json new file mode 100644 index 00000000..657f32be --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_common.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_strip_common", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_leftstrip_common", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_epic.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_epic.json new file mode 100644 index 00000000..0968d736 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_epic.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_strip_epic", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_leftstrip_epic", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_legendary.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_legendary.json new file mode 100644 index 00000000..38d8f998 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_legendary.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_strip_legendary", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_leftstrip_legendary", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_rare.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_rare.json new file mode 100644 index 00000000..1452f6eb --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_rare.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_strip_rare", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_leftstrip_rare", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_reward.json b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_reward.json new file mode 100644 index 00000000..21ce6e8c --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/depot_button_rarity_strip_reward.json @@ -0,0 +1,26 @@ +{ + "name": "depot_button_rarity_strip_reward", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 61, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 14, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "h1_depot_rarity_leftstrip_reward", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_0.json b/data/zonetool/h2_mod_ui/materials/trophy_0.json new file mode 100644 index 00000000..e52fe383 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_0.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_0", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_0", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_1.json b/data/zonetool/h2_mod_ui/materials/trophy_1.json new file mode 100644 index 00000000..a004f76f --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_1.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_1", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_1", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_10.json b/data/zonetool/h2_mod_ui/materials/trophy_10.json new file mode 100644 index 00000000..87809e77 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_10.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_10", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_10", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_11.json b/data/zonetool/h2_mod_ui/materials/trophy_11.json new file mode 100644 index 00000000..1d0de13a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_11.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_11", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_11", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_12.json b/data/zonetool/h2_mod_ui/materials/trophy_12.json new file mode 100644 index 00000000..c910775a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_12.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_12", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_12", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_13.json b/data/zonetool/h2_mod_ui/materials/trophy_13.json new file mode 100644 index 00000000..e762623a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_13.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_13", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_13", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_14.json b/data/zonetool/h2_mod_ui/materials/trophy_14.json new file mode 100644 index 00000000..fff12ee2 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_14.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_14", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_14", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_15.json b/data/zonetool/h2_mod_ui/materials/trophy_15.json new file mode 100644 index 00000000..5c2a3ad0 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_15.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_15", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_15", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_16.json b/data/zonetool/h2_mod_ui/materials/trophy_16.json new file mode 100644 index 00000000..c178e307 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_16.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_16", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_16", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_17.json b/data/zonetool/h2_mod_ui/materials/trophy_17.json new file mode 100644 index 00000000..1d0e8e1c --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_17.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_17", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_17", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_18.json b/data/zonetool/h2_mod_ui/materials/trophy_18.json new file mode 100644 index 00000000..cd2c6c07 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_18.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_18", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_18", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_19.json b/data/zonetool/h2_mod_ui/materials/trophy_19.json new file mode 100644 index 00000000..b107bbce --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_19.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_19", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_19", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_2.json b/data/zonetool/h2_mod_ui/materials/trophy_2.json new file mode 100644 index 00000000..12af97d6 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_2.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_2", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_2", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_20.json b/data/zonetool/h2_mod_ui/materials/trophy_20.json new file mode 100644 index 00000000..a626c97e --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_20.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_20", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_20", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_21.json b/data/zonetool/h2_mod_ui/materials/trophy_21.json new file mode 100644 index 00000000..3e50bbd8 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_21.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_21", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_21", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_22.json b/data/zonetool/h2_mod_ui/materials/trophy_22.json new file mode 100644 index 00000000..94f51cd8 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_22.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_22", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_22", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_23.json b/data/zonetool/h2_mod_ui/materials/trophy_23.json new file mode 100644 index 00000000..acc5773c --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_23.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_23", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_23", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_24.json b/data/zonetool/h2_mod_ui/materials/trophy_24.json new file mode 100644 index 00000000..ad095654 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_24.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_24", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_24", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_25.json b/data/zonetool/h2_mod_ui/materials/trophy_25.json new file mode 100644 index 00000000..d64855d0 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_25.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_25", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_25", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_26.json b/data/zonetool/h2_mod_ui/materials/trophy_26.json new file mode 100644 index 00000000..94c964a1 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_26.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_26", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_26", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_27.json b/data/zonetool/h2_mod_ui/materials/trophy_27.json new file mode 100644 index 00000000..1857b27a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_27.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_27", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_27", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_28.json b/data/zonetool/h2_mod_ui/materials/trophy_28.json new file mode 100644 index 00000000..b9498411 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_28.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_28", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_28", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_29.json b/data/zonetool/h2_mod_ui/materials/trophy_29.json new file mode 100644 index 00000000..1221cbfc --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_29.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_29", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_29", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_3.json b/data/zonetool/h2_mod_ui/materials/trophy_3.json new file mode 100644 index 00000000..f4a4d720 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_3.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_3", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_3", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_30.json b/data/zonetool/h2_mod_ui/materials/trophy_30.json new file mode 100644 index 00000000..1cf51342 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_30.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_30", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_30", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_31.json b/data/zonetool/h2_mod_ui/materials/trophy_31.json new file mode 100644 index 00000000..b89fbac5 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_31.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_31", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_31", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_32.json b/data/zonetool/h2_mod_ui/materials/trophy_32.json new file mode 100644 index 00000000..2173f814 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_32.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_32", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_32", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_33.json b/data/zonetool/h2_mod_ui/materials/trophy_33.json new file mode 100644 index 00000000..04e366c7 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_33.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_33", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_33", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_34.json b/data/zonetool/h2_mod_ui/materials/trophy_34.json new file mode 100644 index 00000000..30ee35d7 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_34.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_34", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_34", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_35.json b/data/zonetool/h2_mod_ui/materials/trophy_35.json new file mode 100644 index 00000000..5587502f --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_35.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_35", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_35", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_36.json b/data/zonetool/h2_mod_ui/materials/trophy_36.json new file mode 100644 index 00000000..7da175db --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_36.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_36", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_36", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_37.json b/data/zonetool/h2_mod_ui/materials/trophy_37.json new file mode 100644 index 00000000..fd50278b --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_37.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_37", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_37", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_38.json b/data/zonetool/h2_mod_ui/materials/trophy_38.json new file mode 100644 index 00000000..9726c743 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_38.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_38", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_38", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_39.json b/data/zonetool/h2_mod_ui/materials/trophy_39.json new file mode 100644 index 00000000..3354b8aa --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_39.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_39", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_39", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_4.json b/data/zonetool/h2_mod_ui/materials/trophy_4.json new file mode 100644 index 00000000..cdf3755a --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_4.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_4", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_4", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_40.json b/data/zonetool/h2_mod_ui/materials/trophy_40.json new file mode 100644 index 00000000..9fbdc7ef --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_40.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_40", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_40", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_41.json b/data/zonetool/h2_mod_ui/materials/trophy_41.json new file mode 100644 index 00000000..a696215d --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_41.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_41", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_41", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_42.json b/data/zonetool/h2_mod_ui/materials/trophy_42.json new file mode 100644 index 00000000..7fbfaf54 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_42.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_42", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_42", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_43.json b/data/zonetool/h2_mod_ui/materials/trophy_43.json new file mode 100644 index 00000000..d8917b33 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_43.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_43", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_43", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_44.json b/data/zonetool/h2_mod_ui/materials/trophy_44.json new file mode 100644 index 00000000..0b468cb8 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_44.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_44", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_44", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_45.json b/data/zonetool/h2_mod_ui/materials/trophy_45.json new file mode 100644 index 00000000..753bdd64 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_45.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_45", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_45", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_46.json b/data/zonetool/h2_mod_ui/materials/trophy_46.json new file mode 100644 index 00000000..752254a0 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_46.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_46", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_46", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_47.json b/data/zonetool/h2_mod_ui/materials/trophy_47.json new file mode 100644 index 00000000..48751180 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_47.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_47", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_47", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_48.json b/data/zonetool/h2_mod_ui/materials/trophy_48.json new file mode 100644 index 00000000..c56a2c98 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_48.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_48", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_48", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_49.json b/data/zonetool/h2_mod_ui/materials/trophy_49.json new file mode 100644 index 00000000..ff714807 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_49.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_49", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_49", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_5.json b/data/zonetool/h2_mod_ui/materials/trophy_5.json new file mode 100644 index 00000000..338edfdd --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_5.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_5", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_5", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_50.json b/data/zonetool/h2_mod_ui/materials/trophy_50.json new file mode 100644 index 00000000..89f2e803 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_50.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_50", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_50", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_51.json b/data/zonetool/h2_mod_ui/materials/trophy_51.json new file mode 100644 index 00000000..53b97db1 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_51.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_51", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_51", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_52.json b/data/zonetool/h2_mod_ui/materials/trophy_52.json new file mode 100644 index 00000000..9314dbca --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_52.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_52", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_52", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_6.json b/data/zonetool/h2_mod_ui/materials/trophy_6.json new file mode 100644 index 00000000..8f3765ff --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_6.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_6", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_6", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_7.json b/data/zonetool/h2_mod_ui/materials/trophy_7.json new file mode 100644 index 00000000..208500f6 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_7.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_7", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_7", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_8.json b/data/zonetool/h2_mod_ui/materials/trophy_8.json new file mode 100644 index 00000000..783f96f5 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_8.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_8", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_8", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_9.json b/data/zonetool/h2_mod_ui/materials/trophy_9.json new file mode 100644 index 00000000..93bae362 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_9.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_9", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_9", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/materials/trophy_border.json b/data/zonetool/h2_mod_ui/materials/trophy_border.json new file mode 100644 index 00000000..a306a105 --- /dev/null +++ b/data/zonetool/h2_mod_ui/materials/trophy_border.json @@ -0,0 +1,26 @@ +{ + "name": "trophy_border", + "techniqueSet->name": "2d", + "gameFlags": 0, + "sortKey": 60, + "renderFlags": 0, + "textureAtlasRowCount": 1, + "textureAtlasColumnCount": 1, + "textureAtlasFrameBlend": 0, + "textureAtlasAsArray": 0, + "surfaceTypeBits": 0, + "cameraRegion": 12, + "materialType": 0, + "assetFlags": 0, + "constantTable": null, + "textureTable": [ + { + "image": "trophy_border", + "semantic": 0, + "samplerState": 226, + "lastCharacter": 112, + "firstCharacter": 99, + "typeHash": 2695565377 + } + ] +} \ No newline at end of file diff --git a/data/zonetool/h2_mod_ui/sounds/ui_achievement_unlocked.json b/data/zonetool/h2_mod_ui/sounds/ui_achievement_unlocked.json new file mode 100644 index 00000000..9bd08cd9 --- /dev/null +++ b/data/zonetool/h2_mod_ui/sounds/ui_achievement_unlocked.json @@ -0,0 +1,192 @@ +{ + "aliasName": "ui_achievement_unlocked", + "count": 1, + "head": [ + { + "aliasName": "ui_achievement_unlocked", + "secondaryAliasName": null, + "chainAliasName": null, + "subtitle": null, + "mixerGroup": null, + "soundfile": { + "type": 1, + "exists": true, + "name": "ui/ui_achievement_unlocked" + }, + "flags": 1048730, + "priority": 20, + "dspBus": "interface", + "volMod": "hud", + "volMin": 1.0, + "volMax": 1.0, + "pitchMin": 1.0, + "pitchMax": 1.0, + "distMin": 120.0, + "distMax": 600.0, + "velocityMin": 0.0, + "probability": 1.0, + "sequence": 1, + "startDelay": 0, + "masterPriority": 70, + "masterPercentage": 0.0, + "slavePercentage": 1.0, + "playbackPercentage": 100, + "lfePercentage": 0.0, + "centerPercentage": 0.0, + "poly": 1, + "polyGlobal": 174, + "polyEntityType": 0, + "polyGlobalType": 0, + "envelopMin": 0.0, + "envelopMax": 0.0, + "envelopPercentage": 0.0, + "reverbWetMixOverride": 0.0, + "reverbMultiplier": 1.0, + "smartPanDistance2d": 0.0, + "smartPanDistance3d": 0.0, + "smartPanAttenuation3d": 1.0, + "stereo3dAngle": 0, + "stereo3dStart": 0.0, + "stereo3dEnd": 0.0, + "sndContext": null, + "sndCurve": "$default", + "lpfCurve": "$default", + "hpfCurve": "$defaultHpf", + "reverbSendCurve": "$default", + "speakerMap": { + "channelMaps": [ + { + "speakerCount": 2, + "speakers": [ + { + "levels0": 1.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 0 + }, + { + "levels0": 1.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 1 + } + ] + }, + { + "speakerCount": 6, + "speakers": [ + { + "levels0": 1.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 0 + }, + { + "levels0": 1.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 1 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 2 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 3 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 4 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 1, + "speaker": 5 + } + ] + }, + { + "speakerCount": 2, + "speakers": [ + { + "levels0": 1.0, + "levels1": 0.0, + "numLevels": 2, + "speaker": 0 + }, + { + "levels0": 0.0, + "levels1": 1.0, + "numLevels": 2, + "speaker": 1 + } + ] + }, + { + "speakerCount": 6, + "speakers": [ + { + "levels0": 1.0, + "levels1": 0.0, + "numLevels": 2, + "speaker": 0 + }, + { + "levels0": 0.0, + "levels1": 1.0, + "numLevels": 2, + "speaker": 1 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 2, + "speaker": 2 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 2, + "speaker": 3 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 2, + "speaker": 4 + }, + { + "levels0": 0.0, + "levels1": 0.0, + "numLevels": 2, + "speaker": 5 + } + ] + } + ], + "isDefault": false, + "name": "front_only" + }, + "allowDoppler": 0, + "dopplerPreset": null, + "unknown": { + "pad": [ + { + "bytes": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "subtype": null + } + ], + "u1": 4, + "u2": 0.5011872053146362 + } + } + ] +} \ No newline at end of file diff --git a/data/zonetool/localizedstrings/arabic.json b/data/zonetool/localizedstrings/arabic.json index 0c838621..f322fdeb 100644 --- a/data/zonetool/localizedstrings/arabic.json +++ b/data/zonetool/localizedstrings/arabic.json @@ -21,5 +21,13 @@ "LUA_MENU_FALLBACK_ENABLE": "ةصّصخم طوطخ مدختسا", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "ﻓﺘﺢ ﺟﻤﻴﻊ ﺍﻟﻤﻬﺎﻡ.", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "ﺇﻟﻐﺎء ﺍﻟﻔﺘﺢ" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "ﺇﻟﻐﺎء ﺍﻟﻔﺘﺢ", + + "LUA_MENU_ACHIEVEMENTS": "تازاجنإلا", + "LUA_MENU_ACHIEVEMENTS_DESC": ".تازاجنإلا ضرع", + + "ACHIEVEMENT_EARNED": "!قحتسم زاجنإ", + + "DEPOT_GO_TO_THE_DEPOT": "طبارلا حتف", + "MENU_OPEN_MOTD": "مويلا ةلاسر" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/czech.json b/data/zonetool/localizedstrings/czech.json index df42afaf..5ce2fdd4 100644 --- a/data/zonetool/localizedstrings/czech.json +++ b/data/zonetool/localizedstrings/czech.json @@ -17,6 +17,14 @@ "LOCALE_15": "Korejština", "LOCALE_16": "Angličtina (bezrizikový)", "LOCALE_17": "Ruština (částečně)", + + "LUA_MENU_ACHIEVEMENTS": "ACHIEVEMENTY", + "LUA_MENU_ACHIEVEMENTS_DESC": "Vaše odemčené achievementy.", + + "ACHIEVEMENT_HIDDEN": "Tajný herní úspěch", + "ACHIEVEMENT_HIDDEN_DESC": "Hrajte dál a odemkněte ho", + "ACHIEVEMENT_EARNED": "Achievement odemčen!", + "LUA_MENU_FALLBACK_DISABLE": "Používat výchozí písma", "LUA_MENU_FALLBACK_ENABLE": "Používat písma h2-mod", "PRESENCE_SP_AF_CAVES": "Jako za starých časů", @@ -5607,5 +5615,8 @@ "SUBTITLE_ROADKILL_INTRO_RPG": "^2Ranger: ^7RPG!!!", "SUBTITLE_TRAIN_FLY_WELCOME": "^2Sgt. Foley: ^7Vítejte na kurzu mladého bojovníka.", "SUBTITLE_FAVELA_GST_NOHESNOT": "^2Ghost: ^7Už ne!", - "SUBTITLE_ROADKILL_AR4_ONEONTHELEFT": "^2Ranger: ^7Ten na levé straně." + "SUBTITLE_ROADKILL_AR4_ONEONTHELEFT": "^2Ranger: ^7Ten na levé straně.", + + "DEPOT_GO_TO_THE_DEPOT": "Otevřít odkaz", + "MENU_OPEN_MOTD": "Zpráva dne" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/english.json b/data/zonetool/localizedstrings/english.json index 184e3e0a..665174ef 100644 --- a/data/zonetool/localizedstrings/english.json +++ b/data/zonetool/localizedstrings/english.json @@ -17,6 +17,8 @@ "LOCALE_15": "Korean", "LOCALE_16": "English (Safe)", "LOCALE_17": "Russian (Partial)", + "LOCALE_18": "Turkish", + "LUA_MENU_FALLBACK_DISABLE": "Apply built-in fonts", "LUA_MENU_FALLBACK_ENABLE": "Apply h2-mod fonts", @@ -64,6 +66,9 @@ "LUA_MENU_INTRO": "Intro movie", "LUA_MENU_INTRO_DESC": "Show or skip intro movie with companies' logos on startup.", + "MENU_MUSIC_VOLUME": "Music Volume", + "MENU_MUSIC_VOLUME_DESC": "Move the slider to adjust the volume of the music.", + "MENU_SYSINFO_CUSTOMER_SUPPORT_LINK": "Github Page:", "MENU_SYSINFO_CUSTOMER_SUPPORT_URL": "https://github.com/fedddddd/h2-mod", "MENU_SYSINFO_DONATION_LINK": "Donation link:", @@ -87,6 +92,7 @@ "MENU_KOREAN": "한국어", "MENU_ENGLISH_SAFE": "English (Safe)", "MENU_RUSSIAN_PARTIAL": "Русский (Англ. озвучка)", + "MENU_TURKISH": "Türkçe", "MENU_CREDITS_1": "momo5502", "MENU_CREDITS_2": "Vlad", @@ -119,5 +125,119 @@ "LUA_MENU_SP_LOCATION_MUSEUM": "LUA_MENU_SP_LOCATION_MUSEUM", "DEPOT_GO_TO_THE_DEPOT": "Open link", - "MENU_OPEN_MOTD": "Open Message of the Day" -} \ No newline at end of file + "MENU_OPEN_MOTD": "Open Message of the Day", + + "LUA_MENU_ACHIEVEMENTS": "ACHIEVEMENTS", + "LUA_MENU_ACHIEVEMENTS_DESC": "View achievements.", + "LUA_MENU_UNKNOWN_ACHIEVEMENT": "???", + + "ACHIEVEMENT_HIDDEN": "Secret achievement", + "ACHIEVEMENT_HIDDEN_DESC": "Keep playing to unlock it", + "ACHIEVEMENT_EARNED": "Achievement Unlocked!", + "ACHIEVEMENT_NAME_0": "Is That All You Got?", + "ACHIEVEMENT_DETAIL_0": "Earn all available trophies for Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "Back in the Saddle", + "ACHIEVEMENT_DETAIL_1": "Help train the local militia.", + "ACHIEVEMENT_NAME_2": "Danger Close", + "ACHIEVEMENT_DETAIL_2": "Get hand picked for Shepherd's elite squad.", + "ACHIEVEMENT_NAME_3": "Cold Shoulder", + "ACHIEVEMENT_DETAIL_3": "Infiltrate the snowy mountain side base.", + "ACHIEVEMENT_NAME_4": "Tag 'em and bag 'em", + "ACHIEVEMENT_DETAIL_4": "Find Rojas in the Favelas.", + "ACHIEVEMENT_NAME_5": "Royale with Cheese", + "ACHIEVEMENT_DETAIL_5": "Defend Burger Town.", + "ACHIEVEMENT_NAME_6": "Soap on a Rope", + "ACHIEVEMENT_DETAIL_6": "Storm the gulag.", + "ACHIEVEMENT_NAME_7": "Desperate Times", + "ACHIEVEMENT_DETAIL_7": "Execute the plan to help the Americans.", + "ACHIEVEMENT_NAME_8": "Whiskey Hotel", + "ACHIEVEMENT_DETAIL_8": "Take back Whiskey Hotel.", + "ACHIEVEMENT_NAME_9": "The Pawn", + "ACHIEVEMENT_DETAIL_9": "Assault Makarov's safehouse.", + "ACHIEVEMENT_NAME_10": "Out of the Frying Pan...", + "ACHIEVEMENT_DETAIL_10": "Complete the mission in the airplane graveyard.", + "ACHIEVEMENT_NAME_11": "For the Record", + "ACHIEVEMENT_DETAIL_11": "Complete the single player campaign on any difficulty.", + "ACHIEVEMENT_NAME_12": "The Price of War", + "ACHIEVEMENT_DETAIL_12": "Complete the single player campaign on Hardened or Veteran difficulty.", + "ACHIEVEMENT_NAME_13": "First Day of School", + "ACHIEVEMENT_DETAIL_13": "Complete 'S.S.D.D.' and 'Team Player' on Veteran difficulty.", + "ACHIEVEMENT_NAME_14": "Black Diamond", + "ACHIEVEMENT_DETAIL_14": "Complete 'Cliffhanger' on Veteran difficulty.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Complete 'Takedown' and 'The Hornet's Nest' on Veteran difficulty.", + "ACHIEVEMENT_NAME_16": "Red Dawn", + "ACHIEVEMENT_DETAIL_16": "Complete 'Wolverines!' and 'Exodus' on Veteran difficulty.", + "ACHIEVEMENT_NAME_17": "Prisoner 627", + "ACHIEVEMENT_DETAIL_17": "Complete 'The Only Easy Day... Was Yesterday' and 'The Gulag' on Veteran difficulty.", + "ACHIEVEMENT_NAME_18": "Ends Justify the Means", + "ACHIEVEMENT_DETAIL_18": "Complete 'Contingency' on Veteran difficulty.", + "ACHIEVEMENT_NAME_19": "Homecoming", + "ACHIEVEMENT_DETAIL_19": "Complete 'Of Their Own Accord', 'Second Sun', and 'Whiskey Hotel' on Veteran difficulty.", + "ACHIEVEMENT_NAME_20": "Queen takes Rook", + "ACHIEVEMENT_DETAIL_20": "Complete 'Loose Ends' and 'The Enemy of My Enemy' on Veteran difficulty.", + "ACHIEVEMENT_NAME_21": "Off the Grid", + "ACHIEVEMENT_DETAIL_21": "Complete 'Just Like Old Times' and 'Endgame' on Veteran difficulty.", + "ACHIEVEMENT_NAME_22": "Pit Boss", + "ACHIEVEMENT_DETAIL_22": "Run The Pit in 'S.S.D.D.' and finish with a final time under 30 seconds.", + "ACHIEVEMENT_NAME_23": "Ghost", + "ACHIEVEMENT_DETAIL_23": "Plant the C4 in 'Cliffhanger' without alerting or injuring anyone in the blizzard.", + "ACHIEVEMENT_NAME_24": "Colonel Sanderson", + "ACHIEVEMENT_DETAIL_24": "Kill 7 chickens in under 10 seconds in 'The Hornet's Nest'.", + "ACHIEVEMENT_NAME_25": "Ten plus foot-mobiles", + "ACHIEVEMENT_DETAIL_25": "Kill at least 10 enemies with one Predator Missile.", + "ACHIEVEMENT_NAME_26": "Unnecessary Roughness", + "ACHIEVEMENT_DETAIL_26": "Use a Riot shield to beat down an enemy.", + "ACHIEVEMENT_NAME_27": "Knock-knock", + "ACHIEVEMENT_DETAIL_27": "Kill 4 enemies with 4 shots during a slow-mo breach.", + "ACHIEVEMENT_NAME_28": "Some Like it Hot", + "ACHIEVEMENT_DETAIL_28": "Kill 6 enemies in a row using a thermal weapon.", + "ACHIEVEMENT_NAME_29": "Two Birds with One Stone", + "ACHIEVEMENT_DETAIL_29": "Kill 2 enemies with a single bullet.", + "ACHIEVEMENT_NAME_30": "The Road Less Traveled", + "ACHIEVEMENT_DETAIL_30": "Collect 22 enemy intel items.", + "ACHIEVEMENT_NAME_31": "Leave No Stone Unturned", + "ACHIEVEMENT_DETAIL_31": "Collect 45 enemy intel items.", + "ACHIEVEMENT_NAME_32": "Drive By", + "ACHIEVEMENT_DETAIL_32": "Kill 20 enemies in a row while driving a vehicle.", + "ACHIEVEMENT_NAME_33": "The Harder They Fall", + "ACHIEVEMENT_DETAIL_33": "Kill 2 rappelling enemies in a row before they land on their feet.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Kill 5 enemies in a row using 5 different weapons or attachments.", + "ACHIEVEMENT_NAME_35": "Look Ma Two Hands", + "ACHIEVEMENT_DETAIL_35": "Kill 10 enemies in a row using akimbo weapons.", + "ACHIEVEMENT_NAME_36": "No Rest For the Wary", + "ACHIEVEMENT_DETAIL_36": "Knife an enemy without him ever knowing you were there.", + "ACHIEVEMENT_NAME_37": "Three-some", + "ACHIEVEMENT_DETAIL_37": "Kill at least 3 enemies with a single shot from a grenade launcher.", + "ACHIEVEMENT_NAME_38": "Target Confirmed", + "ACHIEVEMENT_DETAIL_38": "Instruct the Honey Badger to kill 80 enemies in 'Exodus'.", + "ACHIEVEMENT_NAME_39": "Angel Savior", + "ACHIEVEMENT_DETAIL_39": "Do not get your Predator Drone destroyed in 'Contingency'.", + "ACHIEVEMENT_NAME_40": "Do NOT push this button", + "ACHIEVEMENT_DETAIL_40": "Ring the red bell in both rooms and survive the attack.", + "ACHIEVEMENT_NAME_41": "The Student Surpasses the Master", + "ACHIEVEMENT_DETAIL_41": "Beat Beenox time in 'S.S.D.D.'.", + "ACHIEVEMENT_NAME_42": "The Real Gun Game", + "ACHIEVEMENT_DETAIL_42": "Complete any mission but 'S.S.D.D.' and 'Endgame' without reloading weapons or using melee attacks.", + "ACHIEVEMENT_NAME_43": "Precognitive Paranoia", + "ACHIEVEMENT_DETAIL_43": "Kill Shepherd.", + "ACHIEVEMENT_NAME_44": "Immortal", + "ACHIEVEMENT_DETAIL_44": "Complete every missions without dying or reloading to a checkpoint at any difficulty.", + "ACHIEVEMENT_NAME_45": "Silent Skies", + "ACHIEVEMENT_DETAIL_45": "Destroy both BTRs without using Predator Drones in 'Wolverines!'", + "ACHIEVEMENT_NAME_46": "Clay-more", + "ACHIEVEMENT_DETAIL_46": "Kill 11 enemies using Claymores in 'Loose Ends'.", + "ACHIEVEMENT_NAME_47": "Bird Hunter", + "ACHIEVEMENT_DETAIL_47": "Destroy 10 choppers using the Javelin Launcher in 'Of Their Own Accord'.", + "ACHIEVEMENT_NAME_48": "Hot Potato", + "ACHIEVEMENT_DETAIL_48": "Destroy the helicopter using frag grenades in 'The Only Easy Day... Was Yesterday'.", + "ACHIEVEMENT_NAME_49": "Clown in Training", + "ACHIEVEMENT_DETAIL_49": "The U.S. Army Rangers ain’t no place for clowns.", + "ACHIEVEMENT_NAME_50": "Headbanger", + "ACHIEVEMENT_DETAIL_50": "Kill an enemy with the impact damage from a frag grenade to the head.", + "ACHIEVEMENT_NAME_51": "BRAAAINS...", + "ACHIEVEMENT_DETAIL_51": "Check out Prisoner 227's cell in 'The Gulag'.", + "ACHIEVEMENT_NAME_52": "Ramirez!", + "ACHIEVEMENT_DETAIL_52": "Turn on the radio in 'Museum'." +} diff --git a/data/zonetool/localizedstrings/french.json b/data/zonetool/localizedstrings/french.json index b09e97f9..57cfb741 100644 --- a/data/zonetool/localizedstrings/french.json +++ b/data/zonetool/localizedstrings/french.json @@ -38,5 +38,121 @@ "LUA_MENU_UNLOAD": "Décharger", "LUA_MENU_UNLOAD_DESC": "Déchargez le mod actuellement chargé.", - "LUA_MENU_CHOOSE_LANGUAGE": "Choisissez la langue" -} \ No newline at end of file + "MENU_MUSIC_VOLUME": "Volume musique", + + "LUA_MENU_CHOOSE_LANGUAGE": "Choisissez la langue", + + "DEPOT_GO_TO_THE_DEPOT": "Ouvrir le lien", + "MENU_OPEN_MOTD": "Message du jour", + + "LUA_MENU_ACHIEVEMENTS": "SUCCÈS", + "LUA_MENU_ACHIEVEMENTS_DESC": "Vos succès remportés jusqu'à présent.", + + "ACHIEVEMENT_HIDDEN": "Succès secret", + "ACHIEVEMENT_HIDDEN_DESC": "Continuer de jouer pour le déverrouiller", + "ACHIEVEMENT_EARNED": "Succès déverrouillé !", + "ACHIEVEMENT_NAME_0": "Quoi, c'est tout ?", + "ACHIEVEMENT_DETAIL_0": "Gagnez tous les trophées disponibles de Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "Remise en selle", + "ACHIEVEMENT_DETAIL_1": "Aidez à la formation de la milice locale.", + "ACHIEVEMENT_NAME_2": "Attention, danger", + "ACHIEVEMENT_DETAIL_2": "Faites-vous sélectionner pour l'unité d'élite de Shepherd.", + "ACHIEVEMENT_NAME_3": "Sueurs froides", + "ACHIEVEMENT_DETAIL_3": "Infiltrez la base sur la montagne enneigée.", + "ACHIEVEMENT_NAME_4": "L'affaire est dans le sac", + "ACHIEVEMENT_DETAIL_4": "Trouvez Rojas dans la favela.", + "ACHIEVEMENT_NAME_5": "Menu sur place", + "ACHIEVEMENT_DETAIL_5": "Défendez le Burger Town.", + "ACHIEVEMENT_NAME_6": "Soap sur la corde raide", + "ACHIEVEMENT_DETAIL_6": "Prenez d'assaut le goulag.", + "ACHIEVEMENT_NAME_7": "Situation désespérée", + "ACHIEVEMENT_DETAIL_7": "Mettez à exécution le plan pour aider les Américains.", + "ACHIEVEMENT_NAME_8": "Whiskey Hotel", + "ACHIEVEMENT_DETAIL_8": "Reprenez le Whiskey Hotel.", + "ACHIEVEMENT_NAME_9": "Le pion", + "ACHIEVEMENT_DETAIL_9": "Prenez d'assaut la planque de Makarov.", + "ACHIEVEMENT_NAME_10": "De Charybde en Scylla", + "ACHIEVEMENT_DETAIL_10": "Accomplissez la mission dans le cimetière des avions. ", + "ACHIEVEMENT_NAME_11": "Pour la postérité", + "ACHIEVEMENT_DETAIL_11": "Terminez la campagne solo dans n'importe quelle difficulté.", + "ACHIEVEMENT_NAME_12": "Le prix de la guerre", + "ACHIEVEMENT_DETAIL_12": "Terminez la campagne solo en difficulté Commando ou Vétéran.", + "ACHIEVEMENT_NAME_13": "Premier jour d'école", + "ACHIEVEMENT_DETAIL_13": "Terminez ''S.S.D.D'' et ''Travail d'équipe'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_14": "Diamant noir", + "ACHIEVEMENT_DETAIL_14": "Terminez ''Périlleuse escalade'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Terminez ''Confrontation'' et ''Un nid de frelons'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_16": "Aube rouge", + "ACHIEVEMENT_DETAIL_16": "Terminez ''Wolverines !'' et ''Exode'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_17": "Prisonnier 627", + "ACHIEVEMENT_DETAIL_17": "Terminez ''La seule journée paisible, c'était hier...'' et ''Le goulag'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_18": "La fin justifie les moyens", + "ACHIEVEMENT_DETAIL_18": "Terminez ''Imprévu'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_19": "Retour à la maison", + "ACHIEVEMENT_DETAIL_19": "Terminez ''Sans contrainte'', ''Deuxième soleil'' et ''Whiskey Hotel'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_20": "La reine prend la tour", + "ACHIEVEMENT_DETAIL_20": "Terminez ''Derniers détails'' et ''L'ennemi de mon ennemi...'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_21": "Indépendance", + "ACHIEVEMENT_DETAIL_21": "Terminez ''Comme au bon vieux temps'' et ''Échec et mat'' en difficulté Vétéran.", + "ACHIEVEMENT_NAME_22": "Roi de la fosse", + "ACHIEVEMENT_DETAIL_22": "Parcourez la fosse dans ''S.S.D.D'' et terminez avec un temps final inférieur à 30 secondes.", + "ACHIEVEMENT_NAME_23": "Fantôme", + "ACHIEVEMENT_DETAIL_23": "Placez le C4 dans ''Périlleuse escalade'' sans alerter ou blesser qui que ce soit dans le blizzard.", + "ACHIEVEMENT_NAME_24": "Colonel Sanderson", + "ACHIEVEMENT_DETAIL_24": "Tuez 7 poulets en moins de 10 secondes dans ''Un nid de frelons''.", + "ACHIEVEMENT_NAME_25": "Une dizaine de soldats", + "ACHIEVEMENT_DETAIL_25": "Tuez au moins 10 ennemis avec un seul missile Predator.", + "ACHIEVEMENT_NAME_26": "Brutalité gratuite", + "ACHIEVEMENT_DETAIL_26": "Utilisez un bouclier antiémeute pour vaincre un ennemi.", + "ACHIEVEMENT_NAME_27": "Toc ! Toc !", + "ACHIEVEMENT_DETAIL_27": "Tuez 4 ennemis avec 4 tirs durant une attaque au ralenti.", + "ACHIEVEMENT_NAME_28": "Certains l'aiment chaud", + "ACHIEVEMENT_DETAIL_28": "Tuez 6 ennemis d'affilée en utilisant une arme à lunette thermique.", + "ACHIEVEMENT_NAME_29": "D'une pierre deux coups", + "ACHIEVEMENT_DETAIL_29": "Tuez 2 ennemis d'une seule balle.", + "ACHIEVEMENT_NAME_30": "Chemins détournés", + "ACHIEVEMENT_DETAIL_30": "Récupérez 22 éléments de renseignements ennemis.", + "ACHIEVEMENT_NAME_31": "Une fouille en règle", + "ACHIEVEMENT_DETAIL_31": "Récupérez 45 éléments de renseignements ennemis.", + "ACHIEVEMENT_NAME_32": "Fusillade", + "ACHIEVEMENT_DETAIL_32": "Tuez 20 ennemis d'affilée en pilotant un véhicule.", + "ACHIEVEMENT_NAME_33": "Plus dure sera la chute", + "ACHIEVEMENT_DETAIL_33": "Tuez 2 ennemis faisant du rappel d'affilée avant qu'ils ne touchent le sol.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Tuez 5 ennemis d'affilée en utilisant 5 armes ou accessoires différents.", + "ACHIEVEMENT_NAME_35": "Avec les deux mains", + "ACHIEVEMENT_DETAIL_35": "Tuez 10 ennemis d'affilée en utilisant des armes Akimbo.", + "ACHIEVEMENT_NAME_36": "Pas de repos pour les braves", + "ACHIEVEMENT_DETAIL_36": "Poignardez un ennemi sans qu'il ne remarque votre présence.", + "ACHIEVEMENT_NAME_37": "Plus on est de fous…", + "ACHIEVEMENT_DETAIL_37": "Tuez au moins 3 ennemis avec un seul tir de lance-grenades.", + "ACHIEVEMENT_NAME_38": "Cible confirmée", + "ACHIEVEMENT_DETAIL_38": "Utilisez le Honey Badger pour tuer 80 ennemis dans ''Exode''.", + "ACHIEVEMENT_NAME_39": "Sauvetage venu des cieux", + "ACHIEVEMENT_DETAIL_39": "Empêchez la destruction de votre drone Predator dans ''Imprévu''.", + "ACHIEVEMENT_NAME_40": "N'appuyez PAS sur ce bouton", + "ACHIEVEMENT_DETAIL_40": "Déclenchez la sonnette rouge dans les deux salles et survivez à l'attaque.", + "ACHIEVEMENT_NAME_41": "L'élève dépasse le maître", + "ACHIEVEMENT_DETAIL_41": "Battez le temps de Beenox dans ''S.S.D.D''.", + "ACHIEVEMENT_NAME_42": "Véritable professionnel", + "ACHIEVEMENT_DETAIL_42": "Terminez une mission, sauf ''S.S.D.D'' et ''Échec et mat'', sans recharger ni attaquer au CàC.", + "ACHIEVEMENT_NAME_43": "Paranoïa prémonitoire", + "ACHIEVEMENT_DETAIL_43": "Tuez Shepherd.", + "ACHIEVEMENT_NAME_44": "Immortel", + "ACHIEVEMENT_DETAIL_44": "Terminez chaque mission sans mourir ni recharger un point de contrôle dans tout niv. de difficulté.", + "ACHIEVEMENT_NAME_45": "Silence dans les cieux", + "ACHIEVEMENT_DETAIL_45": "Détruisez les deux BTR sans utiliser de drone Predator dans ''Wolverines !''.", + "ACHIEVEMENT_NAME_46": "Clay-more", + "ACHIEVEMENT_DETAIL_46": "Tuez 11 ennemis en utilisant des claymores dans ''Derniers détails''.", + "ACHIEVEMENT_NAME_47": "Chasseur d'oiseaux", + "ACHIEVEMENT_DETAIL_47": "Détruisez 10 hélicoptères en utilisant un lanceur javelin dans ''Sans contrainte''.", + "ACHIEVEMENT_NAME_48": "Patate chaude", + "ACHIEVEMENT_DETAIL_48": "Détruisez l'hélicoptère avec des grenades à frag. dans 'La seule journée paisible, c'était hier...'.", + "ACHIEVEMENT_NAME_49": "Clown en formation", + "ACHIEVEMENT_DETAIL_49": "Il n'y a pas de place pour les clowns dans l'armée américaine.", + "ACHIEVEMENT_NAME_50": "Headbang", + "ACHIEVEMENT_DETAIL_50": "Tuez un ennemi en le touchant à la tête avec les dégâts d'impact d'une grenade à fragmentation.", + "ACHIEVEMENT_NAME_51": "CEEEEERVEAUUU...", + "ACHIEVEMENT_NAME_52": "Ramirez !" +} diff --git a/data/zonetool/localizedstrings/german.json b/data/zonetool/localizedstrings/german.json index fe5bbb69..d1be7d29 100644 --- a/data/zonetool/localizedstrings/german.json +++ b/data/zonetool/localizedstrings/german.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "h2-mod Schriften verwenden", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "Alle Missionen freischalten", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "Freischalten abbrechen" -} \ No newline at end of file + "LUA_MENU_CANCEL_UNLOCK_CAPS": "Freischalten abbrechen", + + "MENU_MUSIC_VOLUME": "Musiklautstärke", + + "DEPOT_GO_TO_THE_DEPOT": "Link öffnen", + "MENU_OPEN_MOTD": "Nachricht des Tages", + + "LUA_MENU_ACHIEVEMENTS": "ERRUNGENSCHAFTEN", + "LUA_MENU_ACHIEVEMENTS_DESC": "Ihr Errungenschaftsfortschritt.", + + "ACHIEVEMENT_HIDDEN": "Geheimer Erfolg", + "ACHIEVEMENT_HIDDEN_DESC": "Spielen Sie weiter, um diesen Erfolg freizuschalten.", + "ACHIEVEMENT_EARNED": "Errungenschaft freigeschaltet!", + "ACHIEVEMENT_NAME_0": "Mehr hast du nicht drauf?", + "ACHIEVEMENT_DETAIL_0": "Erlangen Sie alle Trophäen von Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "Zurück im Sattel", + "ACHIEVEMENT_DETAIL_1": "Helfen Sie, die örtliche Miliz auszubilden.", + "ACHIEVEMENT_NAME_2": "Direkte Gefahr", + "ACHIEVEMENT_DETAIL_2": "Werden Sie für Shepherds Elitetruppe ausgewählt.", + "ACHIEVEMENT_NAME_3": "Kalte Schulter", + "ACHIEVEMENT_DETAIL_3": "Infiltrieren Sie die verschneite Bergbasis.", + "ACHIEVEMENT_NAME_4": "Hab dich", + "ACHIEVEMENT_DETAIL_4": "Finden Sie Rojas im Elendsviertel.", + "ACHIEVEMENT_NAME_5": "Royal mit Käse", + "ACHIEVEMENT_DETAIL_5": "Verteidigen Sie Burger Town.", + "ACHIEVEMENT_NAME_6": "Soap am Seil", + "ACHIEVEMENT_DETAIL_6": "Stürmen Sie den Gulag.", + "ACHIEVEMENT_NAME_7": "Schlimme Zeiten", + "ACHIEVEMENT_DETAIL_7": "Führen Sie den Plan aus, um den Amerikanern zu helfen.", + "ACHIEVEMENT_NAME_8": "Weißes Haus", + "ACHIEVEMENT_DETAIL_8": "Erobern Sie das Weiße Haus zurück.", + "ACHIEVEMENT_NAME_9": "Bauernfigur", + "ACHIEVEMENT_DETAIL_9": "Greifen Sie Makarovs Unterschlupf an.", + "ACHIEVEMENT_NAME_10": "Raus aus der Bratpfanne ...", + "ACHIEVEMENT_DETAIL_10": "Beenden Sie die Mission auf dem Flugzeugfriedhof.", + "ACHIEVEMENT_NAME_11": "Für die Akten", + "ACHIEVEMENT_DETAIL_11": "Beenden Sie die Einzelspielerkampagne auf einem beliebigen Schwierigkeitsgrad.", + "ACHIEVEMENT_NAME_12": "Der Preis des Krieges", + "ACHIEVEMENT_DETAIL_12": "Beenden Sie die Einzelspielerkampagne auf dem Schwierigkeitsgrad Söldner oder Veteran.", + "ACHIEVEMENT_NAME_13": "Erster Schultag", + "ACHIEVEMENT_DETAIL_13": "Beenden Sie 'Die alte Leier' und 'Teamspieler' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_14": "Schwarzer Diamant", + "ACHIEVEMENT_DETAIL_14": "Beenden Sie 'Cliffhanger' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_15": "Touristen", + "ACHIEVEMENT_DETAIL_15": "Beenden Sie 'Zugriff' und 'Das Hornissennest' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_16": "Roter Morgen", + "ACHIEVEMENT_DETAIL_16": "Beenden Sie 'Wolverines!' und 'Exodus' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_17": "Gefangener 627", + "ACHIEVEMENT_DETAIL_17": "Beenden Sie 'Der einzig schöne Tag ... war gestern' und 'Der Gulag' auf Veteran.", + "ACHIEVEMENT_NAME_18": "Der Zweck heiligt die Mittel", + "ACHIEVEMENT_DETAIL_18": "Beenden Sie 'Notfall' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_19": "Heimkehr", + "ACHIEVEMENT_DETAIL_19": "Beenden Sie 'Auf eigene Verantwortung', 'Zweite Sonne' und 'Weißes Haus' auf Veteran.", + "ACHIEVEMENT_NAME_20": "Dame schlägt Turm", + "ACHIEVEMENT_DETAIL_20": "Beenden Sie 'Lose Enden' und 'Der Feind meines Feindes' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_21": "Aussteiger", + "ACHIEVEMENT_DETAIL_21": "Beenden Sie 'Wie in alten Zeiten' und 'Endphase' auf dem Schwierigkeitsgrad Veteran.", + "ACHIEVEMENT_NAME_22": "Grubenarbeiter", + "ACHIEVEMENT_DETAIL_22": "Rennen Sie durch 'Die Grube' in 'Die alte Leier' und beenden Sie den Parcours in unter 30 Sekunden.", + "ACHIEVEMENT_NAME_23": "Geist", + "ACHIEVEMENT_DETAIL_23": "Platzieren Sie in 'Cliffhanger' C4, ohne jemanden im Schneesturm zu verletzen oder zu alarmieren.", + "ACHIEVEMENT_NAME_24": "Colonel Sanderson", + "ACHIEVEMENT_DETAIL_24": "Erledigen Sie in 'Das Hornissennest' 7 Hühner in unter 10 Sekunden.", + "ACHIEVEMENT_NAME_25": "Mehr als 10 Gegner", + "ACHIEVEMENT_DETAIL_25": "Erledigen Sie mindestens 10 Gegner mit einer Predator-Rakete.", + "ACHIEVEMENT_NAME_26": "Übertriebene Härte", + "ACHIEVEMENT_DETAIL_26": "Schlagen Sie einen Gegner mit dem Einsatzschild nieder.", + "ACHIEVEMENT_NAME_27": "Klopf, klopf", + "ACHIEVEMENT_DETAIL_27": "Erledigen Sie 4 Gegner mit 4 Schüssen in einem Zeitlupen-Vorstoß.", + "ACHIEVEMENT_NAME_28": "Manche mögen's heiß", + "ACHIEVEMENT_DETAIL_28": "Erledigen Sie 6 Gegner hintereinander mit einer Thermalwaffe.", + "ACHIEVEMENT_NAME_29": "Zwei Vögel, ein Stein", + "ACHIEVEMENT_DETAIL_29": "Erledigen Sie 2 Gegner mit nur einer Kugel.", + "ACHIEVEMENT_NAME_30": "Neue Wege", + "ACHIEVEMENT_DETAIL_30": "Sammeln Sie 22 feindliche Aufklärungsdaten.", + "ACHIEVEMENT_NAME_31": "Mir entgeht nichts", + "ACHIEVEMENT_DETAIL_31": "Sammeln Sie 45 feindliche Aufklärungsdaten.", + "ACHIEVEMENT_NAME_32": "Im Vorbeifahren", + "ACHIEVEMENT_DETAIL_32": "Erledigen Sie 20 Gegner hintereinander, während Sie ein Fahrzeug fahren.", + "ACHIEVEMENT_NAME_33": "Tiefer Fall", + "ACHIEVEMENT_DETAIL_33": "Erledigen Sie 2 Gegner am Seil, bevor sie auf ihren Füßen landen.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Schalten Sie 5 Gegner nacheinander mit 5 verschiedenen Waffen/Aufsätzen aus.", + "ACHIEVEMENT_NAME_35": "Schau mal, mit zwei Händen", + "ACHIEVEMENT_DETAIL_35": "Schalten Sie 10 Gegner nacheinander mit Akimbo-Waffen aus.", + "ACHIEVEMENT_NAME_36": "Keine Ruhe für die Wachsamen", + "ACHIEVEMENT_DETAIL_36": "Schalten Sie einen Gegner mit dem Messer aus, ohne dass dieser Sie bemerkt.", + "ACHIEVEMENT_NAME_37": "Dreier", + "ACHIEVEMENT_DETAIL_37": "Erledigen Sie mindestens 3 Gegner mit nur einem Granatwerferschuss.", + "ACHIEVEMENT_NAME_38": "Ziel bestätigt", + "ACHIEVEMENT_DETAIL_38": "Geben Sie in 'Exodus' dem Honey Badger den Befehl, 80 Gegner zu erledigen.", + "ACHIEVEMENT_NAME_39": "Schutzengel", + "ACHIEVEMENT_DETAIL_39": "Lassen Sie nicht zu, dass Ihre Predator-Drohne in 'Notfall' zerstört wird.", + "ACHIEVEMENT_NAME_40": "Knopf NICHT drücken", + "ACHIEVEMENT_DETAIL_40": "Läuten Sie die rote Glocke in beiden Räumen und überleben Sie den Angriff.", + "ACHIEVEMENT_NAME_41": "Schüler übertrifft Lehrer", + "ACHIEVEMENT_DETAIL_41": "Unterbieten Sie die Beenox-Zeit in 'Die alte Leier'.", + "ACHIEVEMENT_NAME_42": "Echtes Waffenspiel", + "ACHIEVEMENT_DETAIL_42": "Schließen Sie 1 Mission (außer 'Die alte Leier' & 'Endphase') ohne Nachladen/Nahkampfangriffe ab.", + "ACHIEVEMENT_NAME_43": "Vorauseilender Verfolgungswahn", + "ACHIEVEMENT_DETAIL_43": "Schalten Sie Shepherd aus.", + "ACHIEVEMENT_NAME_44": "Unsterblich", + "ACHIEVEMENT_DETAIL_44": "Schließen Sie jede Mission auf bel. Schwierigkeitsgrad ohne Sterben und ohne Kontrollpunkt-Laden ab.", + "ACHIEVEMENT_NAME_45": "Stiller Himmel", + "ACHIEVEMENT_DETAIL_45": "Zerstören Sie in 'Wolverines!' beide BTRs ohne Predator-Drohnen.", + "ACHIEVEMENT_NAME_46": "Claymord", + "ACHIEVEMENT_DETAIL_46": "Erledigen Sie in 'Lose Enden' 11 Gegner mit Claymores.", + "ACHIEVEMENT_NAME_47": "Vogeljäger", + "ACHIEVEMENT_DETAIL_47": "Zerstören Sie in 'Auf eigene Verantwortung' 10 Helis mit dem Javelin-Werfer.", + "ACHIEVEMENT_NAME_48": "Heiße Kartoffel", + "ACHIEVEMENT_DETAIL_48": "Zerstören Sie in 'Der einzig schöne Tag ... war gestern' den Helikopter mit Splittergranaten.", + "ACHIEVEMENT_NAME_49": "Clown in Ausbildung", + "ACHIEVEMENT_DETAIL_49": "Die U.S. Army Rangers haben keinen Platz für Clowns.", + "ACHIEVEMENT_NAME_50": "Headbanger", + "ACHIEVEMENT_DETAIL_50": "Erledigen Sie einen Gegner mit dem Einschlagsschaden einer Splittergranate am Kopf.", + "ACHIEVEMENT_NAME_51": "GEEEHIRN...", + "ACHIEVEMENT_NAME_52": "Ramirez!" +} diff --git a/data/zonetool/localizedstrings/italian.json b/data/zonetool/localizedstrings/italian.json index 9a7f3d05..e496102b 100644 --- a/data/zonetool/localizedstrings/italian.json +++ b/data/zonetool/localizedstrings/italian.json @@ -33,6 +33,8 @@ "LUA_MENU_WORKSHOP": "Workshop", "LUA_MENU_WORKSHOP_DESC": "Scarica e installa mod.", + "MENU_MUSIC_VOLUME": "Volume musica", + "MENU_GENERAL": "H2-MOD", "MENU_GENERAL_DESC": "Imposta le opzioni di h2-mod.", "LUA_MENU_AUTO_UPDATE": "Aggiornamenti automatici", @@ -58,5 +60,119 @@ "MENU_SYSINFO_CUSTOMER_SUPPORT_LINK": "Pagina di Github:", "MENU_SYSINFO_CUSTOMER_SUPPORT_URL": "https://github.com/fedddddd/h2-mod", "MENU_SYSINFO_DONATION_LINK": "Link per donazioni:", - "MENU_SYSINFO_DONATION_URL": "https://paypal.me/fedecek" -} \ No newline at end of file + "MENU_SYSINFO_DONATION_URL": "https://paypal.me/fedecek", + + "DEPOT_GO_TO_THE_DEPOT": "Apri il link", + "MENU_OPEN_MOTD": "Bollettino del giorno", + + "LUA_MENU_ACHIEVEMENTS": "ACHIEVEMENT", + "LUA_MENU_ACHIEVEMENTS_DESC": "Il tuo progresso degli achievement.", + + "ACHIEVEMENT_HIDDEN": "Obiettivo segreto", + "ACHIEVEMENT_HIDDEN_DESC": "Continua a giocare per sbloccarlo", + "ACHIEVEMENT_EARNED": "Achievement sbloccato!", + "ACHIEVEMENT_NAME_0": "È tutto quello che hai?", + "ACHIEVEMENT_DETAIL_0": "Guadagna tutti i trofei di Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "Di nuovo in sella", + "ACHIEVEMENT_DETAIL_1": "Aiuta ad addestrare la milizia locale.", + "ACHIEVEMENT_NAME_2": "Mina vagante", + "ACHIEVEMENT_DETAIL_2": "Fatti scegliere per la squadra d'élite di Shepherd.", + "ACHIEVEMENT_NAME_3": "Sangue freddo", + "ACHIEVEMENT_DETAIL_3": "Infiltrati nella base della montagna innevata.", + "ACHIEVEMENT_NAME_4": "Registrali e ficcali nel sacco", + "ACHIEVEMENT_DETAIL_4": "Trova Rojas nelle favelas.", + "ACHIEVEMENT_NAME_5": "Royale con formaggio", + "ACHIEVEMENT_DETAIL_5": "Difendi Burger Town.", + "ACHIEVEMENT_NAME_6": "Fuoco di Soap-pressione", + "ACHIEVEMENT_DETAIL_6": "Conquista il gulag.", + "ACHIEVEMENT_NAME_7": "Tempi disperati", + "ACHIEVEMENT_DETAIL_7": "Esegui il piano per aiutare gli americani.", + "ACHIEVEMENT_NAME_8": "Whiskey Hotel", + "ACHIEVEMENT_DETAIL_8": "Riconquista il Whiskey Hotel.", + "ACHIEVEMENT_NAME_9": "La parola data", + "ACHIEVEMENT_DETAIL_9": "Attacca il rifugio di Makarov.", + "ACHIEVEMENT_NAME_10": "Dalla padella alla brace", + "ACHIEVEMENT_DETAIL_10": "Completa la missione al cimitero degli aerei.", + "ACHIEVEMENT_NAME_11": "Per la cronaca", + "ACHIEVEMENT_DETAIL_11": "Completa la Campagna per giocatore singolo a qualsiasi livello.", + "ACHIEVEMENT_NAME_12": "Il prezzo della guerra", + "ACHIEVEMENT_DETAIL_12": "Completa la Campagna per giocatore singolo a livello Esperto o Veterano.", + "ACHIEVEMENT_NAME_13": "Primo giorno di scuola", + "ACHIEVEMENT_DETAIL_13": "Completa ''Stessa merda, altro giorno'' e ''Gioco di squadra'' a livello Veterano.", + "ACHIEVEMENT_NAME_14": "Diamante nero", + "ACHIEVEMENT_DETAIL_14": "Completa ''Scalata'' a livello Veterano.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Completa ''Atterramento'' e ''Vespaio'' a livello Veterano.", + "ACHIEVEMENT_NAME_16": "Alba rossa", + "ACHIEVEMENT_DETAIL_16": "Completa ''Wolverine!'' e ''Esodo'' a livello Veterano.", + "ACHIEVEMENT_NAME_17": "Detenuto 627", + "ACHIEVEMENT_DETAIL_17": "Completa ''L'unico giorno facile... era ieri'' e ''Il gulag'' a livello Veterano.", + "ACHIEVEMENT_NAME_18": "Il fine giustifica i mezzi", + "ACHIEVEMENT_DETAIL_18": "Completa ''Imprevisto'' a livello Veterano.", + "ACHIEVEMENT_NAME_19": "Ritorno a casa", + "ACHIEVEMENT_DETAIL_19": "Completa ''Secondo le loro fonti'', ''Il secondo sole'' e ''Whiskey Hotel'' a livello Veterano.", + "ACHIEVEMENT_NAME_20": "La regina mangia la torre", + "ACHIEVEMENT_DETAIL_20": "Completa ''Conti in sospeso'' e ''Il nemico del mio nemico'' a livello Veterano.", + "ACHIEVEMENT_NAME_21": "Fuori dai radar", + "ACHIEVEMENT_DETAIL_21": "Completa ''Come ai vecchi tempi'' e ''La fine'' a livello Veterano.", + "ACHIEVEMENT_NAME_22": "Il direttore", + "ACHIEVEMENT_DETAIL_22": "Percorri il pozzo in ''Stessa merda, altro giorno'' in meno di 30 secondi.", + "ACHIEVEMENT_NAME_23": "Fantasma", + "ACHIEVEMENT_DETAIL_23": "Piazza il C4 in ''Scalata'' senza allarmare o ferire nessuno nella tormenta.", + "ACHIEVEMENT_NAME_24": "Polletto alla diavola", + "ACHIEVEMENT_DETAIL_24": "Uccidi 7 galline in meno di 10 secondi in ''Vespaio''.", + "ACHIEVEMENT_NAME_25": "10 pedoni", + "ACHIEVEMENT_DETAIL_25": "Uccidi almeno 10 nemici con un solo missile Predator.", + "ACHIEVEMENT_NAME_26": "Violenza gratuita", + "ACHIEVEMENT_DETAIL_26": "Usa uno scudo antisommossa per abbattere un nemico.", + "ACHIEVEMENT_NAME_27": "Toc-toc", + "ACHIEVEMENT_DETAIL_27": "Uccidi 4 nemici con 4 colpi durante un'irruzione con tempo rallentato.", + "ACHIEVEMENT_NAME_28": "A qualcuno piace caldo", + "ACHIEVEMENT_DETAIL_28": "Uccidi 6 nemici di fila usando un'arma termica.", + "ACHIEVEMENT_NAME_29": "Due piccioni con una fava", + "ACHIEVEMENT_DETAIL_29": "Uccidi 2 nemici con un solo proiettile.", + "ACHIEVEMENT_NAME_30": "Il percorso meno trafficato", + "ACHIEVEMENT_DETAIL_30": "Trova 22 documenti con informazioni nemiche.", + "ACHIEVEMENT_NAME_31": "Guarda dappertutto", + "ACHIEVEMENT_DETAIL_31": "Trova 45 documenti con informazioni nemiche.", + "ACHIEVEMENT_NAME_32": "Sparatoria", + "ACHIEVEMENT_DETAIL_32": "Uccidi 20 nemici di fila mentre guidi un veicolo.", + "ACHIEVEMENT_NAME_33": "Più si fanno male cadendo", + "ACHIEVEMENT_DETAIL_33": "Uccidi 2 nemici che si stanno calando di fila prima che atterrino.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Uccidi 5 nemici di fila usando 5 armi o accessori diversi.", + "ACHIEVEMENT_NAME_35": "Guarda mamma! Con due mani!", + "ACHIEVEMENT_DETAIL_35": "Uccidi 10 nemici di fila usando armi akimbo.", + "ACHIEVEMENT_NAME_36": "Non c'è posto per i deboli", + "ACHIEVEMENT_DETAIL_36": "Accoltella un nemico senza che si accorga di te.", + "ACHIEVEMENT_NAME_37": "Triangolo", + "ACHIEVEMENT_DETAIL_37": "Uccidi almeno 3 nemici con un solo colpo di lanciagranate.", + "ACHIEVEMENT_NAME_38": "Bersaglio confermato", + "ACHIEVEMENT_DETAIL_38": "Ordina all'Honey Badger di uccidere 80 nemici in ''Esodo''.", + "ACHIEVEMENT_NAME_39": "Salvatore angelico", + "ACHIEVEMENT_DETAIL_39": "Impedisci che il tuo drone Predator venga distrutto in ''Imprevisto''.", + "ACHIEVEMENT_NAME_40": "NON premere questo pulsante", + "ACHIEVEMENT_DETAIL_40": "Suona il campanello rosso in entrambe le stanze e sopravvivi all'attacco.", + "ACHIEVEMENT_NAME_41": "L'allievo supera il maestro", + "ACHIEVEMENT_DETAIL_41": "Batti il tempo di Beenox in ''Stessa merda, altro giorno''.", + "ACHIEVEMENT_NAME_42": "Il vero gioco delle armi", + "ACHIEVEMENT_DETAIL_42": "Completa un livello (non 'Stessa merda, altro giorno' e 'La fine') senza ricariche né corpo a corpo.", + "ACHIEVEMENT_NAME_43": "Paranoia precognitiva", + "ACHIEVEMENT_DETAIL_43": "Uccidi Shepherd.", + "ACHIEVEMENT_NAME_44": "Immortale", + "ACHIEVEMENT_DETAIL_44": "Completa l'intera Campagna senza morire né riavviare da un checkpoint (qualsiasi livello).", + "ACHIEVEMENT_NAME_45": "Cieli silenziosi", + "ACHIEVEMENT_DETAIL_45": "Distruggi entrambi i BTR senza usare droni Predator in ''Wolverine!''.", + "ACHIEVEMENT_NAME_46": "Clay-amore", + "ACHIEVEMENT_DETAIL_46": "Uccidi 11 nemici usando Claymore in ''Conti in sospeso''.", + "ACHIEVEMENT_NAME_47": "Caccia grossa", + "ACHIEVEMENT_DETAIL_47": "Distruggi 10 elicotteri usando il lanciatore Javelin in ''Secondo le loro fonti''.", + "ACHIEVEMENT_NAME_48": "Patata bollente", + "ACHIEVEMENT_DETAIL_48": "Distruggi l'elicottero usando granate a frammentazione in ''L'unico giorno facile... era ieri''.", + "ACHIEVEMENT_NAME_49": "Apprendista pagliaccio", + "ACHIEVEMENT_DETAIL_49": "Nei ranger dell'esercito americano non c'è posto per i buffoni.", + "ACHIEVEMENT_NAME_50": "Colpo di testa", + "ACHIEVEMENT_DETAIL_50": "Uccidi un nemico colpendolo alla testa con una granata a frammentazione (solo danni da impatto).", + "ACHIEVEMENT_NAME_51": "CEEERVELLI...", + "ACHIEVEMENT_NAME_52": "Ramirez!" +} diff --git a/data/zonetool/localizedstrings/japanese_full.json b/data/zonetool/localizedstrings/japanese_full.json index b4b9f1fd..5e33cbea 100644 --- a/data/zonetool/localizedstrings/japanese_full.json +++ b/data/zonetool/localizedstrings/japanese_full.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "h2-mod フォントを使用します", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "全ミッションをアンロック", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "アンロックをキャンセル" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "アンロックをキャンセル", + + "MENU_MUSIC_VOLUME": "BGM音量", + + "DEPOT_GO_TO_THE_DEPOT": "リンクを開く", + "MENU_OPEN_MOTD": "本日のメッセージ", + + "LUA_MENU_ACHIEVEMENTS": "実績", + "LUA_MENU_ACHIEVEMENTS_DESC": "実績の状況。", + + "ACHIEVEMENT_HIDDEN": "秘密の実績", + "ACHIEVEMENT_HIDDEN_DESC": "もっとプレイして実績を解除しましょう", + "ACHIEVEMENT_EARNED": "実績のロックを解除しました!", + "ACHIEVEMENT_NAME_0": "全部でこれだけ?", + "ACHIEVEMENT_DETAIL_0": "Call of Duty®: Modern Warfare® 2 Campaign Remasteredでアンロックできるトロフィーを全て獲得", + "ACHIEVEMENT_NAME_1": "久々の教鞭", + "ACHIEVEMENT_DETAIL_1": "地元民兵の訓練を補助", + "ACHIEVEMENT_NAME_2": "デンジャークローズ", + "ACHIEVEMENT_DETAIL_2": "シェパードのエリート部隊に選ばれる", + "ACHIEVEMENT_NAME_3": "冷遇", + "ACHIEVEMENT_DETAIL_3": "雪山にある基地に潜入", + "ACHIEVEMENT_NAME_4": "とっ捕まえろ!", + "ACHIEVEMENT_DETAIL_4": "スラムでロハスを見つける", + "ACHIEVEMENT_NAME_5": "ハンバーガー大好き", + "ACHIEVEMENT_DETAIL_5": "バーガータウンを防衛", + "ACHIEVEMENT_NAME_6": "ソープ・オン・ロープ", + "ACHIEVEMENT_DETAIL_6": "強制労働収容所を襲撃", + "ACHIEVEMENT_NAME_7": "自暴自棄", + "ACHIEVEMENT_DETAIL_7": "アメリカ人を助けるため任務を完遂する", + "ACHIEVEMENT_NAME_8": "ウイスキーホテル", + "ACHIEVEMENT_DETAIL_8": "ウイスキーホテルを奪還", + "ACHIEVEMENT_NAME_9": "人質", + "ACHIEVEMENT_DETAIL_9": "マカロフの隠れ家を襲撃", + "ACHIEVEMENT_NAME_10": "泣きっ面に蜂", + "ACHIEVEMENT_DETAIL_10": "飛行機の墓場でのミッションをクリア", + "ACHIEVEMENT_NAME_11": "記録に残そう", + "ACHIEVEMENT_DETAIL_11": "キャンペーンシングルプレイを全てクリア", + "ACHIEVEMENT_NAME_12": "戦争の対価", + "ACHIEVEMENT_DETAIL_12": "キャンペーンシングルプレイを難易度ハード以上で全てクリア", + "ACHIEVEMENT_NAME_13": "登校初日", + "ACHIEVEMENT_DETAIL_13": "「S.S.D.D.」「チームプレイヤー」をベテランでクリア", + "ACHIEVEMENT_NAME_14": "ブラックダイヤモンド", + "ACHIEVEMENT_DETAIL_14": "「クリフハンガー」をベテランでクリア", + "ACHIEVEMENT_NAME_15": "ブラッド・パラダイス", + "ACHIEVEMENT_DETAIL_15": "「テイクダウン」「スズメバチの巣」をベテランでクリア", + "ACHIEVEMENT_NAME_16": "若き勇者たち", + "ACHIEVEMENT_DETAIL_16": "「バーガータウン」「エクソダス」をベテランでクリア", + "ACHIEVEMENT_NAME_17": "収容者627号", + "ACHIEVEMENT_DETAIL_17": "「ここからが正念場」「強制労働収容所」をベテランでクリア", + "ACHIEVEMENT_NAME_18": "終わり良ければ全て良し", + "ACHIEVEMENT_DETAIL_18": "「不測の事態」をベテランでクリア", + "ACHIEVEMENT_NAME_19": "帰郷", + "ACHIEVEMENT_DETAIL_19": "「自らの意思」「2つめの太陽」「ウイスキーホテル」をベテランでクリア", + "ACHIEVEMENT_NAME_20": "危険な賭け", + "ACHIEVEMENT_DETAIL_20": "「未決事項」「敵の敵は」をベテランでクリア", + "ACHIEVEMENT_NAME_21": "超硬派", + "ACHIEVEMENT_DETAIL_21": "「昔のように」「エンドゲーム」をベテランでクリア", + "ACHIEVEMENT_NAME_22": "ピットのボス", + "ACHIEVEMENT_DETAIL_22": "「S.S.D.D.」のピットを30秒以内でゴール", + "ACHIEVEMENT_NAME_23": "亡霊", + "ACHIEVEMENT_DETAIL_23": "「クリフハンガー」で吹雪の中を誰にも気付かれず、誰も傷つけることなくC4を設置", + "ACHIEVEMENT_NAME_24": "カーネルおじさん", + "ACHIEVEMENT_DETAIL_24": "「スズメバチの巣」で10秒以内に鶏を7羽キル", + "ACHIEVEMENT_NAME_25": "歩兵の一団", + "ACHIEVEMENT_DETAIL_25": "1発のプレデターミサイルで10人以上キル", + "ACHIEVEMENT_NAME_26": "過剰な暴力", + "ACHIEVEMENT_DETAIL_26": "Riot shieldで敵を殴り倒す", + "ACHIEVEMENT_NAME_27": "失礼します", + "ACHIEVEMENT_DETAIL_27": "突入時のスローモーションで4人を4発でキル", + "ACHIEVEMENT_NAME_28": "熱いのがお好き", + "ACHIEVEMENT_DETAIL_28": "サーマルを使って6連続キル", + "ACHIEVEMENT_NAME_29": "一石二鳥", + "ACHIEVEMENT_DETAIL_29": "1発の銃弾で敵を2人キル", + "ACHIEVEMENT_NAME_30": "物知り博士", + "ACHIEVEMENT_DETAIL_30": "敵のインテルを22個入手", + "ACHIEVEMENT_NAME_31": "念には念を", + "ACHIEVEMENT_DETAIL_31": "敵のインテルを45個入手", + "ACHIEVEMENT_NAME_32": "撃ち逃げ", + "ACHIEVEMENT_DETAIL_32": "車両運転中に20連続キル", + "ACHIEVEMENT_NAME_33": "さっさと降りろ", + "ACHIEVEMENT_DETAIL_33": "ロープで下降中の敵が地面に着く前に2連続キル", + "ACHIEVEMENT_NAME_34": "無法者", + "ACHIEVEMENT_DETAIL_34": "5つの異なる武器またはアタッチメントで5連続キル", + "ACHIEVEMENT_NAME_35": "無敵の両腕", + "ACHIEVEMENT_DETAIL_35": "デュアル武器で10連続キル", + "ACHIEVEMENT_NAME_36": "尽きない不安", + "ACHIEVEMENT_DETAIL_36": "敵に気づかれずにナイフでキル", + "ACHIEVEMENT_NAME_37": "3人1組", + "ACHIEVEMENT_DETAIL_37": "グレネードランチャー1発で敵を3人以上キル", + "ACHIEVEMENT_NAME_38": "ターゲットを確認!", + "ACHIEVEMENT_DETAIL_38": "「エクソダス」でハニーバジャーを誘導して80キル", + "ACHIEVEMENT_NAME_39": "守護天使", + "ACHIEVEMENT_DETAIL_39": "「不測の事態」で敵にプレデターを破壊されない", + "ACHIEVEMENT_NAME_40": "絶対押すなよ", + "ACHIEVEMENT_DETAIL_40": "両方の部屋の赤いベルを押して生き延びる", + "ACHIEVEMENT_NAME_41": "藍より青し", + "ACHIEVEMENT_DETAIL_41": "「S.S.D.D.」ピットでBeenoxベストタイムを更新", + "ACHIEVEMENT_NAME_42": "リアルGUN GAME", + "ACHIEVEMENT_DETAIL_42": "キャンペーンで「S.S.D.D.」「エンドゲーム」以外のいずれかを近接攻撃、武器のリロードなしでクリア", + "ACHIEVEMENT_NAME_43": "未来への妄執", + "ACHIEVEMENT_DETAIL_43": "シェパードを排除", + "ACHIEVEMENT_NAME_44": "不死身", + "ACHIEVEMENT_DETAIL_44": "全ミッションを、死んだりチェックポイントへリロードすることなくクリア。難易度は不問", + "ACHIEVEMENT_NAME_45": "サイレントスカイ", + "ACHIEVEMENT_DETAIL_45": "「バーガータウン」でプレデターを使わずにBTRを2つとも破壊", + "ACHIEVEMENT_NAME_46": "もっとクレイモア", + "ACHIEVEMENT_DETAIL_46": "「未決事項」でクレイモアを使って敵を11人キル", + "ACHIEVEMENT_NAME_47": "バードハンター", + "ACHIEVEMENT_DETAIL_47": "「自らの意思」でJavelinを使ってヘリを10機撃墜", + "ACHIEVEMENT_NAME_48": "奇妙な挑戦", + "ACHIEVEMENT_DETAIL_48": "「ここからが正念場」でフラググレネードを使ってヘリを撃墜", + "ACHIEVEMENT_NAME_49": "練習場のピエロ", + "ACHIEVEMENT_DETAIL_49": "米軍レンジャーはおふざけで務まる場所じゃない", + "ACHIEVEMENT_NAME_50": "ヘッドバンギング", + "ACHIEVEMENT_DETAIL_50": "爆発前のフラググレネードを敵の頭に当ててキル", + "ACHIEVEMENT_NAME_51": "脳味噌...", + "ACHIEVEMENT_NAME_52": "ラミレス!" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/japenese_partial.json b/data/zonetool/localizedstrings/japenese_partial.json index b4b9f1fd..5e33cbea 100644 --- a/data/zonetool/localizedstrings/japenese_partial.json +++ b/data/zonetool/localizedstrings/japenese_partial.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "h2-mod フォントを使用します", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "全ミッションをアンロック", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "アンロックをキャンセル" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "アンロックをキャンセル", + + "MENU_MUSIC_VOLUME": "BGM音量", + + "DEPOT_GO_TO_THE_DEPOT": "リンクを開く", + "MENU_OPEN_MOTD": "本日のメッセージ", + + "LUA_MENU_ACHIEVEMENTS": "実績", + "LUA_MENU_ACHIEVEMENTS_DESC": "実績の状況。", + + "ACHIEVEMENT_HIDDEN": "秘密の実績", + "ACHIEVEMENT_HIDDEN_DESC": "もっとプレイして実績を解除しましょう", + "ACHIEVEMENT_EARNED": "実績のロックを解除しました!", + "ACHIEVEMENT_NAME_0": "全部でこれだけ?", + "ACHIEVEMENT_DETAIL_0": "Call of Duty®: Modern Warfare® 2 Campaign Remasteredでアンロックできるトロフィーを全て獲得", + "ACHIEVEMENT_NAME_1": "久々の教鞭", + "ACHIEVEMENT_DETAIL_1": "地元民兵の訓練を補助", + "ACHIEVEMENT_NAME_2": "デンジャークローズ", + "ACHIEVEMENT_DETAIL_2": "シェパードのエリート部隊に選ばれる", + "ACHIEVEMENT_NAME_3": "冷遇", + "ACHIEVEMENT_DETAIL_3": "雪山にある基地に潜入", + "ACHIEVEMENT_NAME_4": "とっ捕まえろ!", + "ACHIEVEMENT_DETAIL_4": "スラムでロハスを見つける", + "ACHIEVEMENT_NAME_5": "ハンバーガー大好き", + "ACHIEVEMENT_DETAIL_5": "バーガータウンを防衛", + "ACHIEVEMENT_NAME_6": "ソープ・オン・ロープ", + "ACHIEVEMENT_DETAIL_6": "強制労働収容所を襲撃", + "ACHIEVEMENT_NAME_7": "自暴自棄", + "ACHIEVEMENT_DETAIL_7": "アメリカ人を助けるため任務を完遂する", + "ACHIEVEMENT_NAME_8": "ウイスキーホテル", + "ACHIEVEMENT_DETAIL_8": "ウイスキーホテルを奪還", + "ACHIEVEMENT_NAME_9": "人質", + "ACHIEVEMENT_DETAIL_9": "マカロフの隠れ家を襲撃", + "ACHIEVEMENT_NAME_10": "泣きっ面に蜂", + "ACHIEVEMENT_DETAIL_10": "飛行機の墓場でのミッションをクリア", + "ACHIEVEMENT_NAME_11": "記録に残そう", + "ACHIEVEMENT_DETAIL_11": "キャンペーンシングルプレイを全てクリア", + "ACHIEVEMENT_NAME_12": "戦争の対価", + "ACHIEVEMENT_DETAIL_12": "キャンペーンシングルプレイを難易度ハード以上で全てクリア", + "ACHIEVEMENT_NAME_13": "登校初日", + "ACHIEVEMENT_DETAIL_13": "「S.S.D.D.」「チームプレイヤー」をベテランでクリア", + "ACHIEVEMENT_NAME_14": "ブラックダイヤモンド", + "ACHIEVEMENT_DETAIL_14": "「クリフハンガー」をベテランでクリア", + "ACHIEVEMENT_NAME_15": "ブラッド・パラダイス", + "ACHIEVEMENT_DETAIL_15": "「テイクダウン」「スズメバチの巣」をベテランでクリア", + "ACHIEVEMENT_NAME_16": "若き勇者たち", + "ACHIEVEMENT_DETAIL_16": "「バーガータウン」「エクソダス」をベテランでクリア", + "ACHIEVEMENT_NAME_17": "収容者627号", + "ACHIEVEMENT_DETAIL_17": "「ここからが正念場」「強制労働収容所」をベテランでクリア", + "ACHIEVEMENT_NAME_18": "終わり良ければ全て良し", + "ACHIEVEMENT_DETAIL_18": "「不測の事態」をベテランでクリア", + "ACHIEVEMENT_NAME_19": "帰郷", + "ACHIEVEMENT_DETAIL_19": "「自らの意思」「2つめの太陽」「ウイスキーホテル」をベテランでクリア", + "ACHIEVEMENT_NAME_20": "危険な賭け", + "ACHIEVEMENT_DETAIL_20": "「未決事項」「敵の敵は」をベテランでクリア", + "ACHIEVEMENT_NAME_21": "超硬派", + "ACHIEVEMENT_DETAIL_21": "「昔のように」「エンドゲーム」をベテランでクリア", + "ACHIEVEMENT_NAME_22": "ピットのボス", + "ACHIEVEMENT_DETAIL_22": "「S.S.D.D.」のピットを30秒以内でゴール", + "ACHIEVEMENT_NAME_23": "亡霊", + "ACHIEVEMENT_DETAIL_23": "「クリフハンガー」で吹雪の中を誰にも気付かれず、誰も傷つけることなくC4を設置", + "ACHIEVEMENT_NAME_24": "カーネルおじさん", + "ACHIEVEMENT_DETAIL_24": "「スズメバチの巣」で10秒以内に鶏を7羽キル", + "ACHIEVEMENT_NAME_25": "歩兵の一団", + "ACHIEVEMENT_DETAIL_25": "1発のプレデターミサイルで10人以上キル", + "ACHIEVEMENT_NAME_26": "過剰な暴力", + "ACHIEVEMENT_DETAIL_26": "Riot shieldで敵を殴り倒す", + "ACHIEVEMENT_NAME_27": "失礼します", + "ACHIEVEMENT_DETAIL_27": "突入時のスローモーションで4人を4発でキル", + "ACHIEVEMENT_NAME_28": "熱いのがお好き", + "ACHIEVEMENT_DETAIL_28": "サーマルを使って6連続キル", + "ACHIEVEMENT_NAME_29": "一石二鳥", + "ACHIEVEMENT_DETAIL_29": "1発の銃弾で敵を2人キル", + "ACHIEVEMENT_NAME_30": "物知り博士", + "ACHIEVEMENT_DETAIL_30": "敵のインテルを22個入手", + "ACHIEVEMENT_NAME_31": "念には念を", + "ACHIEVEMENT_DETAIL_31": "敵のインテルを45個入手", + "ACHIEVEMENT_NAME_32": "撃ち逃げ", + "ACHIEVEMENT_DETAIL_32": "車両運転中に20連続キル", + "ACHIEVEMENT_NAME_33": "さっさと降りろ", + "ACHIEVEMENT_DETAIL_33": "ロープで下降中の敵が地面に着く前に2連続キル", + "ACHIEVEMENT_NAME_34": "無法者", + "ACHIEVEMENT_DETAIL_34": "5つの異なる武器またはアタッチメントで5連続キル", + "ACHIEVEMENT_NAME_35": "無敵の両腕", + "ACHIEVEMENT_DETAIL_35": "デュアル武器で10連続キル", + "ACHIEVEMENT_NAME_36": "尽きない不安", + "ACHIEVEMENT_DETAIL_36": "敵に気づかれずにナイフでキル", + "ACHIEVEMENT_NAME_37": "3人1組", + "ACHIEVEMENT_DETAIL_37": "グレネードランチャー1発で敵を3人以上キル", + "ACHIEVEMENT_NAME_38": "ターゲットを確認!", + "ACHIEVEMENT_DETAIL_38": "「エクソダス」でハニーバジャーを誘導して80キル", + "ACHIEVEMENT_NAME_39": "守護天使", + "ACHIEVEMENT_DETAIL_39": "「不測の事態」で敵にプレデターを破壊されない", + "ACHIEVEMENT_NAME_40": "絶対押すなよ", + "ACHIEVEMENT_DETAIL_40": "両方の部屋の赤いベルを押して生き延びる", + "ACHIEVEMENT_NAME_41": "藍より青し", + "ACHIEVEMENT_DETAIL_41": "「S.S.D.D.」ピットでBeenoxベストタイムを更新", + "ACHIEVEMENT_NAME_42": "リアルGUN GAME", + "ACHIEVEMENT_DETAIL_42": "キャンペーンで「S.S.D.D.」「エンドゲーム」以外のいずれかを近接攻撃、武器のリロードなしでクリア", + "ACHIEVEMENT_NAME_43": "未来への妄執", + "ACHIEVEMENT_DETAIL_43": "シェパードを排除", + "ACHIEVEMENT_NAME_44": "不死身", + "ACHIEVEMENT_DETAIL_44": "全ミッションを、死んだりチェックポイントへリロードすることなくクリア。難易度は不問", + "ACHIEVEMENT_NAME_45": "サイレントスカイ", + "ACHIEVEMENT_DETAIL_45": "「バーガータウン」でプレデターを使わずにBTRを2つとも破壊", + "ACHIEVEMENT_NAME_46": "もっとクレイモア", + "ACHIEVEMENT_DETAIL_46": "「未決事項」でクレイモアを使って敵を11人キル", + "ACHIEVEMENT_NAME_47": "バードハンター", + "ACHIEVEMENT_DETAIL_47": "「自らの意思」でJavelinを使ってヘリを10機撃墜", + "ACHIEVEMENT_NAME_48": "奇妙な挑戦", + "ACHIEVEMENT_DETAIL_48": "「ここからが正念場」でフラググレネードを使ってヘリを撃墜", + "ACHIEVEMENT_NAME_49": "練習場のピエロ", + "ACHIEVEMENT_DETAIL_49": "米軍レンジャーはおふざけで務まる場所じゃない", + "ACHIEVEMENT_NAME_50": "ヘッドバンギング", + "ACHIEVEMENT_DETAIL_50": "爆発前のフラググレネードを敵の頭に当ててキル", + "ACHIEVEMENT_NAME_51": "脳味噌...", + "ACHIEVEMENT_NAME_52": "ラミレス!" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/korean.json b/data/zonetool/localizedstrings/korean.json index c185a24e..10a609ad 100644 --- a/data/zonetool/localizedstrings/korean.json +++ b/data/zonetool/localizedstrings/korean.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "h2-mod 글꼴 사용", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "모든 임무 잠금 해제", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "잠금 해제 취소" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "잠금 해제 취소", + + "MENU_MUSIC_VOLUME": "음악 음량", + + "DEPOT_GO_TO_THE_DEPOT": "링크 열기", + "MENU_OPEN_MOTD": "오늘의 메시지", + + "LUA_MENU_ACHIEVEMENTS": "도전 과제", + "LUA_MENU_ACHIEVEMENTS_DESC": "도전 과제 진행률.", + + "ACHIEVEMENT_HIDDEN": "숨겨진 도전 과제", + "ACHIEVEMENT_HIDDEN_DESC": "계속 플레이해서 도전 과제를 잠금 해제하세요.", + "ACHIEVEMENT_EARNED": "도전 과제를 달성함!", + "ACHIEVEMENT_NAME_0": "이게 전부야?", + "ACHIEVEMENT_DETAIL_0": "콜 오브 듀티®: 모던 워페어 2 캠페인 리마스터의 모든 트로피를 획득하십시오.", + "ACHIEVEMENT_NAME_1": "복귀", + "ACHIEVEMENT_DETAIL_1": "현지 병력의 훈련을 도우십시오.", + "ACHIEVEMENT_NAME_2": "근접위험", + "ACHIEVEMENT_DETAIL_2": "셰퍼드의 엘리트 분대에 선발되십시오.", + "ACHIEVEMENT_NAME_3": "냉대", + "ACHIEVEMENT_DETAIL_3": "눈 덮인 산속 기지에 침투하십시오.", + "ACHIEVEMENT_NAME_4": "숨바꼭질", + "ACHIEVEMENT_DETAIL_4": "파벨라에서 로하스를 찾으십시오.", + "ACHIEVEMENT_NAME_5": "치즈 덕후", + "ACHIEVEMENT_DETAIL_5": "버거 타운을 방어하십시오.", + "ACHIEVEMENT_NAME_6": "로프 위의 소프", + "ACHIEVEMENT_DETAIL_6": "굴라그를 습격하십시오.", + "ACHIEVEMENT_NAME_7": "절박한 시간", + "ACHIEVEMENT_DETAIL_7": "미군을 돕는 계획을 실행하십시오.", + "ACHIEVEMENT_NAME_8": "백악관", + "ACHIEVEMENT_DETAIL_8": "백악관을 탈환하십시오.", + "ACHIEVEMENT_NAME_9": "독 안에 든 쥐", + "ACHIEVEMENT_DETAIL_9": "마카로프의 안전가옥을 습격하십시오.", + "ACHIEVEMENT_NAME_10": "설상가상", + "ACHIEVEMENT_DETAIL_10": "비행기 폐기장에서 미션을 완료하십시오.", + "ACHIEVEMENT_NAME_11": "진실의 기록", + "ACHIEVEMENT_DETAIL_11": "난이도에 상관없이 싱글플레이 캠페인을 완료하십시오.", + "ACHIEVEMENT_NAME_12": "전쟁의 대가", + "ACHIEVEMENT_DETAIL_12": "어려움 또는 베테랑 난이도에서 싱글플레이 캠페인을 완료하십시오.", + "ACHIEVEMENT_NAME_13": "등교 첫날", + "ACHIEVEMENT_DETAIL_13": "베테랑 난이도에서 ‘’엿 같은 날들‘’ 및 ‘’팀 플레이어‘’를 완료하십시오.", + "ACHIEVEMENT_NAME_14": "블랙 다이아몬드", + "ACHIEVEMENT_DETAIL_14": "베테랑 난이도에서 ‘’클리프행어‘’를 완료하십시오.", + "ACHIEVEMENT_NAME_15": "투리스터스", + "ACHIEVEMENT_DETAIL_15": "베테랑 난이도에서 ‘’제압‘’ 및 ‘’말벌집‘’을 완료하십시오.", + "ACHIEVEMENT_NAME_16": "붉은 새벽", + "ACHIEVEMENT_DETAIL_16": "베테랑 난이도에서 ‘’울버린!‘’ 및 ‘’대탈출‘’을 완료하십시오.", + "ACHIEVEMENT_NAME_17": "627번 포로", + "ACHIEVEMENT_DETAIL_17": "베테랑 난이도에서 ‘’더 이상 편한 날은 없다‘’ 및 ‘’굴라그‘’를 완료하십시오.", + "ACHIEVEMENT_NAME_18": "결과는 수단을 정당화한다", + "ACHIEVEMENT_DETAIL_18": "베테랑 난이도에서 ‘’뜻밖의 사고‘’를 완료하십시오.", + "ACHIEVEMENT_NAME_19": "귀향", + "ACHIEVEMENT_DETAIL_19": "베테랑 난이도에서 ‘’자발적 의지‘’, ‘’새로운 태양‘’ 및 ‘’백악관‘’을 완료하십시오.", + "ACHIEVEMENT_NAME_20": "정상에 선 여왕", + "ACHIEVEMENT_DETAIL_20": "베테랑 난이도에서 ‘’골칫거리‘’ 및 ‘’내 적의 원수‘’를 완료하십시오.", + "ACHIEVEMENT_NAME_21": "사라진 흔적", + "ACHIEVEMENT_DETAIL_21": "베테랑 난이도에서 ‘’예전처럼‘’ 및 ‘’종반전‘’을 완료하십시오.", + "ACHIEVEMENT_NAME_22": "참호 대장", + "ACHIEVEMENT_DETAIL_22": "‘’엿 같은 날들‘’에서 30초 내로 사격 연습 훈련을 완료하십시오.", + "ACHIEVEMENT_NAME_23": "고스트", + "ACHIEVEMENT_DETAIL_23": "‘’클리프행어‘’에서 적을 공격하거나 발각되지 않고 눈보라 속에서 C4를 설치하십시오.", + "ACHIEVEMENT_NAME_24": "샌더슨 대령", + "ACHIEVEMENT_DETAIL_24": "‘’말벌집‘’에서 10초 내에 닭 7마리를 처치하십시오.", + "ACHIEVEMENT_NAME_25": "10명 이상의 보병", + "ACHIEVEMENT_DETAIL_25": "프레데터 미사일 1발로 10명 이상의 적을 처치하십시오.", + "ACHIEVEMENT_NAME_26": "과잉진압", + "ACHIEVEMENT_DETAIL_26": "진압 방패로 적을 쓰러뜨리십시오.", + "ACHIEVEMENT_NAME_27": "똑똑", + "ACHIEVEMENT_DETAIL_27": "침투 시 슬로우 모션 상태에서 총알 4발로 적 4명을 처치하십시오.", + "ACHIEVEMENT_NAME_28": "뜨거운 것이 좋아", + "ACHIEVEMENT_DETAIL_28": "열화상 무기로 적을 6명 연달아 처치하십시오.", + "ACHIEVEMENT_NAME_29": "일석이조", + "ACHIEVEMENT_DETAIL_29": "총알 1발로 적 2명을 처치하십시오.", + "ACHIEVEMENT_NAME_30": "가지 않은 길", + "ACHIEVEMENT_DETAIL_30": "적 군사 정보 22개를 수집하십시오.", + "ACHIEVEMENT_NAME_31": "수색작전", + "ACHIEVEMENT_DETAIL_31": "적 군사 정보 45개를 수집하십시오.", + "ACHIEVEMENT_NAME_32": "드라이브", + "ACHIEVEMENT_DETAIL_32": "운전하면서 적 20명을 연달아 처치하십시오.", + "ACHIEVEMENT_NAME_33": "내려올 생각 마", + "ACHIEVEMENT_DETAIL_33": "하강 중인 적 2명을 연달아 처치하십시오.", + "ACHIEVEMENT_NAME_34": "무법자", + "ACHIEVEMENT_DETAIL_34": "5가지 다른 무기 또는 부속으로 적 5명을 연달아 처치하십시오.", + "ACHIEVEMENT_NAME_35": "내 양손을 봐", + "ACHIEVEMENT_DETAIL_35": "아킴보 무기로 적 10명을 연달아 처치하십시오.", + "ACHIEVEMENT_NAME_36": "적에게 휴식은 없다", + "ACHIEVEMENT_DETAIL_36": "플레이어를 발견하지 못한 적을 단검으로 처치하십시오.", + "ACHIEVEMENT_NAME_37": "일석삼조", + "ACHIEVEMENT_DETAIL_37": "유탄발사기 한 발로 적을 3명 이상 처치하십시오.", + "ACHIEVEMENT_NAME_38": "목표 확인", + "ACHIEVEMENT_DETAIL_38": "‘’대탈출‘’에서 허니 배저가 적 80명을 처치하도록 지시하십시오.", + "ACHIEVEMENT_NAME_39": "천사 구세주", + "ACHIEVEMENT_DETAIL_39": "‘’뜻밖의 사고‘’에서 플레이어의 프레데터 드론이 파괴되지 않도록 하십시오.", + "ACHIEVEMENT_NAME_40": "버튼을 누르지 마시오", + "ACHIEVEMENT_DETAIL_40": "두 개의 방에서 적색 벨을 울리고 공격에서 살아남으십시오.", + "ACHIEVEMENT_NAME_41": "개발자 위의 플레이어", + "ACHIEVEMENT_DETAIL_41": "‘’엿 같은 날들‘’에서 Beenox 최고 기록을 깨십시오.", + "ACHIEVEMENT_NAME_42": "리얼 총싸움", + "ACHIEVEMENT_DETAIL_42": "‘’엿 같은 날들‘’과 ‘’종반전‘’을 제외한 임무를 재장전 및 근접 공격을 사용하지 않고 완료하십시오.", + "ACHIEVEMENT_NAME_43": "상상과 망상 사이", + "ACHIEVEMENT_DETAIL_43": "셰퍼드를 처치하십시오.", + "ACHIEVEMENT_NAME_44": "불멸", + "ACHIEVEMENT_DETAIL_44": "난이도에 상관없이 사망하거나 체크포인트로 돌아가지 않고 모든 임무를 완료하십시오.", + "ACHIEVEMENT_NAME_45": "고요한 하늘", + "ACHIEVEMENT_DETAIL_45": "‘’울버린!‘’에서 프레데터 드론을 사용하지 않고 BTR 2대를 파괴하십시오.", + "ACHIEVEMENT_NAME_46": "클레이모어", + "ACHIEVEMENT_DETAIL_46": "‘’골칫거리‘’에서 클레이모어로 적 11명을 처치하십시오.", + "ACHIEVEMENT_NAME_47": "공중 사냥꾼", + "ACHIEVEMENT_DETAIL_47": "‘’자발적 의지‘’에서 재블린으로 헬기 10대를 파괴하십시오.", + "ACHIEVEMENT_NAME_48": "뜨거운 감자", + "ACHIEVEMENT_DETAIL_48": "‘’더 이상 편한 날은 없다‘’에서 수류탄을 사용하여 헬리콥터를 파괴하십시오.", + "ACHIEVEMENT_NAME_49": "훈련소의 광대", + "ACHIEVEMENT_DETAIL_49": "광대는 미 육군 레인저가 될 수 없습니다.", + "ACHIEVEMENT_NAME_50": "뇌진탕", + "ACHIEVEMENT_DETAIL_50": "세열 수류탄으로 머리에 충격을 입혀 적을 처치하십시오.", + "ACHIEVEMENT_NAME_51": "두뇌...", + "ACHIEVEMENT_NAME_52": "라미레즈!" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/polish.json b/data/zonetool/localizedstrings/polish.json index 6494f440..b296877d 100644 --- a/data/zonetool/localizedstrings/polish.json +++ b/data/zonetool/localizedstrings/polish.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "Aplikuj h2-mod czcionki", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "Odblokuj wszystkie misje", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "Anuluj odblokowanie" -} \ No newline at end of file + "LUA_MENU_CANCEL_UNLOCK_CAPS": "Anuluj odblokowanie", + + "MENU_MUSIC_VOLUME": "Głośność muzyki", + + "DEPOT_GO_TO_THE_DEPOT": "Otwórz link", + "MENU_OPEN_MOTD": "Wiadomość dnia", + + "LUA_MENU_ACHIEVEMENTS": "OSIĄGNIĘCIA", + "LUA_MENU_ACHIEVEMENTS_DESC": "Postęp osiągnięć.", + + "ACHIEVEMENT_HIDDEN": "Sekretne osiągnięcie", + "ACHIEVEMENT_HIDDEN_DESC": "Kontynuuj grę, aby je odblokować", + "ACHIEVEMENT_EARNED": "Odblokowano osiągnięcie!", + "ACHIEVEMENT_NAME_0": "To by było na tyle?", + "ACHIEVEMENT_DETAIL_0": "Zdobądź wszystkie trofea w Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "Z powrotem w siodle", + "ACHIEVEMENT_DETAIL_1": "Pomóż szkolić lokalną milicję.", + "ACHIEVEMENT_NAME_2": "Niebezpieczeństwo", + "ACHIEVEMENT_DETAIL_2": "Zakwalifikuj się do elitarnego oddziału Shepherda.", + "ACHIEVEMENT_NAME_3": "Straszny mróz", + "ACHIEVEMENT_DETAIL_3": "Zinfiltruj bazę znajdującą się na śnieżnym górskim szczycie.", + "ACHIEVEMENT_NAME_4": "Do piachu", + "ACHIEVEMENT_DETAIL_4": "Znajdź Rojasa w faweli.", + "ACHIEVEMENT_NAME_5": "Royale z serem", + "ACHIEVEMENT_DETAIL_5": "Obroń Burger Town.", + "ACHIEVEMENT_NAME_6": "Na linie", + "ACHIEVEMENT_DETAIL_6": "Wydostań się z gułagu.", + "ACHIEVEMENT_NAME_7": "Desperacki plan", + "ACHIEVEMENT_DETAIL_7": "Wykonaj plan mający pomóc Amerykanom.", + "ACHIEVEMENT_NAME_8": "Bravo Delta", + "ACHIEVEMENT_DETAIL_8": "Odbij Biały Dom.", + "ACHIEVEMENT_NAME_9": "Pionek", + "ACHIEVEMENT_DETAIL_9": "Zaatakuj kryjówkę Makarowa.", + "ACHIEVEMENT_NAME_10": "Z deszczu...", + "ACHIEVEMENT_DETAIL_10": "Ukończ misję na cmentarzysku samolotów.", + "ACHIEVEMENT_NAME_11": "Do akt", + "ACHIEVEMENT_DETAIL_11": "Ukończ kampanię na dowolnym poziomie trudności.", + "ACHIEVEMENT_NAME_12": "Ofiary wojny", + "ACHIEVEMENT_DETAIL_12": "Ukończ kampanię na poziomie trudności Doświadczony lub Weteran.", + "ACHIEVEMENT_NAME_13": "Pierwszy dzień szkoły", + "ACHIEVEMENT_DETAIL_13": "Ukończ misje 'Syf jak co dzień' i 'Gracz zespołowy' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_14": "Czarny diament", + "ACHIEVEMENT_DETAIL_14": "Ukończ misję 'Na krawędzi' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Ukończ misje 'Zatrzymanie' i 'Gniazdo szerszeni' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_16": "Czerwony świt", + "ACHIEVEMENT_DETAIL_16": "Ukończ misje 'Rosomaki!' i 'Exodus' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_17": "Więzień 627", + "ACHIEVEMENT_DETAIL_17": "Ukończ misje 'Lepsze jutro... było wczoraj' i 'Gułag' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_18": "Cele uświęcają środki", + "ACHIEVEMENT_DETAIL_18": "Ukończ misję 'Plan awaryjny' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_19": "Powrót do domu", + "ACHIEVEMENT_DETAIL_19": "Ukończ misje 'Z własnej woli', 'Drugie słońce' i 'Bravo Delta' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_20": "Królowa bije wieżę", + "ACHIEVEMENT_DETAIL_20": "Ukończ misje 'Niedokończone sprawy' i 'Wróg mojego wroga' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_21": "Poza siecią", + "ACHIEVEMENT_DETAIL_21": "Ukończ misje 'Jak za dawnych czasów' i 'Ostateczna rozgrywka' na poziomie trudności Weteran.", + "ACHIEVEMENT_NAME_22": "Mistrz Piekiełka", + "ACHIEVEMENT_DETAIL_22": "Przejdź Piekiełko w misji 'Syf jak co dzień' w mniej niż 30 sekund.", + "ACHIEVEMENT_NAME_23": "Duch", + "ACHIEVEMENT_DETAIL_23": "Podłóż C4 w misji 'Na krawędzi', nie dając się zauważyć i nie atakując nikogo podczas śnieżycy.", + "ACHIEVEMENT_NAME_24": "Pułkownik Sanderson", + "ACHIEVEMENT_DETAIL_24": "W misji 'Gniazdo szerszeni' zabij 7 kurczaków w mniej niż 10 sekund.", + "ACHIEVEMENT_NAME_25": "Ponad 10 piechurów", + "ACHIEVEMENT_DETAIL_25": "Zabij co najmniej 10 wrogów jednym pociskiem Predatora.", + "ACHIEVEMENT_NAME_26": "Przesadna brutalność", + "ACHIEVEMENT_DETAIL_26": "Użyj tarczy balistycznej do pokonania wroga.", + "ACHIEVEMENT_NAME_27": "Puk, puk", + "ACHIEVEMENT_DETAIL_27": "Zabij 4 wrogów 4 strzałami podczas ujęcia w zwolnionym tempie.", + "ACHIEVEMENT_NAME_28": "Jak Predator", + "ACHIEVEMENT_DETAIL_28": "Zabij 6 wrogów z rzędu bronią termowizyjną.", + "ACHIEVEMENT_NAME_29": "Dwie pieczenie na jednym ogniu", + "ACHIEVEMENT_DETAIL_29": "Zabij 2 wrogów jednym pociskiem.", + "ACHIEVEMENT_NAME_30": "Nieuczęszczane szlaki", + "ACHIEVEMENT_DETAIL_30": "Znajdź 22 dane wywiadu. ", + "ACHIEVEMENT_NAME_31": "Nic się nie ukryje", + "ACHIEVEMENT_DETAIL_31": "Znajdź 45 danych wywiadu. ", + "ACHIEVEMENT_NAME_32": "Przejazdem", + "ACHIEVEMENT_DETAIL_32": "Zabij 20 wrogów z rzędu, jadąc pojazdem.", + "ACHIEVEMENT_NAME_33": "Upadek", + "ACHIEVEMENT_DETAIL_33": "Zabij 2 zjeżdżających po linie wrogów, zanim dotrą na ziemię.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Zabij 5 wrogów z rzędu różną bronią lub dodatkami.", + "ACHIEVEMENT_NAME_35": "Na dwie ręce", + "ACHIEVEMENT_DETAIL_35": "Zabij 10 wrogów z rzędu bronią Akimbo.", + "ACHIEVEMENT_NAME_36": "Podchody", + "ACHIEVEMENT_DETAIL_36": "Zabij wroga nożem tak, by cię nie zauważył.", + "ACHIEVEMENT_NAME_37": "Trójkąt", + "ACHIEVEMENT_DETAIL_37": "Zabij co najmniej 3 wrogów jednym pociskiem z granatnika.", + "ACHIEVEMENT_NAME_38": "Cel potwierdzony", + "ACHIEVEMENT_DETAIL_38": "Poinstruuj Badgera, by zabił 80 wrogów w misji 'Exodus'.", + "ACHIEVEMENT_NAME_39": "Anioł Wybawiciel", + "ACHIEVEMENT_DETAIL_39": "Nie pozwól zniszczyć swojego Predatora w misji 'Plan awaryjny'.", + "ACHIEVEMENT_NAME_40": "Nie wciskać!!!", + "ACHIEVEMENT_DETAIL_40": "Użyj czerwonych dzwonków znajdujących się w obu pokojach i przeżyj atak.", + "ACHIEVEMENT_NAME_41": "Gdy uczeń przerasta mistrza", + "ACHIEVEMENT_DETAIL_41": "Pobij czas Beenox w misji 'Syf jak co dzień'.", + "ACHIEVEMENT_NAME_42": "Prawdziwa zabawa bronią", + "ACHIEVEMENT_DETAIL_42": "Ukończ misję inną niż 'Syf jak co dzień' i 'Ostateczna rozgrywka' bez przeładowania i walki wręcz.", + "ACHIEVEMENT_NAME_43": "Prekognitywna paranoja", + "ACHIEVEMENT_DETAIL_43": "Zabij Shepherda.", + "ACHIEVEMENT_NAME_44": "Nieśmiertelny", + "ACHIEVEMENT_DETAIL_44": "Ukończ każdą z misji na dowolnym poziomie trudności, nie ginąc i nie wczytując punktu kontrolnego.", + "ACHIEVEMENT_NAME_45": "Czyste niebo", + "ACHIEVEMENT_DETAIL_45": "Zniszcz oba BTR-y bez użycia dronów Predator w misji 'Rosomaki!'.", + "ACHIEVEMENT_NAME_46": "Podkładacz min", + "ACHIEVEMENT_DETAIL_46": "Zabij 11 wrogów minami Claymore w misji 'Niedokończone sprawy'.", + "ACHIEVEMENT_NAME_47": "Polowanie na ptaki", + "ACHIEVEMENT_DETAIL_47": "Zniszcz 10 helikopterów wyrzutnią Javelin w misji 'Z własnej woli'.", + "ACHIEVEMENT_NAME_48": "Gorący ziemniak", + "ACHIEVEMENT_DETAIL_48": "Zniszcz helikopter za pomocą granatów odłamkowych w misji 'Lepsze jutro... było wczoraj'.", + "ACHIEVEMENT_NAME_49": "Szkolenie klauna", + "ACHIEVEMENT_DETAIL_49": "U Rangersów nie ma miejsca dla klaunów.", + "ACHIEVEMENT_NAME_50": "W dyńkę", + "ACHIEVEMENT_DETAIL_50": "Zabij wroga bezpośrednim trafieniem granatem odłamkowym w głowę.", + "ACHIEVEMENT_NAME_51": "MÓZGIII...", + "ACHIEVEMENT_NAME_52": "Ramirez!" +} diff --git a/data/zonetool/localizedstrings/portuguese.json b/data/zonetool/localizedstrings/portuguese.json index 295e150e..20e4804b 100644 --- a/data/zonetool/localizedstrings/portuguese.json +++ b/data/zonetool/localizedstrings/portuguese.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "Usar fontes do h2-mod", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "Desbloquear todas as missões", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "Cancelar desbloqueio" -} \ No newline at end of file + "LUA_MENU_CANCEL_UNLOCK_CAPS": "Cancelar desbloqueio", + + "MENU_MUSIC_VOLUME": "Volume da música", + + "DEPOT_GO_TO_THE_DEPOT": "Abrir link", + "MENU_OPEN_MOTD": "Abrir mensagem do dia", + + "LUA_MENU_ACHIEVEMENTS": "CONQUISTAS", + "LUA_MENU_ACHIEVEMENTS_DESC": "O teu progresso em conquistas.", + + "ACHIEVEMENT_HIDDEN": "Conquista secreta", + "ACHIEVEMENT_HIDDEN_DESC": "Continua a jogar para o desbloqueares", + "ACHIEVEMENT_EARNED": "Conquista alcançada!", + "ACHIEVEMENT_NAME_0": "Isso É Tudo?", + "ACHIEVEMENT_DETAIL_0": "Obtenha todos os troféus disponíveis para Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "De Volta à Ativa", + "ACHIEVEMENT_DETAIL_1": "Ajude a treinar a milícia local.", + "ACHIEVEMENT_NAME_2": "Perigo Próximo", + "ACHIEVEMENT_DETAIL_2": "Seja escolhido a dedo para o esquadrão de elite de Shepherd.", + "ACHIEVEMENT_NAME_3": "Entrando Numa Fria", + "ACHIEVEMENT_DETAIL_3": "Infiltre-se na base secundária na montanha nevada.", + "ACHIEVEMENT_NAME_4": "Mande-o Para o Saco", + "ACHIEVEMENT_DETAIL_4": "Encontre Rojas nas favelas.", + "ACHIEVEMENT_NAME_5": "Queijo Duplo, Por Favor", + "ACHIEVEMENT_DETAIL_5": "Defenda o Burger Town.", + "ACHIEVEMENT_NAME_6": "Hora do Rapel!", + "ACHIEVEMENT_DETAIL_6": "Invada o gulag.", + "ACHIEVEMENT_NAME_7": "Medidas Extremas", + "ACHIEVEMENT_DETAIL_7": "Execute o plano para ajudar os Americanos.", + "ACHIEVEMENT_NAME_8": "Whiskey Hotel", + "ACHIEVEMENT_DETAIL_8": "Retome Whiskey Hotel.", + "ACHIEVEMENT_NAME_9": "O Peão", + "ACHIEVEMENT_DETAIL_9": "Ataque o abrigo de Makarov.", + "ACHIEVEMENT_NAME_10": "Saindo de Uma Enrascada...", + "ACHIEVEMENT_DETAIL_10": "Conclua a missão no cemitério de aviões.", + "ACHIEVEMENT_NAME_11": "Para Registrar", + "ACHIEVEMENT_DETAIL_11": "Conclua a Campanha individual em qualquer dificuldade.", + "ACHIEVEMENT_NAME_12": "O Preço da Guerra", + "ACHIEVEMENT_DETAIL_12": "Conclua a Campanha individual na dificuldade Casca-grossa ou Veterano.", + "ACHIEVEMENT_NAME_13": "Primeiro Dia na Escola", + "ACHIEVEMENT_DETAIL_13": "Conclua ''Outro dia, a mesma merda'' e ''Jogador de equipe'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_14": "Diamante Negro", + "ACHIEVEMENT_DETAIL_14": "Conclua ''À beira do abismo'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Conclua ''Derrubada'' e ''O vespeiro'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_16": "Aurora Vermelha", + "ACHIEVEMENT_DETAIL_16": "Conclua ''Wolverines!'' e ''Exodus'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_17": "Prisioneiro 627", + "ACHIEVEMENT_DETAIL_17": "Conclua ''O único dia fácil... foi ontem'' e ''O gulag'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_18": "Os Fins Justificam os Meios", + "ACHIEVEMENT_DETAIL_18": "Conclua ''Contingência'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_19": "De Volta ao Lar", + "ACHIEVEMENT_DETAIL_19": "Conclua ''Por sua própria vontade'', ''Segundo sol'' e ''Whiskey Hotel'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_20": "Rainha Captura Torre", + "ACHIEVEMENT_DETAIL_20": "Conclua ''Pontas soltas'' e ''O inimigo do meu inimigo'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_21": "Fora do Mapa", + "ACHIEVEMENT_DETAIL_21": "Conclua ''Como nos velhos tempos'' e ''Objetivo final'' na dificuldade Veterano.", + "ACHIEVEMENT_NAME_22": "Rei do Fosso", + "ACHIEVEMENT_DETAIL_22": "Conclua ''O fosso'' em ''Outro dia, a mesma merda'' com tempo final menor que 30 segundos.", + "ACHIEVEMENT_NAME_23": "Fantasma", + "ACHIEVEMENT_DETAIL_23": "Arme o C4 em ''À beira do abismo'' sem alertar ou ferir ninguém na nevasca.", + "ACHIEVEMENT_NAME_24": "Coronel Sanderson", + "ACHIEVEMENT_DETAIL_24": "Mate 7 galinhas em menos de 10 segundos em ''O vespeiro''.", + "ACHIEVEMENT_NAME_25": "Dia do Predador", + "ACHIEVEMENT_DETAIL_25": "Mate pelo menos 10 inimigos com um míssil do Predator.", + "ACHIEVEMENT_NAME_26": "Brutalidade Desnecessária", + "ACHIEVEMENT_DETAIL_26": "Use um escudo antimotim para espancar um inimigo.", + "ACHIEVEMENT_NAME_27": "Toc, Toc", + "ACHIEVEMENT_DETAIL_27": "Mate 4 inimigos com 4 disparos durante uma invasão em câmera lenta.", + "ACHIEVEMENT_NAME_28": "Pode Vir Quente", + "ACHIEVEMENT_DETAIL_28": "Mate 6 inimigos seguidos usando uma arma com visão térmica.", + "ACHIEVEMENT_NAME_29": "Dois Pássaros, Uma Pedrada", + "ACHIEVEMENT_DETAIL_29": "Mate 2 inimigos com um único projétil.", + "ACHIEVEMENT_NAME_30": "O Caminho Menos Percorrido", + "ACHIEVEMENT_DETAIL_30": "Colete 22 itens de inteligência inimiga.", + "ACHIEVEMENT_NAME_31": "Pente-Fino", + "ACHIEVEMENT_DETAIL_31": "Colete 45 itens de inteligência inimiga.", + "ACHIEVEMENT_NAME_32": "Passando por Cima", + "ACHIEVEMENT_DETAIL_32": "Mate 20 inimigos seguidos enquanto dirige um veículo.", + "ACHIEVEMENT_NAME_33": "Maior Será a Queda", + "ACHIEVEMENT_DETAIL_33": "Mate 2 inimigos descendo de corda seguidos antes que eles toquem o chão.", + "ACHIEVEMENT_NAME_34": "Desesperado", + "ACHIEVEMENT_DETAIL_34": "Mate 5 inimigos seguidos usando 5 armas ou acessórios diferentes.", + "ACHIEVEMENT_NAME_35": "Com as Duas Mãos", + "ACHIEVEMENT_DETAIL_35": "Mate 10 inimigos seguidos usando armas duplas.", + "ACHIEVEMENT_NAME_36": "Bobeou, Dançou", + "ACHIEVEMENT_DETAIL_36": "Esfaqueie um inimigo sem ele sequer perceber sua presença.", + "ACHIEVEMENT_NAME_37": "Ménage à Trois", + "ACHIEVEMENT_DETAIL_37": "Mate pelo menos 3 inimigos com um único disparo de lança-granadas.", + "ACHIEVEMENT_NAME_38": "Alvo Confirmado", + "ACHIEVEMENT_DETAIL_38": "Ordene o Honey Badger a matar 80 inimigos em ''Exodus''.", + "ACHIEVEMENT_NAME_39": "Anjo Salvador", + "ACHIEVEMENT_DETAIL_39": "Não deixe seu VANT Predator ser destruído em ''Contingência''.", + "ACHIEVEMENT_NAME_40": "NÃO Aperte Este Botão", + "ACHIEVEMENT_DETAIL_40": "Toque o sino vermelho nas duas salas e sobreviva ao ataque.", + "ACHIEVEMENT_NAME_41": "O Aprendiz Supera o Mestre", + "ACHIEVEMENT_DETAIL_41": "Bata o recorde da Beenox em ''Outro dia, a mesma merda''.", + "ACHIEVEMENT_NAME_42": "O Verdadeiro Jogo de Armas", + "ACHIEVEMENT_DETAIL_42": "Complete qualquer missão fora ''Outro dia, a mesma merda'' e ''Objetivo final'' sem CaC ou recargas.", + "ACHIEVEMENT_NAME_43": "Paranoia Precognitiva", + "ACHIEVEMENT_DETAIL_43": "Mate Shepherd.", + "ACHIEVEMENT_NAME_44": "Imortal", + "ACHIEVEMENT_DETAIL_44": "Conclua todas as missões sem morrer ou voltar a pontos de controle em qualquer dificuldade.", + "ACHIEVEMENT_NAME_45": "Céus Silenciosos", + "ACHIEVEMENT_DETAIL_45": "Destrua os dois BTRs sem usar VANTs Predator em ''Wolverines!''", + "ACHIEVEMENT_NAME_46": "Olhe por Onde Anda", + "ACHIEVEMENT_DETAIL_46": "Mate 11 inimigos usando Claymores em ''Pontas soltas''.", + "ACHIEVEMENT_NAME_47": "Caçando Pássaros", + "ACHIEVEMENT_DETAIL_47": "Destrua 10 helicópteros usando o lançador Javelin em ''Por sua própria vontade''.", + "ACHIEVEMENT_NAME_48": "Batata Quente", + "ACHIEVEMENT_DETAIL_48": "Destrua o helicóptero usando granadas de fragmentação em ''O único dia fácil... foi ontem''.", + "ACHIEVEMENT_NAME_49": "Palhaço em Treinamento", + "ACHIEVEMENT_DETAIL_49": "Os Rangers do Exército Americano não aceitam palhaços.", + "ACHIEVEMENT_NAME_50": "Na Cachola", + "ACHIEVEMENT_DETAIL_50": "Mate um inimigo com o dano de impacto de uma granada de fragmentação na cabeça.", + "ACHIEVEMENT_NAME_51": "CÉREBROOOS...", + "ACHIEVEMENT_NAME_52": "Ramirez!" +} diff --git a/data/zonetool/localizedstrings/russian.json b/data/zonetool/localizedstrings/russian.json index 8107342e..f6ca444d 100644 --- a/data/zonetool/localizedstrings/russian.json +++ b/data/zonetool/localizedstrings/russian.json @@ -10,7 +10,7 @@ "LOCALE_8": "Японский", "LOCALE_9": "Японский (английская озвучка)", "LOCALE_10": "Китайский традиционный", - "LOCALE_11": "Китайский упрощенный", + "LOCALE_11": "Китайский упрощëнный", "LOCALE_12": "Арабский", "LOCALE_13": "Чешский", "LOCALE_14": "Испанский (Латинская Америка)", @@ -49,7 +49,7 @@ "LUA_MENU_DRAWING": "Интерфейс (HUD)", "LUA_MENU_UPDATES": "Обновления", "LUA_MENU_RENDERING": "Отрисовка", - "LUA_MENU_DRAW_FPS": "Счетчик кадров", + "LUA_MENU_DRAW_FPS": "Счëтчик кадров", "LUA_MENU_DRAW_FPS_DESC": "Включить или отключить показ на экране частоты кадров в секунду (FPS) или View Pos.", "LUA_MENU_FPS_ONLY": "Только FPS", "LUA_MENU_FPS_AND_VIEWPOS": "FPS и View Pos", @@ -64,11 +64,17 @@ "LUA_MENU_INTRO": "Заставка", "LUA_MENU_INTRO_DESC": "Показывать или пропускать вступительный ролик с логотипами разработчиков при запуске игры.", + "MENU_MUSIC_VOLUME": "Громкость музыки", + "MENU_MUSIC_VOLUME_DESC": "Перемещайте бегунок, чтобы отрегулировать громкость саундтрека.", + "MENU_SYSINFO_CUSTOMER_SUPPORT_LINK": "Страница на GitHub:", "MENU_SYSINFO_CUSTOMER_SUPPORT_URL": "https://github.com/fedddddd/h2-mod", "MENU_SYSINFO_DONATION_LINK": "Ссылка для донатов:", "MENU_SYSINFO_DONATION_URL": "https://paypal.me/fedecek", + "DEPOT_GO_TO_THE_DEPOT": "Открыть ссылку", + "MENU_OPEN_MOTD": "Открыть сообщение дня", + "AF_CAVES_LINE1": "„Как в прежние времена“", "AF_CAVES_LINE3": "«Соуп» Мактавиш", "AF_CAVES_LINE4": "Точка „Хоутел-Браво“, Афганистан", @@ -84,10 +90,10 @@ "BONEYARD_INTROSCREEN_LINE_1": "„Враг моего врага“", "BONEYARD_INTROSCREEN_LINE_3": "Капитан «Соуп» Мактавиш", "BONEYARD_INTROSCREEN_LINE_4": "257 км к юго-востоку от Кандагара, Афганистан", - "BONEYARD_INTROSCREEN_LINE_5": "Свалка самолетов армии США №437", + "BONEYARD_INTROSCREEN_LINE_5": "Свалка самолëтов армии США №437", "CGAME_CONTINUE_SAVING": "Сохранить и выйти", "CGAME_MISSIONOBJECTIVES": "ЦЕЛИ ЗАДАНИЯ", - "CGAME_PRONE_BLOCKED": "Движение лежа заблокировано", + "CGAME_PRONE_BLOCKED": "Движение лëжа заблокировано", "CGAME_PRONE_BLOCKED_WEAPON": "С этим оружием нельзя лечь", "CGAME_RESTART_WARNING": "Если начать игру заново, \nвесь прогресс в текущем \nзадании будет утрачен\n\nНачать заново?", "CGAME_SAVE_WARNING": "Если вы сохраните игру сейчас,\nвесь прогресс с момента последней\nконтрольной точки будет утрачен\n\nСохранить игру?", @@ -110,7 +116,7 @@ "DC_WHITEHOUSE_INTROSCREEN_1": "„Виски-Хоутел“", "DC_WHITEHOUSE_INTROSCREEN_4": "1-й батальон 75-го полка рейнджеров", "DC_WHITEHOUSE_INTROSCREEN_5": "Вашингтон (округ Колумбия), США", - "DEADQUOTE_ALL_THAT_IS_NECESSARY": "\"Когда плохие люди объединяются, хорошие тоже должны действовать сообща,\nиначе все они падут жертвами этой безнадежной борьбы\".", + "DEADQUOTE_ALL_THAT_IS_NECESSARY": "\"Когда плохие люди объединяются, хорошие тоже должны действовать сообща,\nиначе все они падут жертвами этой безнадëжной борьбы\".", "DEADQUOTE_ALL_THAT_IS_NECESSARY_AUTHOR": "- Эдмунд Бёрк, британский философ и государственный деятель", "DEADQUOTE_ALL_WARFARE_IS_BASED": "\"Война – это искусство обмана\".", "DEADQUOTE_BEFORE_YOU_EMBARK_UPON": "\"Проклиная кого-то, ты сам роешь себе могилу\".", @@ -238,12 +244,12 @@ "MENU_CHEATS_HOWTO": "Чтобы получить доступ к чит-кодам, вам нужно полностью пройти игру как минимум один раз на любом уровне сложности.", "MENU_CHEATS_WARNING": "При использовании чит-кодов вы не сможете открывать достижения.", "MENU_CHEAT_ENABLED": "Чит-код активирован", - "MENU_CHEAT_EXCLUSION": "Включение этого параметра приведет к отключению следующих чит-кодов:", + "MENU_CHEAT_EXCLUSION": "Включение этого параметра приведëт к отключению следующих чит-кодов:", "MENU_COMPLETED": "Пройдено", "MENU_COMPLETED_CHEAT": "Доступен чит-код", - "MENU_CORRUPT_SAVEDATA_MESSAGE": "Сохраненные данные не были загружены, поскольку они повреждены. В случае продолжения они будут удалены.", + "MENU_CORRUPT_SAVEDATA_MESSAGE": "Сохранëнные данные не были загружены, поскольку они повреждены. В случае продолжения они будут удалены.", "MENU_CUSTOM": "Свои", - "MENU_DEFAULT_ALT": "Станд. перевернутая", + "MENU_DEFAULT_ALT": "Станд. перевëрнутая", "MENU_DIFFICULTY_WARNING": "Вам рекомендуется другой уровень сложности. Хотите продолжить на этом?", "MENU_DISPLAY_MODE": "Режим вывода", "MENU_DOF": "Глубина резкости", @@ -272,7 +278,7 @@ "MENU_RESTORE_DEFAULTS": "Системные настройки будут возвращены к значениям по умолчанию, продолжить?", "MENU_RESTORE_EACH_SETTING": "Все параметры будут возвращены к значениям по умолчанию, продолжить?", "MENU_RESUMEGAME_Q_DESC": "Хотите возобновить прохождение задания?", - "MENU_SAVEDATA_CORRUPTED": "Невозможно возобновить игру, т.к. поврежден файл сохранения. Пожалуйста, перезапустите уровень из меню выбора задания.", + "MENU_SAVEDATA_CORRUPTED": "Невозможно возобновить игру, т.к. повреждëн файл сохранения. Пожалуйста, перезапустите уровень из меню выбора задания.", "MENU_SAVEQUIT_TEXT": "Если выйти сейчас, весь прогресс с момента последней контрольной точки будет утрачен.", "MENU_SCREENSHOT": "Скриншот", "MENU_SPECULAR_MAP": "Карта бликов", @@ -289,12 +295,12 @@ "MENU_SP_FAVELA": "Задержание", "MENU_SP_FOR_THE_RECORD": "„Для записи“", "MENU_SP_GULAG_DESC": "Освободите заключённого №627 - единственного человека, которого Макаров ненавидит больше, чем американцев.", - "MENU_SP_INVASION_DESC": "Найдите и эвакуируйте важную персону под кодовым названием \"Рэптор\" из подбитого вертолета, пока рейнджеры отражают атаку радикальных националистов в Северной Вирджинии.", + "MENU_SP_INVASION_DESC": "Найдите и эвакуируйте важную персону под кодовым названием \"Рэптор\" из подбитого вертолëта, пока рейнджеры отражают атаку радикальных националистов в Северной Вирджинии.", "MENU_SP_OFFENSIVE_SKIP_2": "В игре есть задание, которое может задеть чувства некоторых игроков.\nНужна ли вам возможность пропустить его?", "MENU_SP_OFFENSIVE_SKIP_4": "У вас будет возможность пропустить задание в меню паузы.", "MENU_SP_OFFENSIVE_SKIP_NO_WONT_GET_OFFENDED": "Не нужна, это не заденет мои чувства", "MENU_SP_OFFENSIVE_SKIP_YES_ASK_LATER": "Да, нужна, спросите позже", - "MENU_SP_OILRIG": "Единственный легкий день... был вчера", + "MENU_SP_OILRIG": "Единственный лëгкий день... был вчера", "MENU_SP_OILRIG_DESC": "Проникните на захваченную буровую вышку. Освободите заложников и нейтрализуйте врага, чтобы американские войска смогли уничтожить ЗРК и расчистить путь к колонии.", "MENU_SP_TRAINER_DESC": "Покажите бойцам местной армии, как надо воевать. И помните: за вами будет наблюдать генерал Шепард.", "MENU_STANDARD_4_3": "Стандартное 4:3", @@ -307,7 +313,7 @@ "MENU_WIDE_21_9": "Сверхширокое 21:9", "MENU_YES": "Да", "OILRIG_HINT_C4_SWITCH": "Нажмите [{+actionslot 2}]^7, чтобы запустить детонатор C4", - "OILRIG_INTROSCREEN_LINE_1": "„Единственный легкий день... был вчера“", + "OILRIG_INTROSCREEN_LINE_1": "„Единственный лëгкий день... был вчера“", "OILRIG_INTROSCREEN_LINE_2": "День 5 - [{FAKE_INTRO_TIME:05:47:10}]", "OILRIG_INTROSCREEN_LINE_3": "Сержант Гари «Роуч» Сандерсон", "OILRIG_INTROSCREEN_LINE_5": "Вихоревка-36, нефтяная платформа, Россия", @@ -341,8 +347,8 @@ "PRESENCE_SP_ENDING_SYSTEM_DIALOG": "Финальный аккорд", "PRESENCE_SP_FAVELA": "Задержание", "PRESENCE_SP_FAVELA_SYSTEM_DIALOG": "Задержание", - "PRESENCE_SP_OILRIG": "Единственный легкий день... был вчера", - "PRESENCE_SP_OILRIG_SYSTEM_DIALOG": "Единственный легкий день... был вчера", + "PRESENCE_SP_OILRIG": "Единственный лëгкий день... был вчера", + "PRESENCE_SP_OILRIG_SYSTEM_DIALOG": "Единственный лëгкий день... был вчера", "ROADKILL_LINE_1": "„Командный игрок“", "ROADKILL_LINE_4": "1-й батальон 75-го полка рейнджеров", "SCRIPT_INVULERABLE_FRAGS": "Осколочные гранаты не могут навредить этой технике", @@ -373,13 +379,13 @@ "SUBTITLE_AIRPORT_VT_BEENOUGH291": "^2Анатолий: ^7Да, Макаров, хороший подарочек мы им преподнесли.", "SUBTITLE_BYARD_MKV_HOTELBRAVO49": "^1Макаров: ^7Шепард держит точку „Хоутел-Браво“. Ты знаешь, где это. Ладно, встретимся в аду.", "SUBTITLE_BYARD_PRI_CONTACTAHEAD102": "^2Капитан Прайс: ^7Контакт, прямо перед нами!", - "SUBTITLE_BYARD_PRI_FOUDNTRANSPORT81": "^2Капитан Прайс: ^7Соуп! Я нашел транспорт! Иди на запад! Я тебя подхвачу по дороге!", - "SUBTITLE_BYARD_PRI_LANDTHEPLANE62": "^2Капитан Прайс: ^7Заткнись уже и сажай самолет! Мы идем к тебе!", + "SUBTITLE_BYARD_PRI_FOUDNTRANSPORT81": "^2Капитан Прайс: ^7Соуп! Я нашëл транспорт! Иди на запад! Я тебя подхвачу по дороге!", + "SUBTITLE_BYARD_PRI_LANDTHEPLANE62": "^2Капитан Прайс: ^7Заткнись уже и сажай самолëт! Мы идëм к тебе!", "SUBTITLE_BYARD_PRI_MYFRIEND247": "^2Капитан Прайс: ^7Макаров... Ты слыхал такую пословицу: «враг моего врага - мой друг»?", "SUBTITLE_BYARD_PRI_MYFRIEND46": "^2Капитан Прайс: ^7Макаров... Ты слыхал такую пословицу: «враг моего врага - мой друг»?", "SUBTITLE_BYARD_PRI_WHEREAREYOU51": "^2Капитан Прайс: ^7Николай, ты где, черт подери?", "SUBTITLE_DCWHITE_CPD_BURNITDOWN215": "^2Капрал Данн: ^7Нескоро, приятель. Но когда мы туда доберёмся, мы сожжём её до основания.", - "SUBTITLE_FAVELA_CMT_DRIVERSDEAD22": "^2Капитан Мактавиш: ^7Гоуст! Наш водитель убит! Идем пешком! Жди нас у гостиницы Рио и постарайся задержать объект!", + "SUBTITLE_FAVELA_CMT_DRIVERSDEAD22": "^2Капитан Мактавиш: ^7Гоуст! Наш водитель убит! Идëм пешком! Жди нас у гостиницы Рио и постарайся задержать объект!", "TRAINER_INTROSCREEN_LINE_1": "„Курс молодого бойца“", "TRAINER_INTROSCREEN_LINE_4": "1-й батальон 75-го полка рейнджеров", "TRAINER_INTROSCREEN_LINE_5": "База огневой поддержки „Феникс“, Афганистан", @@ -397,14 +403,14 @@ "WEAPON_FN2000_FMJ": "F2000 с ЦМ патронами", "WEAPON_GLOCK_FMJ": "G18 с ЦМ патронами", "WEAPON_KRISS_ACOG_SILENCER": "\"Вектор\" с глушителем и прицелом ACOG", - "WEAPON_M16A4_GRENADIER": "M16A4 с гранатометом", + "WEAPON_M16A4_GRENADIER": "M16A4 с гранатомëтом", "WEAPON_M16_FMJ": "M16A4 с ЦМ патронами", "WEAPON_M21_FMJ": "M21 EBR с ЦМ патронами", "WEAPON_M240_FMJ": "M240 с ЦМ патронами", "WEAPON_M4M203_SILENCER": "M4A1 SOPMOD", "WEAPON_M4_CARBINE_FMJ": "M4A1 с ЦМ патронами", "WEAPON_MASADA_FMJ": "ACR с ЦМ патронами", - "WEAPON_MASADA_GL_EOTECH": "ACR с гранатометом и голографическим прицелом", + "WEAPON_MASADA_GL_EOTECH": "ACR с гранатомëтом и голографическим прицелом", "WEAPON_MODEL1887_BLING": "1887 класса люкс", "WEAPON_MP5K_FMJ": "MP5K с ЦМ патронами", "WEAPON_MP5_SILENCED_REDDOT": "MP5K с глушителем и коллиматорным прицелом", @@ -417,7 +423,7 @@ "WEAPON_SA80_GRIP": "L86 LSW с тактической рукоятью", "WEAPON_SA80_SILENCER": "L86 LSW с глушителем", "WEAPON_SAW_ACOG": "M249 с прицелом ACOG", - "WEAPON_SMGS": "Пистолеты-пулеметы", + "WEAPON_SMGS": "Пистолеты-пулемëты", "WEAPON_TAVOR_FMJ": "TAR-21 с ЦМ патронами", "WEAPON_TMP_FMJ": "TMP с ЦМ патронами", "WEAPON_UMP45_ACOG": "UMP45 с прицелом ACOG", @@ -430,6 +436,119 @@ "WEAPON_UMP45_ROF": "Скорострельный UMP45", "WEAPON_UMP45_SILENCER": "UMP45 с глушителем", "WEAPON_UMP45_THERMAL": "UMP45 с тепловизором", - "WEAPON_UMP45_XMAGS": "UMP45 с магазином повышенной емкости", - "WEAPON_WA2000_FMJ": "WA2000 с ЦМ патронами" -} \ No newline at end of file + "WEAPON_UMP45_XMAGS": "UMP45 с магазином повышенной ëмкости", + "WEAPON_WA2000_FMJ": "WA2000 с ЦМ патронами", + + "LUA_MENU_ACHIEVEMENTS": "ДОСТИЖЕНИЯ", + "LUA_MENU_ACHIEVEMENTS_DESC": "Посмотреть прогресс ваших достижений.", + + "ACHIEVEMENT_HIDDEN": "Секретное достижение", + "ACHIEVEMENT_HIDDEN_DESC": "Играйте больше, чтобы разблокировать его", + "ACHIEVEMENT_EARNED": "Получено достижение!", + "ACHIEVEMENT_NAME_0": "Это всë, на что вы способны?", + "ACHIEVEMENT_DETAIL_0": "Открыть все достижения игры «Call of Duty®: Modern Warfare® 2. Обновлëнная кампания».", + "ACHIEVEMENT_NAME_1": "Снова в седле", + "ACHIEVEMENT_DETAIL_1": "Помочь обучить местное ополчение.", + "ACHIEVEMENT_NAME_2": "В непосредственной близости", + "ACHIEVEMENT_DETAIL_2": "Пройти отбор в элитный отряд Шепарда.", + "ACHIEVEMENT_NAME_3": "Холодный приëм", + "ACHIEVEMENT_DETAIL_3": "Проникнуть на базу на заснеженном горном склоне.", + "ACHIEVEMENT_NAME_4": "Всем лежать!", + "ACHIEVEMENT_DETAIL_4": "Найти Рохаса в фавелах.", + "ACHIEVEMENT_NAME_5": "¼-фунтовый чизбургер", + "ACHIEVEMENT_DETAIL_5": "Защитить закусочную «Бургер Таун».", + "ACHIEVEMENT_NAME_6": "Мыло и верëвка", + "ACHIEVEMENT_DETAIL_6": "Взять штурмом колонию.", + "ACHIEVEMENT_NAME_7": "Отчаянные времена", + "ACHIEVEMENT_DETAIL_7": "Выполнить план помощи американцам.", + "ACHIEVEMENT_NAME_8": "Виски-Хоутел", + "ACHIEVEMENT_DETAIL_8": "Вернуть «Виски-Хоутел».", + "ACHIEVEMENT_NAME_9": "Пешка", + "ACHIEVEMENT_DETAIL_9": "Взять штурмом логово Макарова.", + "ACHIEVEMENT_NAME_10": "Как у чëрта со сковороды...", + "ACHIEVEMENT_DETAIL_10": "Выполнить задание на свалке для самолëтов.", + "ACHIEVEMENT_NAME_11": "Для записи", + "ACHIEVEMENT_DETAIL_11": "Пройти одиночную кампанию на любом уровне сложности.", + "ACHIEVEMENT_NAME_12": "Цена войны", + "ACHIEVEMENT_DETAIL_12": "Пройти одиночную кампанию на сложности «Закалëнный» или «Ветеран».", + "ACHIEVEMENT_NAME_13": "Первый раз в первый класс", + "ACHIEVEMENT_DETAIL_13": "Завершить уровни «Курс молодого бойца» и «Командный игрок» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_14": "Вертикаль", + "ACHIEVEMENT_DETAIL_14": "Завершить уровень «Скалолаз» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_15": "Экстремальный туризм", + "ACHIEVEMENT_DETAIL_15": "Завершить уровни «Задержание» и «Осиное гнездо» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_16": "Красноватый рассвет", + "ACHIEVEMENT_DETAIL_16": "Завершить уровни «Росомахи!» и «Исход» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_17": "Заключëнный №627", + "ACHIEVEMENT_DETAIL_17": "Завершить уровни «Единственный лëгкий день… был вчера» и «Колония» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_18": "Цель оправдывает средства", + "ACHIEVEMENT_DETAIL_18": "Завершить уровень «Досадная случайность» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_19": "Возвращение домой", + "ACHIEVEMENT_DETAIL_19": "Завершить «По доброй воле», «Второе солнце», «Виски-Хоутел» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_20": "Ферзь бьет ладью", + "ACHIEVEMENT_DETAIL_20": "Завершить уровни «Неоконченные дела» и «Враг моего врага» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_21": "Вне зоны доступа", + "ACHIEVEMENT_DETAIL_21": "Завершить уровни «Как в прежние времена» и «Финальный аккорд» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_22": "Мастер полигона", + "ACHIEVEMENT_DETAIL_22": "Пройти полигон на уровне «Курс молодого бойца» менее чем за 30 секунд.", + "ACHIEVEMENT_NAME_23": "Призрак", + "ACHIEVEMENT_DETAIL_23": "Заложить заряд C4 на уровне «Скалолаз», не подняв тревогу и не ранив ни одного врага.", + "ACHIEVEMENT_NAME_24": "Полковник Сандерсон", + "ACHIEVEMENT_DETAIL_24": "Убить 7 куриц менее чем за 10 секунд на уровне «Осиное гнездо».", + "ACHIEVEMENT_NAME_25": "Десять пеших целей", + "ACHIEVEMENT_DETAIL_25": "Убить не менее 10 противников одной ракетой «Хищник».", + "ACHIEVEMENT_NAME_26": "Полицейский произвол", + "ACHIEVEMENT_DETAIL_26": "Убить противника ударами полицейского щита.", + "ACHIEVEMENT_NAME_27": "Тук-тук", + "ACHIEVEMENT_DETAIL_27": "Убить 4 противников четырьмя выстрелами во время штурма в замедлении.", + "ACHIEVEMENT_NAME_28": "Люблю погорячее", + "ACHIEVEMENT_DETAIL_28": "Убить 6 противников подряд из оружия с тепловизором.", + "ACHIEVEMENT_NAME_29": "Двух зайцев одним выстрелом", + "ACHIEVEMENT_DETAIL_29": "Убить 2 противников одной пулей.", + "ACHIEVEMENT_NAME_30": "Нехоженые тропы", + "ACHIEVEMENT_DETAIL_30": "Собрать 22 фрагмента разведданных.", + "ACHIEVEMENT_NAME_31": "Заглянуть под каждый камень", + "ACHIEVEMENT_DETAIL_31": "Собрать 45 фрагментов разведданных.", + "ACHIEVEMENT_NAME_32": "Гроза пешеходов", + "ACHIEVEMENT_DETAIL_32": "Убить 20 противников подряд, управляя транспортным средством.", + "ACHIEVEMENT_NAME_33": "Жëсткая посадка", + "ACHIEVEMENT_DETAIL_33": "Убить подряд 2 противников, спускающихся по тросам.", + "ACHIEVEMENT_NAME_34": "Универсал", + "ACHIEVEMENT_DETAIL_34": "Убить 5 противников подряд, используя 5 разных видов оружия или модулей.", + "ACHIEVEMENT_NAME_35": "Стрельба по-македонски", + "ACHIEVEMENT_DETAIL_35": "Убить 10 противников подряд из парного оружия.", + "ACHIEVEMENT_NAME_36": "Нет покоя осмотрительным", + "ACHIEVEMENT_DETAIL_36": "Зарезать противника, не подозревающего о вашем присутствии.", + "ACHIEVEMENT_NAME_37": "Взрывное трио", + "ACHIEVEMENT_DETAIL_37": "Убить 3 противников одним выстрелом из гранатомëта.", + "ACHIEVEMENT_NAME_38": "Цель подтверждена", + "ACHIEVEMENT_DETAIL_38": "Обеспечить убийство Бэджером 80 противников на уровне «Исход».", + "ACHIEVEMENT_NAME_39": "Ангел-спаситель", + "ACHIEVEMENT_DETAIL_39": "Не допустить уничтожения БПЛА «Хищник» на уровне «Досадная случайность».", + "ACHIEVEMENT_NAME_40": "НЕ нажимай на кнопку!", + "ACHIEVEMENT_DETAIL_40": "Позвонить в красный колокольчик в обеих комнатах и пережить атаку.", + "ACHIEVEMENT_NAME_41": "Ученик превзошëл учителя", + "ACHIEVEMENT_DETAIL_41": "Побить рекорд Beenox на уровне «Курс молодого бойца».", + "ACHIEVEMENT_NAME_42": "Эталонная «Перестрелка»", + "ACHIEVEMENT_DETAIL_42": "Завершить любое задание кроме «Курса молодого бойца» и «Финального аккорда» без перезарядки/рукопашного боя.", + "ACHIEVEMENT_NAME_43": "Превентивная паранойя", + "ACHIEVEMENT_DETAIL_43": "Убить Шепарда.", + "ACHIEVEMENT_NAME_44": "Бессмертный", + "ACHIEVEMENT_DETAIL_44": "Завершить все задания на любом уровне сложности, не погибая и не возвращаясь к контрольным точкам.", + "ACHIEVEMENT_NAME_45": "Мирное небо", + "ACHIEVEMENT_DETAIL_45": "Уничтожить оба БТР-а, не используя БПЛА «Хищник» на уровне «Росомахи!».", + "ACHIEVEMENT_NAME_46": "Минëр", + "ACHIEVEMENT_DETAIL_46": "Убить 11 противников с помощью мин на уровне «Неоконченные дела».", + "ACHIEVEMENT_NAME_47": "Птицелов", + "ACHIEVEMENT_DETAIL_47": "Сбить 10 вертолëтов из ПТРК «Джавелин» на уровне «По доброй воле».", + "ACHIEVEMENT_NAME_48": "Горячая картошка", + "ACHIEVEMENT_DETAIL_48": "Уничтожить вертолëт осколочными гранатами на уровне «Единственный лëгкий день… был вчера».", + "ACHIEVEMENT_NAME_49": "Клоун на полигоне", + "ACHIEVEMENT_DETAIL_49": "В рядах рейнджеров не место клоунам.", + "ACHIEVEMENT_NAME_50": "Расколбас", + "ACHIEVEMENT_DETAIL_50": "Убить противника прямым попаданием осколочной гранаты в голову.", + "ACHIEVEMENT_NAME_51": "МОЗГИИИ...", + "ACHIEVEMENT_DETAIL_51": "Проверить камеру заключенного №227 на уровне «Колония».", + "ACHIEVEMENT_NAME_52": "Рамирес!", + "ACHIEVEMENT_DETAIL_52": "Включить радио в музее." +} diff --git a/data/zonetool/localizedstrings/russian_partial.json b/data/zonetool/localizedstrings/russian_partial.json index 4959cfc2..72d02e66 100644 --- a/data/zonetool/localizedstrings/russian_partial.json +++ b/data/zonetool/localizedstrings/russian_partial.json @@ -10,7 +10,7 @@ "LOCALE_8": "Японский", "LOCALE_9": "Японский (английская озвучка)", "LOCALE_10": "Китайский традиционный", - "LOCALE_11": "Китайский упрощенный", + "LOCALE_11": "Китайский упрощëнный", "LOCALE_12": "Арабский", "LOCALE_13": "Чешский", "LOCALE_14": "Испанский (Латинская Америка)", @@ -49,7 +49,7 @@ "LUA_MENU_DRAWING": "Интерфейс (HUD)", "LUA_MENU_UPDATES": "Обновления", "LUA_MENU_RENDERING": "Отрисовка", - "LUA_MENU_DRAW_FPS": "Счетчик кадров", + "LUA_MENU_DRAW_FPS": "Счëтчик кадров", "LUA_MENU_DRAW_FPS_DESC": "Включить или отключить показ на экране частоты кадров в секунду (FPS) или View Pos.", "LUA_MENU_FPS_ONLY": "Только FPS", "LUA_MENU_FPS_AND_VIEWPOS": "FPS и View Pos", @@ -64,11 +64,17 @@ "LUA_MENU_INTRO": "Заставка", "LUA_MENU_INTRO_DESC": "Показывать или пропускать вступительный ролик с логотипами разработчиков при запуске игры.", + "MENU_MUSIC_VOLUME": "Громкость музыки", + "MENU_MUSIC_VOLUME_DESC": "Перемещайте бегунок, чтобы отрегулировать громкость саундтрека.", + "MENU_SYSINFO_CUSTOMER_SUPPORT_LINK": "Страница на GitHub:", "MENU_SYSINFO_CUSTOMER_SUPPORT_URL": "https://github.com/fedddddd/h2-mod", "MENU_SYSINFO_DONATION_LINK": "Ссылка для донатов:", "MENU_SYSINFO_DONATION_URL": "https://paypal.me/fedecek", + "DEPOT_GO_TO_THE_DEPOT": "Открыть ссылку", + "MENU_OPEN_MOTD": "Открыть сообщение дня", + "AF_CAVES_LINE1": "„Как в прежние времена“", "AF_CAVES_LINE3": "«Соуп» Мактавиш", "AF_CAVES_LINE4": "Точка „Хоутел-Браво“, Афганистан", @@ -84,10 +90,10 @@ "BONEYARD_INTROSCREEN_LINE_1": "„Враг моего врага“", "BONEYARD_INTROSCREEN_LINE_3": "Капитан «Соуп» Мактавиш", "BONEYARD_INTROSCREEN_LINE_4": "257 км к юго-востоку от Кандагара, Афганистан", - "BONEYARD_INTROSCREEN_LINE_5": "Свалка самолетов армии США №437", + "BONEYARD_INTROSCREEN_LINE_5": "Свалка самолëтов армии США №437", "CGAME_CONTINUE_SAVING": "Сохранить и выйти", "CGAME_MISSIONOBJECTIVES": "ЦЕЛИ ЗАДАНИЯ", - "CGAME_PRONE_BLOCKED": "Движение лежа заблокировано", + "CGAME_PRONE_BLOCKED": "Движение лëжа заблокировано", "CGAME_PRONE_BLOCKED_WEAPON": "С этим оружием нельзя лечь", "CGAME_RESTART_WARNING": "Если начать игру заново, \nвесь прогресс в текущем \nзадании будет утрачен\n\nНачать заново?", "CGAME_SAVE_WARNING": "Если вы сохраните игру сейчас,\nвесь прогресс с момента последней\nконтрольной точки будет утрачен\n\nСохранить игру?", @@ -110,6 +116,7 @@ "DC_WHITEHOUSE_INTROSCREEN_1": "„Виски-Хоутел“", "DC_WHITEHOUSE_INTROSCREEN_4": "1-й батальон 75-го полка рейнджеров", "DC_WHITEHOUSE_INTROSCREEN_5": "Вашингтон (округ Колумбия), США", + "DEADQUOTE_ALL_THAT_IS_NECESSARY": "\"Когда плохие люди объединяются, хорошие тоже должны действовать сообща,\nиначе все они падут жертвами этой безнадëжной борьбы\".", "DEADQUOTE_ALL_THAT_IS_NECESSARY_AUTHOR": "- Эдмунд Бёрк, британский философ и государственный деятель", "DEADQUOTE_ALL_WARFARE_IS_BASED": "\"Война – это искусство обмана\".", "DEADQUOTE_BEFORE_YOU_EMBARK_UPON": "\"Проклиная кого-то, ты сам роешь себе могилу\".", @@ -237,12 +244,12 @@ "MENU_CHEATS_HOWTO": "Чтобы получить доступ к чит-кодам, вам нужно полностью пройти игру как минимум один раз на любом уровне сложности.", "MENU_CHEATS_WARNING": "При использовании чит-кодов вы не сможете открывать достижения.", "MENU_CHEAT_ENABLED": "Чит-код активирован", - "MENU_CHEAT_EXCLUSION": "Включение этого параметра приведет к отключению следующих чит-кодов:", + "MENU_CHEAT_EXCLUSION": "Включение этого параметра приведëт к отключению следующих чит-кодов:", "MENU_COMPLETED": "Пройдено", "MENU_COMPLETED_CHEAT": "Доступен чит-код", - "MENU_CORRUPT_SAVEDATA_MESSAGE": "Сохраненные данные не были загружены, поскольку они повреждены. В случае продолжения они будут удалены.", + "MENU_CORRUPT_SAVEDATA_MESSAGE": "Сохранëнные данные не были загружены, поскольку они повреждены. В случае продолжения они будут удалены.", "MENU_CUSTOM": "Свои", - "MENU_DEFAULT_ALT": "Станд. перевернутая", + "MENU_DEFAULT_ALT": "Станд. перевëрнутая", "MENU_DIFFICULTY_WARNING": "Вам рекомендуется другой уровень сложности. Хотите продолжить на этом?", "MENU_DISPLAY_MODE": "Режим вывода", "MENU_DOF": "Глубина резкости", @@ -271,7 +278,7 @@ "MENU_RESTORE_DEFAULTS": "Системные настройки будут возвращены к значениям по умолчанию, продолжить?", "MENU_RESTORE_EACH_SETTING": "Все параметры будут возвращены к значениям по умолчанию, продолжить?", "MENU_RESUMEGAME_Q_DESC": "Хотите возобновить прохождение задания?", - "MENU_SAVEDATA_CORRUPTED": "Невозможно возобновить игру, т.к. поврежден файл сохранения. Пожалуйста, перезапустите уровень из меню выбора задания.", + "MENU_SAVEDATA_CORRUPTED": "Невозможно возобновить игру, т.к. повреждëн файл сохранения. Пожалуйста, перезапустите уровень из меню выбора задания.", "MENU_SAVEQUIT_TEXT": "Если выйти сейчас, весь прогресс с момента последней контрольной точки будет утрачен.", "MENU_SCREENSHOT": "Скриншот", "MENU_SPECULAR_MAP": "Карта бликов", @@ -288,12 +295,12 @@ "MENU_SP_FAVELA": "Задержание", "MENU_SP_FOR_THE_RECORD": "„Для записи“", "MENU_SP_GULAG_DESC": "Освободите заключённого №627 - единственного человека, которого Макаров ненавидит больше, чем американцев.", - "MENU_SP_INVASION_DESC": "Найдите и эвакуируйте важную персону под кодовым названием \"Рэптор\" из подбитого вертолета, пока рейнджеры отражают атаку радикальных националистов в Северной Вирджинии.", + "MENU_SP_INVASION_DESC": "Найдите и эвакуируйте важную персону под кодовым названием \"Рэптор\" из подбитого вертолëта, пока рейнджеры отражают атаку радикальных националистов в Северной Вирджинии.", "MENU_SP_OFFENSIVE_SKIP_2": "В игре есть задание, которое может задеть чувства некоторых игроков.\nНужна ли вам возможность пропустить его?", "MENU_SP_OFFENSIVE_SKIP_4": "У вас будет возможность пропустить задание в меню паузы.", "MENU_SP_OFFENSIVE_SKIP_NO_WONT_GET_OFFENDED": "Не нужна, это не заденет мои чувства", "MENU_SP_OFFENSIVE_SKIP_YES_ASK_LATER": "Да, нужна, спросите позже", - "MENU_SP_OILRIG": "Единственный легкий день... был вчера", + "MENU_SP_OILRIG": "Единственный лëгкий день... был вчера", "MENU_SP_OILRIG_DESC": "Проникните на захваченную буровую вышку. Освободите заложников и нейтрализуйте врага, чтобы американские войска смогли уничтожить ЗРК и расчистить путь к колонии.", "MENU_SP_TRAINER_DESC": "Покажите бойцам местной армии, как надо воевать. И помните: за вами будет наблюдать генерал Шепард.", "MENU_STANDARD_4_3": "Стандартное 4:3", @@ -306,7 +313,7 @@ "MENU_WIDE_21_9": "Сверхширокое 21:9", "MENU_YES": "Да", "OILRIG_HINT_C4_SWITCH": "Нажмите [{+actionslot 2}]^7, чтобы запустить детонатор C4", - "OILRIG_INTROSCREEN_LINE_1": "„Единственный легкий день... был вчера“", + "OILRIG_INTROSCREEN_LINE_1": "„Единственный лëгкий день... был вчера“", "OILRIG_INTROSCREEN_LINE_2": "День 5 - [{FAKE_INTRO_TIME:05:47:10}]", "OILRIG_INTROSCREEN_LINE_3": "Сержант Гари «Роуч» Сандерсон", "OILRIG_INTROSCREEN_LINE_5": "Вихоревка-36, нефтяная платформа, Россия", @@ -340,8 +347,8 @@ "PRESENCE_SP_ENDING_SYSTEM_DIALOG": "Финальный аккорд", "PRESENCE_SP_FAVELA": "Задержание", "PRESENCE_SP_FAVELA_SYSTEM_DIALOG": "Задержание", - "PRESENCE_SP_OILRIG": "Единственный легкий день... был вчера", - "PRESENCE_SP_OILRIG_SYSTEM_DIALOG": "Единственный легкий день... был вчера", + "PRESENCE_SP_OILRIG": "Единственный лëгкий день... был вчера", + "PRESENCE_SP_OILRIG_SYSTEM_DIALOG": "Единственный лëгкий день... был вчера", "ROADKILL_LINE_1": "„Командный игрок“", "ROADKILL_LINE_4": "1-й батальон 75-го полка рейнджеров", "SCRIPT_INVULERABLE_FRAGS": "Осколочные гранаты не могут навредить этой технике", @@ -373,13 +380,13 @@ "SUBTITLE_AIRPORT_VT_BEENOUGH291": "^2Анатолий: ^7Да, Макаров, хороший подарочек мы им преподнесли.", "SUBTITLE_BYARD_MKV_HOTELBRAVO49": "^1Макаров: ^7Шепард держит точку „Хоутел-Браво“. Ты знаешь, где это. Ладно, встретимся в аду.", "SUBTITLE_BYARD_PRI_CONTACTAHEAD102": "^2Капитан Прайс: ^7Контакт, прямо перед нами!", - "SUBTITLE_BYARD_PRI_FOUDNTRANSPORT81": "^2Капитан Прайс: ^7Соуп! Я нашел транспорт! Иди на запад! Я тебя подхвачу по дороге!", - "SUBTITLE_BYARD_PRI_LANDTHEPLANE62": "^2Капитан Прайс: ^7Заткнись уже и сажай самолет! Мы идем к тебе!", + "SUBTITLE_BYARD_PRI_FOUDNTRANSPORT81": "^2Капитан Прайс: ^7Соуп! Я нашëл транспорт! Иди на запад! Я тебя подхвачу по дороге!", + "SUBTITLE_BYARD_PRI_LANDTHEPLANE62": "^2Капитан Прайс: ^7Заткнись уже и сажай самолëт! Мы идëм к тебе!", "SUBTITLE_BYARD_PRI_MYFRIEND247": "^2Капитан Прайс: ^7Макаров... Ты слыхал такую пословицу: «враг моего врага - мой друг»?", "SUBTITLE_BYARD_PRI_MYFRIEND46": "^2Капитан Прайс: ^7Макаров... Ты слыхал такую пословицу: «враг моего врага - мой друг»?", "SUBTITLE_BYARD_PRI_WHEREAREYOU51": "^2Капитан Прайс: ^7Николай, ты где, черт подери?", "SUBTITLE_DCWHITE_CPD_BURNITDOWN215": "^2Капрал Данн: ^7Нескоро, приятель. Но когда мы туда доберёмся, мы сожжём её до основания.", - "SUBTITLE_FAVELA_CMT_DRIVERSDEAD22": "^2Капитан Мактавиш: ^7Гоуст! Наш водитель убит! Идем пешком! Жди нас у гостиницы Рио и постарайся задержать объект!", + "SUBTITLE_FAVELA_CMT_DRIVERSDEAD22": "^2Капитан Мактавиш: ^7Гоуст! Наш водитель убит! Идëм пешком! Жди нас у гостиницы Рио и постарайся задержать объект!", "TRAINER_INTROSCREEN_LINE_1": "„Курс молодого бойца“", "TRAINER_INTROSCREEN_LINE_4": "1-й батальон 75-го полка рейнджеров", "TRAINER_INTROSCREEN_LINE_5": "База огневой поддержки „Феникс“, Афганистан", @@ -397,14 +404,14 @@ "WEAPON_FN2000_FMJ": "F2000 с ЦМ патронами", "WEAPON_GLOCK_FMJ": "G18 с ЦМ патронами", "WEAPON_KRISS_ACOG_SILENCER": "\"Вектор\" с глушителем и прицелом ACOG", - "WEAPON_M16A4_GRENADIER": "M16A4 с гранатометом", + "WEAPON_M16A4_GRENADIER": "M16A4 с гранатомëтом", "WEAPON_M16_FMJ": "M16A4 с ЦМ патронами", "WEAPON_M21_FMJ": "M21 EBR с ЦМ патронами", "WEAPON_M240_FMJ": "M240 с ЦМ патронами", "WEAPON_M4M203_SILENCER": "M4A1 SOPMOD", "WEAPON_M4_CARBINE_FMJ": "M4A1 с ЦМ патронами", "WEAPON_MASADA_FMJ": "ACR с ЦМ патронами", - "WEAPON_MASADA_GL_EOTECH": "ACR с гранатометом и голографическим прицелом", + "WEAPON_MASADA_GL_EOTECH": "ACR с гранатомëтом и голографическим прицелом", "WEAPON_MODEL1887_BLING": "1887 класса люкс", "WEAPON_MP5K_FMJ": "MP5K с ЦМ патронами", "WEAPON_MP5_SILENCED_REDDOT": "MP5K с глушителем и коллиматорным прицелом", @@ -417,7 +424,7 @@ "WEAPON_SA80_GRIP": "L86 LSW с тактической рукоятью", "WEAPON_SA80_SILENCER": "L86 LSW с глушителем", "WEAPON_SAW_ACOG": "M249 с прицелом ACOG", - "WEAPON_SMGS": "Пистолеты-пулеметы", + "WEAPON_SMGS": "Пистолеты-пулемëты", "WEAPON_TAVOR_FMJ": "TAR-21 с ЦМ патронами", "WEAPON_TMP_FMJ": "TMP с ЦМ патронами", "WEAPON_UMP45_ACOG": "UMP45 с прицелом ACOG", @@ -430,6 +437,119 @@ "WEAPON_UMP45_ROF": "Скорострельный UMP45", "WEAPON_UMP45_SILENCER": "UMP45 с глушителем", "WEAPON_UMP45_THERMAL": "UMP45 с тепловизором", - "WEAPON_UMP45_XMAGS": "UMP45 с магазином повышенной емкости", - "WEAPON_WA2000_FMJ": "WA2000 с ЦМ патронами" -} \ No newline at end of file + "WEAPON_UMP45_XMAGS": "UMP45 с магазином повышенной ëмкости", + "WEAPON_WA2000_FMJ": "WA2000 с ЦМ патронами", + + "LUA_MENU_ACHIEVEMENTS": "ДОСТИЖЕНИЯ", + "LUA_MENU_ACHIEVEMENTS_DESC": "Посмотреть прогресс ваших достижений.", + + "ACHIEVEMENT_HIDDEN": "Секретное достижение", + "ACHIEVEMENT_HIDDEN_DESC": "Играйте больше, чтобы разблокировать его", + "ACHIEVEMENT_EARNED": "Получено достижение!", + "ACHIEVEMENT_NAME_0": "Это всë, на что вы способны?", + "ACHIEVEMENT_DETAIL_0": "Открыть все достижения игры «Call of Duty®: Modern Warfare® 2. Обновлëнная кампания».", + "ACHIEVEMENT_NAME_1": "Снова в седле", + "ACHIEVEMENT_DETAIL_1": "Помочь обучить местное ополчение.", + "ACHIEVEMENT_NAME_2": "В непосредственной близости", + "ACHIEVEMENT_DETAIL_2": "Пройти отбор в элитный отряд Шепарда.", + "ACHIEVEMENT_NAME_3": "Холодный приëм", + "ACHIEVEMENT_DETAIL_3": "Проникнуть на базу на заснеженном горном склоне.", + "ACHIEVEMENT_NAME_4": "Всем лежать!", + "ACHIEVEMENT_DETAIL_4": "Найти Рохаса в фавелах.", + "ACHIEVEMENT_NAME_5": "¼-фунтовый чизбургер", + "ACHIEVEMENT_DETAIL_5": "Защитить закусочную «Бургер Таун».", + "ACHIEVEMENT_NAME_6": "Мыло и верëвка", + "ACHIEVEMENT_DETAIL_6": "Взять штурмом колонию.", + "ACHIEVEMENT_NAME_7": "Отчаянные времена", + "ACHIEVEMENT_DETAIL_7": "Выполнить план помощи американцам.", + "ACHIEVEMENT_NAME_8": "Виски-Хоутел", + "ACHIEVEMENT_DETAIL_8": "Вернуть «Виски-Хоутел».", + "ACHIEVEMENT_NAME_9": "Пешка", + "ACHIEVEMENT_DETAIL_9": "Взять штурмом логово Макарова.", + "ACHIEVEMENT_NAME_10": "Как у чëрта со сковороды...", + "ACHIEVEMENT_DETAIL_10": "Выполнить задание на свалке для самолëтов.", + "ACHIEVEMENT_NAME_11": "Для записи", + "ACHIEVEMENT_DETAIL_11": "Пройти одиночную кампанию на любом уровне сложности.", + "ACHIEVEMENT_NAME_12": "Цена войны", + "ACHIEVEMENT_DETAIL_12": "Пройти одиночную кампанию на сложности «Закалëнный» или «Ветеран».", + "ACHIEVEMENT_NAME_13": "Первый раз в первый класс", + "ACHIEVEMENT_DETAIL_13": "Завершить уровни «Курс молодого бойца» и «Командный игрок» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_14": "Вертикаль", + "ACHIEVEMENT_DETAIL_14": "Завершить уровень «Скалолаз» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_15": "Экстремальный туризм", + "ACHIEVEMENT_DETAIL_15": "Завершить уровни «Задержание» и «Осиное гнездо» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_16": "Красноватый рассвет", + "ACHIEVEMENT_DETAIL_16": "Завершить уровни «Росомахи!» и «Исход» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_17": "Заключëнный №627", + "ACHIEVEMENT_DETAIL_17": "Завершить уровни «Единственный лëгкий день… был вчера» и «Колония» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_18": "Цель оправдывает средства", + "ACHIEVEMENT_DETAIL_18": "Завершить уровень «Досадная случайность» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_19": "Возвращение домой", + "ACHIEVEMENT_DETAIL_19": "Завершить «По доброй воле», «Второе солнце», «Виски-Хоутел» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_20": "Ферзь бьет ладью", + "ACHIEVEMENT_DETAIL_20": "Завершить уровни «Неоконченные дела» и «Враг моего врага» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_21": "Вне зоны доступа", + "ACHIEVEMENT_DETAIL_21": "Завершить уровни «Как в прежние времена» и «Финальный аккорд» на сложности «Ветеран».", + "ACHIEVEMENT_NAME_22": "Мастер полигона", + "ACHIEVEMENT_DETAIL_22": "Пройти полигон на уровне «Курс молодого бойца» менее чем за 30 секунд.", + "ACHIEVEMENT_NAME_23": "Призрак", + "ACHIEVEMENT_DETAIL_23": "Заложить заряд C4 на уровне «Скалолаз», не подняв тревогу и не ранив ни одного врага.", + "ACHIEVEMENT_NAME_24": "Полковник Сандерсон", + "ACHIEVEMENT_DETAIL_24": "Убить 7 куриц менее чем за 10 секунд на уровне «Осиное гнездо».", + "ACHIEVEMENT_NAME_25": "Десять пеших целей", + "ACHIEVEMENT_DETAIL_25": "Убить не менее 10 противников одной ракетой «Хищник».", + "ACHIEVEMENT_NAME_26": "Полицейский произвол", + "ACHIEVEMENT_DETAIL_26": "Убить противника ударами полицейского щита.", + "ACHIEVEMENT_NAME_27": "Тук-тук", + "ACHIEVEMENT_DETAIL_27": "Убить 4 противников четырьмя выстрелами во время штурма в замедлении.", + "ACHIEVEMENT_NAME_28": "Люблю погорячее", + "ACHIEVEMENT_DETAIL_28": "Убить 6 противников подряд из оружия с тепловизором.", + "ACHIEVEMENT_NAME_29": "Двух зайцев одним выстрелом", + "ACHIEVEMENT_DETAIL_29": "Убить 2 противников одной пулей.", + "ACHIEVEMENT_NAME_30": "Нехоженые тропы", + "ACHIEVEMENT_DETAIL_30": "Собрать 22 фрагмента разведданных.", + "ACHIEVEMENT_NAME_31": "Заглянуть под каждый камень", + "ACHIEVEMENT_DETAIL_31": "Собрать 45 фрагментов разведданных.", + "ACHIEVEMENT_NAME_32": "Гроза пешеходов", + "ACHIEVEMENT_DETAIL_32": "Убить 20 противников подряд, управляя транспортным средством.", + "ACHIEVEMENT_NAME_33": "Жëсткая посадка", + "ACHIEVEMENT_DETAIL_33": "Убить подряд 2 противников, спускающихся по тросам.", + "ACHIEVEMENT_NAME_34": "Универсал", + "ACHIEVEMENT_DETAIL_34": "Убить 5 противников подряд, используя 5 разных видов оружия или модулей.", + "ACHIEVEMENT_NAME_35": "Стрельба по-македонски", + "ACHIEVEMENT_DETAIL_35": "Убить 10 противников подряд из парного оружия.", + "ACHIEVEMENT_NAME_36": "Нет покоя осмотрительным", + "ACHIEVEMENT_DETAIL_36": "Зарезать противника, не подозревающего о вашем присутствии.", + "ACHIEVEMENT_NAME_37": "Взрывное трио", + "ACHIEVEMENT_DETAIL_37": "Убить 3 противников одним выстрелом из гранатомëта.", + "ACHIEVEMENT_NAME_38": "Цель подтверждена", + "ACHIEVEMENT_DETAIL_38": "Обеспечить убийство Бэджером 80 противников на уровне «Исход».", + "ACHIEVEMENT_NAME_39": "Ангел-спаситель", + "ACHIEVEMENT_DETAIL_39": "Не допустить уничтожения БПЛА «Хищник» на уровне «Досадная случайность».", + "ACHIEVEMENT_NAME_40": "НЕ нажимай на кнопку!", + "ACHIEVEMENT_DETAIL_40": "Позвонить в красный колокольчик в обеих комнатах и пережить атаку.", + "ACHIEVEMENT_NAME_41": "Ученик превзошëл учителя", + "ACHIEVEMENT_DETAIL_41": "Побить рекорд Beenox на уровне «Курс молодого бойца».", + "ACHIEVEMENT_NAME_42": "Эталонная «Перестрелка»", + "ACHIEVEMENT_DETAIL_42": "Завершить любое задание кроме «Курса молодого бойца» и «Финального аккорда» без перезарядки/рукопашного боя.", + "ACHIEVEMENT_NAME_43": "Превентивная паранойя", + "ACHIEVEMENT_DETAIL_43": "Убить Шепарда.", + "ACHIEVEMENT_NAME_44": "Бессмертный", + "ACHIEVEMENT_DETAIL_44": "Завершить все задания на любом уровне сложности, не погибая и не возвращаясь к контрольным точкам.", + "ACHIEVEMENT_NAME_45": "Мирное небо", + "ACHIEVEMENT_DETAIL_45": "Уничтожить оба БТР-а, не используя БПЛА «Хищник» на уровне «Росомахи!».", + "ACHIEVEMENT_NAME_46": "Минëр", + "ACHIEVEMENT_DETAIL_46": "Убить 11 противников с помощью мин на уровне «Неоконченные дела».", + "ACHIEVEMENT_NAME_47": "Птицелов", + "ACHIEVEMENT_DETAIL_47": "Сбить 10 вертолëтов из ПТРК «Джавелин» на уровне «По доброй воле».", + "ACHIEVEMENT_NAME_48": "Горячая картошка", + "ACHIEVEMENT_DETAIL_48": "Уничтожить вертолëт осколочными гранатами на уровне «Единственный лëгкий день… был вчера».", + "ACHIEVEMENT_NAME_49": "Клоун на полигоне", + "ACHIEVEMENT_DETAIL_49": "В рядах рейнджеров не место клоунам.", + "ACHIEVEMENT_NAME_50": "Расколбас", + "ACHIEVEMENT_DETAIL_50": "Убить противника прямым попаданием осколочной гранаты в голову.", + "ACHIEVEMENT_NAME_51": "МОЗГИИИ...", + "ACHIEVEMENT_DETAIL_51": "Проверить камеру заключенного №227 на уровне «Колония».", + "ACHIEVEMENT_NAME_52": "Рамирес!", + "ACHIEVEMENT_DETAIL_52": "Включить радио в музее." +} diff --git a/data/zonetool/localizedstrings/simplified_chinese.json b/data/zonetool/localizedstrings/simplified_chinese.json index da99654f..b5959e4e 100644 --- a/data/zonetool/localizedstrings/simplified_chinese.json +++ b/data/zonetool/localizedstrings/simplified_chinese.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "使用 h2-mod 字体", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "解锁全部任务", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "取消解锁" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "取消解锁", + + "MENU_MUSIC_VOLUME": "音乐音量", + + "DEPOT_GO_TO_THE_DEPOT": "打开链接", + "MENU_OPEN_MOTD": "每日信息", + + "LUA_MENU_ACHIEVEMENTS": "成就", + "LUA_MENU_ACHIEVEMENTS_DESC": "您的成就进度。", + + "ACHIEVEMENT_HIDDEN": "秘密成就", + "ACHIEVEMENT_HIDDEN_DESC": "继续游玩以解锁它", + "ACHIEVEMENT_EARNED": "成就已解锁!", + "ACHIEVEMENT_NAME_0": "轻而易举", + "ACHIEVEMENT_DETAIL_0": "获得《使命召唤®:现代战争®2战役重制版》的全部奖杯。", + "ACHIEVEMENT_NAME_1": "欢迎回来", + "ACHIEVEMENT_DETAIL_1": "协助培训当地民兵。", + "ACHIEVEMENT_NAME_2": "危险任务", + "ACHIEVEMENT_DETAIL_2": "被谢菲尔德选入精英部队。", + "ACHIEVEMENT_NAME_3": "冰入膏肓", + "ACHIEVEMENT_DETAIL_3": "渗透进入被大雪覆盖的山腰基地。", + "ACHIEVEMENT_NAME_4": "打包带走", + "ACHIEVEMENT_DETAIL_4": "在贫民窟找到罗哈斯。", + "ACHIEVEMENT_NAME_5": "芝士汉堡", + "ACHIEVEMENT_DETAIL_5": "守住汉堡城。", + "ACHIEVEMENT_NAME_6": "肥皂挂好", + "ACHIEVEMENT_DETAIL_6": "勇闯苦力营。", + "ACHIEVEMENT_NAME_7": "特殊情况", + "ACHIEVEMENT_DETAIL_7": "执行协助美军的行动。", + "ACHIEVEMENT_NAME_8": "威士忌酒店", + "ACHIEVEMENT_DETAIL_8": "夺回白宫。", + "ACHIEVEMENT_NAME_9": "过河小兵", + "ACHIEVEMENT_DETAIL_9": "突袭马卡洛夫的安全屋。", + "ACHIEVEMENT_NAME_10": "刚出狼窝……", + "ACHIEVEMENT_DETAIL_10": "完成飞机坟场任务。", + "ACHIEVEMENT_NAME_11": "我们的故事", + "ACHIEVEMENT_DETAIL_11": "在任何难度下完成单人游戏战役。", + "ACHIEVEMENT_NAME_12": "战争代价", + "ACHIEVEMENT_DETAIL_12": "在熟练或老兵难度下完成单人游戏战役。", + "ACHIEVEMENT_NAME_13": "开学日", + "ACHIEVEMENT_DETAIL_13": "在老兵难度下完成“日常工作”和“团队合作”。", + "ACHIEVEMENT_NAME_14": "黑色钻石", + "ACHIEVEMENT_DETAIL_14": "在老兵难度下完成“巅峰战士”。", + "ACHIEVEMENT_NAME_15": "南美旅行", + "ACHIEVEMENT_DETAIL_15": "在老兵难度下完成“追捕”和“马蜂窝”。", + "ACHIEVEMENT_NAME_16": "赤色黎明", + "ACHIEVEMENT_DETAIL_16": "在老兵难度下完成“我们是狼獾!”和“大撤退”。", + "ACHIEVEMENT_NAME_17": "627号囚犯", + "ACHIEVEMENT_DETAIL_17": "在老兵难度下完成“愈发艰难”和“勇闯夺命岛”。", + "ACHIEVEMENT_NAME_18": "不择手段", + "ACHIEVEMENT_DETAIL_18": "在老兵难度下完成“特别手段”。", + "ACHIEVEMENT_NAME_19": "本土反攻", + "ACHIEVEMENT_DETAIL_19": "在老兵难度下完成“自告奋勇”、“第二轮太阳”和“白宫”。", + "ACHIEVEMENT_NAME_20": "车后之争", + "ACHIEVEMENT_DETAIL_20": "在老兵难度下完成“收拾残局”和“敌人的敌人”。", + "ACHIEVEMENT_NAME_21": "消声匿迹", + "ACHIEVEMENT_DETAIL_21": "在老兵难度下完成“犹如往日”和“曲终人散”。", + "ACHIEVEMENT_NAME_22": "训练场", + "ACHIEVEMENT_DETAIL_22": "进入“日常工作“中的训练场,并在30秒完成。", + "ACHIEVEMENT_NAME_23": "幽灵", + "ACHIEVEMENT_DETAIL_23": "在“巅峰战士”中不惊动或杀伤任何敌人,安放C4炸弹。", + "ACHIEVEMENT_NAME_24": "山德士上校", + "ACHIEVEMENT_DETAIL_24": "在”马蜂窝“中在10秒内杀死7只鸡。", + "ACHIEVEMENT_NAME_25": "瞬间爆炸", + "ACHIEVEMENT_DETAIL_25": "使用一枚“捕食者”导弹击杀至少10个敌人。", + "ACHIEVEMENT_NAME_26": "过度防卫", + "ACHIEVEMENT_DETAIL_26": "使用防爆盾击倒一个敌人。", + "ACHIEVEMENT_NAME_27": "把门儿开开", + "ACHIEVEMENT_DETAIL_27": "在破门慢放中开4枪消灭4个敌人。", + "ACHIEVEMENT_NAME_28": "趁热吃掉", + "ACHIEVEMENT_DETAIL_28": "使用装备了热成像瞄具的枪械连续击杀6个敌人。", + "ACHIEVEMENT_NAME_29": "一石二鸟", + "ACHIEVEMENT_DETAIL_29": "用1发子弹击杀2个敌人。", + "ACHIEVEMENT_NAME_30": "走自己的路", + "ACHIEVEMENT_DETAIL_30": "收集22件敌方情报。", + "ACHIEVEMENT_NAME_31": "让敌人无路可走", + "ACHIEVEMENT_DETAIL_31": "收集45件敌方情报。", + "ACHIEVEMENT_NAME_32": "公路杀手", + "ACHIEVEMENT_DETAIL_32": "在驾驶载具时连续击杀20个敌人。", + "ACHIEVEMENT_NAME_33": "站得越高,摔得越重", + "ACHIEVEMENT_DETAIL_33": "连续击杀2个正在索降的敌人。", + "ACHIEVEMENT_NAME_34": "手忙脚乱", + "ACHIEVEMENT_DETAIL_34": "用5件不同的武器或配件连续击杀5个敌人。", + "ACHIEVEMENT_NAME_35": "双手打枪", + "ACHIEVEMENT_DETAIL_35": "使用双持武器连续击杀10个敌人。", + "ACHIEVEMENT_NAME_36": "死于安乐", + "ACHIEVEMENT_DETAIL_36": "用匕首杀死一个没有察觉到自己的敌人。", + "ACHIEVEMENT_NAME_37": "三人同行", + "ACHIEVEMENT_DETAIL_37": "用一发枪榴弹击杀至少3个敌人。", + "ACHIEVEMENT_NAME_38": "目标确认", + "ACHIEVEMENT_DETAIL_38": "在“大撤退”中指示蜜獾击杀80个敌人。", + "ACHIEVEMENT_NAME_39": "守护天使", + "ACHIEVEMENT_DETAIL_39": "在“特别手段”中避免自己的“捕食者”无人机被摧毁。", + "ACHIEVEMENT_NAME_40": "别按按钮", + "ACHIEVEMENT_DETAIL_40": "按响两个房间里的红色警铃,然后在攻击中幸存。", + "ACHIEVEMENT_NAME_41": "青出于蓝", + "ACHIEVEMENT_DETAIL_41": "在“日常工作”中打破Beenox记录。", + "ACHIEVEMENT_NAME_42": "枪械游戏", + "ACHIEVEMENT_DETAIL_42": "不换弹匣不用近战完成“日常工作”和“曲终人散”之外的任何一个任务。", + "ACHIEVEMENT_NAME_43": "不详预感", + "ACHIEVEMENT_DETAIL_43": "杀死谢菲尔德。", + "ACHIEVEMENT_NAME_44": "一命通关", + "ACHIEVEMENT_DETAIL_44": "在任何难度下不死亡或读取进度完成所有任务。", + "ACHIEVEMENT_NAME_45": "无声打击", + "ACHIEVEMENT_DETAIL_45": "在“特别手段”中不使用“捕食者”无人机,将两辆BTR摧毁。", + "ACHIEVEMENT_NAME_46": "阔剑斩杀", + "ACHIEVEMENT_DETAIL_46": "在“收拾残局”中使用“阔剑”地雷击杀11个敌人。", + "ACHIEVEMENT_NAME_47": "大鸟猎人", + "ACHIEVEMENT_DETAIL_47": "在“自告奋勇”中使用“标枪”导弹摧毁10架直升机。", + "ACHIEVEMENT_NAME_48": "烫手山芋", + "ACHIEVEMENT_DETAIL_48": "在“愈发艰难”中使用枪榴弹摧毁直升机。", + "ACHIEVEMENT_NAME_49": "训练场滑稽", + "ACHIEVEMENT_DETAIL_49": "美国陆军游骑兵容不下滑稽的家伙。", + "ACHIEVEMENT_NAME_50": "当头一发", + "ACHIEVEMENT_DETAIL_50": "用枪榴弹击中敌人头部,靠冲击力将其击杀。", + "ACHIEVEMENT_NAME_51": "大脑……", + "ACHIEVEMENT_NAME_52": "拉米雷斯!" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/spanish.json b/data/zonetool/localizedstrings/spanish.json index abc9ecf8..ea123f48 100644 --- a/data/zonetool/localizedstrings/spanish.json +++ b/data/zonetool/localizedstrings/spanish.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "Usar tipografías de h2-mod", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "Desbloquear todas las misiones", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "Cancelar desbloqueo" -} \ No newline at end of file + "LUA_MENU_CANCEL_UNLOCK_CAPS": "Cancelar desbloqueo", + + "MENU_MUSIC_VOLUME": "Volumen de la música", + + "DEPOT_GO_TO_THE_DEPOT": "Abrir vínculo", + "MENU_OPEN_MOTD": "Mensaje del día", + + "LUA_MENU_ACHIEVEMENTS": "LOGROS", + "LUA_MENU_ACHIEVEMENTS_DESC": "Avance en tus logros.", + + "ACHIEVEMENT_HIDDEN": "Logro secreto", + "ACHIEVEMENT_HIDDEN_DESC": "Sigue jugando para desbloquearlo", + "ACHIEVEMENT_EARNED": "¡Logro desbloqueado!", + "ACHIEVEMENT_NAME_0": "¿Eso es todo?", + "ACHIEVEMENT_DETAIL_0": "Consigue todos los trofeos disponibles en Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "De vuelta a la acción", + "ACHIEVEMENT_DETAIL_1": "Instruye a la milicia local.", + "ACHIEVEMENT_NAME_2": "Peligro cercano", + "ACHIEVEMENT_DETAIL_2": "Haz que te escojan para el pelotón de Shepherd.", + "ACHIEVEMENT_NAME_3": "Recibimiento frío", + "ACHIEVEMENT_DETAIL_3": "Infíltrate en la base de la ladera nevada.", + "ACHIEVEMENT_NAME_4": "Identifícalo y a la bolsa", + "ACHIEVEMENT_DETAIL_4": "Encuentra a Rojas en las favelas.", + "ACHIEVEMENT_NAME_5": "Royal con queso", + "ACHIEVEMENT_DETAIL_5": "Defiende el Burger Town.", + "ACHIEVEMENT_NAME_6": "Soap en apuros", + "ACHIEVEMENT_DETAIL_6": "Asalta el gulag.", + "ACHIEVEMENT_NAME_7": "Tiempos desesperados", + "ACHIEVEMENT_DETAIL_7": "Ejecuta el plan para ayudar a los americanos.", + "ACHIEVEMENT_NAME_8": "Whiskey Hotel", + "ACHIEVEMENT_DETAIL_8": "Recupera Whiskey Hotel.", + "ACHIEVEMENT_NAME_9": "El peón", + "ACHIEVEMENT_DETAIL_9": "Ataca el piso franco de Makarov.", + "ACHIEVEMENT_NAME_10": "De la sartén al fuego...", + "ACHIEVEMENT_DETAIL_10": "Completa la misión en el cementerio de aviones.", + "ACHIEVEMENT_NAME_11": "Para que conste", + "ACHIEVEMENT_DETAIL_11": "Completa la campaña individual en cualquier dificultad.", + "ACHIEVEMENT_NAME_12": "El precio de la guerra", + "ACHIEVEMENT_DETAIL_12": "Completa la campaña individual en dificultad Curtido o Veterano.", + "ACHIEVEMENT_NAME_13": "Primer día de clase", + "ACHIEVEMENT_DETAIL_13": "Completa 'Otro día, la misma mierda' y 'Jugador de equipo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_14": "Diamante negro", + "ACHIEVEMENT_DETAIL_14": "Completa 'Máximo riesgo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Completa 'En búsqueda y captura' y 'Avispero' en dificultad Veterano.", + "ACHIEVEMENT_NAME_16": "Amanecer rojo", + "ACHIEVEMENT_DETAIL_16": "Completa '¡Wolverines!' y 'Éxodo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_17": "Prisionero 627", + "ACHIEVEMENT_DETAIL_17": "Completa 'El único día fácil... fue ayer' y 'El gulag' en dificultad Veterano.", + "ACHIEVEMENT_NAME_18": "El fin justifica los medios", + "ACHIEVEMENT_DETAIL_18": "Completa 'Contingencia' en dificultad veterano.", + "ACHIEVEMENT_NAME_19": "Vuelta a casa", + "ACHIEVEMENT_DETAIL_19": "Completa 'Por voluntad propia', 'Segundo sol' y 'Whiskey Hotel' en dificultad Veterano.", + "ACHIEVEMENT_NAME_20": "La reina se come a la torre", + "ACHIEVEMENT_DETAIL_20": "Completa 'Cabos sueltos' y 'El enemigo de mi enemigo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_21": "Invisible", + "ACHIEVEMENT_DETAIL_21": "Completa 'Como en los viejos tiempos' y 'Fin de partida' en Veterano.", + "ACHIEVEMENT_NAME_22": "Jefe del foso", + "ACHIEVEMENT_DETAIL_22": "Recorre el foso en 'Otro día, la misma mierda' y acaba en menos de 30 segundos.", + "ACHIEVEMENT_NAME_23": "Fantasma", + "ACHIEVEMENT_DETAIL_23": "Coloca el C4 en 'Máximo riesgo' sin alertar ni herir a nadie en la ventisca.", + "ACHIEVEMENT_NAME_24": "Coronel Sanderson", + "ACHIEVEMENT_DETAIL_24": "Mata a 7 gallinas en menos de 10 segundos en 'Avispero'.", + "ACHIEVEMENT_NAME_25": "Más de 10 enemigos", + "ACHIEVEMENT_DETAIL_25": "Mata al menos a 10 enemigos con un misil del Predator.", + "ACHIEVEMENT_NAME_26": "Violencia innecesaria", + "ACHIEVEMENT_DETAIL_26": "Usa un escudo antidisturbios para derribar a un enemigo.", + "ACHIEVEMENT_NAME_27": "Toc toc", + "ACHIEVEMENT_DETAIL_27": "Mata a 4 enemigos con 4 tiros durante una incursión a cámara lenta.", + "ACHIEVEMENT_NAME_28": "En caliente", + "ACHIEVEMENT_DETAIL_28": "Mata a 6 enemigos seguidos con un arma térmica.", + "ACHIEVEMENT_NAME_29": "Dos pájaros de un tiro", + "ACHIEVEMENT_DETAIL_29": "Mata a 2 enemigos con una sola bala.", + "ACHIEVEMENT_NAME_30": "El camino menos transitado", + "ACHIEVEMENT_DETAIL_30": "Consigue 22 objetos con información enemiga.", + "ACHIEVEMENT_NAME_31": "Remover cielo y tierra", + "ACHIEVEMENT_DETAIL_31": "Consigue 45 objetos con información enemiga.", + "ACHIEVEMENT_NAME_32": "Tiroteo en marcha", + "ACHIEVEMENT_DETAIL_32": "Mata a 20 enemigos seguidos conduciendo un vehículo.", + "ACHIEVEMENT_NAME_33": "Más dura será la caída", + "ACHIEVEMENT_DETAIL_33": "Mata a 2 enemigos seguidos que hagan rápel antes de que aterricen.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Mata a 5 rivales seguidos con 5 armas o accesorios distintos.", + "ACHIEVEMENT_NAME_35": "Mira mamá, con dos manos", + "ACHIEVEMENT_DETAIL_35": "Mata a 10 enemigos seguidos empuñando armas duales.", + "ACHIEVEMENT_NAME_36": "No hay paz para los cautos", + "ACHIEVEMENT_DETAIL_36": "Apuñala a un enemigo sin que se percate de tu presencia.", + "ACHIEVEMENT_NAME_37": "Trío", + "ACHIEVEMENT_DETAIL_37": "Mata al menos a 3 enemigos de un solo tiro de lanzagranadas.", + "ACHIEVEMENT_NAME_38": "Blanco confirmado", + "ACHIEVEMENT_DETAIL_38": "Ordena que el Honey Badger mate a 80 enemigos en 'Éxodo'.", + "ACHIEVEMENT_NAME_39": "Ángel salvador", + "ACHIEVEMENT_DETAIL_39": "Evita que destruyan tu dron Predator en 'Contingencia'.", + "ACHIEVEMENT_NAME_40": "NO pulses este botón", + "ACHIEVEMENT_DETAIL_40": "Dale a la campanilla roja en ambas salas y sobrevive al ataque.", + "ACHIEVEMENT_NAME_41": "El estudiante supera al maestro", + "ACHIEVEMENT_DETAIL_41": "Supera el tiempo de Beenox en 'Otro día, la misma mierda'.", + "ACHIEVEMENT_NAME_42": "El verdadero juego de armas", + "ACHIEVEMENT_DETAIL_42": "Completa una misión salvo 'Otro día, la misma mierda' y 'Fin de partida' sin recargar ni usar CaC.", + "ACHIEVEMENT_NAME_43": "Paranoia precognitiva", + "ACHIEVEMENT_DETAIL_43": "Mata a Shepherd.", + "ACHIEVEMENT_NAME_44": "Inmortal", + "ACHIEVEMENT_DETAIL_44": "Completa todas las misiones sin morir ni recargar puntos de control en cualquier dificultad.", + "ACHIEVEMENT_NAME_45": "Cielo silencioso", + "ACHIEVEMENT_DETAIL_45": "Destruye los dos BTR sin usar drones Predator en '¡Wolverines!'.", + "ACHIEVEMENT_NAME_46": "Claymore", + "ACHIEVEMENT_DETAIL_46": "Mata a 11 enemigos con claymore en 'Cabos sueltos'.", + "ACHIEVEMENT_NAME_47": "Cazador de pájaros", + "ACHIEVEMENT_DETAIL_47": "Destruye 10 helicópteros con el Javelin en 'Por voluntad propia'.", + "ACHIEVEMENT_NAME_48": "Patata caliente", + "ACHIEVEMENT_DETAIL_48": "Destruye el helicóptero con granadas de fragmentación en 'El único día fácil... fue ayer'.", + "ACHIEVEMENT_NAME_49": "Escuela de payasos", + "ACHIEVEMENT_DETAIL_49": "El cuerpo de Rangers del ejército de EE. UU. no es lugar para payasos.", + "ACHIEVEMENT_NAME_50": "Cabecear", + "ACHIEVEMENT_DETAIL_50": "Mata a un enemigo con el impacto de una granada de fragmentación en la cabeza.", + "ACHIEVEMENT_NAME_51": "CEREBROOOS...", + "ACHIEVEMENT_NAME_52": "¡Ramírez!" +} diff --git a/data/zonetool/localizedstrings/spanishna.json b/data/zonetool/localizedstrings/spanishna.json index abc9ecf8..6361958a 100644 --- a/data/zonetool/localizedstrings/spanishna.json +++ b/data/zonetool/localizedstrings/spanishna.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "Usar tipografías de h2-mod", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "Desbloquear todas las misiones", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "Cancelar desbloqueo" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "Cancelar desbloqueo", + + "MENU_MUSIC_VOLUME": "Volumen de la música", + + "DEPOT_GO_TO_THE_DEPOT": "Abrir vínculo", + "MENU_OPEN_MOTD": "Mensaje del día", + + "LUA_MENU_ACHIEVEMENTS": "LOGROS", + "LUA_MENU_ACHIEVEMENTS_DESC": "Avance en tus logros.", + + "ACHIEVEMENT_HIDDEN": "Logro secreto", + "ACHIEVEMENT_HIDDEN_DESC": "Sigue jugando para desbloquearlo", + "ACHIEVEMENT_EARNED": "¡Logro desbloqueado!", + "ACHIEVEMENT_NAME_0": "¿Eso es todo?", + "ACHIEVEMENT_DETAIL_0": "Consigue todos los trofeos disponibles en Call of Duty®: Modern Warfare® 2 Campaign Remastered.", + "ACHIEVEMENT_NAME_1": "De vuelta a la acción", + "ACHIEVEMENT_DETAIL_1": "Instruye a la milicia local.", + "ACHIEVEMENT_NAME_2": "Peligro cercano", + "ACHIEVEMENT_DETAIL_2": "Haz que te escojan para el pelotón de Shepherd.", + "ACHIEVEMENT_NAME_3": "Recibimiento frío", + "ACHIEVEMENT_DETAIL_3": "Infíltrate en la base de la ladera nevada.", + "ACHIEVEMENT_NAME_4": "Identifícalo y a la bolsa", + "ACHIEVEMENT_DETAIL_4": "Encuentra a Rojas en las favelas.", + "ACHIEVEMENT_NAME_5": "Royal con queso", + "ACHIEVEMENT_DETAIL_5": "Defiende el Burger Town.", + "ACHIEVEMENT_NAME_6": "Soap en apuros", + "ACHIEVEMENT_DETAIL_6": "Asalta el gulag.", + "ACHIEVEMENT_NAME_7": "Tiempos desesperados", + "ACHIEVEMENT_DETAIL_7": "Ejecuta el plan para ayudar a los americanos.", + "ACHIEVEMENT_NAME_8": "Whiskey Hotel", + "ACHIEVEMENT_DETAIL_8": "Recupera Whiskey Hotel.", + "ACHIEVEMENT_NAME_9": "El peón", + "ACHIEVEMENT_DETAIL_9": "Ataca el piso franco de Makarov.", + "ACHIEVEMENT_NAME_10": "De la sartén al fuego...", + "ACHIEVEMENT_DETAIL_10": "Completa la misión en el cementerio de aviones.", + "ACHIEVEMENT_NAME_11": "Para que conste", + "ACHIEVEMENT_DETAIL_11": "Completa la campaña individual en cualquier dificultad.", + "ACHIEVEMENT_NAME_12": "El precio de la guerra", + "ACHIEVEMENT_DETAIL_12": "Completa la campaña individual en dificultad Curtido o Veterano.", + "ACHIEVEMENT_NAME_13": "Primer día de clase", + "ACHIEVEMENT_DETAIL_13": "Completa 'Otro día, la misma mierda' y 'Jugador de equipo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_14": "Diamante negro", + "ACHIEVEMENT_DETAIL_14": "Completa 'Máximo riesgo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_15": "Turistas", + "ACHIEVEMENT_DETAIL_15": "Completa 'En búsqueda y captura' y 'Avispero' en dificultad Veterano.", + "ACHIEVEMENT_NAME_16": "Amanecer rojo", + "ACHIEVEMENT_DETAIL_16": "Completa '¡Wolverines!' y 'Éxodo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_17": "Prisionero 627", + "ACHIEVEMENT_DETAIL_17": "Completa 'El único día fácil... fue ayer' y 'El gulag' en dificultad Veterano.", + "ACHIEVEMENT_NAME_18": "El fin justifica los medios", + "ACHIEVEMENT_DETAIL_18": "Completa 'Contingencia' en dificultad veterano.", + "ACHIEVEMENT_NAME_19": "Vuelta a casa", + "ACHIEVEMENT_DETAIL_19": "Completa 'Por voluntad propia', 'Segundo sol' y 'Whiskey Hotel' en dificultad Veterano.", + "ACHIEVEMENT_NAME_20": "La reina se come a la torre", + "ACHIEVEMENT_DETAIL_20": "Completa 'Cabos sueltos' y 'El enemigo de mi enemigo' en dificultad Veterano.", + "ACHIEVEMENT_NAME_21": "Invisible", + "ACHIEVEMENT_DETAIL_21": "Completa 'Como en los viejos tiempos' y 'Fin de partida' en Veterano.", + "ACHIEVEMENT_NAME_22": "Jefe del foso", + "ACHIEVEMENT_DETAIL_22": "Recorre el foso en 'Otro día, la misma mierda' y acaba en menos de 30 segundos.", + "ACHIEVEMENT_NAME_23": "Fantasma", + "ACHIEVEMENT_DETAIL_23": "Coloca el C4 en 'Máximo riesgo' sin alertar ni herir a nadie en la ventisca.", + "ACHIEVEMENT_NAME_24": "Coronel Sanderson", + "ACHIEVEMENT_DETAIL_24": "Mata a 7 gallinas en menos de 10 segundos en 'Avispero'.", + "ACHIEVEMENT_NAME_25": "Más de 10 enemigos", + "ACHIEVEMENT_DETAIL_25": "Mata al menos a 10 enemigos con un misil del Predator.", + "ACHIEVEMENT_NAME_26": "Violencia innecesaria", + "ACHIEVEMENT_DETAIL_26": "Usa un escudo antidisturbios para derribar a un enemigo.", + "ACHIEVEMENT_NAME_27": "Toc toc", + "ACHIEVEMENT_DETAIL_27": "Mata a 4 enemigos con 4 tiros durante una incursión a cámara lenta.", + "ACHIEVEMENT_NAME_28": "En caliente", + "ACHIEVEMENT_DETAIL_28": "Mata a 6 enemigos seguidos con un arma térmica.", + "ACHIEVEMENT_NAME_29": "Dos pájaros de un tiro", + "ACHIEVEMENT_DETAIL_29": "Mata a 2 enemigos con una sola bala.", + "ACHIEVEMENT_NAME_30": "El camino menos transitado", + "ACHIEVEMENT_DETAIL_30": "Consigue 22 objetos con información enemiga.", + "ACHIEVEMENT_NAME_31": "Remover cielo y tierra", + "ACHIEVEMENT_DETAIL_31": "Consigue 45 objetos con información enemiga.", + "ACHIEVEMENT_NAME_32": "Tiroteo en marcha", + "ACHIEVEMENT_DETAIL_32": "Mata a 20 enemigos seguidos conduciendo un vehículo.", + "ACHIEVEMENT_NAME_33": "Más dura será la caída", + "ACHIEVEMENT_DETAIL_33": "Mata a 2 enemigos seguidos que hagan rápel antes de que aterricen.", + "ACHIEVEMENT_NAME_34": "Desperado", + "ACHIEVEMENT_DETAIL_34": "Mata a 5 rivales seguidos con 5 armas o accesorios distintos.", + "ACHIEVEMENT_NAME_35": "Mira mamá, con dos manos", + "ACHIEVEMENT_DETAIL_35": "Mata a 10 enemigos seguidos empuñando armas duales.", + "ACHIEVEMENT_NAME_36": "No hay paz para los cautos", + "ACHIEVEMENT_DETAIL_36": "Apuñala a un enemigo sin que se percate de tu presencia.", + "ACHIEVEMENT_NAME_37": "Trío", + "ACHIEVEMENT_DETAIL_37": "Mata al menos a 3 enemigos de un solo tiro de lanzagranadas.", + "ACHIEVEMENT_NAME_38": "Blanco confirmado", + "ACHIEVEMENT_DETAIL_38": "Ordena que el Honey Badger mate a 80 enemigos en 'Éxodo'.", + "ACHIEVEMENT_NAME_39": "Ángel salvador", + "ACHIEVEMENT_DETAIL_39": "Evita que destruyan tu dron Predator en 'Contingencia'.", + "ACHIEVEMENT_NAME_40": "NO pulses este botón", + "ACHIEVEMENT_DETAIL_40": "Dale a la campanilla roja en ambas salas y sobrevive al ataque.", + "ACHIEVEMENT_NAME_41": "El estudiante supera al maestro", + "ACHIEVEMENT_DETAIL_41": "Supera el tiempo de Beenox en 'Otro día, la misma mierda'.", + "ACHIEVEMENT_NAME_42": "El verdadero juego de armas", + "ACHIEVEMENT_DETAIL_42": "Completa una misión salvo 'Otro día, la misma mierda' y 'Fin de partida' sin recargar ni usar CaC.", + "ACHIEVEMENT_NAME_43": "Paranoia precognitiva", + "ACHIEVEMENT_DETAIL_43": "Mata a Shepherd.", + "ACHIEVEMENT_NAME_44": "Inmortal", + "ACHIEVEMENT_DETAIL_44": "Completa todas las misiones sin morir ni recargar puntos de control en cualquier dificultad.", + "ACHIEVEMENT_NAME_45": "Cielo silencioso", + "ACHIEVEMENT_DETAIL_45": "Destruye los dos BTR sin usar drones Predator en '¡Wolverines!'.", + "ACHIEVEMENT_NAME_46": "Claymore", + "ACHIEVEMENT_DETAIL_46": "Mata a 11 enemigos con claymore en 'Cabos sueltos'.", + "ACHIEVEMENT_NAME_47": "Cazador de pájaros", + "ACHIEVEMENT_DETAIL_47": "Destruye 10 helicópteros con el Javelin en 'Por voluntad propia'.", + "ACHIEVEMENT_NAME_48": "Patata caliente", + "ACHIEVEMENT_DETAIL_48": "Destruye el helicóptero con granadas de fragmentación en 'El único día fácil... fue ayer'.", + "ACHIEVEMENT_NAME_49": "Escuela de payasos", + "ACHIEVEMENT_DETAIL_49": "El cuerpo de Rangers del ejército de EE. UU. no es lugar para payasos.", + "ACHIEVEMENT_NAME_50": "Cabecear", + "ACHIEVEMENT_DETAIL_50": "Mata a un enemigo con el impacto de una granada de fragmentación en la cabeza.", + "ACHIEVEMENT_NAME_51": "CEREBROOOS...", + "ACHIEVEMENT_NAME_52": "¡Ramirez!" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/traditional_chinese.json b/data/zonetool/localizedstrings/traditional_chinese.json index abad4b8c..6a10a7e3 100644 --- a/data/zonetool/localizedstrings/traditional_chinese.json +++ b/data/zonetool/localizedstrings/traditional_chinese.json @@ -21,5 +21,121 @@ "LUA_MENU_FALLBACK_ENABLE": "使用 h2-mod 字型", "LUA_MENU_CAMPAIGN_UNLOCKED_ALL_TITLE": "解鎖所有任務", - "LUA_MENU_CANCEL_UNLOCK_CAPS": "取消解鎖" + "LUA_MENU_CANCEL_UNLOCK_CAPS": "取消解鎖", + + "MENU_MUSIC_VOLUME": "音樂音量", + + "DEPOT_GO_TO_THE_DEPOT": "開啟連結", + "MENU_OPEN_MOTD": "今日訊息", + + "LUA_MENU_ACHIEVEMENTS": "成就", + "LUA_MENU_ACHIEVEMENTS_DESC": "您的成就進度。", + + "ACHIEVEMENT_HIDDEN": "秘密成就", + "ACHIEVEMENT_HIDDEN_DESC": "繼續玩以將此解除鎖定", + "ACHIEVEMENT_EARNED": "成就解除鎖定!", + "ACHIEVEMENT_NAME_0": "就這點本事?", + "ACHIEVEMENT_DETAIL_0": "獲得《決勝時刻®:現代戰爭®2》劇情戰役重製版的所有獎盃。", + "ACHIEVEMENT_NAME_1": "整鞍上馬", + "ACHIEVEMENT_DETAIL_1": "幫助訓練本地民兵。", + "ACHIEVEMENT_NAME_2": "危險距離", + "ACHIEVEMENT_DETAIL_2": "被挑選成為謝菲爾德的精銳小隊。", + "ACHIEVEMENT_NAME_3": "冰冷肩膀", + "ACHIEVEMENT_DETAIL_3": "滲透雪山山壁的基地。", + "ACHIEVEMENT_NAME_4": "探囊取物", + "ACHIEVEMENT_DETAIL_4": "在貧民區中找出羅哈斯。", + "ACHIEVEMENT_NAME_5": "四盎司牛肉堡", + "ACHIEVEMENT_DETAIL_5": "防守漢堡城。", + "ACHIEVEMENT_NAME_6": "繩上索普", + "ACHIEVEMENT_DETAIL_6": "攻陷古拉格。", + "ACHIEVEMENT_NAME_7": "絕望時刻", + "ACHIEVEMENT_DETAIL_7": "執行幫助美國人的計劃。", + "ACHIEVEMENT_NAME_8": "白宮", + "ACHIEVEMENT_DETAIL_8": "奪回白宮。", + "ACHIEVEMENT_NAME_9": "棋子一枚", + "ACHIEVEMENT_DETAIL_9": "突襲馬卡洛夫的安全屋。", + "ACHIEVEMENT_NAME_10": "禍不單行……", + "ACHIEVEMENT_DETAIL_10": "完成在飛機墳場的任務。", + "ACHIEVEMENT_NAME_11": "記錄在案", + "ACHIEVEMENT_DETAIL_11": "在任何難度下完成單人遊戲劇情戰役。", + "ACHIEVEMENT_NAME_12": "戰爭代價", + "ACHIEVEMENT_DETAIL_12": "在困難或老手難度下完成單人遊戲劇情戰役。", + "ACHIEVEMENT_NAME_13": "開學第一天", + "ACHIEVEMENT_DETAIL_13": "在老手難度下完成「例行公事」和「團隊精神」。", + "ACHIEVEMENT_NAME_14": "黑鑽", + "ACHIEVEMENT_DETAIL_14": "在老手難度下完成「巔峰戰士」。", + "ACHIEVEMENT_NAME_15": "死觀光客", + "ACHIEVEMENT_DETAIL_15": "在老手難度下完成「大追捕」和「黃蜂窩」。", + "ACHIEVEMENT_NAME_16": "赤色黎明", + "ACHIEVEMENT_DETAIL_16": "在老手難度下完成「狼獾!」和「撤離」。", + "ACHIEVEMENT_NAME_17": "627號囚犯", + "ACHIEVEMENT_DETAIL_17": "在老手難度下完成「昨日遠比今日容易」和「古拉格」。", + "ACHIEVEMENT_NAME_18": "不擇手段", + "ACHIEVEMENT_DETAIL_18": "在老手難度下完成「應急計劃」。", + "ACHIEVEMENT_NAME_19": "直指老家", + "ACHIEVEMENT_DETAIL_19": "在老手難度下完成「自發獻身」、「第二太陽」和「白宮」。", + "ACHIEVEMENT_NAME_20": "皇后吃車", + "ACHIEVEMENT_DETAIL_20": "在老手難度下完成「要事未了」和「敵人的敵人」。", + "ACHIEVEMENT_NAME_21": "失去蹤跡", + "ACHIEVEMENT_DETAIL_21": "在老手難度下完成「當年今日」和「遊戲結束」。", + "ACHIEVEMENT_NAME_22": "訓練場之王", + "ACHIEVEMENT_DETAIL_22": "在「例行公事」進入訓練場並在30秒內完成。", + "ACHIEVEMENT_NAME_23": "魑魅魍魎", + "ACHIEVEMENT_DETAIL_23": "在「巔峰戰士」的暴風雪中於不驚動或傷害任何人的情況下設置C4炸藥。", + "ACHIEVEMENT_NAME_24": "啃得雞爺爺", + "ACHIEVEMENT_DETAIL_24": "在「黃蜂窩」中10秒內殺死7隻雞。", + "ACHIEVEMENT_NAME_25": "十死零生", + "ACHIEVEMENT_DETAIL_25": "以掠奪者飛彈擊殺最少10個敵人。", + "ACHIEVEMENT_NAME_26": "非必要粗暴動作", + "ACHIEVEMENT_DETAIL_26": "用鎮暴盾擊倒敵人。", + "ACHIEVEMENT_NAME_27": "咚咚咚", + "ACHIEVEMENT_DETAIL_27": "在慢動作突破時以4發子彈擊殺4個敵人。", + "ACHIEVEMENT_NAME_28": "熱力四射", + "ACHIEVEMENT_DETAIL_28": "用熱成像武器連續擊殺6個敵人。", + "ACHIEVEMENT_NAME_29": "一石二鳥", + "ACHIEVEMENT_DETAIL_29": "以一發子彈擊殺2個敵人。", + "ACHIEVEMENT_NAME_30": "罕至之路", + "ACHIEVEMENT_DETAIL_30": "收集22件敵人情報物品。", + "ACHIEVEMENT_NAME_31": "竭力搜刮", + "ACHIEVEMENT_DETAIL_31": "收集45件敵人情報物品。", + "ACHIEVEMENT_NAME_32": "飛車射擊", + "ACHIEVEMENT_DETAIL_32": "駕駛載具時連續擊殺20個敵人。", + "ACHIEVEMENT_NAME_33": "摔得越重", + "ACHIEVEMENT_DETAIL_33": "連續擊殺2個正在垂降並且尚未抵達地面的敵人。", + "ACHIEVEMENT_NAME_34": "亡命之徒", + "ACHIEVEMENT_DETAIL_34": "用5種不同武器或配件連續擊殺5個敵人。", + "ACHIEVEMENT_NAME_35": "左右開弓", + "ACHIEVEMENT_DETAIL_35": "用雙持武器連續擊殺10個敵人。", + "ACHIEVEMENT_NAME_36": "無暇鬆懈", + "ACHIEVEMENT_DETAIL_36": "在敵人未察覺之下用小刀將其擊殺。.", + "ACHIEVEMENT_NAME_37": "三人地府行", + "ACHIEVEMENT_DETAIL_37": "用榴彈發射器一發擊殺最少3個敵人。", + "ACHIEVEMENT_NAME_38": "確認目標", + "ACHIEVEMENT_DETAIL_38": "在「撤離」中指示「蜜獾」擊殺80個敵人。", + "ACHIEVEMENT_NAME_39": "天使守護者", + "ACHIEVEMENT_DETAIL_39": "在「應急計劃」中不讓掠奪者無人機被擊落。", + "ACHIEVEMENT_NAME_40": "千萬別按", + "ACHIEVEMENT_DETAIL_40": "按響兩個房間裡的紅色響鈴,然後在敵人的攻擊下生還。", + "ACHIEVEMENT_NAME_41": "青出於藍", + "ACHIEVEMENT_DETAIL_41": "在「例行公事」中擊敗Beenox時間。", + "ACHIEVEMENT_NAME_42": "槍神再世", + "ACHIEVEMENT_DETAIL_42": "在沒有裝填武器或用近戰攻擊的情況下完成「例行公事」和「遊戲結束」以外的任何任務。", + "ACHIEVEMENT_NAME_43": "偏執先知", + "ACHIEVEMENT_DETAIL_43": "擊殺謝菲爾德。", + "ACHIEVEMENT_NAME_44": "不朽傳說", + "ACHIEVEMENT_DETAIL_44": "在任何難度下完成每一個任務抵達儲存點,且未曾死亡或裝填。", + "ACHIEVEMENT_NAME_45": "寂靜天空", + "ACHIEVEMENT_DETAIL_45": "在「狼獾!」中不使用掠奪者無人機而摧毀兩架BTR。", + "ACHIEVEMENT_NAME_46": "大刀闊斧", + "ACHIEVEMENT_DETAIL_46": "在「要事未了」中用闊刀式地雷擊殺11個敵人。", + "ACHIEVEMENT_NAME_47": "大鳥獵人", + "ACHIEVEMENT_DETAIL_47": "在「自發獻身」中用標槍飛彈發射器摧毀10架直升機。", + "ACHIEVEMENT_NAME_48": "燙手山芋", + "ACHIEVEMENT_DETAIL_48": "在「昨日遠比今日容易」中用破片手榴彈摧毀直升機。", + "ACHIEVEMENT_NAME_49": "小丑也訓練", + "ACHIEVEMENT_DETAIL_49": "美國陸軍遊騎兵可不是給小丑來的地方。", + "ACHIEVEMENT_NAME_50": "花式爆頭", + "ACHIEVEMENT_DETAIL_50": "透過手榴彈丟中頭部的撞擊傷害殺死一個敵人。", + "ACHIEVEMENT_NAME_51": "大腦……", + "ACHIEVEMENT_NAME_52": "拉米瑞茲!" } \ No newline at end of file diff --git a/data/zonetool/localizedstrings/turkish.json b/data/zonetool/localizedstrings/turkish.json new file mode 100644 index 00000000..3f071aa2 --- /dev/null +++ b/data/zonetool/localizedstrings/turkish.json @@ -0,0 +1,4980 @@ +{ + "AF_CAVES_FOLLOW_PRICE": "Yüzbaşı Price'ı takip edin.", + "AF_CAVES_SUPPORT_PRICE": "Yüzbaşı Price'ı destekleyin.", + "AF_CAVES_OBJ_MARKER_SUPPORT": "Destekle", + "AF_CAVES_OBJ_GET_C4": "Düşman devriyesini pusuya düşürmek için kullanabileceğiniz biraz C4 bulun.", + "AF_CAVES_OBJ_PLANT_C4": "Kapının yanına C4 yerleştir.", + "AF_CAVES_OBJ_MARKER_C4_PLANT": "C4 yerleştir", + "AF_CAVES_HINT_C4_SWITCH": "C4 patlatıcısına geçmek için^3 [{+actionslot 2}] ^7 tuşuna basın.", + "AF_CAVES_OBJ_AMBUSH": "Price ile yeniden toplanın ve düşman devriyesini pusuya düşürün.", + "AF_CAVES_HINT_C4_DETONATE": "C4'ü tetiklemek için^3 [{+attack}] ^7tuşuna basın.", + "AF_CAVES_LOCATE_SHEPHERD": "Shepherd'ın yerini tespit edin.", + "AF_CAVES_OBJ_FLANK_AND_KILL": "Düşman direnişini ortadan kaldırın.", + "AF_CAVES_LINE1": "\"Tıpkı Eski Günlerdeki Gibi\"", + "AF_CAVES_LINE2": "7. Gün - [{FAKE_INTRO_TIME:17:32:22}]", + "AF_CAVES_LINE3": "'Soap' MacTavish", + "AF_CAVES_LINE4": "Site Hotel Bravo, Afganistan", + "AF_CAVES_RAPPEL": "Korkuluklara bağlayın.", + "AF_CAVES_RAPPEL_HINT_PC": "Bağlanmak için ^3 &&1 ^7 tuşuna basın.", + "AF_CAVES_RAPPEL_HINT": "Bağlanmak için ^3 &&1 ^7 tuşlarını basılı tutun.", + "AF_CAVES_DESCEND": "Frenlemek için ^3[{+attack}]^7 tuşunu basılı tutun.", + "AF_CAVES_OBJ_LEDGE_TRAVERSE": "Kaya köprüsünden geçin.", + "AF_CAVES_OBJ_BREACH": "Shepherd'ın Komuta Merkezine Ulaşın.", + "AF_CAVES_OBJ_DOOR_CONTROLS": "Kapı kontrollerini geçersiz kılın.", + "AF_CAVES_USE_KEYBOARD_PC": "Kapı kilidini geçersiz kılmak için ^3&&1^7 düğmesine basın.", + "AF_CAVES_USE_KEYBOARD": "Kapı kilidini geçersiz kılmak için ^3&&1^7 tuşlarını basılı tutun.", + "AF_CAVES_MISSIONFAIL_EXPLOSIVES": "Görev Başarısız.\nDüzenlenmiş patlayıcıları patlattınız.", + "AF_CAVES_TIME_REMAINING": "Çıkışa ulaş:", + "AF_CAVES_RAN_OUT_OF_TIME": "Mağara çıkışına zamanında ulaşamadınız.", + "AF_CAVES_OBJ_ESCAPE": "Mağaradan kaçın", + "AF_CAVES_OBJ_LAATPV": "Tareti monte edin", + "AF_CAVES_OBJ_LAATPV_GUNNER": "Tüm düşman direncini ortadan kaldırın", + "AF_CAVES_REGROUP_WITH_PRICE": "Price ile yeniden toplanın.", + "AF_CAVES_FELL_TO_DEATH": "Zamanında fren yapmadın.", + "AF_CAVES_DEADQUOTE_ABANDONED_PRICE": "Yüzbaşı Price'ı terk ettiniz.", + "AF_CAVES_OVERRIDE": "Geçersiz kıl", + "AF_CAVES_HOOKUP": "Bağlan", + "AF_CAVES_OBJ_RAPPEL": "Uçurumdan aşağı inin.", + "AF_CAVES_OBJ_BREACH_DOOR": "Komuta Merkezinin kapısına ulaş.", + "AF_CAVES_OBJ_REACH_SHEPHERD": "Shepherd'ın yolunu kes.", + "SENTRY_PICKUP": "M-5 nöbetçi silahını almak için ^3&&1^7tuşlarını basılı tutun.", + "SENTRY_MOVE": "M-5 nöbetçi silahını hareket ettirmek için ^3&&1^7tuşlarını basılı tutun.", + "SENTRY_PLACE": "M-5 nöbetçi silahını yerleştirmek için ^3[{+activate}]^7tuşuna basın.", + "SENTRY_CANNOT_PLACE": "M-5 nöbetçi silahını geçerli bir konuma taşıyın.", + "AF_CHASE_OBJ_CRASH": "Kaza yerini arayın.", + "AF_CHASE_PURSUE": "Shepherd'ın kaçmasına izin vermeyin.", + "AF_CHASE_MISSION_FAILED_KEEP_UP": "Shepherd kaçtı.", + "AF_CHASE_MISSION_FAILED_IN_THE_OPEN": "Açık alanlardan mümkün olduğunca uzak durun!", + "AF_CHASE_FAILED_TO_SHOOT_DOWN": "Shepherd helikoptere binip kaçtı.", + "AF_CHASE_FAILED_TO_PULL_KNIFE": "Price öldürüldü.", + "AF_CHASE_LOCATE_SHEPHERD": "Shepherd'ın yerini tespit et.", + "AF_CHASE_OBJ_KILL": "Öldür", + "AF_CHASE_KILL_SHEPHERD": "Shepherd'ı öldür.", + "AF_CHASE_PRESS_USE": "^3[{+activate}]^7", + "AF_CHASE_PRESS_USE_KEYBOARD": "^3[{+activate}]^7 Çek", + "AF_CHASE_INTROSCREEN_LINE1": "\"Her Şeyin Sonu\"", + "AF_CHASE_INTROSCREEN_LINE2": "7. Gün - [{FAKE_INTRO_TIME:18:10:22}]", + "AF_CHASE_INTROSCREEN_LINE3": "'Soap' MacTavish", + "AF_CHASE_INTROSCREEN_LINE4": "Site Hotel Bravo, Afganistan", + "AF_CHASE_HINT_CRAWL_RIGHT_PC": "Sürünmek için ^3[{+ads}]^7 tuşuna basın.", + "AF_CHASE_HINT_CRAWL_LEFT_PC": "Sürünmek için ^3[{+attack}]^7 tuşuna basın.", + "AF_CHASE_HINT_CRAWL_RIGHT": "Press \u0013 to crawl.", + "AF_CHASE_HINT_CRAWL_LEFT": "Press \u0012 to crawl.", + "AIRPORT_LINE1": "\"RUSÇA YOK\"", + "AIRPORT_LINE2": "3. Gün - 08:40:[{FAKE_INTRO_SECONDS:32}]", + "AIRPORT_LINE3": "Er Joseph Allen, nam-ı diğer Alexei Borodin", + "AIRPORT_LINE4": "Zakhaev Uluslararası Havalimanı", + "AIRPORT_LINE5": "Moskova, Rusya", + "AIRPORT_OBJ_COVER": "Kimliğini açığa çıkarma.", + "AIRPORT_OBJ_TRUST": "Makarov'un güvenini kazan.", + "AIRPORT_OBJ_COVER_TRUST": "Kimliğini açığa çıkarma ve Makarov'un güvenini kazan.", + "AIRPORT_OBJ_GET_IN_VAN": "Minibüse bin.", + "AIRPORT_OBJ_COVER_COST": "Ne pahasına olursa olsun kimliğini açığa çıkarma.", + "AIRPORT_FAIL_BLEW_COVER_FIRE": "Kimliğini açığa çıkardın... Makarov'un ekibine ateş etme.", + "AIRPORT_FAIL_BLEW_COVER_WANDER": "Kimliğini açığa çıkardın. Makarov'u davaya sadık olduğuna ikna et.", + "AIRPORT_FAIL_POLICE_BARRICADE": "Polis barikatının karşı koymak için çok fazla ateş gücü var.", + "AIRPORT_OBJ_TRUST_COST": "Makarov'u takip et.", + "AIRPORT_EXPLODING_JET_ENGINE_DEATH": "Patlayan bir jet motoru tarafından öldürüldün.\nYanan jet motorlarının patlaması muhtemeldir.", + "\\\\": "\\\\", + "ARCADIA_INTROSCREEN_LINE_1": "\"Göç\"", + "ARCADIA_INTROSCREEN_LINE_2": "4. Gün - 18:51:[{FAKE_INTRO_SECONDS:28}]", + "ARCADIA_INTROSCREEN_LINE_3": "Er James Ramirez", + "ARCADIA_INTROSCREEN_LINE_4": "1. Bölük, 75. Korucu Alayı", + "ARCADIA_INTROSCREEN_LINE_5": "Kuzeydoğu Virginia, A.B.D.", + "ARCADIA_OBJECTIVE_AA_GUNS": "Uçaksavar silahlarının yerini belirle ve etkisiz hâle getir.", + "ARCADIA_OBJECTIVE_BROOKMERE": "4677 Brookmere Yolu'na gidin.", + "ARCADIA_OBJECTIVE_INTEL": "Brookmere Yolu 4677 numaradaki 'panik odasından' bilgi alın.", + "ARCADIA_LASER_HINT": "Stryker için bir hedef belirlemek üzere^3 [{+actionslot 4}] ^7 tuşuna basın.", + "ARCADIA_LASER_ATTACK_HINT": "Hedef bölgeyi onaylamak için^3 [{+attack}] ^7 tuşlarını kullanın.", + "ARCADIA_LASER_HINT_GOLFCOURSE": "Topçular için AA silahlarını oyalamak için^3 [{+actionslot 4}] ^7 tuşuna basın.\nHedef araçları onaylamak için^3 [{+attack}] ^7 tuşuna kullanın.", + "ARCADIA_PICK_UP_BRIEFCASE_HINT_PC": "Çantayı almak için ^3 &&1 ^7 tuşuna basın.", + "ARCADIA_PICK_UP_BRIEFCASE_HINT": "Çantayı almak için ^3 &&1 ^7 tuşlarını basılı tutun.", + "ARCADIA_OBJECTIVE_LOCATE_AA_GUNS": "Uçaksavar silahlarının yerini belirleyin.", + "ARCADIA_OBJECTIVE_NEUTRALIZE_AA_GUNS": "Uçaksavar silahlarını etkisiz hâle getirin.", + "ARCADIA_OBJECTIVE_EXTRACT_VIP": "HVI'yı 'panik odasından' çıkarın.", + "ARCADIA_OBJECTIVE_INTEL_BRIEFCASE": "Çantadan istihbaratı alın.", + "BONEYARD_INTROSCREEN_LINE_1": "\"Düşmanımın Düşmanı\"", + "BONEYARD_INTROSCREEN_LINE_2": "6. Gün - [{FAKE_INTRO_TIME:16:03:21}]", + "BONEYARD_INTROSCREEN_LINE_3": "Cpt. 'Soap' MacTavish", + "BONEYARD_INTROSCREEN_LINE_4": "Kandahar'ın 160 mil Güneybatısı, Afganistan", + "BONEYARD_INTROSCREEN_LINE_5": "ABD Araç İmha Alanı 437", + "BONEYARD_OBJ_RALLYPOINT": "Toplanma noktasına gidin.", + "BONEYARD_OBJ_RIDE": "Askerî araca binin.", + "BONEYARD_DEADQUOTE_MOUNT": "Kaçış aracına binmeyi başaramadın.", + "BONEYARD_OBJ_C130": "Nikolai'nin uçağına binin.", + "BONEYARD_DEADQUOTE_CRASH": "Aracın kontrolünü ele geçiremedin.", + "BONEYARD_DEADQUOTE_TAKEOFF": "Uçağı yakalayamadınız.", + "BONEYARD_OBJ_RIDE_ICON": "Bin", + "SUBTITLE_AFCAVES_PRI_HOLDUP01": "^2Price: ^7Soap, bekle.", + "SUBTITLE_AFCAVES_PRI_ENEMYPATROL02": "^2Price: ^7Düşman devriyesi.", + "SUBTITLE_AFCAVES_PRI_THERMALSPIKE03": "^2Price: ^7Soap, ileride bir termal yükselti alıyorum. Mağara kenarda bir yerde olmalı.", + "SUBTITLE_AFCAVES_PRI_HOOKUP04": "^2Price: ^7İşte gidiyoruz - buraya bağlanın.", + "SUBTITLE_AFCAVES_PRI_SOAPHOOKUP05": "^2Price: ^7Soap, bağla.", + "SUBTITLE_AFCAVES_PRI_WHATSTHEPROBLEM06": "^2Price: ^7Soap, sorun nedir? Korkuluklara bağla.", + "SUBTITLE_AFCAVES_PRI_HOOKUPLETSGO07": "^2Price: ^7Soap, bağla, gidelim.", + "SUBTITLE_AFCAVES_PRI_GO08": "^2Price: ^7Gidelim.", + "SUBTITLE_AFCAVES_PRI_2INTHECHEST09": "^2Price: ^7Aşağıda iki tango var.", + "SUBTITLE_AFCAVES_NKL_WAITFORYOU21": "^2Nikolai: ^7Seni çıkış noktasında bekleyeceğim. Üç saat.", + "SUBTITLE_AFCAVES_PRI_DONTBOTHER22": "^2Price: ^7Zahmet etme. Bu tek yönlü bir uçuştu, dostum.", + "SUBTITLE_AFCAVES_NKL_GOODLUCK23": "^2Nikolai: ^7O zaman iyi şanslar dostum.", + "SUBTITLE_AFCAVES_PRI_MOVEOUT24": "^2Price: ^7Dışarı çık.", + "SUBTITLE_AFCAVES_PRI_DECRYPTIONCODE31": "^2Price: ^7Bu şifre çözme kodu ödediğimiz bedele değse iyi olur...", + "SUBTITLE_AFCAVES_PRI_INTELWASSOLID36": "^2Price: ^7Görünüşe göre Makarov'un istihbaratı sağlammış. İşte bu.", + "SUBTITLE_AFCAVES_PRI_HOLDUP241": "^2Price: ^7Dur bakalım.", + "SUBTITLE_AFCAVES_PRI_SPLITUP43": "^2Price: ^7Ateş etmeyin.", + "SUBTITLE_AFCAVES_PRI_GROUPONRIGHT44": "^2Price: ^7Sağ taraftaki, tam altımızdaki gruba odaklanın. Önce onları halledelim.", + "SUBTITLE_AFCAVES_PRI_TWOONLEFT45": "^2Price: ^7Ben soldaki ikisini alacağım.", + "SUBTITLE_AFCAVES_PRI_ONMYMARK46": "^2Price: ^7İşaretimle.", + "SUBTITLE_AFCAVES_PRI_THREE47": "^2Price: ^7Üç...", + "SUBTITLE_AFCAVES_PRI_TWO48": "^2Price: ^7İki...", + "SUBTITLE_AFCAVES_PRI_ONE49": "^2Price: ^7Bir...", + "SUBTITLE_AFCAVES_PRI_MARK410": "^2Price: ^7İşaretle.", + "SUBTITLE_AFCAVES_PRI_JUSTLIKEOLDTIMES411": "^2Price: ^7Tıpkı eski günlerdeki gibi.", + "SUBTITLE_AFCAVES_PRI_DOGNEUTRALIZED412": "^2Price: ^7Köpek etkisiz hâle getirildi, beş tango aşağı sayıyorum.", + "SUBTITLE_AFCAVES_PRI_CLOSEENOUGH413": "^2Price: ^7Yeterince yakın.", + "SUBTITLE_AFCAVES_PRI_BEENSPOTTED414": "^2Price: ^7Tespit edildik - telsizle geri dönmeden önce onları yok edin!", + "SUBTITLE_AFCAVES_PRI_STICKTOPLAN415": "^2Price: ^7Birlikte çalışmalıyız, Soap - bir dahaki sefere plana sadık kal.", + "SUBTITLE_AFCAVES_PRI_NOMISTAKES417": "^2Price: ^7Soap, bunlar sıradan kuklalar değil. Artık hata yok, gidelim.", + "SUBTITLE_AFCAVES_PRI_WASNTTHEPLAN418": "^2Yzb. Price: ^7Plan bu değildi.", + "SUBTITLE_AFCAVES_PRI_BEFORECOMEBACK51": "^2Price: ^7Pekâlâ, onlar geri gelmeden diğer grubu halletmeliyiz. Yürüyün.", + "SUBTITLE_AFCAVES_PRI_DOWNHERE52": "^2Price: ^7Soap! Aşağıya, gidelim!", + "SUBTITLE_AFCAVES_PRI_TAKETHEOTHERS53": "^2Price: ^7Çabuk, yukarı çıkalım ve diğerlerini alalım.", + "SUBTITLE_AFCAVES_PRI_GROUPSBACK54": "^2Price: ^7İlerleyin! Diğer grup geri geliyor!", + "SUBTITLE_AFCAVES_PRI_TAKETHESHOT55": "^2Price: ^7Yerimi aldım, ateş et.", + "SUBTITLE_AFCAVES_PRI_FOUNDBODIES56": "^2Price: ^7Soap, ikinci grup cesetleri buldu! Telsizle haber vermeden önce onları halledin!", + "SUBTITLE_AFCAVES_PRI_REPOSITIONING57": "^2Price: ^7Soap, geri geliyorlar - görüş alanından çıkmak için yeniden konumlanıyorum.", + "SUBTITLE_AFCAVES_PRI_READYTOSHOOT58": "^2Price: ^7Pozisyonumu aldım, ateş etmeye hazırım.", + "SUBTITLE_AFCAVES_SC2_SENDVINSON59": "^1Gölge Bölüğü: ^7Anlaşıldı Oxide, Vinson ve Lambert'i gönderiyorum. Butcher Yedi tamam.", + "SUBTITLE_AFCAVES_PRI_FINDTHEBODIES59": "^2Price: ^7Soap, cesetleri bulmak üzereler! Onları dışarı çıkarmalıyız!", + "SUBTITLE_AFCAVES_PRI_MUCHTIME510": "^2Price: ^7Onlar cesetleri bulmadan önce fazla zamanımız yok. Devam edelim.", + "SUBTITLE_AFCAVES_PRI_TANGOUPAHEAD61": "^2Price: ^7Tango ileride. Çatışmaya girmeyin.", + "SUBTITLE_AFCAVES_PRI_PATROLCOMING62": "^2Price: ^7Devriye bize doğru geliyor - sola dön, çabuk!", + "SUBTITLE_AFCAVES_PRI_LETTHEMPASS64": "^2Price: ^7Bırakın geçsinler.", + "SUBTITLE_AFCAVES_PRI_ONTOUSGOLOUD65": "^2Price: ^7Peşimizdeler - sesinizi yükseltin.", + "SUBTITLE_AFCAVES_PRI_COMPROMISEDGOLOUD66": "^2Price: ^7Tehlikedeyiz - sesinizi yükseltin.", + "SUBTITLE_AFCAVES_PRI_GOTLUCKY67": "^2Price: ^7Bu sefer şanslıydık.", + "SUBTITLE_AFCAVES_PRI_THATWASCLOSE68": "^2Price: ^7Çok yakındı.", + "SUBTITLE_AFCAVES_PRI_HAVINGASMOKE69": "^2Price: ^7Sigara içen muhafızı indir ya da ilerlemesini bekle.", + "SUBTITLE_AFCAVES_PRI_GUARDSKNOW610": "^2Price: ^7Muhafızlar bir şeylerin yolunda gitmediğini biliyor. Gözden kaybol ve sessiz ol.", + "SUBTITLE_AFCAVES_PRI_SUPPRESSEDWEAPON611": "^2Price: ^7Susturuculu bir silah kullandığınızdan emin olun, yoksa ölürüz.", + "SUBTITLE_AFCAVES_PRI_GETBACKHERE612": "^2Price: ^7Soap, neredesin? Buraya geri dön!", + "SUBTITLE_AFCAVES_PRI_AVOIDBEINGSPOTTED613": "^2Price: ^7Soap, o bölge düşmanlarla dolu. Soldan devam et.", + "SUBTITLE_AFCAVES_PRI_INCORRIDOR614": "^2Price: ^7Bu koridorda iki tango var - ateş etmeyin ve solda kalın.", + "SUBTITLE_AFCAVES_PRI_TANGOSONSIX615": "^2Price: ^7Tangolar altı yönünde.", + "SUBTITLE_AFCAVES_SC1_ISEEHIM615": "^1Gölge Bölüğü: ^7Onu görüyorum, burada!", + "SUBTITLE_AFCAVES_PRI_EASYNOW616": "^2Price: ^7Sakin ol...", + "SUBTITLE_AFCAVES_SC1_SPOTTED616": "^1Gölge Bölüğü: ^7Davetsiz misafir tespit edildi!", + "SUBTITLE_AFCAVES_PRI_LETSGO617": "^2Price: ^7Hadi gidelim.", + "SUBTITLE_AFCAVES_SC1_HOSTILEMYLOC617": "^1Gölge Bölüğü: ^7Bulunduğum yerde düşman var!", + "SUBTITLE_AFCAVES_PRI_GOODNIGHT618": "^2Price: ^7İyi geceler.", + "SUBTITLE_AFCAVES_PRI_TANGOSWITHTACLIGHTS83": "^2Price: ^7Soap, kırmızı ışığın altındaki merdivenlerden aşağı inen iki tango var, tam önümüzde.", + "SUBTITLE_AFCAVES_PRI_TAKEONERIGHT84": "^2Price: ^7Ben sağdakini alacağım. İşaretimle.", + "SUBTITLE_AFCAVES_PRI_CLEARGO85": "^2Price: ^7Temiz. Başla.", + "SUBTITLE_AFCAVES_PRI_TANGOSWITHTACLIGHTS288": "^2Price: ^7Onlar bizi bulmadan önce onları halletmeliyiz.", + "SUBTITLE_AFCAVES_SCHQ_LOSTCONTACT91": "^1Gölge Bölüğü Karargâhı: ^7Öğrenci Altı, Öğrenci Beş ile tüm bağlantıyı kaybettik. Kontrol edin.", + "SUBTITLE_AFCAVES_SCHQ_2DEADBODIES91": "^1Gölge Bölüğü Karargâhı: ^7Oxide'dan Öğrenci Altı'ya, arka kapıda iki ceset var. Saldırganlığı artırın ve bölgeyi tarayın.", + "SUBTITLE_AFCAVES_SC3_ONCATWALK92": "^1Mürit Altı: ^7Anlaşıldı Oksit, podyumdayız, buhar odasına doğru gidiyoruz. Beklemede kalın.", + "SUBTITLE_AFCAVES_SC3_ROGERSTANDBY92": "^1Disciple Six: ^7Anlaşıldı Oxide, beklemedeyiz.", + "SUBTITLE_AFCAVES_SC3_ATSTEAMROOM93": "^1Disciple Six: ^7Oksit, Öğrenci Altı buhar odasında. Beş'ten iz yok, tamam.", + "SUBTITLE_AFCAVES_SCHQ_GODARK94": "^1Gölge Bölüğü Karargâhı: ^7Mürit Altı, karanlığa git, yar ve temizle.", + "SUBTITLE_AFCAVES_SCHQ_FLATLINED102": "^1Gölge Bölüğü Karargâhı: ^7Mürit Dokuz, arka muhafızlarınız düzleşti!", + "SUBTITLE_AFCAVES_SC3_NOTPOSSIBLE103": "^1Havari Altı: ^7Mümkün değil. O bölgeyi daha yeni temizledik. Kimse o kadar iyi Oxi değildir.", + "SUBTITLE_AFCAVES_SHP_ITSPRICE104": "^1Shepherd: ^7Bu Price.", + "SUBTITLE_AFCAVES_SHP_BURNTHEREST105": "^1Shepherd: ^7Öncelikli maddeleri yedekleyin ve gerisini yakın. Yangın ekipleri - biz çekilmeye hazır olana kadar onları oyalayın.", + "SUBTITLE_AFCAVES_PRI_CLOCKSTICKING106": "^2Price: ^7Zaman geçiyor! Hadi gidelim!", + "SUBTITLE_AFCAVES_SCHQ_CATWALK111": "^1Gölge Bölüğü Karargâhı: ^7Avatar Bir, ben Oksit, buhar odasının yakınında birden fazla ekiple bağlantıyı kaybettik. Podyumun kamerayla taranmasını istiyorum, tamam.", + "SUBTITLE_AFCAVES_SC4_UAVONLINE112": "^1Gölge Bölüğü: ^7Anlaşıldı Oxide, İHA devrede. Beklemede kalın.", + "SUBTITLE_AFCAVES_PRI_PICKUPRIOTSHEILD113": "^2Price: ^7Bir isyan kalkanı alın... Burada korunmaya ihtiyacımız olacak.", + "SUBTITLE_AFCAVES_PRI_TAKEPOINT2114": "^2Price: ^7İsyan kalkanıyla nişan al. Ben herhangi bir direnişle ilgileneceğim.", + "SUBTITLE_AFCAVES_PRI_STAYLOW115": "^2Price: ^7O kalkanla alçakta kal ki temiz bir atış yapabileyim!", + "SUBTITLE_AFCAVES_PRI_KEEPLOW116": "^2Price: ^7O kalkanla alçakta kal!", + "SUBTITLE_AFCAVES_PRI_CROUCHDOWN117": "^2Price: ^7O kalkanla çömel, Soap! Ben nişancıların icabına bakacağım.", + "SUBTITLE_AFCAVES_PRI_SWITCHTOSHEILD118": "^2Price: ^7Kalkana geç, burada açıktayız!", + "SUBTITLE_AFCAVES_PRI_BRINGUP119": "^2Price: ^7İsyan kalkanını getir, Soap!", + "SUBTITLE_AFCAVES_PRI_GIVEUSCOVER1110": "^2Price: ^7O isyan kalkanıyla bizi biraz koru, Soap!", + "SUBTITLE_AFCAVES_PRI_WERECLEARMOVE1111": "^2Price: ^7Temiziz. İçeri girin.", + "SUBTITLE_AFCAVES_PRI_HESDOWN21113": "^2Price: ^7Düştü.", + "SUBTITLE_AFCAVES_PRI_GOTEM1114": "^2Price: ^7Yakaladım.", + "SUBTITLE_AFCAVES_PRI_GOTONE21115": "^2Price: ^7Bir tane buldum.", + "SUBTITLE_AFCAVES_PRI_PICKUPRIOTSHEILD21116": "^2Price: ^7Soap, bir isyan kalkanı kap ve yolu göster. Ateş edenlerin icabına bakacağım!", + "SUBTITLE_AFCAVES_PRI_PICKUPRIOTSHEILD31117": "SUBTITLE_AFCAVES_PRI_PICKUPRIOTSHEILD31117", + "SUBTITLE_AFCAVES_PRI_GRABASHEILD1118": "^2Price: ^7Soap, bir isyan kalkanı kap ve yolu göster.", + "SUBTITLE_AFCAVES_SC4_GETTINGTHIS1119": "^1Gölge Bölüğü: ^7Oksit, Avatar Bir. Podyumda yetkisiz personel var. Tekrar ediyorum, podyumda yetkisiz personel var, anlıyor musun?", + "SUBTITLE_AFCAVES_SCHQ_FACIALRECOG1120": "^1Gölge Bölüğü Karargâhı: ^7Avatar Bir, kamera yayınını Langley'deki yüz tanıma veritabanına yönlendir. Ara verin. Kürk için beklemede kalın. (Diğer emirler.)", + "SUBTITLE_AFCAVES_SHP_SHEPOUT1121": "^1Shepherd: ^7Price. Öncelikli maddeleri yedekleyin ve gerisini yakın. Tüm yangın ekipleri - biz ayrılmaya hazır olana kadar onları oyalayın. Shepherd tamam.", + "SUBTITLE_AFCAVES_PRI_MOVEUP1123": "^2Price:^7İlerleyin.", + "SUBTITLE_AFCAVES_PRI_TAKEPOINTDRAW1124": "^2Price: ^7Kalkanla nişan al ve ateşlerini üzerine çek. Ben seni korurum.", + "SUBTITLE_AFCAVES_SC5_50METERS121": "^1Gölge Bölüğü: ^7Oxide, Disciple Nine, yuvadan yaklaşık 50 metre uzakta düşman teması var, tamam.", + "SUBTITLE_AFCAVES_PRI_EXPOSEDGOLOUD122": "^2Price: ^7Açığa çıktık! Yüksek sesle!", + "SUBTITLE_AFCAVES_SCHQ_2ENEMIES123": "^1Gölge Bölüğü Karargâhı: ^7Tüm personelin dikkatine, podyumda karga yuvasına doğru giden iki düşman yaya aracımız var.", + "SUBTITLE_AFCAVES_SCHQ_PREJUDICE124": "^1Gölge Bölüğü Karargâhı: ^7Aşırı önyargı ile sonlandırın.", + "SUBTITLE_AFCAVES_SCHQ_ESCOURTGOLDEAGLE125": "^1Gölge Bölüğü Karargâhı: ^7Butcher Bir-Beş, yuvada buluşun ve Altın Kartal'a LZ'ye kadar eşlik etmeye hazırlanın.", + "SUBTITLE_AFCAVES_PRI_MUSTBESHEPHERD126": "^2Price: ^7Altın Kartal Shepherd olmalı! Zamanımız azalıyor, gidelim!", + "SUBTITLE_AFCAVES_SC5_RAPELLINGIN131": "^1Gölge Bölüğü: ^7Mürit Üç içeri giriyor!", + "SUBTITLE_AFCAVES_SC6_SEVEREDDET132": "^1Gölge Bölüğü: ^7Oksit, Butcher Beş-Aktüel. Kopmuş bir detektör kordonum var - bagajı donatmak ve EBC'yi hazır hâle getirmek için on mikrofona ihtiyacımız olacak, tamam.", + "SUBTITLE_AFCAVES_SCHQ_CHARGESHOT133": "^1Gölge Bölüğü Karargâhı: ^7Olumsuz, Altın Kartal o patlayıcıları üç dakikadan kısa sürede ateşlemek istiyor. Halledin, tamam.", + "SUBTITLE_AFCAVES_SCHQ_EXSAS2134": "^1Gölge Bölük Karargâhı: ^7Tüm yangın ekiplerinin dikkatine, kimlikleri tespit edildi. Düşman operatörleri eski SAS ve Görev Gücü 141. Çok dikkatli yaklaşın, tamam.", + "SUBTITLE_AFCAVES_SCHQ_EXSAS135": "^1Gölge Bölüğü Karargâhı: ^7Tüm ateş ekipleri, dikkatli olun - düşman operatörleri eski SAS ve Görev Gücü 141. Çok dikkatli yaklaşın, tamam.", + "SUBTITLE_AFCAVES_PRI_POPPINGSMOKE136": "^2Price: ^7Duman patlatıyorum! Sağ kanattan dolaşın!", + "SUBTITLE_AFCAVES_PRI_DRAWFIRE137": "^2Price: ^7Ateşlerini dumanın içinden çekeceğim! Yan yollara dikkat edin!", + "SUBTITLE_AFCAVES_PRI_MOVERIGHT138": "^2Price: ^7Kazıyorlar, Shepherd yakınlarda olmalı! Yarmak zorundayız!", + "SUBTITLE_AFCAVES_PRI_USINGTHERMAL139": "^2Price: ^7Dumanın içinden termal kullanıyorlar!", + "SUBTITLE_AFCAVES_PRI_SWITCHINGTOTHERM1310": "^2Price: ^7Termale geçiliyor! Kanatlarımıza göz kulak olun!", + "SUBTITLE_AFCAVES_PRI_TRYTOFLANK1311": "^2Price: ^7Onları kuşatın!", + "SUBTITLE_AFCAVES_PRI_SHEILDSUSEFLASH1312": "^2Price: ^7Kalkan kullanıyorlar! Flaş bombası kullanın!", + "SUBTITLE_AFCAVES_PRI_HITFROMSIDES1313": "^2Price: ^7Soap! Onları yanlardan vur!", + "SUBTITLE_AFCAVES_PRI_SHEILDSTHROWFRAGS1314": "^2Price: ^7Kalkan kullanıyorlar! Fişekleri kullan!", + "SUBTITLE_AFCAVES_PRI_FLANKANDHITSIDES1315": "^2Price: ^7Yanlardan vurmaya çalışın!", + "SUBTITLE_AFCAVES_PRI_GETFRAMECHARGE1316": "^2Price: ^7Kontrol odasını mühürlediler. Kapıya bir çerçeve yükleyin!", + "SUBTITLE_AFCAVES_PRI_BREACHTHEDOOR1317": "^2Price: ^7Soap! Hemen gitmeliyiz! Kapıyı kırın!", + "SUBTITLE_AFCAVES_PRI_BLOWTHEDOOR1318": "^2Price: ^7Kapıyı patlatın! Shepherd'ın kaçmasına izin veremeyiz!", + "SUBTITLE_AFCAVES_PRI_CHARGEDOIT1319": "^2Price: ^7Kapıyı patlatın! Yapın!", + "SUBTITLE_AFCAVES_PRI_DOOROPEN141": "^2Price: ^7Soap! Şuradaki kapıyı aç! Panele vur!", + "SUBTITLE_AFCAVES_PRI_OVERRIDECONTROL142": "^2Price: ^7Kapı kontrollerini geçersiz kıl! Acele et!", + "SUBTITLE_AFCAVES_PRI_GETDOOROPEN143": "^2Price: ^7Soap! Kapıyı aç!", + "SUBTITLE_AFCAVES_PRI_USEKEYBOARD144": "^2Price: ^7Kapı kontrollerini geçersiz kıl! Klavyeyi kullan!", + "SUBTITLE_AFCAVES_PRI_OPENTHEDOOR145": "SUBTITLE_AFCAVES_PRI_OPENTHEDOOR145", + "SUBTITLE_AFCAVES_PRI_COMEONCOMEON146": "^2Price: ^7Hadinn...hadinn...", + "SUBTITLE_AFCAVES_SHP_SITECOMPROMISED147": "^1Shepherd: ^7Tüm birimlerin dikkatine, burası Gold Eagle. Site ele geçirildi.", + "SUBTITLE_AFCAVES_SHP_DIRECTIVE116148": "^1Shepherd: ^7Bir-Bir-Altı Bravo direktifini uyguluyorum. Eğer hâlâ içerideyseniz, hizmetiniz onurlandırılacaktır. Shepherd tamam.", + "SUBTITLE_AFCAVES_PRI_GONNABLOW1411": "^2Price: ^7Devam edin! Burası havaya uçacak!", + "SUBTITLE_AFCAVES_PRI_STAYCLOSE161": "^2Price: ^7Gidelim! Yakın durun ve beni takip edin!", + "SUBTITLE_AFCAVES_PRI_FOLLOWMELETSGO162": "^2Price: ^7Soap! Beni takip et! Hadi gidelim!", + "SUBTITLE_AFCAVES_PRI_HEADFORLATVEE163": "^2Price: ^7Şuna doğru git, seni koruyacağım!", + "SUBTITLE_AFCAVES_PRI_TOTHEWEST164": "^2Price: ^7Batıya, Soap, Git!", + "SUBTITLE_AFCAVES_PRI_COMETOME165": "^2Price: ^7Bana gel, seni koruyacağım. Git!", + "SUBTITLE_AFCAVES_PRI_TOWERAHEAD166": "^2Price: ^7Şu kuleye doğru koş, tam önümüzde! Seni koruyacağım!", + "SUBTITLE_AFCAVES_PRI_FORWARDTOTOWER167": "^2Price: ^7O kuleye doğru ilerleyin!", + "SUBTITLE_AFCAVES_SCHQ_RISKYFORFLIGHTOPS171": "^1Gölge Bölüğü Karargâhı: ^7Efendim, burada kum fırtınası hareketliliği artıyor. Uçuş operasyonları için çok riskli.", + "SUBTITLE_AFCAVES_SHP_TAKEZODIACS172": "^1Shepherd: ^7Anlaşıldı. Tünele doğru gidin. Biz Zodyak'ları alacağız.", + "SUBTITLE_AFCAVES_SCHQ_YESSIR2173": "^1Gölge Bölüğü Karargâhı: ^7Emredersiniz efendim!", + "SUBTITLE_AFCAVES_PRI_GETTINGAWAY2174": "^2Price: ^7Tünele doğru gidin! Kaçıyor!", + "SUBTITLE_AFCAVES_PRI_RIVERNEARBY175": "^2Price: ^7Shepherd Zodyaklardan bahsetti... Yakınlarda nehir erişimi olmalı - hadi gidelim!", + "SUBTITLE_AFCAVES_PRI_TARGETSWEST184": "^2Price: ^7Hedefler batıda! Yak onları!", + "SUBTITLE_AFCAVES_PRI_SNIPERFROMTOWER186": "^2Price: ^7Kuleden keskin nişancı! İndirin onu!", + "SUBTITLE_AFCAVES_SHP_DANGERCLOSE191": "^1Shepherd: ^7Excalibur, burası Altın Kartal. Ateş görevi - hedef paket Romeo - tehlike yakın.", + "SUBTITLE_AFCAVES_SCHQ_100METERS192": "^1Gölge Bölüğü Karargâhı: ^7Konumunuza yüz metre mesafede efendim!", + "SUBTITLE_AFCAVES_PRI_SINCEWHEN193": "^2Price: ^7Shepherd ne zamandan beri yakın tehlikeyi önemsiyor...", + "SUBTITLE_AFCAVES_SHP_SENDIT194": "^1Shepherd: ^7Bu bir öneri değil! Gönderin!", + "SUBTITLE_AFCAVES_SCHQ_FIREMISSIONCLOSE195": "^1Gölge Bölüğü Karargâhı: ^7Anlaşıldı, yangın görevi tehlikesi yakın!", + "SUBTITLE_AFCAVES_PRI_FALLBACK196": "^2Price: ^7Soap! Geliyor! Geri çekilin, geri çekilin!", + "SUBTITLE_AFCAVES_PRI_MOVEWESTTOWER197": "^2Price: ^7Batıya kuleye doğru ilerleyin! Beni takip edin!", + "SUBTITLE_AFCAVES_PRI_DOIT198": "^2Price: ^7Yap şunu.", + "SUBTITLE_AFCAVES_PRI_FALLBACK196_2": "^2Price: ^7Soap! Geliyor! Yere yat! Yere yatın!", + "SUBTITLE_AFCAVES_PRI_FALLBACK196_3": "^2Price: ^7Defolun buradan! Toplar geliyor!", + "SUBTITLE_AFCAVES_PRI_MEETEMHEADON201": "^2Price: ^7Görünüşe göre onlarla kafa kafaya çarpışacağız, Soap.", + "SUBTITLE_AFCAVES_PRI_GETREADY202": "^2Price: ^7İşte başlıyoruz - hazır olun.", + "SUBTITLE_AFCAVES_PRI_GOLOUD204": "^2Price: ^7Yüksek sesle! Ateş açın!", + "SUBTITLE_AFCAVES_PRI_EYESUP205": "^2Price: ^7Gözler yukarı! Bizi kuşatıyorlar!", + "SUBTITLE_AFCAVES_SC3_CHARGEPLANTED206": "^1Disciple Six: ^7Kapı hücumu yerleştirildi. Yarmaya hazırız.", + "SUBTITLE_AFCAVES_SCL_HITIT207": "^1Gölge Bölüğü: ^7Vur onu.", + "SUBTITLE_AFCAVES_SCL_FOXTROTELEMENT208": "^1Gölge Bölüğü: ^7Foxtrot elemanı, sola süpür.", + "SUBTITLE_AFCAVES_SCL_PATTERNECHO209": "^1Gölge Birliği: ^7Arama düzeni Echo Charlie. Başla.", + "SUBTITLE_AFCAVES_SC3_AREACLEAR2010": "^1Disciple Six: ^7Kapı alanı temiz.", + "SUBTITLE_AFCAVES_SCL_CHECKCORNERS2011": "^1Gölge Bölüğü: ^7Köşelerinizi kontrol edin.", + "SUBTITLE_AFCAVES_SCL_THEYREHERE2012": "^1Gölge Bölüğü: ^7Buradalar! Ateş açın!", + "SUBTITLE_AFCAVES_SCL_HUNTTHEMDOWN2013": "^1Gölge Bölüğü: ^7Soğukkanlı kalın, onları avlayın!", + "SUBTITLE_AFCAVES_SC5_PAPAQUEBEC2014": "^1Gölge Bölüğü: ^7Butcher İki, Papa Quebec sektörüne giriyor!", + "SUBTITLE_AFCAVES_SC3_BREACHING2015": "^1Disciple Six: ^7Yarma, yarma!", + "SUBTITLE_AFCAVES_PRI_SPLITTINGUP2017": "^2Price: ^7Güzel, ayrılıyorlar. Bırakın ayrılsınlar.", + "SUBTITLE_AFCAVES_SCHQ_LOSTCONTACT22018": "^1Gölge Bölüğü Karargâhı: ^7Butcher Yedi, Oksit. Mürit Beş ile bağlantıyı kaybettik.", + "SUBTITLE_AFCAVES_SCHQ_BADTRANSMITTER22019": "^1Gölge Bölüğü Karargâhı: ^7Muhtemelen sadece kum fırtınası ya da kötü bir verici.", + "SUBTITLE_AFCAVES_SCHQ_SENDATEAM22020": "^1Gölge Bölüğü Karargâhı: ^7Kontrol için bir ekip gönderin, tamam.", + "SUBTITLE_AFCAVES_PRI_TOPOFSTAIRS2021": "^2Price: ^7Merdivenin tepesinde - o benim.", + "SUBTITLE_AFCAVES_PRI_NEVERMIND2022": "^2Price: ^7Boş ver o zaman.", + "SUBTITLE_AFCAVES_PRI_IMPRESSIVE2023": "^2Price: ^7Etkileyici.", + "SUBTITLE_AFCAVES_PRI_MOVE22025": "^2Price: ^7Hareket et.", + "SUBTITLE_AFCAVES_PRI_KEEPMOVING2026": "^2Price: ^7Devam edelim.", + "SUBTITLE_AFCHASE_PRI_GETTINGAWAY13": "^2Price: ^7Kaçıyor!", + "SUBTITLE_AFCHASE_PRI_GETONBOAT": "^2Price: ^7Soap, şu tekneye bin!", + "SUBTITLE_AFCHASE_PRI_GOGOGO14": "^2Price: ^7Hadi! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_AFCHASE_UAV_RPGUNITS15": "^1İHA Operatörü: ^7Haberiniz olsun, Price ve MacTavish'in önünü kesmek için köprülere RPG birimleri gönderiyoruz.", + "SUBTITLE_AFCHASE_UAV_ANYBOATS16": "^1İHA Operatörü: ^7Tüm köprü ateş ekipleri - RPG'leri donatın ve Altın Kartal'ı takip eden tekneleri durdurun.", + "SUBTITLE_AFCHASE_UAV_ETA40SECS17": "^1İHA Operatörü: ^7Küçük Kuşlar geliyor, E.T.A. kırk saniye.", + "SUBTITLE_AFCHASE_LBP_DONTHAVEVISUAL18": "^2Küçük Kuş Pilotu: ^7Altın Kartal, burası Kerkenez Üç-İki, rezervuarın üzerindeyiz... görsel temas yok, tamam.", + "SUBTITLE_AFCHASE_SHP_STILLINCAVES19": "^1Shepherd: ^7Kerkenez Üç-İki, hâlâ mağaralardayız, beklemedeyiz.", + "SUBTITLE_AFCHASE_SHP_OBSERVE110": "^1Shepherd: ^7Kerkenez Üç-İki, hâlâ mağaralardalar, pozisyonunuzu koruyun ve gözlemlemeye devam edin, Altın Kartal tamam.", + "SUBTITLE_AFCHASE_PRI_CANTLET21": "^2Price: ^7Shepherd'ın kaçmasına izin veremeyiz!", + "SUBTITLE_AFCHASE_PRI_LOSINGHIM22": "^2Price: ^7Onu kaybediyoruz!", + "SUBTITLE_AFCHASE_PRI_DRIVINGTHEBOAT23": "^2Price: ^7Tekneyi sürmeye odaklanın, ben onları baskı altında tutacağım!", + "SUBTITLE_AFCHASE_PRI_THRUCAVE31": "^2Price: ^7Şu mağaraya doğru!", + "SUBTITLE_AFCHASE_PRI_WRONGWAY32": "^2Price: ^7Yanlış yöne gidiyorsun!", + "SUBTITLE_AFCHASE_PRI_TURNTOOBJECTIVE33": "^2Price: ^7Hedefe doğru dönün! Gidelim! Kaçacak!", + "SUBTITLE_AFCHASE_PRI_FULLPOWER34": "^2Price: ^7Soap! Ne yapıyorsun!? Tam güç, gidelim!", + "SUBTITLE_AFCHASE_PRI_WHEREGOING35": "^2Price: ^7Nereye gidiyorsun?!", + "SUBTITLE_AFCHASE_PRI_DODGEHELI41": "^2Price: ^7Soap, helikopterden kaç!", + "SUBTITLE_AFCHASE_PRI_EVASIVE42": "^2Price: ^7Altımızda bir helikopter var! Kaçış manevraları yapın!", + "SUBTITLE_AFCHASE_PRI_ENEMYSIX51": "^2Price: ^7Düşman botu altımıza yaklaşıyor!", + "SUBTITLE_AFCHASE_PRI_ZODIACNINE52": "^2Price: ^7Düşman Zodiac'ı saat 9 yönünde!", + "SUBTITLE_AFCHASE_PRI_ZODIACSIX53": "^2Price: ^7Zodyak saat 6 yönünde hızla yaklaşıyor!", + "SUBTITLE_AFCHASE_UAV_10SECONDS55": "^1İHA Operatörü: ^7Anlaşıldı, İHA desteği 10 saniye içinde hazır.", + "SUBTITLE_AFCHASE_UAV_MISSILESONLINE56": "^1İHA Operatörü: ^7Havadan karaya füzeler devrede. Siz hazır olduğunuzda, efendim.", + "SUBTITLE_AFCHASE_SHP_DANGERCLOSE57": "^1Shepherd: ^7Sıcak temizlendi, tehlike yakın!", + "SUBTITLE_AFCHASE_SHP_CLEAREDHOT58": "^1Shepherd: ^7Sıcak temizlendi!", + "SUBTITLE_AFCHASE_SHP_TAKEEM59": "^1Shepherd: ^7Al onları!", + "SUBTITLE_AFCHASE_SHP_TRYAGAIN510": "^1Shepherd: ^7Avatar Bir, hedefi yeniden ele geçir ve tekrar dene! Sıcak temizlendi!", + "SUBTITLE_AFCHASE_UAV_MISSILEAWAY1511": "^1İHA Operatörü: ^7Anlaşıldı. Füze uzaklaştı.", + "SUBTITLE_AFCHASE_UAV_MISSILEAWAY2512": "^1İHA Operatörü: ^7Anlaşıldı, füze uzaklaştı!", + "SUBTITLE_AFCHASE_UAV_FOXTHREE1513": "^1İHA Operatörü: ^7Tilki Üç.", + "SUBTITLE_AFCHASE_UAV_FOXTHREE2514": "^1İHA Operatörü: ^7Tilki Üç!", + "SUBTITLE_AFCHASE_PRI_RAPIDSAHEAD61": "^2Price: ^7İleride akıntı var! Zorlaşacak, dayanın!", + "SUBTITLE_AFCHASE_PRI_GUNSSPINUP71": "^2Price: ^7Silahları patlamadan önce şu Küçük Kuş'u geç!", + "SUBTITLE_AFCHASE_PRI_STEERCLEAR72": "^2Price: ^7Helikopterden uzak dur! Hadi! Hadi! Git!", + "SUBTITLE_AFCHASE_PRI_BEHINDROCKS81": "^2Price: ^7Şu kayaların arkasına geçin!", + "SUBTITLE_AFCHASE_PRI_MINIGUNS82": "^2Price: ^7Bu makinalılar durmayacak, salla onları!", + "SUBTITLE_AFCHASE_PRI_SHAKEEMOFF83": "^2Price: ^7Onları kaybetmeliyiz! Salla onları!", + "SUBTITLE_AFCHASE_PRI_THREADTHENEEDLE84": "^2Price: ^7İğneyi geçirin!", + "SUBTITLE_AFCHASE_PRI_ENEMYBOATS85": "^2Price: ^7Düşman tekneleri saat 3 yönünde!", + "SUBTITLE_AFCHASE_PRI_OPENAREAS86": "^2Price: ^7Açık alanlardan uzak durun!", + "SUBTITLE_AFCHASE_PRI_DODGEDODGE87": "^2Price: ^7Kaç, kaç!", + "SUBTITLE_AFCHASE_PRI_LEFTLEFT88": "^2Price: ^7Sol, sol!", + "SUBTITLE_AFCHASE_PRI_RIGHTRIGHT89": "^2Price: ^7Sağ, sağa git!", + "SUBTITLE_AFCHASE_PRI_LEFT810": "^2Price: ^7Sola!", + "SUBTITLE_AFCHASE_PRI_RIGHT811": "^2Price: ^7Sağ!", + "SUBTITLE_AFCHASE_PRI_RPGSONBRIDGE812": "^2Price: ^7RPG köprüde!", + "SUBTITLE_AFCHASE_PRI_OTHERSIDE813": "^2Price: ^7Onu diğer tarafta yakalayacağız!", + "SUBTITLE_AFCHASE_PRI_TECHNICAL814": "^2Price: ^7Teknik!", + "SUBTITLE_AFCHASE_SHP_SITREP91": "^1Shepherd: ^7Avatar Bir, bana bir durum raporu ver, tamam!", + "SUBTITLE_AFCHASE_UAV_DOWNRIVER92": "^1İHA Operatörü: ^7Savaş Atı Beş-Bir beklemede. Pave Low nehrin aşağısında efendim.", + "SUBTITLE_AFCHASE_SHP_COMININHOT93": "^1Shepherd: ^7Anlaşıldı! Savaş Atı Beş-Bir, haberiniz olsun, yaklaşıyoruz!", + "SUBTITLE_AFCHASE_PLP_ABOVE30KNOTS94": "^1Pave Low Pilot: ^7Anlaşıldı - kapağın açılması - 30 knot'ın üzerinde tutun ve dikey boşluğa dikkat edin.", + "SUBTITLE_AFCHASE_PLP_ONBOARD": "^1Pave Low Pilot: ^7Mürettebat, Gold Eagle gemide. Buradan gidiyoruz.", + "SUBTITLE_AFCHASE_PLP_THELONGWAY": "^1Pave Low Pilot: ^7Mürettebat, saat on ikide kum fırtınası var... uzun yoldan gidiyoruz, bekleyin.", + "SUBTITLE_AFCHASE_SHP_SOLIDCOPY95": "^1Shepherd: ^7Anlaşıldı! Beklemede kalın!", + "SUBTITLE_AFCHASE_PRI_HOLDSTEADY101": "^2Price: ^7Soap! Sabit tutun!", + "SUBTITLE_AFCHASE_PRI_STEADY1102": "^2Price: ^7Sabit tutun!", + "SUBTITLE_AFCHASE_PRI_STEADY2103": "SUBTITLE_AFCHASE_PRI_STEADY2103", + "SUBTITLE_AFCHASE_PRI_BACKUP104": "^2Price: ^7Geri çekilin!", + "SUBTITLE_AFCHASE_SHP_WAITINGFOR151": "^1Shepherd: ^7Ne bekliyorsun MacTavish...", + "SUBTITLE_AFCHASE_SHP_DIGTWOGRAVES152": "^1Shepherd: ^7İntikam hakkında ne derler bilirsin... iki mezar kazmaya hazır olsan iyi edersin...", + "SUBTITLE_AFCHASE_SHP_GOAHEAD153": "^1Shepherd: ^7Devam et, bitir. Bu hiçbir şeyi değiştirmeyecek.", + "SUBTITLE_AFCHASE_SHP_COULDNTDOIT154": "^1Shepherd: ^7Hmph. Bunu yapamayacağını biliyordum...", + "SUBTITLE_AFCHASE_SHP_GOODWARRIOR155": "^1Shepherd: ^7Sen iyi bir savaşçısın...", + "SUBTITLE_AFCHASE_SHP_EXTRASTEP156": "^1Shepherd: ^7...ama asla fazladan bir adım atamazsın...", + "SUBTITLE_AFCHASE_SHP_NECESSARY157": "^1Shepherd: ^7...kesinlikle gerekli olanı yapmak için.", + "SUBTITLE_AFCHASE_PRI_DONTWORRY204": "^2Price: ^7Merak etme -", + "SUBTITLE_AFCHASE_PRI_WEWONT205": "^2Price: ^7...yapmayacağız.", + "SUBTITLE_AFCHASE_PRI_WEKNOW207": "^2Price: ^7Biliyoruz.", + "SUBTITLE_AFCHASE_PRI_SOAP1221": "^2Price: ^7Soap!", + "SUBTITLE_AFCHASE_PRI_HOLDFORNOW251": "^2Price: ^7Şimdilik dayan. Hadi, ayağa kalk!", + "SUBTITLE_AFCHASE_PRI_TOLDYOU252": "^2Price: ^7Sana bunun tek yönlü bir yolculuk olduğunu söylediğimi sanıyordum!", + "SUBTITLE_AFCHASE_NKL_LOOKINGFORUS253": "^2Nikolai: ^7Görünüşe göre hâlâ öyle...bizi arıyor olacaklar biliyorsun...", + "SUBTITLE_AFCHASE_PRI_SOAPOUTTAHERE254": "^2Price: ^7Nikolai, Soap'u buradan götürmeliyiz...", + "SUBTITLE_AFCHASE_NKL_KNOWAPLACE255": "^2Nikolai: ^7Da - Bir yer biliyorum.", + "SUBTITLE_AFCHASE_SHP_NEEDTOASK261": "^1Shepherd: ^7Neden? Neden mi? Gerçekten sorman gerekiyor mu?", + "SUBTITLE_AFCHASE_SHP_BEENATWAR262": "^1Shepherd: ^7Uzun zamandır savaştayız.", + "SUBTITLE_AFCHASE_SHP_MOUNTINGLOSS263": "^1Shepherd: ^7Artan kayıplardan bıkmış bir koalisyon için savaşıyoruz.", + "SUBTITLE_AFCHASE_SHP_DECISIVEACTION264": "^1Shepherd: ^7Doğrudan tehditler kararlı eylem gerektirir.", + "SUBTITLE_AFCHASE_SHP_NOSHORTAGE266": "^1Shepherd: ^7Yarın gönüllü sıkıntısı olmayacak, vatansever sıkıntısı olmayacak.", + "SUBTITLE_AFCHASE_SHP_IKNOW267": "^1Shepherd: ^7Anladığınızı biliyorum.", + "SUBTITLE_AFCHASE_SHP_APATRIOT268": "^1Shepherd: ^7Ben bir vatanseverim MacTavish.", + "SUBTITLE_AFCHASE_SHP_ONLYDID269": "^1Shepherd: ^7Ben sadece yapılması gerekeni yaptım.", + "SUBTITLE_AFCHASE_SHP_NOTHINGMORE2610": "^1Shepherd: ^7Daha fazlasını değil.", + "SUBTITLE_AFCHASE_SHP_WONTCHANGE2611": "^1Shepherd: ^7Beni öldürmek bunu değiştirmeyecek.", + "SUBTITLE_AFCHASE_SHP_LOSTOURWILL2612": "^1Shepherd: ^7O gün savaşma isteğimizi kaybettik.", + "SUBTITLE_AFCHASE_SHP_FORGIVEME2613": "^1Shepherd: ^7Affet beni...", + "SUBTITLE_AFCHASE_SHP_YOUUNDERSTAND2614": "^1Shepherd: ^7Anlıyorsun.", + "SUBTITLE_AFCHASE_SHP_WILLTOFIGHTWEAK2615": "^1Shepherd: ^7Amerika'nın savaşma isteği zayıfladı.", + "SUBTITLE_AFCHASE_SHP_FIVEYEARSAGOPG2616": "^1Shepherd: ^7Beş yıl önce Zakhaev göz açıp kapayıncaya kadar 30.000 denizciyi öldürdü...... ve dünya sadece izledi.", + "SUBTITLE_AFCHASE_SHP_FIVEYEARSAGO_A265_2": "^1Shepherd: ^7Beş yıl önce, göz açıp kapayıncaya kadar 30,000 adamımı kaybettim.", + "SUBTITLE_AFCHASE_SHP_FIVEYEARSAGO_B265_3": "^1Shepherd: ^7Ve dünya sadece izledi.", + "SUBTITLE_11": "^2Soap: ^7Bizim bir tane iyi SMG'miz var. Onlarda bin tane var. Makarov'un istihbaratının iyi olup olmadığını bile bilmiyoruz. Price?", + "SUBTITLE_12": "^2Price: ^7Sağlıklı bir insan zihni sabah uyandığında bunun dünyadaki son günü olduğunu düşünmez.", + "SUBTITLE_13": "^2Price: ^7Ama bence bu bir lüks. Bir lanet değil. Sona yaklaştığınızı bilmek bir tür özgürlüktür. Envanter çıkarmak için iyi bir zaman.", + "SUBTITLE_14": "^2Price: ^7Silahsız. Sayıca üstün. Aklımızı kaçırdık. İntihar görevindeyiz. Ama buradaki kum ve kayalar, binlerce yıllık savaşla lekelenmiş -- Bizi hatırlayacaklar. Bunun için.", + "SUBTITLE_17": "^2Price: ^7Çünkü tüm kâbuslarımız arasında kendimiz için seçtiğimiz tek kâbus bu.", + "SUBTITLE_110": "^2Price: ^7Biz......onu......öldüreceğiz.", + "SUBTITLE_15": "^2Price: ^7Shepherd bir kahraman olacak... çünkü dünyayı değiştirmek için ihtiyacınız olan tek şey iyi bir yalan ve bir nehir dolusu kan.", + "SUBTITLE_16": "^2Price: ^7Bir yalancının tarih üzerinde oynadığı en büyük oyunu tamamlamak üzere.", + "SUBTITLE_AIRPORT_MKV_NORUSS12": "^2Makarov: ^7Unutma - Rusça yok.", + "SUBTITLE_AIRPORT_MKV_LETSGO13": "^2Makarov: ^7Hadi gidelim.", + "SUBTITLE_AIRPORT_MKV_MOVEUP214": "^2Makarov: ^7İlerleyin.", + "SUBTITLE_AIRPORT_MKV_UPSTAIRS15": "^2Makarov: ^7Merdivenlerden yukarı. Hadi.", + "SUBTITLE_AIRPORT_MKV_30SECS51": "^2Makarov: ^730 saniye. Git.", + "SUBTITLE_AIRPORT_MKV_LETSMOVEUP52": "^2Makarov: ^7Gidelim, ilerleyin!", + "SUBTITLE_AIRPORT_MKV_LETSGO253": "^2Makarov: ^7Hadi gidelim!", + "SUBTITLE_AIRPORT_MKV_GO54": "^2Makarov: ^7Git.", + "SUBTITLE_AIRPORT_MKV_KEEPMOVING55": "^2Makarov: ^7Devam edin!", + "SUBTITLE_AIRPORT_AT1_SECURITY56": "^2Kiril: ^7Güvenlik detayı ileride!", + "SUBTITLE_AIRPORT_MKV_CAREOFIT57": "^2Makarov: ^7İcabına bakın!", + "SUBTITLE_AIRPORT_AT1_FRAGOUT58": "^2Kiril: ^7Dağılın!", + "SUBTITLE_AIRPORT_MKV_ELEVATORS59": "^2Makarov: ^7Asansörlerde hareketlilik var!", + "SUBTITLE_AIRPORT_MKV_COPY510": "^2Makarov: ^7Anlaşıldı.", + "SUBTITLE_AIRPORT_MKV_FIREINHOLE511": "^2Makarov: ^7Deliğe ateş!", + "SUBTITLE_AIRPORT_MKV_DOUBTYOU61": "^2Makarov: ^7Bu zamana kadar bana iyi hizmet ettin. Senden şüphe etmem için bana bir sebep verme.", + "SUBTITLE_AIRPORT_MKV_OPENFIRE62": "^2Makarov: ^7Ateş açın, bu bir emirdir.", + "SUBTITLE_AIRPORT_MKV_FSB63": "^2Makarov: ^7F.S.B. - Çıkarın onları.", + "SUBTITLE_AIRPORT_MKV_WELLDONE64": "^2Makarov: ^7Aferin sana. Beni hayal kırıklığına uğratmayacağını biliyordum.", + "SUBTITLE_AIRPORT_MKV_YOUTRAITOR65": "^1Makarov: ^7Seni hain.", + "SUBTITLE_AIRPORT_MKV_COWARDS66": "^1Makarov: ^7Korkaklara tahammülüm yok.", + "SUBTITLE_AIRPORT_MKV_CHECKFIRE67": "^2Makarov: ^7Ateşinizi kontrol edin!", + "SUBTITLE_AIRPORT_MKV_RUNNER71": "^2Makarov: ^7Bir kaçağım var!", + "SUBTITLE_AIRPORT_AT1_GOTMOREFSB72": "^2Kiril: ^7Daha fazla F.S.B.'miz var.", + "SUBTITLE_AIRPORT_MKV_TAKECARE73": "^2Makarov: ^7İcabına bakın.", + "SUBTITLE_AIRPORT_AT1_ROGER74": "^2Kiril: ^7Anlaşıldı.", + "SUBTITLE_AIRPORT_MKV_FRAGOUT75": "^2Makarov: ^7Dağılın!", + "SUBTITLE_AIRPORT_MKV_FORZAKHAEV91": "^2Makarov: ^7Zakhaev için.", + "SUBTITLE_AIRPORT_MKV_ONTIME92": "^2Makarov: ^7Tam zamanında geldiler.", + "SUBTITLE_AIRPORT_MKV_THISWAY93": "^2Makarov: ^7Bu taraftan gidelim.", + "SUBTITLE_AIRPORT_MKV_HOLDFIRE94": "^2Makarov: ^7Ateş etmeyin.", + "SUBTITLE_AIRPORT_MKV_HALLWAY95": "^2Makarov: ^7Koridor temiz.", + "SUBTITLE_AIRPORT_MKV_RIGHTONTIME96": "^2Makarov: ^7Güzel. Tam zamanında geldiler.", + "SUBTITLE_AIRPORT_MKV_CHECKAMMO97": "^2Makarov: ^7Silahlarınızı ve cephânenizi kontrol edin.", + "SUBTITLE_AIRPORT_VKT_BEENWAITING98": "^2Viktor: ^7Bunun için uzun süre bekledim.", + "SUBTITLE_AIRPORT_MKV_HAVENTWEALL910": "^2Makarov: ^7Hepimiz öyle değil miyiz?", + "SUBTITLE_AIRPORT_MKV_GOGOGO101": "^2Makarov: ^7Git! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_AIRPORT_MKV_LANDINGGEAR2272": "^2Makarov: ^7İniş takımları!", + "SUBTITLE_AIRPORT_MKV_LUGGAGECART2273": "^2Makarov: ^7Bagaj arabası!", + "SUBTITLE_AIRPORT_MKV_2NDFLRWNDWS2274": "^2Makarov: ^7İkinci kat penceresi!", + "SUBTITLE_AIRPORT_VT_MADEIT281": "^2Anatoly: ^7Güzel, başardın! İçeri gir.", + "SUBTITLE_AIRPORT_VT_COMEON282": "^2Anatoly: ^7Hadi, gidelim.", + "SUBTITLE_AIRPORT_VT_WAITINGFOR283": "^2Anatoly: ^7Ne bekliyorsun? Atla hadi.", + "SUBTITLE_AIRPORT_MKV_COMEON284": "^2Makarov: ^7Hadi, gidelim.", + "SUBTITLE_AIRPORT_MKV_GETIN285": "^2Makarov: ^7Gitmeliyiz, bin.", + "SUBTITLE_AIRPORT_VT_BEENOUGH291": "^2Anatoly: ^7Bu saldırıyla güçlü bir mesaj gönderdik, Makarov.", + "SUBTITLE_AIRPORT_MKV_NOMESSAGE292": "^2Makarov: ^7Bu bir mesaj değildi...", + "SUBTITLE_AIRPORT_MKV_THISWILL293": "^1Makarov: ^7Bu bir mesaj.", + "SUBTITLE_AIRPORT_MKV_ALLOFRUSSIA294": "^1Makarov: ^7Amerikalı bizi kandırabileceğini sandı. O cesedi bulduklarında... tüm Rusya savaş çığlıkları atacak.", + "SUBTITLE_18": "^2Shepherd: ^7O senin yeni en iyi arkadaşın.", + "SUBTITLE_19": "^2Shepherd: ^7Seni onun yanına koymanın zaten neye mal olduğunu bilmek istemezsin. Orada kalmak sana daha da pahalıya mal olacak.", + "SUBTITLE_111": "^2Shepherd: ^7Tasarruf edeceğin her şeyle karşılaştırıldığında hiçbir maliyeti olmayacak.", + "SUBTITLE_ARCADIA_FLY_DESTROYTRIPLEA12": "^2Çvş. Foley: ^7O üçlü A pozisyonlarını yok etmeliyiz ki geri kalan sivilleri buradan çıkarabilsinler! Hadi gidelim!", + "SUBTITLE_ARCADIA_FLY_USEDESIGNATOR13": "^2Çvş. Foley: ^7İşaretleyicinizi kullanın! Stryker için tembel hedefler!", + "SUBTITLE_ARCADIA_FLY_PAINTTARGETS14": "^2Çvş. Foley: ^7Manga, lazer işaretleyicilerinizi kullanın! Stryker için hedefleri boyayın!", + "SUBTITLE_ARCADIA_STR_LASETARGET21": "^2Stryker Nişancısı: ^7Tüm Avcı birimleri, burası Porsuk Bir. Hedefi tembelleştirin, tamam.", + "SUBTITLE_ARCADIA_STR_STANDINGBY22": "^2Stryker Nişancısı: ^7Tüm Avcı birimleri, burası Porsuk Bir. Hedeflerinize saldırmak için beklemedeyiz, tamam.", + "SUBTITLE_ARCADIA_STR_PAINTTARGET23": "^2Stryker Nişancısı: ^7Tüm Avcı ekipleri, burası Porsuk Bir. Hedefi boyayın, tamam.", + "SUBTITLE_ARCADIA_STR_WEHAVELOCK31": "^2Stryker Nişancısı: ^7Anlaşıldı, hedefe kilitlendik. Hedefe nişan alınıyor.", + "SUBTITLE_ARCADIA_STR_ENGAGING32": "^2Stryker Nişancısı: ^7Porsuk Bir kopyalandı, hedefe kilitlenildi.", + "SUBTITLE_ARCADIA_STR_ATTACKING33": "^2Stryker Nişancısı: ^7Anlaşıldı, hedefine saldırıyor.", + "SUBTITLE_ARCADIA_STR_SOLIDCOPYENG34": "^2Stryker Nişancısı: ^7Anlaşıldı. Hedefe saldırılıyor.", + "SUBTITLE_ARCADIA_STR_HAVEALOCK35": "^2Stryker Nişancısı: ^7Anlaşıldı, kilitlendik. Eve giriliyor.", + "SUBTITLE_ARCADIA_STR_BADGERONECOPIES36": "^2Stryker Nişancısı: ^7Porsuk Bir anlaşıldı, eve giriyoruz.", + "SUBTITLE_ARCADIA_STR_ATTACKINGVEHICLE37": "^2Stryker Nişancısı: ^7Anlaşıldı, araca saldırıyor.", + "SUBTITLE_ARCADIA_STR_ENGAGINGINFANTRY38": "^2Stryker Nişancısı: ^7Anlaşıldı. Piyadelere saldırıyor.", + "SUBTITLE_ARCADIA_STR_ENGAGINGVEHICLE39": "^2Stryker Topçusu: ^7Anlaşıldı. Araca ateş ediliyor.", + "SUBTITLE_ARCADIA_STR_APARTMENTOFFICE310": "^2Stryker Nişancısı: ^7Porsuk Bir kopyalandı, apartman ofisine giriliyor.", + "SUBTITLE_ARCADIA_STR_SECURITYSTATION311": "^2Stryker Nişancısı: ^7Anlaşıldı, güvenlik istasyonundaki hedeflere saldırıyor.", + "SUBTITLE_ARCADIA_STR_CHECKPOINT312": "^2Stryker Nişancısı: ^7Onaylandı, kontrol noktasındaki piyadelere saldırılıyor.", + "SUBTITLE_ARCADIA_STR_ENGYELLOWHOUSE313": "^2Stryker Nişancısı: ^7Porsuk Bir sarı eve saldırıyor.", + "SUBTITLE_ARCADIA_STR_TARGGREYHOUSE314": "^2Stryker Nişancısı: ^7Anlaşıldı. Gri evdeki piyadeler hedef alınıyor.", + "SUBTITLE_ARCADIA_STR_ENGFIRETRUCK315": "^2Stryker Topçusu: ^7Anlaşıldı, itfaiye aracının yakınındaki hedefler vuruluyor.", + "SUBTITLE_ARCADIA_STR_CONFPOLICECAR316": "^2Stryker Topçusu: ^7Onaylandı, polis arabasının yakınındaki hedefler bastırılıyor", + "SUBTITLE_ARCADIA_STR_ENGCHOPPER317": "^2Stryker Topçusu: ^7Anlaşıldı. Helikopterle bağlantı kuruluyor", + "SUBTITLE_ARCADIA_STR_TARGDESTROYED41": "^2Stryker Topçusu: ^7Porsuk Bir'den Avcı İki'ye, hedef yok edildi.", + "SUBTITLE_ARCADIA_STR_AREASUPPRESSED42": "^2Stryker Nişancısı: ^7Porsuk Bir'den Avcı İki'ye, alan bastırıldı.", + "SUBTITLE_ARCADIA_STR_TASUPPRESSED43": "^2Stryker Nişancısı: ^7Porsuk Bir'den Avcı İki'ye, hedef alan bastırıldı.", + "SUBTITLE_ARCADIA_STR_UHNEGATIVE51": "^2Stryker Nişancısı: ^7Olumsuz, hedef menzil dışında, tamam.", + "SUBTITLE_ARCADIA_STR_INVALIDTARGET62": "^2Stryker Nişancısı: ^7Olumsuz, bu geçersiz bir hedef, tamam.", + "SUBTITLE_ARCADIA_STR_OUTTARANGE63": "^2Stryker Nişancısı: ^7Olumsuz, hedef menzil dışında!", + "SUBTITLE_ARCADIA_STR_OUTTARANGE63_1": "SUBTITLE_ARCADIA_STR_OUTTARANGE63_1", + "SUBTITLE_ARCADIA_STR_OUTOFRANGE64": "^2Stryker Topçusu: ^7Hedef menzil dışında.", + "SUBTITLE_ARCADIA_STR_WEREROLLIN71": "^2Stryker Nişancısı: ^7Uzak durun, gidiyoruz.", + "SUBTITLE_ARCADIA_STR_STANDCLEAR72": "^2Stryker Nişancısı: ^7Dikkatli olun, hareket ediyoruz. Uzak durun.", + "SUBTITLE_ARCADIA_STR_OSCARMIKE73": "^2Stryker Nişancısı: ^7Tüm kara birimleri, hazır olun. Porsuk Bir, Oscar Mike.", + "SUBTITLE_ARCADIA_STR_ROLLING74": "^2Stryker Nişancısı: ^7Dikkatli olun, Bal Porsuğu yuvarlanıyor. Yoldan çekilin.", + "SUBTITLE_ARCADIA_STR_STEPASIDE75": "^2Stryker Gunner: ^7Kenara çekilin, yuvarlanıyoruz.", + "SUBTITLE_ARCADIA_FLY_GETRUNOVER76": "^2Çvş. Foley: ^7Ramirez! Seni ezecekler! Yollarından çekilin!", + "SUBTITLE_ARCADIA_CPD_GETOUTTA77": "^2Çvş. Dunn: ^7Ramirez! Bal Porsuğu hareket ediyor! Kıçını yoldan çek!", + "SUBTITLE_ARCADIA_CPD_GETOUTTA77_1": "^2Çvş. Dunn: ^7Ramirez! Bal Porsuğu hareket ediyor! Yoldan çekil!", + "SUBTITLE_ARCADIA_CPD_GETOUTTA77_2": "SUBTITLE_ARCADIA_CPD_GETOUTTA77_2", + "SUBTITLE_ARCADIA_CPD_GETOUTTA77_3": "^2Çvş. Dunn: ^7Ramirez! Bal Porsuğu hareket ediyor! Yoldan çekilin!", + "SUBTITLE_ARCADIA_STR_HOLDINGPOSITION81": "^2Stryker Gunner: ^7Porsuk Bir pozisyonunu koruyor.", + "SUBTITLE_ARCADIA_STR_RPGFIRE91": "^2Stryker Nişancısı: ^7Avcı İki-Bir Gerçek, burası Porsuk Bir! Anti-füze sistemimiz RPG ateşinin hacmini kaldıramıyor, ekibinizin onları azaltmasına ihtiyacımız var, nasıl anlaşıldı, tamam mı?", + "SUBTITLE_ARCADIA_FLY_WEREONIT92": "^2Çvş. Foley: ^7Anlaşıldı Badger Bir, ilgileniyoruz! Dışarı!", + "SUBTITLE_ARCADIA_FLY_PROTECTSTRYKER93": "^2Çvş. Foley: ^7Takım! Stryker'ı koruyun! RPG'li yaya araçlarına dikkat edin!", + "SUBTITLE_ARCADIA_FLY_WATCHFORRPGS94": "^2Çvş. Foley: ^7Manga! Stryker'ı hedef alıyorlar! Roketatarlara dikkat edin!", + "SUBTITLE_ARCADIA_FLY_LOSTBADGERONE105": "^2Çvş. Foley: ^7Tüm Avcı birimlerinin dikkatine, Porsuk Bir'i kaybettik. Stryker desteği mevcut değil, tekrar ediyorum, Stryker desteği mevcut değil. Elinizdekilerle idare edin", + "SUBTITLE_ARCADIA_FLY_EVERYONEUP111": "^2Çvş. Foley: ^7Herkes ilerlesin!", + "SUBTITLE_ARCADIA_FLY_MOVEUP112": "^2Çvş. Foley: ^7İlerleyin!", + "SUBTITLE_ARCADIA_CPD_MOVEUP113": "^2Çvş. Dunn: ^7İlerleyin!", + "SUBTITLE_ARCADIA_CPD_LETSGO114": "^2Çvş. Dunn: ^7Gidelim, gidelim!", + "SUBTITLE_ARCADIA_FLY_SENTRYGUNS121": "^2Çvş. Foley: ^7Manga, nöbetçi silahlarını indirin!", + "SUBTITLE_ARCADIA_FLY_TAKEOUTSGUN122": "^2Çvş. Foley: ^7Şu nöbetçi silahını halledin!", + "SUBTITLE_ARCADIA_FLY_SUPPRESSINGFIRE131": "^2Çvş. Foley: ^7Manga, o eve bastırma ateşi açın!", + "SUBTITLE_ARCADIA_FLY_CONCENTRATEFIRE132": "^2Çvş. Foley: ^7Manga, ateşinizi o eve yoğunlaştırın!", + "SUBTITLE_ARCADIA_FLY_YELLOWHOUSE133": "^2Çvş. Foley: ^7Sarı evde düşmanlarımız var!", + "SUBTITLE_ARCADIA_CPD_GREYHOUSE134": "^2Çvş. Dunn: ^7Gri evde düşmanlar var!", + "SUBTITLE_ARCADIA_FLY_GREYHOUSE135": "^2Çvş. Foley: ^7Manga, gri evde düşmanlar var! Çıkarın onları!", + "SUBTITLE_ARCADIA_CPD_APARTMENTS136": "^2Çvş. Dunn: ^7Apartmanların yanında düşman yaya arabaları var!", + "SUBTITLE_ARCADIA_FLY_APARTMENTS137": "^2Çvş. Foley: ^7Anlaşıldı, apartmanların yanında düşman yaya araçları var, halledin onları!", + "SUBTITLE_ARCADIA_FLY_OFFSTREETS138": "^2Çvş. Foley: ^7Sokaklardan çekilin, evleri siper olarak kullanın!", + "SUBTITLE_ARCADIA_FLY_FLANKTHRUHOUSES139": "^2Çvş. Foley: ^7Onları evlerden kuşatın! Hadi, hadi, hadi!", + "SUBTITLE_ARCADIA_FLY_MOVETHRUHOUSES1310": "^2Çvş. Foley: ^7Manga, bu evlerin arasından ilerleyin, gidelim, gidelim!", + "SUBTITLE_ARCADIA_STR_THANKS1311": "^2Stryker Topçusu: ^7Yardımın için teşekkürler Avcı İki-Bir.", + "SUBTITLE_ARCADIA_STR_THANKS1312": "^2Stryker Topçusu: ^7İyi iş, Avcı İki-Bir. Yardımın için teşekkürler.", + "SUBTITLE_ARCADIA_FLY_GETOFFSTREETS141": "^2Çvş. Foley: ^7Sokaklardan defolun!", + "SUBTITLE_ARCADIA_FLY_OUTTASTREETS142": "^2Çvş. Foley: ^7Sokaklardan defolun!", + "SUBTITLE_ARCADIA_HQR_SITREP151": "^2Overlord: ^7Avcı İki-Bir-Aktüel, Overlord. Bana bir durum raporu ver.", + "SUBTITLE_ARCADIA_FLY_INTOARCADIA152": "^2Çvş. Foley: ^7Lima Kontrol Noktası'ndaki düşman ablukasını geçtik. Şimdi Arcadia'ya doğru ilerliyoruz, tamam.", + "SUBTITLE_ARCADIA_HQR_NEWORDERS153": "^2Overlord: ^7Anlaşıldı. Sizin için yeni emirlerim var. Bu yukarıdan aşağıya geliyor, tamam.", + "SUBTITLE_ARCADIA_FLY_SOLIDCOPY154": "^2Çvş. Foley: ^7Anlaşıldı Overlord, gönder.", + "SUBTITLE_ARCADIA_HQR_DIVERTTO4677155": "^2Overlord: ^7Üçlü A'yı ortadan kaldırdıktan sonra ekibiniz 4677 Brookmere Yolu'na yönlendirilecek.", + "SUBTITLE_ARCADIA_FLY_DIVERTTO4677156": "^2Çvş. Foley: ^7Anlaşıldı Overlord. Silahlar yok edildikten sonra 4677 Brookmere Yolu'na yönelin. Tamamdır.", + "SUBTITLE_ARCADIA_HQR_CHECKBACK157": "^2Overlord: ^7Ana hedefinizi tamamladığınızda bana geri dönün. Overlord tamam.", + "SUBTITLE_ARCADIA_FLY_LASERDES161": "^2Çvş. Foley: ^7Ramirez, o araçlara topçu ateşi açmak için lazer işaretleyicini kullan!", + "SUBTITLE_ARCADIA_FLY_CALLARTILLERY162": "^2Çvş. Foley: ^7Ramirez, düşman araçlarına topçu ateşi aç! Lazer işaretleyicini kullan!", + "SUBTITLE_ARCADIA_ART_MISSIONREC163": "^2Topçu Bataryası: ^7Ateş görevi alındı, topçular geliyor.", + "SUBTITLE_ARCADIA_ART_CONFIRMED164": "^2Topçu Bataryası: ^7Koordinatlar onaylandı. Ateş ediliyor!", + "SUBTITLE_ARCADIA_ART_INVALIDTARGET165": "^2Topçu Bataryası: ^7Olumsuz, bu geçersiz bir hedef, tamam.", + "SUBTITLE_ARCADIA_ART_INVALIDCOORDINATES166": "^2Topçu Bataryası: ^7Olumsuz, bunlar geçersiz koordinatlar, tamam.", + "SUBTITLE_ARCADIA_FLY_GOLFCOURSE167": "^2Çvş. Foley: ^7Ramirez, golf sahasındaki araçların üzerindeki işaretleyiciyi kullan!", + "SUBTITLE_ARCADIA_FLY_ONEMORETOGO168": "^2Çvş. Foley: ^7İyi iş Ramirez, bir tane daha kaldı.", + "SUBTITLE_ARCADIA_FLY_HEADINGTO4677171": "^2Çvş. Foley: ^7Overlord, Avcı İki-Bir-Aktüel. Üçlü-A etkisiz hâle getirildi. 4677 Brookmere Yolu'na gidiyoruz.", + "SUBTITLE_ARCADIA_FLY_LOOKINGFOR172": "^2Çvş. Foley: ^7Sorgulayıcı - tam olarak ne arıyoruz, tamam?", + "SUBTITLE_ARCADIA_SHP_GENSHEP173": "^2Shepherd: ^7Çavuş Foley, ben General Shepherd.", + "SUBTITLE_ARCADIA_SHP_PANICROOM174": "^2Shepherd: ^7Göreviniz, evin ikinci katındaki bir 'panik odasından' yüksek değerde bir kişiyi çıkarmak.", + "SUBTITLE_ARCADIA_FLY_YESSIR175": "^2Çvş. Foley: ^7Emredersiniz efendim!", + "SUBTITLE_ARCADIA_SHP_PHOENIX176": "^2Shepherd: ^7Seni bekliyor olacak. Meydan okuma \"Icepick\", karşı işaret \"Phoenix\".", + "SUBTITLE_ARCADIA_SHP_REPORTBACK177": "^2Shepherd: ^7Onu oradan çıkar ve Overlord'a rapor ver. Shepherd tamam.", + "SUBTITLE_ARCADIA_FLY_HEARDTHEMAN178": "^2Çvş. Foley: ^7Pekâlâ, adamı duydunuz. 4677 Brookmere Yolu. Çekilin!", + "SUBTITLE_ARCADIA_FLY_ICEPICK1181": "^2Çvş. Foley: ^7Icepick.", + "SUBTITLE_ARCADIA_FLY_ICEPICK2182": "^2Çvş. Foley: ^7Icepick!", + "SUBTITLE_ARCADIA_FLY_NOTRIGHT183": "^2Çvş. Foley: ^7Burada doğru olmayan bir şeyler var... Panik odasını kontrol edin - hareket edin!", + "SUBTITLE_ARCADIA_FLY_GETTHATBRIEFCASE184": "^2Çvş. Foley: ^7Ramirez, o çantayı al... ondan geriye ne kaldıysa.", + "SUBTITLE_ARCADIA_CPD_CHECKOUTTATS185": "^2Çvş. Dunn: ^7Çavuş, şu dövmelere bak. Sıradan bir polis değil, ha?", + "SUBTITLE_ARCADIA_FLY_PHOTOSFORG2186": "^2Çvş. Foley: ^7Hooah. G-2 için birkaç fotoğraf çek ve istihbarat için cesetleri kontrol et.", + "SUBTITLE_ARCADIA_CPD_HUAH187": "^2Çvş. Dunn: ^7Hooah.", + "SUBTITLE_ARCADIA_FLY_HVIISDEAD188": "^2Çvş. Foley: ^7Overlord, burası bir mezar. HVI öldü. Görünüşe göre bu adamın peşinde olan sadece biz değilmişiz.", + "SUBTITLE_ARCADIA_FLY_OVERLORDHVI1814": "^2Çvş. Foley: ^7Overlord, HVI öldü.", + "SUBTITLE_ARCADIA_FLY_NOTGOINGTOLIKE1815": "^2Çvş. Foley: ^7Shepherd bundan hoşlanmayacak.", + "SUBTITLE_ARCADIA_FLY_INTELOFFBODY189": "^2Çvş. Foley: ^7Yine de cesetten bazı bilgiler aldık. Bu Shepherd'ın hoşuna gitmeyecek.", + "SUBTITLE_ARCADIA_HQR_GETINTELTOCP1810": "^2Overlord: ^7Anlaşıldı. İstihbaratı merkeze götürün. Overlord tamam.", + "SUBTITLE_ARCADIA_FLY_BREAKSOVER1811": "^2Çvş. Foley: ^7Pekâlâ, mola bitti! Hadi buradan gidelim.", + "SUBTITLE_ARCADIA_FLY_NOSIGN1812": "^2Çvş. Foley: ^7Hmph. Zorla giriş izi yok...", + "SUBTITLE_CLIFF_PRI_BREAKSOVER11": "^2Yzb. MacTavish: ^7Mola bitti, Roach. Hadi gidelim.", + "SUBTITLE_CLIFF_PRI_SPOTME12": "^2Yzb. MacTavish: ^7Burada kal ve beni fark et. Gitmemi bekle.", + "SUBTITLE_CLIFF_PRI_ICEISGOOD13": "^2Yzb. MacTavish: ^7Pekâlâ, buz iyi. Beni takip et.", + "SUBTITLE_CLIFF_PRI_THEFARSIDE14": "^2Yzb. MacTavish: ^7İyi şanslar dostum. Uzak tarafta görüşürüz.", + "SUBTITLE_CLIFF_PRI_HOLDON16": "^2Yzb. MacTavish: ^7Sıkı tutun! Sakın bırakma!", + "SUBTITLE_NA17": "^2Yzb. MacTavish: ^7(Oyuncuyu yukarı çekme çabası)", + "SUBTITLE_CLIFF_PRI_CHECKSENSOR21": "^2Yzb. MacTavish: ^7Roach, kalp atışı sensörünü kontrol et.", + "SUBTITLE_CLIFF_PRI_SEEME22": "^2Yzb. MacTavish: ^7Beni dürbünde görebiliyor olmalısın.", + "SUBTITLE_CLIFF_PRI_BLUEDOT23": "^2Yzb. MacTavish: ^7O mavi nokta benim.", + "SUBTITLE_CLIFF_PRI_WHITEDOTS24": "^2Yzb. MacTavish: ^7Tanınmayan kişiler beyaz noktalar olarak görünecektir.", + "SUBTITLE_CLIFF_PRI_GETOVERHERE31": "^2Yzb. MacTavish: ^7Buraya gel.", + "SUBTITLE_CLIFF_PRI_NOIDEA32": "^2Yzb. MacTavish: ^7Roach, bu kuklaların burada olduğumuzdan haberi yok. Bunu yavaşça halledelim.", + "SUBTITLE_CLIFF_PRI_YOUTAKELEFT33": "^2Yzb. MacTavish: ^7Sen soldakini al.", + "SUBTITLE_CLIFF_PRI_ONTHREE34": "^2Yzb. MacTavish: ^7Üç deyince.", + "SUBTITLE_CLIFF_PRI_ONE35": "^2Yzb. MacTavish: ^7Bir...", + "SUBTITLE_CLIFF_PRI_TWO36": "^2Yzb. MacTavish: ^7İki...", + "SUBTITLE_CLIFF_PRI_THREE37": "^2Yzb. MacTavish: ^7Üç.", + "SUBTITLE_CLIFF_PRI_NICELYDONE38": "^2Yzb. MacTavish: ^7İyi işti.", + "SUBTITLE_CLIFF_PRI_NOTSNEAKY41": "^2Yzb. MacTavish: ^7Pek sinsice değil, Roach.", + "SUBTITLE_CLIFF_PRI_DONTALERTTHEM42": "^2Yzb. MacTavish: ^7Onları uyarmadığın zaman bu daha kolay.", + "SUBTITLE_CLIFF_PRI_SILENCERS43": "^2Yzb. MacTavish: ^7Susturucu getirmemizin bir nedeni var.", + "SUBTITLE_CLIFF_PRI_SOMEWORK44": "^2Yzb. MacTavish: ^7İşin bir kısmını sen yapınca daha kolay oluyor.", + "SUBTITLE_CLIFF_PRI_DOEVERYTHING45": "^2Yzb. MacTavish: ^7Sanırım her şeyi ben yapmak zorundayım?", + "SUBTITLE_CLIFF_PRI_SLOPPY46": "^2Yzb. MacTavish: ^7Bu özensizdi.", + "SUBTITLE_CLIFF_PRI_ALERTEDTHEM47": "^2Yzb. MacTavish: ^7Onları uyardın.", + "SUBTITLE_CLIFF_PRI_ATTRACTATTN51": "^2Yzb. MacTavish: ^7Düşman silahlarını toplarken dikkatli ol, Roach. Bastırılmamış ateşli silahlar çok dikkat çekecektir.", + "SUBTITLE_CLIFF_PRI_SAMEPLAN52": "^2Yzb. MacTavish: ^7Aynı plân.", + "SUBTITLE_CLIFF_PRI_NICEWORK53": "^2Yzb. MacTavish: ^7İyi işti.", + "SUBTITLE_CLIFF_PRI_STORMSBREWING61": "^2Yzb. MacTavish: ^7Fırtına yaklaşıyor.", + "SUBTITLE_CLIFF_PRI_SPLITUP62": "^2Yzb. MacTavish: ^7Ayrılalım. Ben termal dürbünü kullanacağım ve bu tepeden gözetleme yapacağım.", + "SUBTITLE_CLIFF_PRI_COVEROFSTORM63": "^2Yzb. MacTavish: ^7Üsse girmek için fırtınanın örtüsünü kullanın.", + "SUBTITLE_CLIFF_PRI_LIKEAGHOST64": "^2Yzb. MacTavish: ^7Bu kar fırtınasında bir hayalet gibi olacaksın, bu yüzden çok yaklaşana kadar muhafızlar seni görmeyecek.", + "SUBTITLE_CLIFF_PRI_KEEPEYEONHEART65": "^2Yzb. MacTavish: ^7Gözünüz kalp atışı sensörünüzde olsun, iyi şanslar.", + "SUBTITLE_CLIFF_PRI_KILLFIRM_PLYR71": "^2Yzb. MacTavish: ^7Güzel atış.", + "SUBTITLE_CLIFF_PRI_KILLFIRM_PLYR72": "^2Yzb. MacTavish: ^7İyi öldürüş.", + "SUBTITLE_CLIFF_PRI_KILLFIRM_PLYR73": "^2Yzb. MacTavish: ^7Onu hakladın.", + "SUBTITLE_CLIFF_PRI_KILLFIRM_PLYR74": "^2Yzb. MacTavish: ^7İyi atış.", + "SUBTITLE_CLIFF_PRI_KILLFIRM_PLYR75": "^2Yzb. MacTavish: ^7Güzel atış.", + "SUBTITLE_CLIFF_PRI_KILLFIRM_PLYR76": "^2Yzb. MacTavish: ^7Fena değil.", + "SUBTITLE_CLIFF_PRI_TAKETHISONE81": "^2Yzb. MacTavish: ^7Bunu ben alıyorum.", + "SUBTITLE_CLIFF_PRI_HESMINE82": "^2Yzb. MacTavish: ^7O benim.", + "SUBTITLE_CLIFF_PRI_NEVERMIND83": "^2Yzb. MacTavish: ^7Boş ver.", + "SUBTITLE_CLIFF_PRI_MAYBENOT84": "^2Yzb. MacTavish: ^7Sonra tekrar, belki de değil.", + "SUBTITLE_CLIFF_PRI_KILLFIRM91": "^2Yzb. MacTavish: ^7Tango aşağı.", + "SUBTITLE_CLIFF_PRI_KILLFIRM92": "^2Yzb. MacTavish: ^7İyi geceler.", + "SUBTITLE_CLIFF_PRI_IVEGOTHIM93": "^2Yzb. MacTavish: ^7Onu yakaladım.", + "SUBTITLE_CLIFF_PRI_ONESMINE94": "^2Yzb. MacTavish: ^7Bu benim.", + "SUBTITLE_CLIFF_PRI_ILLTAKEHIM95": "^2Yzb. MacTavish: ^7Onu ben alacağım.", + "SUBTITLE_CLIFF_PRI_KILLFIRM96": "^2Yzb. MacTavish: ^7Bir tane buldum.", + "SUBTITLE_CLIFF_PRI_KILLFIRM97": "^2Yzb. MacTavish: ^7Hedef elendi.", + "SUBTITLE_CLIFF_PRI_KILLFIRM98": "^2Yzb. MacTavish: ^7Hedef vuruldu.", + "SUBTITLE_CLIFF_PRI_KILLFIRM99": "^2Yzb. MacTavish: ^7Onu yakaladım.", + "SUBTITLE_CLIFF_PRI_KEEPQUIET101": "^2Yzb. MacTavish: ^7Görünüşe göre bir ceset buldular ama seni henüz görmediler. Sessiz olun.", + "SUBTITLE_CLIFF_PRI_STAYCALM102": "^2Yzb. MacTavish: ^7Roach - bir ceset buldular ama henüz senin peşinde değiller. Sakin ol.", + "SUBTITLE_CLIFF_PRI_FOUNDABODY103": "^2Yzb. MacTavish: ^7Bekle - sadece bir ceset buldular. Nerede olduğunu bilmiyorlar.", + "SUBTITLE_CLIFF_PRI_SIGHTALERTEDONE111": "^2Yzb. MacTavish: ^7Gözden uzak durun - onlardan birini alarma geçirdiniz!", + "SUBTITLE_CLIFF_PRI_SIGHTBEENSPOTTED112": "^2Yzb. MacTavish: ^7Gözden uzak durun - fark edildiniz!", + "SUBTITLE_CLIFF_PRI_ONESEENYOU113": "^2Yzb. MacTavish: ^7Onlardan biri seni gördü, gözden uzak dur!", + "SUBTITLE_CLIFF_PRI_HIDEALERTED114": "^2Yzb. MacTavish: ^7Saklan! Muhafızlardan birini alarma geçirdin.", + "SUBTITLE_CLIFF_PRI_OUTOFSIGHT115": "^2Yzb. MacTavish: ^7Gözden uzak dur - bazı muhafızları alarma geçirdin.", + "SUBTITLE_CLIFF_PRI_TAKECOVER116": "^2Yzb. MacTavish: ^7Siper alın! Peşindeler!", + "SUBTITLE_CLIFF_PRI_BEENSPOTTED117": "^2Yzb. MacTavish: ^7Tespit edildiniz, siper alın!", + "SUBTITLE_CLIFF_PRI_FOUNDYOU118": "^2Yzb. MacTavish: ^7Çık oradan, seni buldular!", + "SUBTITLE_CLIFF_PRI_MULTIPLEDIRECTIONS119": "^2Yzb. MacTavish: ^7Dikkat! Birden fazla yönden gelen tangolar görüyorum!", + "SUBTITLE_CLIFF_PRI_TANGOLEFT121": "^2Yzb. MacTavish: ^7Tango solunda.", + "SUBTITLE_CLIFF_PRI_HOSTILERIGHT122": "^2Yzb. MacTavish: ^7Düşman sağa.", + "SUBTITLE_CLIFF_PRI_TARGETLEFT123": "^2Yzb. MacTavish: ^7Hedef solunuzda.", + "SUBTITLE_CLIFF_PRI_TARGETRIGHT124": "^2Yzb. MacTavish: ^7Hedef sağında.", + "SUBTITLE_CLIFF_PRI_TANGOSIX125": "^2Yzb. MacTavish: ^7Tango altı yönünde.", + "SUBTITLE_CLIFF_PRI_TARGETBEHINDYOU126": "^2Yzb. MacTavish: ^7Hedef arkanızda.", + "SUBTITLE_CLIFF_PRI_THEYGOINGBACK131": "^2Yzb. MacTavish: ^7Pozisyonlarına geri dönüyorlar.", + "SUBTITLE_CLIFF_PRI_YOURECLEAR132": "^2Yzb. MacTavish: ^7Temizsiniz, pozisyonlarına geri dönüyorlar.", + "SUBTITLE_CLIFF_PRI_RESTHAVEGIVENUP133": "^2Yzb. MacTavish: ^7Geri kalanlar seni aramaktan vazgeçtiler ve eski yerlerine dönüyorlar.", + "SUBTITLE_CLIFF_PRI_PRETTYSNEAKY141": "^2Yzb. MacTavish: ^7Öldürme yok, uyarı yok, etkileyici Roach.", + "SUBTITLE_CLIFF_PRI_TAPPEDCOMMS151": "^2Yzb. MacTavish: ^7Pekâlâ, telsizlerine girdim.", + "SUBTITLE_CLIFF_PRI_YOUREIN_2152": "^2Yzb. MacTavish: ^7Güneydoğuya gidin ve C4'ünüzü yakıt istasyonuna yerleştirin.", + "SUBTITLE_CLIFF_PRI_YOUREIN_3153": "^2Yzb. MacTavish: ^7İşler kötüye giderse 'B Planı'na geçmemiz gerekebilir.", + "SUBTITLE_CLIFF_PRI_NECORNER154": "^2Yzb. MacTavish: ^7Roach, yakıt istasyonu pistin kuzeydoğu köşesine yakın.", + "SUBTITLE_CLIFF_PRI_SEARCHNTHEAST155": "^2Yzb. MacTavish: ^7Roach - yakıt istasyonu için pistin kuzeydoğu kısmını araştır.", + "SUBTITLE_CLIFF_PRI_TRUCKCOMING161": "^2Yzb. MacTavish: ^7Bir kamyon geliyor! Görüş alanından uzak dur.", + "SUBTITLE_CLIFF_PRI_TRUCKBACK162": "^2Yzb. MacTavish: ^7Kamyon geri geliyor.", + "SUBTITLE_CLIFF_PRI_TANGOSOUT163": "^2Yzb. MacTavish: ^7Tangolar az önce kamyondan indi.", + "SUBTITLE_CLIFF_PRI_ANOTHERTRUCK164": "^2Yzb. MacTavish: ^7Başka bir kamyon geliyor.", + "SUBTITLE_CLIFF_PRI_TRUCKCOMING2165": "^2Yzb. MacTavish: ^7Kamyon geliyor.", + "SUBTITLE_CLIFF_PRI_HEADSUP166": "^2Yzb. MacTavish: ^7Dikkat, kamyon az önce durdu.", + "SUBTITLE_CLIFF_PRI_TRUCKCOMINGBACK167": "^2Yzb. MacTavish: ^7Kamyon geri geliyor.", + "SUBTITLE_CLIFF_PRI_TRUCKISCOMING168": "^2Yzb. MacTavish: ^7Kamyon geliyor.", + "SUBTITLE_CLIFF_PRI_LOOKINGAROUND169": "^2Yzb. MacTavish: ^7Dört tango dışarı çıktı ve etrafa bakıyorlar.", + "SUBTITLE_CLIFF_PRI_FLAMINGWRECK1610": "^2Yzb. MacTavish: ^7Acaba yolun ortasında yanan bir enkazı fark edecekler mi....", + "SUBTITLE_CLIFF_PRI_HOLDUP171": "^2Yzb. MacTavish: ^7Durun bakalım.", + "SUBTITLE_CLIFF_PRI_ACTIVITYONRUNWAY172": "^2Yzb. MacTavish: ^7Pistte bir hareketlilik görüyorum.", + "SUBTITLE_CLIFF_PRI_FOOTMOBILES173": "^2Yzb. MacTavish: ^7Görünüşe göre yirmiden fazla ayaklı araç size doğru geliyor.", + "SUBTITLE_CLIFF_PRI_FUELINGSTATION174": "^2Yzb. MacTavish: ^7Bu yakıt istasyonu.", + "SUBTITLE_CLIFF_PRI_FOUNDIT175": "^2Yzb. MacTavish: ^7Onu buldun.", + "SUBTITLE_CLIFF_PRI_GOBACK176": "^2Yzb. MacTavish: ^7Roach, yakıt istasyonuna geri dön ve C4'ünü yerleştir.", + "SUBTITLE_CLIFF_PRI_RADIOTRAFFIC181": "^2Yzb. MacTavish: ^7Uydu hakkında daha fazla radyo trafiği alıyorum. Beklemede kalın.", + "SUBTITLE_CLIFF_PRI_INFARHANGAR182": "^2Yzb. MacTavish: ^7Anlaşıldı. Uydu uzak hangarda gibi görünüyor.", + "SUBTITLE_CLIFF_PRI_OSCARMIKE183": "^2Yzb. MacTavish: ^7Orada yarışalım. Oscar Mike", + "SUBTITLE_CLIFF_PRI_GETTHEREASAP184": "^2Yzb. MacTavish: ^7Hangara doğru gidiyorum. En kısa zamanda orada ol.", + "SUBTITLE_CLIFF_PRI_BEHINDHANGARS185": "^2Yzb. MacTavish: ^7Roach, pistin güneybatı köşesindeki hangarların arkasında bekliyorum.", + "SUBTITLE_CLIFF_PRI_MEETME186": "^2Yzb. MacTavish: ^7Roach, benimle pistin güneybatı köşesindeki hangarların arkasında buluş.", + "SUBTITLE_CLIFF_PRI_AVOIDAREA191": "^2Yzb. MacTavish: ^7Kule yakınlarında büyük ısı sinyalleri alıyorum, BMP'ler olabilir. Ben olsam o bölgeden uzak dururdum.", + "SUBTITLE_CLIFF_PRI_GETOUTOFTHERE192": "^2Yzb. MacTavish: ^7O BMP'nin termal dürbünü var! Çekil oradan!", + "SUBTITLE_CLIFF_PRI_SCENICROUTE201": "^2Yzb. MacTavish: ^7Manzaralı yoldan gittin ha?", + "SUBTITLE_CLIFF_PRI_LETSGO202": "^2Yzb. MacTavish: ^7Hadi gidelim.", + "SUBTITLE_CLIFF_PRI_BROUGHTFRIENDS203": "^2Yzb. MacTavish: ^7Yanında arkadaşlarını da getirdin mi?", + "SUBTITLE_CLIFF_PRI_WATCHMYBACK211": "^2Yzb. MacTavish: ^7Arkamı kolla.", + "SUBTITLE_CLIFF_PRI_GOUPSTAIRS212": "^2Yzb. MacTavish: ^7Yukarı çık ve ACS modülünü ara.", + "SUBTITLE_CLIFF_PRI_DOWNLOADFILES213": "^2Yzb. MacTavish: ^7Roach, yukarı çık ve ACS modülünü ara.", + "SUBTITLE_CLIFF_PRI_COMPROMISED221": "^2Yzb. MacTavish: ^7Roach, açığa çıktım! Dikkat çekmeyin ve ateş etmeyin.", + "SUBTITLE_CLIFF_PET_THISISPETROV222": "^1Binbaşı Petrov: ^7Ben Binbaşı Petrov! Elleriniz havada dışarı çıkın!", + "SUBTITLE_CLIFF_PET_CAPTUREDCOMRADE223": "^1Binbaşı Petrov: ^7Düşman sızmacılarına, yoldaşlarınızdan birini ele geçirdik!", + "SUBTITLE_CLIFF_PET_SURRENDER224": "^1Binbaşı Petrov: ^7Orada olduğunuzu biliyoruz! Şimdi teslim ol ve yoldaşının canını bağışlayalım!", + "SUBTITLE_CLIFF_PET_WILLDIE225": "^1Binbaşı Petrov: ^7Eğer teslim olmazsanız, yoldaşınız ölecek.", + "SUBTITLE_CLIFF_PET_HANDSUP226": "^1Binbaşı Petrov: ^7Elleriniz havada dışarı çıkın!", + "SUBTITLE_CLIFF_PET_VERYWELL227": "^1Binbaşı Petrov: ^7Çok iyi - yoldaşınızı infaz etmeden önce size beş saniye vereceğim!", + "SUBTITLE_CLIFF_PET_FIVESECONDS228": "^1Binbaşı Petrov: ^7Uymak için beş saniyeniz var!", + "SUBTITLE_CLIFF_PET_COUNTFIVE229": "^1Binbaşı Petrov: ^7Beş!", + "SUBTITLE_CLIFF_PET_COUNTFOUR2210": "^1Binbaşı Petrov: ^7Dört!", + "SUBTITLE_CLIFF_PET_COUNTTHREE2211": "^1Binbaşı Petrov: ^7Üç!", + "SUBTITLE_CLIFF_PET_COUNTTWO2212": "^1Binbaşı Petrov: ^7İki!", + "SUBTITLE_CLIFF_PET_COUNTONE2213": "^1Binbaşı Petrov: ^7Bir!", + "SUBTITLE_CLIFF_PRI_GOPLANB2214": "^2Yzb. MacTavish: ^7Roach, B planına geç.", + "SUBTITLE_CLIFF_PRI_HUGTHEWALL231": "^2Yzb. MacTavish: ^7Yakın durun ve duvara sarılın! MiG'leri siper olarak kullanacağız ve asfaltı güneydoğuya geçeceğiz!", + "SUBTITLE_CLIFF_PRI_FOLLOWMELETSGO232": "^2Yzb. MacTavish: ^7Roach! Beni takip edin! Hadi gidelim!", + "SUBTITLE_CLIFF_PRI_RUNFORMIGEAST233": "^2Yzb. MacTavish: ^7Roach! Doğudaki MiG'e doğru koş!", + "SUBTITLE_CLIFF_PRI_EASTGO234": "^2Yzb. MacTavish: ^7Doğuya, Roach! Koş!", + "SUBTITLE_CLIFF_PRI_HEADFORMIG235": "^2Yzb. MacTavish: ^7MiG'e doğru git, seni koruyacağım!", + "SUBTITLE_CLIFF_PRI_RUNTONEXTMIG236": "^2Yzb. MacTavish: ^7Bir sonraki MiG'e koşacağım! Bana biraz koruma ateşi verin!", + "SUBTITLE_CLIFF_PRI_SNOWMOIBLES237": "^2Yzb. MacTavish: ^7Kar motosikletleri! İndirin onları!", + "SUBTITLE_CLIFF_PRI_MOVEUP238": "^2Yzb. MacTavish: ^7Seni koruyorum Roach! İlerleyin! Kımılda!", + "SUBTITLE_CLIFF_PRI_ALLRIGHT239": "^2Yzb. MacTavish: ^7Pekâlâ, gidelim!", + "SUBTITLE_CLIFF_PRI_COMETOME2310": "^2Yzb. MacTavish: ^7Seni koruyacağım! Bana doğru gel!", + "SUBTITLE_CLIFF_PRI_MAKINGABREAK2311": "^2Yzb. MacTavish: ^7Koru beni, kaçmaya çalışıyorum!", + "SUBTITLE_CLIFF_PRI_HEADINGFORJEEPS2312": "^2Yzb. MacTavish: ^7Şu jiplere doğru gidiyorum, beni koruyun!", + "SUBTITLE_CLIFF_PRI_MAKEABREAK2313": "^2Yzb. MacTavish: ^7Roach! İşaretimle kaçmaya hazır olun!", + "SUBTITLE_CLIFF_PRI_MORETANGOS2314": "^2Yzb. MacTavish: ^7Altımızda daha fazla tango var! İndirin onları!", + "SUBTITLE_CLIFF_PRI_SOUTHEASTCOVERED2315": "^2Yzb. MacTavish: ^7Roach! Güneydoğuya doğru! Seni koruyorum!", + "SUBTITLE_CLIFF_PRI_TAKESNOWMOBILE251": "^2Yzb. MacTavish: ^7Roach, al şu kar arabasını! Buradan defolup gidelim!", + "SUBTITLE_CLIFF_PRI_SNOWMOBILELETSGO252": "^2Yzb. MacTavish: ^7Roach! Bin şu kar arabasına, gidelim!", + "SUBTITLE_CLIFF_PRI_ENROUTE253": "^2Yzb. MacTavish: ^7Kilo Altı-Bir, birincil çıkış noktası tehlikede! Düşman araçlarını kullanarak yedek LZ'ye gidiyoruz! Bizimle orada buluşun! Tamam!", + "SUBTITLE_CLIFF_HP1_SEEYOUATBRAVO254": "^2Helikopter Pilotu: ^7Bravo Altı, burası Kilo Altı-Bir, anlaşıldı, tamam.", + "SUBTITLE_CLIFF_PRI_OUTRUNTHEM255": "^2Yzb. MacTavish: ^7Arkaya daha fazla tango! Onlardan kaç! Kaçın! Hadi! Hadi!", + "SUBTITLE_CLIFF_PRI_KEEPMOVING256": "^2Yzb. MacTavish: ^7Yavaşlamayın! Devam edin yoksa ölürsünüz!", + "SUBTITLE_CLIFF_PRI_GOGOGO257": "^2Yzb. MacTavish: ^7Gidin! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_CLIFF_PRI_COMEONCOMEON258": "^2Yzb. MacTavish: ^7Haydi! Hadi! Hadi!", + "SUBTITLE_CLIFF_HP1_STATUS259": "^2Helikopter Pilotu: ^7Bravo Altı, bingo yakıtındayız. Durumunuz nedir? Tamam.", + "SUBTITLE_CLIFF_PRI_ALMOSTTHERE2510": "^2Yzb. MacTavish: ^7Kilo Altı-Bir, ağır ateş altındayız ama neredeyse vardık! Beklemede kalın!", + "SUBTITLE_CLIFF_PRI_GONNAMAKEIT2511": "^2Yzb. MacTavish: ^7Başaracağız! Sadece dayanın!", + "SUBTITLE_CLIFF_PRI_PINTHROTTLE2512": "^2Yzb. MacTavish: ^7Gazı sabitle! Devam edin!", + "SUBTITLE_CLIFF_PRI_HANGON22513": "^2Yzb. MacTavish: ^7Dayan!", + "SUBTITLE_CLIFF_HP1_FUMES2514": "^2Helikopter Pilotu: ^7Bravo Altı, sizi görüntüledik. Uçağa binin! Yakıtımız bitmek üzere!", + "SUBTITLE_CLIFF_PRI_THECHOPPER2515": "^2Yzb. MacTavish: ^7Helikopter orada! Hadi gidelim!", + "SUBTITLE_CLIFF_CRC_GOTACS261": "^2Mürettebat Şefi: ^7Tamam, ACS'yi aldılar! Buradan gidiyoruz!", + "SUBTITLE_CONT_PRI_FOUNDROACH12": "^2Yzb. Price: ^7Anlaşıldı Soap. Roach'u buldum. Sağlam görünüyor.", + "SUBTITLE_CONT_PRI_HEADNW13": "^2Yzb. Price: ^7Kuzeybatıya, alt üsse doğru gidiyoruz, tamam.", + "SUBTITLE_CONT_CMT_FAREAST14": "^2Soap: ^7Anlaşıldı. Ekibin geri kalanı Ghost'in yakınına, oldukça doğuya indi.", + "SUBTITLE_CONT_PRI_PROCEED15": "^2Yzb. Price: ^7Onlara göreve devam etmelerini söyle, mümkünse yeniden toplanacağız.", + "SUBTITLE_CONT_PRI_FOUNDTRANSPORT16": "^2Yzb. Price: ^7Bize bir ulaşım aracı buldun mu?", + "SUBTITLE_CONT_CMT_WORKINGONIT17": "^2Soap: ^7Üzerinde çalışıyorum", + "SUBTITLE_CONT_PRI_OUTOFSIGHT21": "^2Yzb. Price: ^7Roach, beni takip et ve gözden uzak dur.", + "SUBTITLE_CONT_PRI_30METERSFRONT22": "^2Yzb. Price: ^7Temas. Düşman devriyesi 30 metre önümüzde.", + "SUBTITLE_CONT_PRI_FIVEMEN23": "^2Yzb. Price: ^7Beş adam, otomatik tüfekler, parça tesirli el bombaları. Bir Alman Çoban Köpeği.", + "SUBTITLE_CONT_CMT_HATEDOGS24": "^2Soap: ^7Köpekler. Köpeklerden nefret ederim.", + "SUBTITLE_CONT_PRI_RUSSIANDOGS26": "^2Yzb. Price: ^7Bu Rus köpekleri Pripyat'takilerin yanında kedi gibi kalıyor.", + "SUBTITLE_CONT_CMT_HAVEYOUBACK27": "^2Soap: ^7Geri dönmene sevindim, ihtiyar.", + "SUBTITLE_CONT_PRI_ROGERTHAT228": "^2Yzb. Price: ^7Anlaşıldı.", + "SUBTITLE_CONT_PRI_PICKOFFSTRAGGLERS29": "^2Yzb. Price: ^7Onları sessizce takip edelim ve geride kalanları temizleyelim.", + "SUBTITLE_CONT_PRI_DONTGETCLOSE31": "^2Yzb. Price: ^7Çok yaklaşmayın.", + "SUBTITLE_CONT_PRI_PATIENCE32": "^2Yzb. Price: ^7Sabırlı ol... Aptalca bir şey yapma.", + "SUBTITLE_CONT_PRI_SAMETIME33": "^2Yzb. Price: ^7Onları aynı anda halletmemiz gerekecek.", + "SUBTITLE_CONT_PRI_WAITPOSITION34": "^2Yzb. Price: ^7Pozisyon almamı bekleyin.", + "SUBTITLE_CONT_PRI_WAITFORME35": "^2Yzb. Price: ^7Beni bekle.", + "SUBTITLE_CONT_PRI_WHENYOUREREADY36": "^2Yzb. Price: ^7Yerimi aldım - hazır olduğunda ateş et.", + "SUBTITLE_CONT_PRI_MOVEUP37": "^2Yzb. Price: ^7İlerleyin.", + "SUBTITLE_CONT_PRI_MOVE38": "^2Yzb. Price: ^7Hareket et.", + "SUBTITLE_CONT_PRI_HIDEINWOODS41": "^2Yzb. Price: ^7Çabuk! Ormana saklanın! Onlardan birini uyardın!", + "SUBTITLE_CONT_PRI_GETINTOWOODS42": "^2Yzb. Price: ^7Ormana girin! Saklanın!", + "SUBTITLE_CONT_PRI_THEYREALERTED43": "^2Yzb. Price: ^7Alarma geçtiler! Ormanda saklanın! Kımıldayın!", + "SUBTITLE_CONT_PRI_ONTOUS51": "^2Yzb. Price: ^7Peşimizdeler! Ateş açın!", + "SUBTITLE_CONT_PRI_WERESPOTTED52": "^2Yzb. Price: ^7Fark edildik! İndirin onları!", + "SUBTITLE_CONT_PRI_GETUSKILLED53": "^2Yzb. Price: ^7Bu da neydi böyle? Bizi öldürtmeye mi çalışıyorsun?", + "SUBTITLE_CONT_PRI_THEWORDSTEALTH54": "^2Yzb. Price: ^7Gizlilik kelimesi sana bir şey ifade ediyor mu?", + "SUBTITLE_CONT_PRI_GIVEAWAYPOSITION55": "^2Yzb. Price: ^7Konumumuzu belli etme, Roach. Bu iş daha da zorlaşacak.", + "SUBTITLE_CONT_PRI_LOWPROFILE56": "^2Yzb. Price: ^7Roach, konumumuzu bu şekilde ele vermeye devam edemeyiz. Dikkat çekmemeye çalış!", + "SUBTITLE_CONT_PRI_ARENTLOOKING61": "^2Yzb. Price: ^7Diğerleri bakmıyorken onu hakla.", + "SUBTITLE_CONT_PRI_YOURCHANCE62": "^2Yzb. Price: ^7İşte sana fırsat. Onlardan birini indir.", + "SUBTITLE_CONT_PRI_SPLITTINGUP63": "^2Yzb. Price: ^7Ayrılıyorlar. İndirin onu.", + "SUBTITLE_CONT_PRI_FORASMOKE64": "^2Yzb. Price: ^7İkisi sigara içmek için durdu. Birini halledin, ben de diğerini halledeyim.", + "SUBTITLE_CONT_PRI_TWOINWOODS65": "^2Yzb. Price: ^7Köprünün diğer tarafındaki ormandaki ikisini hallet.", + "SUBTITLE_CONT_PRI_IMREADY66": "^2Yzb. Price: ^7Ben hazırım. Hepsini aynı anda halledelim.", + "SUBTITLE_CONT_PRI_BEAUTIFUL71": "^2Yzb. Price: ^7Çok güzel.", + "SUBTITLE_CONT_PRI_GOODSHOT72": "^2Yzb. Price: ^7İyi atış.", + "SUBTITLE_CONT_PRI_GOTONE73": "^2Yzb. Price: ^7Bir tane yakaladım.", + "SUBTITLE_CONT_PRI_HESDOWN274": "^2Yzb. Price: ^7Düştü.", + "SUBTITLE_CONT_PRI_TANGODOWN75": "^2Yzb. Price: ^7Tango düştü.", + "SUBTITLE_CONT_PRI_GOODNIGHT76": "^2Yzb. Price: ^7İyi geceler.", + "SUBTITLE_CONT_PRI_TARGETELIMINATED77": "^2Yzb. Price: ^7Hedef ortadan kaldırıldı.", + "SUBTITLE_CONT_PRI_TARGETDOWN78": "^2Yzb. Price: ^7Hedef vuruldu.", + "SUBTITLE_CONT_PRI_NICELYDONE79": "^2Yzb. Price: ^7İyi işti.", + "SUBTITLE_CONT_PRI_WELLDONE710": "^2Yzb. Price: ^7İyi işti.", + "SUBTITLE_CONT_PRI_GOOD711": "^2Yzb. Price: ^7Güzel.", + "SUBTITLE_CONT_PRI_SEENBETTER712": "^2Yzb. Price: ^7Fena değil ama daha iyilerini görmüştüm.", + "SUBTITLE_CONT_PRI_GOODWORK713": "^2Yzb. Price: ^7İyi iş çıkarmışsın.", + "SUBTITLE_CONT_PRI_IMPRESSIVE714": "^2Yzb. Price: ^7Etkileyici.", + "SUBTITLE_CONT_PRI_YOURPARACHUTE81": "^2Yzb. Price: ^7Görünüşe göre inişinizi görmüşler. Devam edelim.", + "SUBTITLE_CONT_PRI_KEEPMOVING82": "^2Yzb. Price: ^7Devam edelim.", + "SUBTITLE_CONT_PRI_GETDOWN91": "^2Yzb. Price: ^7Helikopterler geliyor! Yere yatın!", + "SUBTITLE_CONT_PRI_HUGTHEWALLS92": "^2Yzb. Price: ^7Duvarlara sarılın!", + "SUBTITLE_CONT_PRI_THATWASCLOSE101": "^2Yzb. Price: ^7Bu çok yakındı. Devam edelim.", + "SUBTITLE_CONT_PRI_HENOTICED111": "^2Yzb. Price: ^7Bunu fark etti! Saklanın!", + "SUBTITLE_CONT_PRI_GETOUTOFSIGHT112": "^2Yzb. Price: ^7Gözden kaybolun! O buraya geliyor!", + "SUBTITLE_CONT_PRI_HIDEBEENALERTED113": "^2Yzb. Price: ^7Saklanın! İçlerinden biri alarma geçti!", + "SUBTITLE_CONT_PRI_HESALERTED114": "^2Yzb. Price: ^7Alarma geçti! Saklanın!", + "SUBTITLE_CONT_PRI_FOUNDABODY121": "^2Yzb. Price: ^7Görünüşe göre bir ceset bulmuşlar.", + "SUBTITLE_CONT_PRI_FOUNDABODY2122": "^2Yzb. Price: ^7Bir ceset bulmuşlar.", + "SUBTITLE_CONT_PRI_DOGPATROL131": "^2Yzb. Price: ^7Köpek devriyesi.", + "SUBTITLE_CONT_PRI_3MANPATROL132": "^2Yzb. Price: ^7Önümüzde üç kişilik devriye var.", + "SUBTITLE_CONT_PRI_ALERTENEMIES133": "^2Yzb. Price: ^7Bastırılmamış bir silahla ateş etmek birçoğunu alarma geçirecektir, Roach.", + "SUBTITLE_CONT_PRI_LARGEPATROL12134": "^2Yzb. Price: ^7Saat 12 yönünde büyük bir devriye var.", + "SUBTITLE_CONT_PRI_ANOTHERDOGPATROL136": "^2Yzb. Price: ^7Bir köpek devriyesi daha var.", + "SUBTITLE_CONT_PRI_ANOTHERPATROL137": "^2Yzb. Price: ^7İleride bir devriye daha var.", + "SUBTITLE_CONT_PRI_YOURCALL141": "^2Yzb. Price: ^7Onları dışarı çıkarın ya da bırakın. Karar sizin.", + "SUBTITLE_CONT_PRI_CANTSLIPBY142": "^2Yzb. Price: ^7Susturuculu bir silah kullanın. Onları aynı anda halletmemiz gerekecek.", + "SUBTITLE_CONT_PRI_OUTORAROUND143": "^2Yzb. Price: ^7Onları indir ya da etraflarından dolaş.", + "SUBTITLE_CONT_PRI_LETPASS144": "^2Yzb. Price: ^7Bırakın geçsinler.", + "SUBTITLE_CONT_PRI_TWOONRIGHT145": "^2Yzb. Price: ^7Sağdaki ikisini al.", + "SUBTITLE_CONT_PRI_TWOONLEFT145": "^2Yzb. Price: ^7Soldaki terbiyeciyi ve köpeğini al.", + "SUBTITLE_CONT_PRI_SLIPPAST146": "^2Yzb. Price: ^7Onları indir ya da geçmeye çalış. Karar senin.", + "SUBTITLE_CONT_CMT_ROGERTHAT147": "^2Soap: ^7Anlaşıldı.", + "SUBTITLE_CONT_PRI_CONVOYCOMING151": "^2Yzb. Price: ^7Konvoy geliyor, görüş alanından çıkın.", + "SUBTITLE_CONT_PRI_LETTHEMPASS152": "^2Yzb. Price: ^7Geçmelerine izin ver ya da onları indir... karar senin.", + "SUBTITLE_CONT_PRI_INTELWASOFF153": "^2Yzb. Price: ^7Soap, istihbaratımız yanlışmış. Rusların mobil FÜZE'leri var.", + "SUBTITLE_CONT_PRI_GOLOUD155": "^2Yzb. Price: ^7Fark edildik! Gürültü yapın! İndirin onları!", + "SUBTITLE_CONT_PRI_INCOMING161": "^2Yzb. Price: ^7Geliyorlar! Dikkat edin!", + "SUBTITLE_CONT_PRI_INTOTHEWOODS163": "^2Yzb. Price: ^7Ormana doğru! Gidelim, gidelim!", + "SUBTITLE_CONT_PRI_FOLLOWME164": "^2Yzb. Price: ^7Beni takip edin!", + "SUBTITLE_CONT_PRI_SLOWDOWN171": "^2Yzb. Price: ^7Yavaşlayın. Araçları bizi bu kadar uzağa kadar takip edemez.", + "SUBTITLE_CONT_PRI_SEARCHINGFORUS172": "^2Yzb. Price: ^7Görünüşe göre bizi arıyorlar.", + "SUBTITLE_CONT_PRI_HATEDOGS172": "^2Yzb. Price: ^7Köpekler. Köpeklerden nefret ederim. Önce sen git.", + "SUBTITLE_CONT_PRI_GOTM173": "^2Yzb. Price: ^7Anladım.", + "SUBTITLE_CONT_PRI_HESDOWN174": "^2Yzb. Price: ^7Düştü.", + "SUBTITLE_CONT_PRI_DOWNBOY175": "^2Yzb. Price: ^7Aşağı çocuk.", + "SUBTITLE_CONT_PRI_NAPTIME176": "^2Yzb. Price: ^7Uyku zamanı.", + "SUBTITLE_CONT_PRI_AIRSUPPORT181": "^2Yzb. Price: ^7Soap, hava desteğimizin durumu nedir, tamam?", + "SUBTITLE_CONT_CMT_ALMOSTINPOS182": "^2MacTavish: ^7AGM yüklü bir İHA konumunuza doğru yola çıktı.", + "SUBTITLE_CONT_PRI_RIDGEISPERFECT184": "^2Yzb. Price: ^7Bu sırt mükemmel.", + "SUBTITLE_CONT_PRI_CONTROLUAV185": "^2Yzb. Price: ^7Roach, Predator insansız hava aracının kontrolünü ele geçir.", + "SUBTITLE_CONT_PRI_TAKECONTROL185": "^2Yzb. Price: ^7Roach İHA'nın kontrolünü ele geçirdi.", + "SUBTITLE_CONT_PRI_BOLLOCKS186": "^2Yzb. Price: ^7Bollocks!", + "SUBTITLE_CONT_CMT_WHATHAPPENED187": "^2Soap: ^7Az önce ne oldu?", + "SUBTITLE_CONT_PRI_MOBILESAMINVILLAGE188": "^2Yzb. Price: ^7Köyde mobil bir FÜZE alanı var. Az önce Predator'ümüzü vurdu.", + "SUBTITLE_CONT_PRI_SAMSITEINVILLAGE188": "^2Yzb. Price: ^7Köyde mobil bir FÜZE alanı var. Az önce İHA'mızı vurdu.", + "SUBTITLE_CONT_PRI_UAVSHARPISH1810": "^2Yzb. Price: ^7Soap, başka bir Predator'a ihtiyacımız var!", + "SUBTITLE_CONT_PRI_ROACHLETSGO1811": "^2Yzb. Price: ^7Roach - hadi gidelim.", + "SUBTITLE_CONT_CMT_2NDUAV1812": "^2Soap: ^7Anlaşıldı. İkinci Predator neredeyse yerini aldı. İşe yarasın, bu şeyler ağaçta yetişmiyor.", + "SUBTITLE_CONT_CMT_GROWONTREES1813": "^2MacTavish: ^7Anlaşıldı. İkinci İHA neredeyse pozisyonunu aldı. İşe yarasın, bu şeyler ağaçta yetişmiyor.", + "SUBTITLE_CONT_RST_CHECKFIRE191": "^2Ghost: ^7Ateşi kontrol edin! Ateşi kontrol edin! Dostlar 12'nizden geliyor!", + "SUBTITLE_CONT_RST_STANDBACK192": "^2Ghost: ^7Geri çekilin!", + "SUBTITLE_CONT_RST_GETBACK193": "^2Ghost: ^7Geri çekilin!", + "SUBTITLE_CONT_PRI_RASTAANDBRICKTOP194": "^2Yzb. Price: ^7Soap, Ghost ve ekibin geri kalanıyla bağlantı kurduk.", + "SUBTITLE_CONT_PRI_NICEWORK195": "^2Yzb. Price: ^7SAM sitesinde iyi iş çıkardınız.", + "SUBTITLE_CONT_RST_GETMOVING196": "^2Ghost: ^7Teşekkürler ama yola çıksak iyi olur - bu patlamalar çok dikkat çekecek.", + "SUBTITLE_CONT_PRI_GRABWEAPON197": "^2Yzb. Price: ^7Roach, burada olduğumuzu biliyorlar. Başka bir silah almak isteyebilirsin.", + "SUBTITLE_CONT_RST_HEADSUP198": "^2Ghost: ^7Dikkat, iki kamyon, kuzey doğumuzda 10'dan fazla adam var!", + "SUBTITLE_CONT_PRI_BELOWCRANE199": "^2Yzb. Price: ^7Denizaltı orada! Vincin hemen altında!", + "SUBTITLE_CONT_PRI_SOFTENDEFENSES1911": "^2Yzb. Price: ^7Roach, Predator ile savunmalarını yumuşat!", + "SUBTITLE_CONT_PRI_STROBES1911_1": "^2Yzb. Price: ^7Yanıp sönen flaşlara dikkat edin. Bu biziz.", + "SUBTITLE_CONT_CMT_GOTATTENTION201": "^2Soap: ^7Bu onların dikkatini çekti!", + "SUBTITLE_CONT_CMT_BASEONALERT202": "^2Soap: ^7Tüm üs alarmda!", + "SUBTITLE_CONT_CMT_BETTERHURRY203": "^2Soap: ^7Acele etseniz iyi olur. O denizaltı dalmadan önce sadece birkaç dakikanız var.", + "SUBTITLE_CONT_PRI_WEREMOVING204": "^2Yzb. Price: ^7Hareket ediyoruz!", + "SUBTITLE_CONT_PRI_ARMOREDVEHICLE205": "^2Yzb. Price: ^7O zırhlı aracı yok edin!", + "SUBTITLE_CONT_PRI_USEHELLFIRE207": "^2Yzb. Price: ^7O kamyonda bir Predator füzesi kullan!", + "SUBTITLE_CONT_PRI_TAKEOUTHELI208": "^2Yzb. Price: ^7Şu helikopteri indir!", + "SUBTITLE_CONT_PRI_GOINGFORSUB209": "^2Yzb. Price: ^7Denizaltıya gidiyorum!", + "SUBTITLE_CONT_CMT_HALWAYTHERE2010": "^2Soap: ^7Yolu yarıladın!", + "SUBTITLE_CONT_PRI_COVERME2011": "^2Yzb. Price: ^7Batı kapısının yanındaki nöbetçi kulübesinden beni koru!", + "SUBTITLE_CONT_CMT_90SECS2012": "^2Soap: ^790 saniye!", + "SUBTITLE_CONT_GST_ROGERTHAT2013": "^2Ghost: ^7Anlaşıldı!", + "SUBTITLE_CONT_CMT_60SECS2014": "^2Soap: ^760 saniye!", + "SUBTITLE_CONT_GST_GUARDHOUSE2015": "^2Ghost: ^7Roach, Price'ı korumak için batı kapısındaki nöbetçi kulübesine gitmeliyiz! Beni takip et!", + "SUBTITLE_CONT_CMT_30SECS2016": "^2Soap: ^730 saniye! Kımıldayın!", + "SUBTITLE_CONT_PRI_INSIDESUB2017": "^2Yzb. Price: ^7Pekâlâ, denizaltının içindeyim! Koru beni, birkaç dakikaya ihtiyacım var!", + "SUBTITLE_CONT_PRI_SUBWONTWAIT2018": "^2Yzb. Price: ^7Acele etmeliyiz! O denizaltı bizi beklemeyecek!", + "SUBTITLE_CONT_PRI_GOGOGO2019": "^2Yzb. Price: ^7Hadi, hadi, hadi!", + "SUBTITLE_CONT_GST_TWOTRUCKSEAST2020": "^2Ghost: ^7Geliyor! Doğuda iki kamyon var!", + "SUBTITLE_CONT_PRI_GETTOSUB2021": "^2Yzb. Price: ^7Denizaltıya gidin! Acele edin!", + "SUBTITLE_CONT_GST_MOREVEHICLESEAST2023": "^2Ghost: ^7Doğuda daha fazla araç var! İHA'yı kullanın!", + "SUBTITLE_CONT_PRI_REACHEDSUB2024": "^2Yzb. Price: ^7Soap, denizaltına ulaştık!", + "SUBTITLE_CONT_GST_NEXTTOSUB2025": "^2Ghost: ^7Kuzeyde, denizaltının yanındaki rıhtımda temas kurun!", + "SUBTITLE_CONT_GST_YOUTHERE211": "^2Ghost: ^7Price, orada mısın? Denizaltının silo kapıları açılıyor, tekrar ediyorum, denizaltının silo kapıları açılıyor!", + "SUBTITLE_CONT_CMT_ROGERTHAT2212": "^2Soap: ^7Anlaşıldı!", + "SUBTITLE_CONT_GST_COMEIN213": "^2Ghost: ^7Price, cevap ver! Denizaltının silo kapılarını açıyorlar! Acele edin!", + "SUBTITLE_CONT_GST_DOYOUCOPY214": "^2Ghost: ^7Price, duyuyor musun? Silo kapıları açık, tekrar ediyorum, silo kapıları açık!", + "SUBTITLE_CONT_CMT_AGMREADY262": "^2Soap: ^7AGM Füzesi hazır.", + "SUBTITLE_CONT_CMT_AGMONLINE264": "^2Soap: ^7AGM Füzesi çevrimiçi.", + "SUBTITLE_CONT_CMT_REPEATONLINE266": "^2Soap: ^7AGM Füzesi çevrimiçi. Tekrar ediyorum AGM Füzesi çevrimiçi.", + "SUBTITLE_CONT_CMT_AGMOFFLINE268": "^2Soap: ^7AGM'ler çevrimdışı.", + "SUBTITLE_CONT_CMT_REARMHELLFIRES2610": "^2Soap: ^7AGM'ler devreye alınıyor. Beklemede.", + "SUBTITLE_CONT_CMT_UAVDOWN2612": "^2Soap: ^7İHA desteği kapalı.", + "SUBTITLE_CONT_CMT_PREDATORDOWN2613": "^2Soap: ^7Predator insansız hava aracı çalışmıyor.", + "SUBTITLE_CONT_CMT_PREDATOROFFLINE2614": "^2Soap: ^7Predator insansız hava aracı çevrimdışı.", + "SUBTITLE_CONT_CMT_UAVOFFLINE2615": "^2Soap: ^7İHA çevrimdışı.", + "SUBTITLE_CONT_CMT_PREDATOROFFLINE22616": "^2Soap: ^7Predator drone çevrimdışı.", + "SUBTITLE_CONT_CMT_UAVOFFLINE22617": "^2Soap: ^7İHA çevrimdışı.", + "SUBTITLE_CONT_CMT_DIRECTHITSHELO2618": "^2Soap: ^7Düşman helikopteri doğrudan vuruldu. İyi atış Roach.", + "SUBTITLE_CONT_CMT_BTRDESTROYED2619": "^2Soap: ^7Hedef üzerinde iyi etki. BTR yok edildi.", + "SUBTITLE_CONT_CMT_DIRECTHITJEEP2620": "^2Soap: ^7Cip doğrudan vuruldu.", + "SUBTITLE_CONT_CMT_GOODKILLTRUCK2621": "^2Soap: ^7İyi öldürüş. Kamyon yok edildi.", + "SUBTITLE_CONT_CMT_GOODHITVEHICLES2622": "^2Soap: ^7İyi vuruş. Birden fazla araç yok edildi.", + "SUBTITLE_CONT_CMT_GOODEFFECTKIA2623": "^2Soap: ^7Hedef üzerinde iyi etki. Birden fazla düşman aracı öldürüldü.", + "SUBTITLE_CONT_CMT_FIVEPLUSKIAS2624": "^2Soap: ^7Beş artı ölü. İyi vuruş. İyi vuruş.", + "SUBTITLE_CONT_CMT_MUTLIPLECONFIRMED2625": "^2Soap: ^7Birden fazla ölüm teyit edildi. İyi işti.", + "SUBTITLE_CONT_CMT_3KILLS2626": "^2Soap: ^7İyi vuruş. En az üç öldürme gibi görünüyor.", + "SUBTITLE_CONT_CMT_THEYREDOWN2627": "^2Soap: ^7Düştüler.", + "SUBTITLE_CONT_CMT_DIRECTHIT2628": "^2Soap: ^7Doğrudan vuruş.", + "SUBTITLE_CONT_CMT_HESDOWN2629": "^2Soap: ^7Düştü.", + "SUBTITLE_112": "^2General Shepherd: ^7Her zaman.", + "SUBTITLE_113": "^2Yzb. Price: ^7Oldukça büyük bir yangınımız var. Büyük bir patlamaya ihtiyacımız olacak.", + "SUBTITLE_114": "^2Shepherd: ^7Gulag'da çok uzun süre kaldın Price. Makarov'u indirmeye odaklan.", + "SUBTITLE_115": "^2Yzb. Price: ^7Zaman yok, efendim. Bu savaşı bugün bitirmeliyiz.", + "SUBTITLE_116": "^2Shepherd: ^7Sana sormuyorum, Price. Bu bir emirdir. Sen -", + "SUBTITLE_117": "^2Yzb. Price: ^7Huh. Görünüşe göre bağlantımızı kaybettik...", + "SUBTITLE_DCEMP_AR2_LETSGO1321": "^2Ranger: ^7Hadi gidelim! Hadi gidelim!", + "SUBTITLE_DCEMP_AR3_HUSTLEUP1322": "^2Ranger: ^7Acele edin! Whiskey Otel'e gidin! Yürüyün!", + "SUBTITLE_DCEMP_AR3_THISWAY1323": "^2Ranger: ^7Hadi, gidelim millet! Bu taraftan!", + "SUBTITLE_DCEMP_AR3_MOVEMOVE1324": "^2Ranger: ^7Yürüyün! Yürüyün! Whiskey Otel'e gidin!", + "SUBTITLE_DCEMP_CPD_PARTYSTARTED141": "^2Çvş. Dunn: ^7Parti çoktan başlamış gibi görünüyor.", + "SUBTITLE_DCEMP_FLY_ROGERSTAYFROSTY142": "^2Çvş. Foley: ^7Anlaşıldı. Soğukkanlı kalın.", + "SUBTITLE_DCEMP_AR2_REPORTTOMARSHALL143": "^2Ranger: ^7Gelebildiğinize sevindim! Yukarıdaki Albay Marshall'a rapor verin! Gidin!", + "SUBTITLE_DCEMP_CML_MOREMEN151": "^2Albay Marshall: ^7Two-Forty Bravos ile vurmaya devam edin! Sol kanada daha fazla adam gönderin!", + "SUBTITLE_DCEMP_FLY_SITUATIONHERE152": "^2Çvş. Foley: ^7Efendim, burada durum nedir?", + "SUBTITLE_DCEMP_CML_HIGHGROUND153": "^2Albay Marshall: ^7Yüksek bir yere bakıyorsun Çavuş! Beyaz Saray'da hâlâ güç var!", + "SUBTITLE_DCEMP_CML_RETAKEIT154": "^2Albay Marshall: ^7Bu da demek oluyor ki, eğer orayı geri alabilirsek Merkez Komutanlığı ile konuşmak için hâlâ bir yolumuz var!", + "SUBTITLE_DCEMP_CML_GETYOURSQUAD155": "^2Albay Marshall: ^7Şimdi takımını sol kanada doğru hareket ettir! Hadi!", + "SUBTITLE_DCEMP_FLY_SQUADOSCARMIKE156": "^2Çvş. Foley: ^7Anlaşıldı! Manga! Gidelim! Biz Oscar Mike'ız!", + "SUBTITLE_DCEMP_FLY_WORKYOURWAYLEFT161": "^2Çvş. Foley: ^7Sola doğru ilerleyin!", + "SUBTITLE_DCEMP_FLY_RAMIREZGO162": "^2Çvş. Foley: ^7Ramirez, gidelim!", + "SUBTITLE_DCEMP_FLY_TAKELEFTFLANK163": "^2Çvş. Foley: ^7İlerleyin! Sol kanadı ele geçirmeliyiz!", + "SUBTITLE_DCEMP_FLY_PUNCHTHROUGH171": "^2Çvş. Foley: ^7Tam burayı delip geçmeliyiz!", + "SUBTITLE_DCEMP_FLY_MACHINEGUNS172": "^2Çvş. Foley: ^7Şu makineli tüfekleri çıkarın!", + "SUBTITLE_DCWHITE_FLY_DUNNGETDOOR173": "^2Çvş. Foley: ^7Dunn, kapıya bak!", + "SUBTITLE_DCWHITE_FLY_DUNN174": "^2Çvş. Foley: ^7Dunn!", + "SUBTITLE_DCWHITE_CPD_READINGTHIS175": "^2Çvş. Dunn: ^7Çavuş, bunu okuyor musun?!", + "SUBTITLE_DCWHITE_FLY_THATSWHY176": "^2Çvş. Foley: ^7Bu yüzden gitmeliyiz! Şimdi kapıyı aç!", + "SUBTITLE_DCEMP_CPD_TALKINGABOUT1811": "^2Çvş. Dunn: ^7İki dakika mı? Neden bahsediyor bu?", + "SUBTITLE_DCEMP_FLY_FLATTENTHECITY1812": "^2Çvş. Foley: ^7Şehri dümdüz etmeden önce iki dakikadan az vaktimiz var! Çatıya çıkıp onları durdurmalıyız!", + "SUBTITLE_DCEMP_FLY_LESSTHANTWOMINS1813": "^2Çvş. Foley: ^7İki dakikadan az vaktimiz var, gidelim!", + "SUBTITLE_DCEMP_FLY_90SECONDS192": "^2Çvş. Foley: ^790 saniye! Zorlamalıyız!", + "SUBTITLE_DCEMP_FLY_60SECONDS194": "^2Çvş. Foley: ^7Bir dakika! Hadi, hadi, hadi!", + "SUBTITLE_DCEMP_FLY_30SECONDS196": "^2Çvş. Foley: ^730 saniye! Hemen çatıya çıkmalıyız! Hadi! Hadi! Hadi! Hadi!", + "SUBTITLE_DCEMP_FLY_POPTHEFLARES197": "^2Çvş. Foley: ^7İşaret fişeklerini patlatın!", + "SUBTITLE_DCEMP_AR1_LETSGO198": "^2Ranger: ^7Temizleyin! Gidelim!", + "SUBTITLE_DCEMP_FLY_GETTOROOF199": "^2Çvş. Foley: ^7Çatıya çıkın! Yürüyün!", + "SUBTITLE_DCEMP_FLY_USEYOURFLARES1910": "^2Çvş. Foley: ^7İşaret fişeklerini kullan!", + "SUBTITLE_DCEMP_CPD_HAPPENSNOW211": "^2Çvş. Dunn: ^7Peki şimdi ne olacak?", + "SUBTITLE_DCEMP_FLY_WARAINTOVER212": "^2Çvş. Foley: ^7Bu savaş henüz bitmedi Onbaşı... Tek yaptığımız oyun alanını eşitlemekti.", + "SUBTITLE_DCEMP_FLY_BACKDOWNSTAIRS213": "^2Çvş. Foley: ^7Herkes aşağıya dönsün. Şu telsizdeki vericiyi çalıştırmayı deneyelim.", + "SUBTITLE_DCEMP_AR1_MOSCOW214": "^2Ranger: ^7Moskova'ya ne zaman gidiyoruz?", + "SUBTITLE_DCWHITE_CPD_BURNITDOWN215": "^2Çvş. Dunn: ^7Yeterince yakın değil, dostum. Ama oraya vardığımızda orayı yakıp yıkacağımızı biliyorum.", + "SUBTITLE_DCEMP_FLY_TIMEISRIGHT217": "^2Çvş. Foley: ^7Doğru zaman geldiğinde, Onbaşı. Zamanı geldiğinde.", + "SUBTITLE_DCBURN_MCY_OSCARMIKE92": "^2Çvş. Foley: ^7Anlaşıldı...İki-Bir Oscar Mike.", + "SUBTITLE_DCBURN_GR1_ONYOURFEET95": "^2Ranger: ^7Ayağa kalkın - biz Oscar Mike'ız!", + "SUBTITLE_DCBURN_MCY_TWOONEOUT96": "^2Çvş. Foley: ^7Anlaşıldı, İki-Bir Gerçek dışarı.", + "SUBTITLE_DCBURN_MCY_BUYTIME297": "^2Çvş. Foley: ^7Dinleyin! Bu tahliye alanı sert darbe alıyor ve onlara biraz zaman kazandırmalıyız! Hooah?", + "SUBTITLE_DCBURN_GM1_TAKECOVER111": "^2Ranger: ^7Geliyor! Siper alın!", + "SUBTITLE_DCBURN_GM2_JAVELINS12112": "^2Ranger: ^7Bazukalar! Saat 12 yönünde!", + "SUBTITLE_DCBURN_GM2_INCOMING113": "^2Ranger: ^7Geliyor!", + "SUBTITLE_DCBURN_CPD_STAYINTRENCH114": "^2Çvş. Dunn: ^7Ramirez! Siperde kal, kıçını havaya uçuracaklar!", + "SUBTITLE_DCBURN_CPD_STAYLOW115": "^2Çvş. Dunn: ^7Eğil! Siperlerden ayrılmayın!", + "SUBTITLE_DCBURN_CPD_BACKINTRENCH116": "^2Çvş. Dunn: ^7Kıçını siperlere geri sok!", + "SUBTITLE_DCBURN_CPD_WHEREGOING117": "^2Çvş. Dunn: ^7Ramirez, ne yapıyorsun? Siperlerden ayrılma!", + "SUBTITLE_DCBURN_MCY_MOVEUPGOGO118": "^2Çvş. Foley: ^7İlerleyin! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_DCBURN_MCY_MOVEIN119": "^2Çvş. Foley: ^7İlerleyin!", + "SUBTITLE_DCBURN_MCY_PUSHFORWARD1110": "^2Çvş. Foley: ^7İlerleyin! İlerleyin! Kımılda!", + "SUBTITLE_DCBURN_MCY_MOVEFORWARD1111": "^2Çvş. Foley: ^7İlerlemeye devam edin!", + "SUBTITLE_DCBURN_MCY_MOVEUP21112": "^2Çvş. Foley: ^7İlerleyin! İlerleyin!", + "SUBTITLE_DCBURN_HQR_ROGERTHAT1713": "^2Overlord: ^7Anlaşıldı, İki-Bir.", + "SUBTITLE_DCBURN_MCY_REQAIRSTRIKE121": "^2Çvş. Foley: ^7Overlord, burası Avcı İki-Bir. Hava saldırısı talep ediyorum, tamam!", + "SUBTITLE_DCBURN_HQR_ALONGPOTOMAC122": "^2Overlord: ^7Uh, negatif İki-Bir Gerçek, mevcut tüm hava birimleri şu anda Potomac boyunca çoklu casevac ile görevlendirildi. Batıya, hedef binaya doğru ilerleyin ve destek sağlayın, tamam.", + "SUBTITLE_DCBURN_MCY_BUYTIME123": "^2Çvş. Foley: ^7Herkes ilerlesin, ölüm bölgesinden çıkın! O casevac kuşları için biraz zaman kazanmalıyız!", + "SUBTITLE_DCBURN_MCY_GRENADELAUNCH124": "^2Çvş. Foley: ^7El bombası fırlatıcılarınızı kullanın!", + "SUBTITLE_DCBURN_MCY_HAULINGPASTUS131": "^2Çvş. Foley: ^7Overlord, İki-Bir Gerçek! Bitişik desteğimiz olmadan batıyı tarıyoruz ve BCT Bir'den dost galipler bizi geçiyorlar, tamam!", + "SUBTITLE_DCBURN_HQR_LATVEE132": "^2Overlord: ^7Anlaşıldı. Birinci Tugay Muharebe Timi bastırma sağlamak için bir LAV çıkardı bile, tamam.", + "SUBTITLE_DCBURN_MCY_COPYTHAT133": "^2Çvş. Foley: ^7Anlaşıldı!", + "SUBTITLE_DCBURN_MCY_FIRELOW134": "^2Çvş. Foley: ^7Ateşinizi alçak tutun... oraya dostlarımız giriyor.", + "SUBTITLE_DCBURN_CPD_FOOTMOBILES135": "^2Çvş. Dunn: ^7Ayak hareketleri görüyorum... Saat 12 yönünde, 100 metre!", + "SUBTITLE_DCBURN_MCY_LATVEESUPP141": "^2Çvş. Foley: ^7Tamamdır! BCT 1'in LAV'ı onları bastırdı! İşaretimle harekete geçmeye hazır olun!", + "SUBTITLE_DCBURN_MCY_READY142": "^2Çvş. Foley: ^7Hazır....!", + "SUBTITLE_DCBURN_MCY_GOMOVEUP143": "^2Çvş. Foley: ^7Hadi, hadi, hadi! İlerleyin! İlerleyin!", + "SUBTITLE_DCBURN_MCY_LINEOFFIRE144": "^2Çvş. Foley: ^7Ramirez! İlerleyin ve LAV'ın ateş hattından uzak durun!", + "SUBTITLE_DCBURN_MCY_MOVEMOVE145": "^2Çvş. Foley: ^7Çekilin! Çekilin!", + "SUBTITLE_DCBURN_MCY_50CALSUPP146": "^2Çvş. Foley: ^7Ramirez! LAV onları bastırdı! İçeri girin! İçeri girin!", + "SUBTITLE_DCBURN_MCY_SITTINGDUCKS147": "^2Çvş. Foley: ^7İt, it, it! Burada keklik gibi oturuyoruz!", + "SUBTITLE_DCBURN_MCY_BLOWNOFF148": "^2Çvş. Foley: ^7Ramirez! Kıçını havaya uçurmadan önce ölüm bölgesinden çık! İlerleyin!", + "SUBTITLE_DCBURN_MCY_MOVEUP149": "^2Çvş. Foley: ^7Ramirez! İlerleyin, ölüm bölgesinden çıkın!", + "SUBTITLE_DCBURN_MCY_INTOTARGBUILDING1410": "^2Çvş. Foley: ^7Ramirez! Kıçını ölüm bölgesinden çıkar ve hedef binaya gir, hemen!", + "SUBTITLE_DCBURN_HQR_LINKUP151": "^2Overlord: ^7Avcı İki-Bir, ben Overlord. SEAL timleri hedef binanın kuzeybatı köşesinde manevra yapıyor. En üst katta onlarla bağlantı kurun ve düşman ateş timlerini ortadan kaldırın, tamam.", + "SUBTITLE_DCBURN_MCY_SOLIDCOPYONALL152": "^2Çvş. Foley: ^7Anlaşıldı, tamam.", + "SUBTITLE_DCBURN_MCY_DROPONTHEM153": "^2Çvş. Foley: ^7Hadi onları yakalayalım... Ramirez, kalp atışı sensörünü çalıştır.", + "SUBTITLE_DCBURN_MCY_HITEMFAST154": "^2Çvş. Foley: ^7Gözün kalp atışı sensöründe olsun Ramirez. Onlara hızlı ve sert vurmak istiyorum.", + "SUBTITLE_DCBURN_MCY_UPPERFLOORS161": "^2Çvş. Foley: ^7Overlord, burası Two-One Actual, haberiniz olsun, içerideyiz ve üst katlara doğru ilerliyoruz.", + "SUBTITLE_DCBURN_HQR_COPIESALL162": "^2Overlord: ^7Anlaşıldı, Overlord hepsini kopyalıyor.", + "SUBTITLE_DCBURN_MCY_WHATSEEING_R171": "^2Çvş. Foley: ^7Haydut İki-Üç, burası İki-Bir-Aktüel. Sorgulama - bulunduğunuz konumdan ne görüyorsunuz?", + "SUBTITLE_DCBURN_GM5_LZHEAVYFIRE172": "^2Ranger: ^7LZ hâlâ hedef binadan yoğun ateş alıyor, mola - üst katlarda RPG ekipleri görüyorum ve güneybatı köşesinden orta kalibreli ateş geliyor.", + "SUBTITLE_DCBURN_MCY_SOLIDCOPY173": "^2Çvş. Foley: ^7Anlaşıldı, İki-Bir tamam.", + "SUBTITLE_DCBURN_MCY_WATCHSECTORS175": "^2Çvş. Foley: ^7Sektörlerinize dikkat edin.", + "SUBTITLE_DCBURN_MCY_CHECKCORNERS176": "^2Çvş. Foley: ^7Köşeleri kontrol edin.", + "SUBTITLE_DCBURN_MCY_FIVEALPHA177": "^2Çvş. Foley: ^7Rpg takımı elendi, bölüm beş-alfa.", + "SUBTITLE_DCBURN_MCY_FIVEBRAVO179": "^2Çvş. Foley: ^7Düşman ateş timi bastırıldı, bölüm beş-bravo.", + "SUBTITLE_DCBURN_MCY_FIVECHARLIE1710": "^2Çvş. Foley: ^7Düşman ateş timi bastırıldı, bölüm beş-charlie.", + "SUBTITLE_DCBURN_MCY_FIVEECHO1711": "^2Çvş. Foley: ^7Düşman RPG ekibi vuruldu, bölüm beş-eko.", + "SUBTITLE_DCBURN_MCY_FIVEINDIA1712": "^2Çvş. Foley: ^7Düşman ateş timi vuruldu, bölüm 5-Hindistan.", + "SUBTITLE_DCBURN_HQR_COPYTHAT1714": "^2Overlord: ^7Anlaşıldı, İki-Bir.", + "SUBTITLE_DCBURN_HQR_SOLIDCOPY1715": "^2Overlord: ^7Anlaşıldı, İki-Bir.", + "SUBTITLE_DCBURN_HQR_PROCEEDSWCORNER1716": "^2Overlord: ^7Overlord hepsini kopyalıyor. İki-Bir, güneybatı köşesine ilerle", + "SUBTITLE_DCBURN_MCY_FIRETEAMSUPP191": "^2Çvş. Foley: ^7Ateş takımı Bölüm Bir-Alfa'da bastırıldı.", + "SUBTITLE_DCBURN_MCY_MEZZANINE192": "^2Çvş. Foley: ^7Overlord, burası Avcı İki-Bir Gerçek. Asma kata ilerliyoruz. BCT Bir'den LAV'a ateş etmemelerini söyle, tamam.", + "SUBTITLE_DCBURN_HQR_GOODHUNTING193": "^2Overlord: ^7Anlaşıldı, İki-Bir, iyi avlar.", + "SUBTITLE_DCBURN_MCY_HOSTSUPP194": "^2Çvş. Foley: ^7Bölüm İki-Echo'daki düşmanlar bastırıldı.", + "SUBTITLE_DCBURN_HQR_SWCORN5TH196": "^2Overlord: ^7Avcı İki-Bir'in dikkatine, beşinci katın güneybatı köşesindeki düşmanlar tahliye bölgesini dövüyorlar, tamam.", + "SUBTITLE_DCBURN_MCY_OMTO5TH197": "^2Çvş. Foley: ^7Anlaşıldı Overlord. Oscar Mike beşinci katta. Tamam.", + "SUBTITLE_DCBURN_MCY_FIRETEAMELIM198": "^2Çvş. Foley: ^7Düşman ateş timi Bölüm 4-Charlie'de etkisiz hâle getirildi.", + "SUBTITLE_DCBURN_MCY_SWCORNER199": "^2Çvş. Foley: ^7Overlord, beşinci kattayız, güneybatı köşesine doğru ilerliyoruz.", + "SUBTITLE_DCBURN_CPD_GOTMVMNT1911": "^2Çvş. Dunn: ^7Hareket var.", + "SUBTITLE_DCBURN_MCY_STANDBYENG1912": "^2Çvş. Foley: ^7Çatışmaya hazır olun.", + "SUBTITLE_DCBURN_MCY_CLAYMORES1913": "^2Çvş. Foley: ^7Düşman mayınları... adımınıza dikkat edin.", + "SUBTITLE_DCBURN_MCY_VISCROWSNEST211": "^2Çvş. Foley: ^7Tüm Avcı birimleri, düşmanın güneybatı köşesindeki karga yuvasını gördüm. İlerleyin ve orayı temizleyin.", + "SUBTITLE_DCBURN_MCY_SECCROWSNEST212": "^2Çvş. Foley: ^7Komutanım, burası Avcı İki-Bir Gerçek. Güneybatı köşesindeki düşman karga yuvasını ele geçirdik.", + "SUBTITLE_DCBURN_HQR_STILLVULN213": "^2Overlord: ^7Overlord hepsini duyuyor. Washington Anıtı'ndaki tahliye alanı birkaç nakliye aracının uzaklaştığını bildiriyor, ancak hâlâ savunmasızlar. Konumunuzdan destek sağlayabilir misiniz, tamam?", + "SUBTITLE_DCBURN_MCY_STOCKPILE214": "^2Çvş. Foley: ^7Anlaşıldı! Düşman mühimmat stokunun üzerinde oturuyoruz! Kazacağız ve cephânelerini yakacağız! Dışarı!", + "SUBTITLE_DCBURN_MCY_SNIPERRIFLE221": "^2Çvş. Foley: ^7Ramirez, keskin nişancı tüfeğini al! Washington Anıtı'nın güneyindeki hedefleri tara!", + "SUBTITLE_DCBURN_MCY_COVEROURBACKS222": "^2Çvş. Foley: ^7Diğer herkes, varsa kapının dışına birkaç mayın yerleştirsin... arkamızı kollamamız gerek!", + "SUBTITLE_DCBURN_MCY_SCANFORTARGETS223": "^2Çvş. Foley: ^7Ramirez, Washington Anıtı'nın güneyindeki hedefleri tara!", + "SUBTITLE_DCBURN_CPD_PLANTINGCLAYMORES224": "^2Çvş. Dunn: ^7Kil mayınları yerleştiriliyor!", + "SUBTITLE_DCBURN_EVC_ALLCALLSIGNS225": "^2Tahliye Alanı: ^7Bu ağdaki tüm çağrı işaretleri, batıdan ağır ateş altında olduğumuzu bilmenizi isteriz. Düşman piyade ve topçu gözcüleri, konumumuzun batısında olduğumuzu doğruladı.", + "SUBTITLE_DCBURN_MCY_WW2MEM226": "^2Çvş. Foley: ^7Tahliye bölgesine Javelin roketleri atan ayaklı araçlar var! Ramirez, Barrett'a bin ve onları indir!", + "SUBTITLE_DCBURN_MCY_GETONBARRETT227": "^2Çvş. Foley: ^7Washington Anıtı tahliye alanı hâlâ ateş altında. Barrett'a bin ve onları dışarı çıkar!", + "SUBTITLE_DCBURN_MCY_GETONRIFLE228": "^2Çvş. Foley: ^7Ramirez - kıçını keskin nişancı tüfeğine koy. Hadi!", + "SUBTITLE_DCBURN_MCY_TARGETENEMY229": "^2Çvş. Foley: ^7Tahliye alanı hâlâ yoğun ateş altında! Ramirez - Javelin roketlerini ateşleyen tüm düşman yaya araçlarını hedef al!", + "SUBTITLE_DCBURN_MCY_TARGETINFANTRY2210": "^2Çvş. Foley: ^7Ramirez! Düşman piyadelerini hedef alın! İndirin onları!", + "SUBTITLE_DCBURN_MCY_BEFOREOVERRUN2211": "^2Çvş. Foley: ^7Ramirez, buraya gel! İstila edilmeden önce tahliye bölgesine destek sağlamalıyız!", + "SUBTITLE_DCBURN_MCY_COVEREVACSITE2212": "^2Çvş. Foley: ^7Hangi cehenneme gidiyorsun? Washington Anıtı'ndaki tahliye alanını korumamız gerekiyor!", + "SUBTITLE_DCBURN_MCY_RETURNTOPOST2213": "^2Çvş. Foley: ^7Ramirez, görev yerine dön! Tahliye bölgesini korumalıyız!", + "SUBTITLE_DCBURN_EVC_GLASSEDENEMIESWEST2214": "^2Tahliye Alanı: ^7Bu ağdaki tüm çağrı işaretleri, burası Washington Anıtı Tahliye Bölgesi! Kendimizi koruyoruz ancak batıda düşmanlar var ve o yönden ateş alıyoruz!", + "SUBTITLE_DCBURN_EVC_ENGAGEALLTARGETSWEST2215": "^2 Tahliye Bölgesi: ^7Washington Anıtı'nın batısındaki tüm düşman hedeflerine saldırmanızı talep ediyorum! Tekrar ediyorum - Washington Anıtı'nın batısındaki tüm düşman hedeflerini vurmanızı talep ediyorum, tamam!", + "SUBTITLE_DCBURN_EVC_ALLSNIPERS2216": "^2Tahliye Alanı: ^7Tüm keskin nişancılar, düşman ateşi sivillerin tahliyesini engelliyor! Anıtın batısındaki düşman hedeflerine ek keskin nişancı ateşi talep ediyorum, tamam!", + "SUBTITLE_DCBURN_EVC_80PERCENTEFFECTIVE2217": "^2Tahliye Alanı: ^7Washington Anıtı'nda ateş altındayız! Savaş etkinliğimiz %80'e düştü! Anıtın batısındaki hedeflere acil keskin nişancı ateşi talep ediyoruz, tamam!", + "SUBTITLE_DCBURN_EVC_ENEMYAIRCRAFT2218": "^2Tahliye Alanı: ^7Burası Washington Anıtı tahliye bölgesi! Düşman zırhlıları ve uçakları tarafından yoğun ateş altındayız! Savaş etkinliğimiz %80'e düştü!", + "SUBTITLE_DCBURN_EVC_FORCEINDETAIL2219": "^2Tahliye Bölgesi: ^7Tüm çağrı işaretlerinin dikkatine, batıdaki düşmanlar Washington Anıtı tahliye bölgesine ayrıntılı bir saldırı girişiminde bulunuyor!", + "SUBTITLE_DCBURN_EVC_ANYUNITS2220": "^2Tahliye Alanı: ^7Haberiniz olsun, düşman kuvvetleri Washington Anıtı tahliye bölgesine saldırıyor! Bölgedeki tüm birimlerden destek istiyoruz, tamam!", + "SUBTITLE_DCBURN_EVC_MAJORCASUALTIES2221": "^2Tahliye Alanı: ^7Askerî ve sivil büyük kayıplar veriyoruz! Anıtın batısındaki hedeflere saldırmanızı talep ediyoruz! Tamam!", + "SUBTITLE_DCBURN_EVC_60PERCENTEFFECTVIE2222": "^2Tahliye Bölgesi: ^7Tüm çağrı işaretleri, tahliye bölgesinde yoğun ateş altındayız ve araç ve zırh kaybediyoruz! Savaş etkinliğimiz %60'a düştü! Tamam!", + "SUBTITLE_DCBURN_EVC_CANTTAKEMUCHMORE2223": "^2Tahliye Alanı: ^7Washington Anıtı tahliye bölgesinden tüm çağrı işaretlerine! Batıdan gelen düşman ateşi pozisyonumuzu yok etmekle tehdit ediyor! Buna daha fazla dayanamayız!", + "SUBTITLE_DCBURN_EVC_DESTROYPOSITION2224": "^2Tahliye Alanı: ^7Washington Anıtı tahliye bölgesinden tüm çağrı işaretlerine! Düşman ateşi pozisyonumuzu yok etmekle tehdit ediyor! Buna daha fazla dayanamayız!", + "SUBTITLE_DCBURN_EVC_50PERCENTEFFECTIVE2225": "^2Tahliye Alanı: ^7Washington Anıtı tahliye bölgesi yoğun ateş altında! Savaş etkinliğimiz %50'ye düştü! Daha fazla ateş desteği almalıyız yoksa bu tahliye alanı düşecek! Tamam!", + "SUBTITLE_DCBURN_EVC_AIRCRAFT502226": "^2Tahliye Alanı: ^7Washington Anıtı tahliye alanı düşman zırhlıları ve uçakları tarafından yoğun ateş altında! Savaş etkinliğimiz %50'ye düştü!", + "SUBTITLE_DCBURN_EVC_CIVVIESOUTTAHERE2227": "^2Tahliye Alanı: ^7Tüm çağrı işaretleri, burası Washington Anıtı tahliye bölgesi! Dikkatli olun, durumumuz kritik! Buna daha fazla dayanamayız! Bu sivilleri buradan çıkarmak için daha fazla zamana ihtiyacımız var!", + "SUBTITLE_DCBURN_EVC_STATUSISCRIT2228": "^2Tahliye Alanı: ^7Tüm çağrı işaretleri, burası Washington Anıtı tahliye bölgesi! Durumumuz kritik, hâlâ düşman zırhlılarından ve uçaklarından ateş altındayız, lütfen yardım edin!", + "SUBTITLE_DCBURN_EVC_30PERCENTEFFECTIVE2229": "^2Tahliye Bölgesi: ^7Tahliye bölgesinde ağır kayıplar veriyoruz! Savaş etkinliği yüzde 30'da! Daha fazla hasara dayanamayız!", + "SUBTITLE_DCBURN_EVC_VERGEOFOVERRUN2230": "^2Tahliye Alanı: ^7Tüm çağrı işaretlerinin dikkatine, tahliye alanını savunmak için silahlanan siviller var ama tamamen eğitimsizler! İstila edilmenin eşiğindeyiz! Hemen yardıma ihtiyacımız var!", + "SUBTITLE_DCBURN_EVC_10PERCENTEFFECTIVE2231": "^2Tahliye Alanı: ^7Burası Whiskey Mike tahliye bölgesi! Savaş personelinin çoğu öldü! Savaş etkinliğimiz %10'un altında! Ek ateş desteği talep ediyoruz, tamam!", + "SUBTITLE_DCBURN_EVC_BYATHREAD2232": "^2Tahliye Bölgesi: ^7Whiskey Mike tahliye bölgesinden tüm çağrı işaretlerine! Düşman hızla mevzimize yaklaşıyor! Burada pamuk ipliğine bağlıyız, tamam!", + "SUBTITLE_DCBURN_EVC_COMBATINEFFECTIVE2233": "^2Tahliye Alanı: ^7Tüm çağrı işaretleri uyarılsın! Whiskey Mike tahliye bölgesi savaş etkisiz! Tamamen sıkıştık, her an gelebilirler!", + "SUBTITLE_DCBURN_EVC_LOSTCIVVIES2234": "^2Tahliye Alanı: ^7Düşman birlikleri tahliye alanının içinde! Tekrar ediyorum, düşman birlikleri tahliye alanının içinde! Sivilleri kaybettik! Hayır!", + "SUBTITLE_DCBURN_HQR_STAYFROSTY231": "^2Overlord: ^7Avcı İki-Bir'in dikkatine, düşman yaya birlikleri bulunduğunuz yere yaklaşıyor... soğukkanlı olun.", + "SUBTITLE_DCBURN_CPD_INPERIMETER232": "^2Çvş. Dunn: ^7Çevrede düşmanlar var! Ateş açın! Ateş açın!", + "SUBTITLE_DCBURN_CPD_HOSTATSIX233": "^2Çvş. Dunn: ^7Gözler yukarı! Düşmanlar altımızda!", + "SUBTITLE_DCBURN_CPD_TAKINGFIRE234": "^2Çvş. Dunn: ^7Ateş ediliyor! Ateş ediliyor! Çevrede yaya mobilleri var!", + "SUBTITLE_DCBURN_HQR_CLEAROUT241": "^2Overlord: ^7Avcı İki-Bir, oradan uzaklaşmanızı tavsiye ederim... Pozisyonunuza yaklaşan bir yaya mobil kitlesi görüyorum...", + "SUBTITLE_DCBURN_MCY_NEGATIVE242": "^2Çvş. Foley: ^7Negatif negatif! Güney ve güneybatıdan tahliye bölgesine ilerleyen düşman zırhlıları ve helikopterleri görüyorum!", + "SUBTITLE_DCBURN_MCY_WHATWECAN243": "^2Çvş. Foley: ^7Onlara daha fazla zaman kazandırmak için elimizden geleni yapacağız! Dışarı!", + "SUBTITLE_DCBURN_MCY_LISTENUP251": "^2Çvş. Foley: ^7Manga, dinleyin! Biz, tekrar ediyorum - biz o casevac'ları terk etmiyoruz, hooah?", + "SUBTITLE_DCBURN_HOH_2252": "^2Korucular: ^7Hooah!", + "SUBTITLE_DCBURN_MCY_HEAVYORD255": "^2Çvş. Foley: ^7Ramirez! Biraz ağır mühimmat bul ve zırhlıları ve helikopterleri indir... yerdeki adamlarımıza dışarı çıkmaları için zaman vermeliyiz.", + "SUBTITLE_DCBURN_MCY_HEAVYWEAP256": "^2Çvş. Foley: ^7Ramirez! Birkaç ağır silah bul ve zırhlıları ve düşman havasını yok et. Acele edin!", + "SUBTITLE_DCBURN_MCY_WHATEVERYOUFIND257": "^2Çvş. Foley: ^7Bulabildiğiniz düşman mühimmatını kullanın ve o helikopterleri ve zırhlıları yok edin. Yürüyün!", + "SUBTITLE_DCBURN_MCY_USEORDNANCE258": "^2Çvş. Foley: ^7Ramirez, bu mühimmatın bir kısmını düşman araçlarını yok etmek için kullan! Yürüyün!", + "SUBTITLE_DCBURN_MCY_GRABAJAVELIN259": "^2Çvş. Foley: ^7Bir Javelin kap ve o araçları yok et!", + "SUBTITLE_DCBURN_MCY_TAKEOUTVEH261": "^2Çvş. Foley: ^7Tahliye alanı istila ediliyor! Düşman araçlarını yok edin!", + "SUBTITLE_DCBURN_MCY_HEAVYFIRE262": "^2Çvş. Foley: ^7Ramirez! Şu araçları halledin! Tahliye alanı yoğun ateş altında!", + "SUBTITLE_DCBURN_MCY_CLOSINGIN263": "^2Çvş. Foley: ^7Düşman araçları yaklaşıyor! İndirin onları!", + "SUBTITLE_DCBURN_HQR_ROOFASAP271": "^2Overlord: ^7Avcı İki-Bir, tahliye bölgesine değerli bir zaman kazandırdın! Aferin sana! Şimdi hemen çatıya çıkın... İstila edilme tehlikesiyle karşı karşıyasınız!", + "SUBTITLE_DCBURN_MCY_ROOFTOP272": "^2Çvş. Foley: ^7Anlaşıldı, çatıya çıkıyoruz! Herkes dışarı çıksın!", + "SUBTITLE_DCBURN_MCY_CRAWLIN273": "^2Çvş. Foley: ^7Devam edin! Bu bölge düşman kaynıyor olacak! Hemen gitmeliyiz!", + "SUBTITLE_DCBURN_MCY_NOTIME274": "^2Çvş. Foley: ^7Zamanımız yok! Devam edin!", + "SUBTITLE_DCBURN_MCY_KEEPMOVING275": "^2Çvş. Foley: ^7Devam etmeliyiz! Yürü! Yürü! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_DCBURN_MCY_OVERRUN276": "^2Çvş. Foley: ^7İstila ediliyoruz! Yürüyün! Yürüyün! Yürüyün! Yürüyün! Yürüyün! Yürüyün!", + "SUBTITLE_DCBURN_MCY_OUTOFTIMEGO277": "^2Çvş. Foley: ^7Zamanımız tükeniyor! Hadi!", + "SUBTITLE_DCBURN_MCY_RVWITHSEALS278": "^2Çvş. Foley: ^7Çatıya çıkın ve SEAL Ekibi ile karavana gidin! Hadi! Yürüyün! Yürüyün!", + "SUBTITLE_DCBURN_MCY_OUTNUMBERED279": "^2Çvş. Foley: ^7Sayıca azız - bir an önce çatıya çıkmalıyız! Hadi! Hadi! Hadi! Hadi! Hadi! Hadi!", + "SUBTITLE_DCBURN_MCY_GETTOROOFNOW2710": "^2Çvş. Foley: ^7Ramirez! Kaldır kıçını! Hemen çatıya çıkmalıyız!", + "SUBTITLE_DCBURN_MCY_OVERRUNNINGPOS2711": "^2Çvş. Foley: ^7Ramirez, gidelim! Düşmanlar burayı ele geçiriyor!", + "SUBTITLE_DCBURN_MCY_LETSMOVEOUT2712": "^2Çvş. Foley: ^7Ramirez! Gidelim!", + "SUBTITLE_DCBURN_MCY_UPTHESTAIRSGO2713": "^2Çvş. Foley: ^7Ramirez! Merdivenlerden yukarı! Gidelim!", + "SUBTITLE_DCBURN_MCY_WAITALLDAY2714": "^2Çvş. Foley: ^7Ramirez! Hemen merdivenlerden çatıya çık... Tahliye helikopterlerimiz bütün gün beklemeyecek!", + "SUBTITLE_DCBURN_MCY_GETTINGOVERRUN2715": "^2Çvş. Foley: ^7İstila ediliyoruz! Herkes çatıya! Hemen!", + "SUBTITLE_DCBURN_BHP_WHATSYOURSTATUS2716": "^2Hançer İki-Bir: ^7Hunter, ben Hançer İki-Bir. Çatıdaki LZ'de yerimizi aldık, durumunuz nedir?", + "SUBTITLE_DCBURN_MCY_HOSTILESCLOSE2717": "^2Çvş. Foley: ^7Yoldayız! Düşmanlar yakın takipte!", + "SUBTITLE_DCBURN_MCY_GETINCHOPPER2718": "^2Çvş. Foley: ^7Ramirez! Helikoptere binin!", + "SUBTITLE_DCBURN_MCY_WAYOUTNUMBERED2719": "^2Çvş. Foley: ^7Ramirez! Sayımız çok az! Helikoptere binin! Hadi!", + "SUBTITLE_DCBURN_MCY_FORGETABOUTIT2720": "^2Çvş. Foley: ^7Ramirez! Unutun onu! Gemide bir minigun var! Helikoptere binin! Gidelim!", + "SUBTITLE_DCBURN_MCY_BRASSONTITANIC2721": "^2Çvş. Foley: ^7Ramirez! Titanik'te pirinç parlatıyorsun! Minigun'a bin, gidelim!", + "SUBTITLE_DCBURN_MCY_SPINHERUP2722": "^2Çvş. Foley: ^7Ramirez, döndür onu ve bırak gitsin!", + "SUBTITLE_DCBURN_MCY_BUNKEREVAC281": "^2Çvş. Foley: ^7Overlord, çatıdaki SEAL'larla bağlantı kurduk ve dışarı çıkıyoruz. Sorgulama - Washington Anıtı bölgesi boşaltıldı mı, tamam?", + "SUBTITLE_DCBURN_HQR_STILLPINNED282": "^2Overlord: ^7Negatif İki-Bir, hâlâ İkinci Dünya Savaşı Anıtı'ndaki piyade ve hafif zırhlılar tarafından sıkıştırılmış durumdalar. Buradan iyi görünmüyor, tamam!", + "SUBTITLE_DCBURN_MCY_FROMTHEAIR283": "^2Çvş. Foley: ^7Anlaşıldı Overlord, havadan elimizden geleni yapacağız, tamam.", + "SUBTITLE_DCBURN_CPD_CLOSINGIN284": "^2Çvş. Dunn: ^7Düşmanlar yaklaşıyor!", + "SUBTITLE_DCBURN_MCY_GETONMINIGUN285": "^2Çvş. Foley: ^7Ramirez, minigun'a bin!", + "SUBTITLE_DCBURN_MCY_MOVEMINIGUN286": "^2Çvş. Foley: ^7Hareket etmeliyiz! Ramirez, minigun'a bin!", + "SUBTITLE_DCBURN_MCY_HITGOINGDOWN287": "^2Çvş. Foley: ^7Overlord, Hançer İki-İki vuruldu ve düşüyor!", + "SUBTITLE_DCBURN_MCY_PERMISSION291": "^2Çvş. Foley: ^7Burası Avcı İki-Bir Gerçek! Birden fazla düşman galip ve ayak mobilleri görüyoruz.... çatışmaya girmek için izin istiyoruz, tamam!", + "SUBTITLE_DCBURN_HQR_CLEAREDHOT292": "^2Overlord: ^7Karar senin, İki-Bir. Outlaw sığınaklarda sıkıştırıldı. MSR boyunca temizlendiniz, tamam.", + "SUBTITLE_DCBURN_MCY_ONEWAYTRIP293": "^2Çvş. Foley: ^7Manga, Outlaw'a kaçması için zaman kazandırmak için tüm düşman hedeflerine saldırıyoruz! Bu tek yönlü bir yolculuk olabilir! Hooah?", + "SUBTITLE_DCBURN_CPD_LEADTHEWAY294": "^2Çvş. Dunn: ^7Hooah. Korucular önden!", + "SUBTITLE_DCBURN_MCY_ALLTHEWAY295": "^2Çvş. Foley: ^7Sonuna kadar.", + "SUBTITLE_DCBURN_SLL_WITHYOU296": "^2SEAL Takım Lideri: ^7Seninleyiz, İki-Bir. Hadi yapalım şu işi.", + "SUBTITLE_DCBURN_LBP1_CLEAREDHOT301": "^2Hançer İki-Bir: ^7Ramirez, aşağıda piyadelerimiz ve hafif zırhlılarımız var. Sıcaktan temizlendin.", + "SUBTITLE_DCBURN_LBP1_GUNSHIPLIFTINGOFF302": "^2Hançer İki-Bir: ^7Düşman savaş gemisi saat 12 yönünde havalanıyor, Savaş Anıtı.", + "SUBTITLE_DCBURN_LBP1_ARMORROLLINGIN303": "^2Hançer İki-Bir: ^7Hafif zırhlılar geliyor.", + "SUBTITLE_DCBURN_LBP1_FOOTMOBILES304": "^2Hançer İki-Bir: ^7Ayak mobilleri... onları dışarı çıkarın.", + "SUBTITLE_DCBURN_BHP_DONTGETUP305": "^2Dagger Two-One: ^7İkinci Dünya Savaşı anıtındaki RPG ekipleri... kalkmayana kadar tetiği çekin.", + "SUBTITLE_DCBURN_EVC_MAINROAD306": "^2Tahliye Alanı: ^7Hançer İki, Washington Anıtı ana yoldan ateş alıyor!", + "SUBTITLE_DCBURN_LBP1_WEREONIT307": "^2Hançer İki-Bir: ^7Anlaşıldı, ilgileniyoruz.", + "SUBTITLE_DCBURN_LBP1_TAKENHEATOFF308": "^2Hançer İki-Bir: ^7Overlord, ben Hançer İki-Bir. Tahliye bölgesinin üzerindeki baskıyı biraz azalttık -", + "SUBTITLE_DCBURN_LBP1_BREAKLEFTBREAKLEFT309": "^2Hançer İki-Bir: ^7Hançer İki, FÜZE fırlat! Sola kır, sola kır!", + "SUBTITLE_DCBURN_BHP_INCOMING3010": "^2Hançer İki-Bir: ^7Geliyor! Geliyor!", + "SUBTITLE_DCBURN_LBP1_22AND23AREDOWN3011": "^2Hançer İki-Bir: ^7Overlord, Hançer İki-İki ve İki-Üç düştü. Tekrar ediyorum, Hançer İki-İki ve İki-Üç düştü, tamam.", + "SUBTITLE_DCBURN_MCY_STILLINTHEAIR3012": "^2Çvş. Foley: ^7Overlord, vurulduk ama hâlâ havadayız. Adalet Bakanlığı'nda büyük bir FÜZE bataryamız var... içeri giriyoruz!", + "SUBTITLE_DCBURN_BHP_RPGTEAMS3013": "^2Dagger Two-One: ^7RPG ekipleri! Saat 12 yönünde!", + "SUBTITLE_DCBURN_BHP_ATTITUDECONTROL3014": "^2Dagger Two-One: ^7Tutum kontrolünü kaybediyoruz!", + "SUBTITLE_DCBURN_MCY_TAKEUSUP3015": "^2Çvş. Foley: ^7Bizi yukarı çıkar! Eğer düşeceksek o FÜZE alanlarını da yanımızda götürürüz!", + "SUBTITLE_DCBURN_BHP_FIRETEAMS3016": "^2Dagger Two-One: ^7Birden fazla ateş ekibi tespit edildi!", + "SUBTITLE_DCBURN_LBP1_SAMLAUNCH3017": "^2Hançer İki-Bir: ^7FÜZE fırlatıldı! Dayanın!", + "SUBTITLE_DCBURN_LBP1_MAYDAYMAYDAY3018": "^2Hançer İki-Bir: ^7Vurulduk! Mayday mayday, burası Hançer İki-Bir. Papa Bravo, 2. kareye iniyoruz.", + "SUBTITLE_DCBURN_LBP1_BRACEFORIMPACT3019": "^2Hançer İki-Bir: ^7Çarpışmaya hazır olun!", + "SUBTITLE_DCBURN_GR1_HANGON341": "^2Er Wade: ^7Bunu al ve yerde kal!", + "SUBTITLE_DCBURN_MCY_LASTONE343": "^2Çvş. Foley: ^7Ramirez! Son şarjör! Saydır!", + "SUBTITLE_DCBURN_CPD_LASTMAG344": "^2Çvş. Dunn: ^7Foley, son şarjör!", + "SUBTITLE_DCBURN_CPD_IMOUT345": "^2Çvş. Dunn: ^7Ben yokum!", + "SUBTITLE_DCBURN_CPD_TOOMANY346": "^2Çvş. Dunn: ^7Onlardan çok fazla var!", + "SUBTITLE_DCBURN_MCY_DEFENDTHISPOS347": "^2Çvş. Foley: ^7Bu pozisyonu koruyun!", + "SUBTITLE_DCBURN_MCY_GETDOWN348": "^2Çvş. Foley: ^7Yere yatın!", + "SUBTITLE_DCEMP_ISS_REQUESTFEED01": "^2ISS Kontrol: ^7Cevap ver Sat1. Burası ISS Kontrol. Houston kask kameranızdan bir görüntü istiyor, tamam.", + "SUBTITLE_DCEMP_ISS_THEYWANTYOU02": "^2UUİ Kontrol: ^7Dünyanın karanlık tarafına doğru bakmanızı istiyorlar. Sancak tarafındaki PV dizilerinin yaklaşık 15 derece doğusunda ufukta tepe yapıyor olmalı.", + "SUBTITLE_DCEMP_ISS_ROTATEVIEW03": "^2UUİ Kontrol: ^7Sat1, görüşünü biraz daha sağa çevirir misin?", + "SUBTITLE_DCEMP_ISS_THEREITIS04": "^2UUİ Kontrol: ^7İşte orada, Sat1'den yayın alıyoruz. Houston'a gel, bunu alıyor musun?", + "SUBTITLE_DCEMP_HSC_COPYTHAT05": "^2Houston Komutanlığı: ^7Anlaşıldı ISS, Sat1'den gelen video beslemesi temiz.", + "SUBTITLE_DCEMP_HSC_KEEPTRACKING06": "^2Houston Komutanlığı: ^7Sat1, öcüyü izlemeye devam et. Araştırıyoruz, beklemedeyiz.", + "SUBTITLE_DCEMP_ISS_NOTSCHEDULED07": "^2UUİ Kontrol: ^7Houston, bugün herhangi bir uydu fırlatma planımız yok, değil mi?", + "SUBTITLE_DCEMP_HSC_STANDBY08": "^2Houston Komutanlığı: ^7ISS, Houston. Beklemede kalın. Burada bir sorunumuz olabilir.", + "SUBTITLE_DCEMP_ISS_ANYWORD012": "^2UUİ Kontrol: ^7Houston, burası ISS Kontrol, uh....", + "SUBTITLE_DCEMP_CPD_WHATSGOINON11": "^2Çvş. Dunn: ^7Neler oluyor?", + "SUBTITLE_DCEMP_FLY_SEEKSHELTER12": "^2Çvş. Foley: ^7Hemen sokaktan çıkın! Gidin!", + "SUBTITLE_DCEMP_CPD_NOTGOOD13": "^2Çvş. Dunn: ^7Bu hiç iyi değil, dostum!", + "SUBTITLE_DCEMP_FLY_GOGOGO14": "^2Çvş. Foley: ^7Hadi, hadi, hadi!", + "SUBTITLE_DCEMP_FLY_DONTSTOP15": "^2Çvş. Foley: ^7Durmayın! Devam edin!", + "SUBTITLE_DCEMP_CPD_WHOA16": "^2Çvş. Dunn: ^7Whoa!", + "SUBTITLE_DCEMP_CPD_EMP17": "^2Çvş. Dunn: ^7EMP!", + "SUBTITLE_DCEMP_CPD_HOLY17": "^2Çvş. Dunn: ^7Lanet olsun!", + "SUBTITLE_DCEMP_FLY_GOGO19": "^2Çvş. Foley: ^7Gidin! Yürü! Yürü!", + "SUBTITLE_DCEMP_AR1_WHATSGOINON110": "^2Ranger: ^7Ne haltlar dönüyor?!", + "SUBTITLE_DCEMP_FLY_JUSTKEEPMOVIN111": "^2Çvş. Foley: ^7Devam edin!", + "SUBTITLE_DCEMP_CPD_LOOKOUT112": "^2Çvş. Dunn: ^7Dikkat et!", + "SUBTITLE_DCEMP_CPD_WEARETOTALLY21": "^2Çvş. Dunn: ^7Şimdi ne halt edeceğiz, dostum? Ruslar sayıca üstün, gökten bok yağıyor. Boku yedik dostum! Biz tamamen -", + "SUBTITLE_DCEMP_FLY_GETAGRIP22": "^2Çvş. Foley: ^7Kapa çeneni! Kendine gel Onbaşı! Silahlarımız hâlâ çalışıyor, bu da hâlâ kıç tekmeleyebileceğimiz anlamına geliyor, hooah?", + "SUBTITLE_DCEMP_AR1_HUAH24": "^2Ranger: ^7Hooah.", + "SUBTITLE_DCEMP_AR1_WHATWASTHAT31": "^2Ranger: ^7Bu da neydi böyle?!", + "SUBTITLE_DCEMP_FLY_STAYHERE32": "^2Çvş. Foley: ^7Burada kal.", + "SUBTITLE_DCEMP_CPD_YOUNUTS33": "^2Çvş. Dunn: ^7Oraya mı gidiyorsun? Delirdin mi sen?", + "SUBTITLE_DCEMP_FLY_WARTOFIGHT34": "^2Çvş. Foley: ^7Bitti artık! Hadi, hâlâ savaşmamız gereken bir savaş var.", + "SUBTITLE_DCEMP_AR1_THISISWEIRD41": "^2Ranger: ^7Burada ne oldu böyle?", + "SUBTITLE_DCEMP_CPD_SOQUIET42": "^2Çvş. Dunn: ^7Oh, adamım çok sessiz.", + "SUBTITLE_DCEMP_CPD_HEYWHATTHE43": "^2Çvş. Dunn: ^7kırmızı optik'in çalışıyor mu? Benimki çalışmıyor.", + "SUBTITLE_DCEMP_AR1_MINEDOWNTOO44": "^2Ranger: ^7Benimki de çalışmıyor. Bu çok garip, kardeşim.", + "SUBTITLE_DCEMP_FLY_EMPBLAST45": "^2Çvş. Foley: ^7Görünüşe göre optikler çalışmıyor... iletişim de. Bloklar boyunca sokak lambası bile yok.", + "SUBTITLE_DCEMP_CPD_SAVEDOURBUTTS46": "^2Çvş. Dunn: ^7Evet, belki de yukarıdakilerden biri gidip bir çift büyüdü. Kıçımızı kurtardı, orası kesin.", + "SUBTITLE_DCEMP_CPD_CHECKITOUT47": "^2Çvş. Dunn: ^7Vay canına... Şuna bak dostum.", + "SUBTITLE_DCEMP_CPD_FINDIRONSITE48": "^2Çvş. Dunn: ^7Bana demir dürbünlü bir tüfek bulmalıyım. Bu kırmızı noktalar beş para etmez.", + "SUBTITLE_DCEMP_AR1_FINDIRONSITE49": "^2Ranger: ^7Bunu söyleyeceğim hiç aklıma gelmezdi ama keşke demir dürbünlü bir tüfeğim olsaydı. Bu kırmızı noktalar beş para etmez.", + "SUBTITLE_DCEMP_FLY_DAMMIT51": "^2Çvş. Foley: ^7Kahretsin.", + "SUBTITLE_DCEMP_FLY_REGROUP52": "^2Çvş. Foley: ^7Pekâlâ. Dışarıda kalanlarla yeniden toplanmalıyız. Onbaşı Dunn, yerinizi alın.", + "SUBTITLE_DCEMP_CPD_STAR61": "^2Çvş. Dunn: ^7Yıldız!", + "SUBTITLE_DCEMP_CPD_WILLFIRE62": "^2Çvş. Dunn: ^7Yıldız, yoksa sana ateş edeceğiz!", + "SUBTITLE_DCEMP_AR3_DONTSHOOT63": "^2Ranger: ^7Lanet olası karşı işareti hatırlamıyorum, tamam mı? Ben sadece bir koşucuyum! Ateş etmeyin!", + "SUBTITLE_DCEMP_FLY_PROPERRESPONSE64": "^2Çvş. Foley: ^7Doğru cevap 'Teksas', asker. Neyin var?", + "SUBTITLE_DCEMP_AR3_WHISKEYHOTEL65": "^2Ranger: ^7Albay Marshall Whiskey Otel'de bir özel tim topluyor. Kuzeye gitmeye devam etmelisiniz.", + "SUBTITLE_DCEMP_CPD_WHEREGOIN66": "^2Çvş. Dunn: ^7Peki nereye gidiyorsunuz?", + "SUBTITLE_DCEMP_AR3_EVERYONEELSE67": "^2Ranger: ^7Herkese söylemeye! Whiskey Otel'e gidin! Gidin!", + "SUBTITLE_DCEMP_FLY_HEARDTHEMAN68": "^2Çvş. Foley: ^7Adamı duydunuz, gidelim.", + "SUBTITLE_DCEMP_FLY_DUNNYOUREUP71": "^2Çvş. Foley: ^7Dunn, sıra sende.", + "SUBTITLE_DCEMP_CPD_CLEAR72": "^2Çvş. Dunn: ^7Temiz.", + "SUBTITLE_DCEMP_AR2_GOTOURSIX73": "^2Ranger: ^7Altı adamımız var.", + "SUBTITLE_DCEMP_FLY_COPYTHAT74": "^2Çvş. Foley: ^7Anlaşıldı.", + "SUBTITLE_DCEMP_AR3_STAR75": "^2Ranger: ^7Yıldız!", + "SUBTITLE_DCEMP_CPD_SONOFA76": "^2Çvş. Dunn: ^7Adi herif....", + "SUBTITLE_DCEMP_FLY_CONTACT77": "^2Çvş. Foley: ^7Temas!", + "SUBTITLE_DCEMP_CPD_CONACT78": "^2Çvş. Dunn: ^7Temas!", + "SUBTITLE_DCEMP_FLY_FLASHBANGOUT79": "^2Çvş. Foley: ^7Flaş bombası!", + "SUBTITLE_DCEMP_CPD_HUAAH710": "^2Çvş. Dunn: ^7Öldüler, değil mi?!", + "SUBTITLE_DCEMP_AR2_CLEAR711": "^2Ranger: ^7Temiz!", + "SUBTITLE_DCEMP_FLY_ROOMCLEAR712": "^2Çvş. Foley: ^7Oda temiz! Gidelim!", + "SUBTITLE_DCEMP_FLY_OLDEXECBUILDING81": "^2Çvş. Foley: ^7İşte Eisenhower Binası. Whiskey Oteli diğer tarafta.", + "SUBTITLE_DCEMP_CPD_GOTTAGOOUT82": "^2Çvş. Dunn: ^7Ah dostum, oraya gitmeliyiz...", + "SUBTITLE_DCEMP_FLY_CHECKVITALS91": "^2Çvş. Foley: ^7Dunn. Hayati fonksiyonları kontrol et, seni koruyacağız.", + "SUBTITLE_DCEMP_CPD_GONNER92": "^2Çvş. Dunn: ^7Gidici.", + "SUBTITLE_DCEMP_FLY_KEEPQUIET101": "^2Çvş. Foley: ^7Sessiz olun...", + "SUBTITLE_DCEMP_AR2_GOTAVISUAL1015": "^2Ranger: ^7Üç tangoyu gördüm.", + "SUBTITLE_DCEMP_FLY_MOVEINTOPOS1016": "^2Çvş. Foley: ^7Alçakta kalın, pozisyon alın.", + "SUBTITLE_DCEMP_AR2_CLEARSHOT1017": "^2Ranger: ^7Temiz atış.", + "SUBTITLE_DCEMP_FLY_SMOKEEM1018": "^2Çvş. Foley: ^7Dumanla onları.", + "SUBTITLE_DCEMP_FLY_MOVEUP111": "^2Çvş. Foley: ^7İlerleyin.", + "SUBTITLE_DCEMP_CPD_WHATABOUT112": "^2Çvş. Dunn: ^7İçerideki adamlar ne olacak?", + "SUBTITLE_DCEMP_FLY_WHATABOUTEM113": "^2Çvş. Foley: ^7Ne olmuş onlara?", + "SUBTITLE_DCEMP_AR2_GOTOURSIXGO114": "^2Ranger: ^7Altı adamımız var, gidin.", + "SUBTITLE_DCEMP_CPD_ITSCLEAR115": "^2Çvş. Dunn: ^7Temiz.", + "SUBTITLE_DCEMP_CPD_FREEZINGMONSOON121": "^2Çvş. Dunn: ^7Hangisi daha kötü bilmiyorum dostum, düşen helikopterlerden kaçmak mı yoksa bu muson yağmurunda kıçımın donması mı?", + "SUBTITLE_DCEMP_FLY_QUIETSEESOMETHING123": "^2Çvş. Foley: ^7Sessiz ol. Sanırım bir şey görüyorum.", + "SUBTITLE_DCEMP_FLY_HOLDYOURFIRE124": "^2Çvş. Foley: ^7Ateş etmeyin.", + "SUBTITLE_DCEMP_CPD_ARETHEYFRIENDLY125": "^2Çvş. Dunn: ^7Dostlar mı?", + "SUBTITLE_DCEMP_FLY_DONTKNOWSTAR126": "^2Çvş. Foley: ^7Bilmiyorum... Star!", + "SUBTITLE_DCEMP_FLY_COVERME127": "^2Çvş. Foley: ^7Koru beni.", + "SUBTITLE_DCEMP_FLY_STAAAR128": "^2Çvş. Foley: ^7Yıldız!", + "SUBTITLE_DCEMP_CPD_SAYTEXAS129": "^2Çvş. Dunn: ^7Teksas de, lanet olsun...sadece söyle.", + "SUBTITLE_DCEMP_AR2_STREETCLEAR1210": "^2Ranger: ^7Sokak temiz!", + "SUBTITLE_DCEMP_FLY_OSCARMIKE1211": "^2Çvş. Foley: ^7Biz Oscar Mike'ız. Hadi gidelim!", + "SUBTITLE_DCEMP_FLY_WATCHMOVEMENT1212": "^2Çvş. Foley: ^7Harekete dikkat edin.", + "SUBTITLE_DCEMP_AR1_FEETDRY1315": "^2Ranger: ^7Ayaklar kuru.", + "SUBTITLE_DCEMP_FLY_CUTCHATTER1317": "^2Çvş. Foley: ^7Gevezeliği kes. Ramirez, yerini al.", + "SUBTITLE_DCEMP_CPD_WESTWING1318": "^2Çvş. Dunn: ^7Şu kapıdaki mühre bakın... Başkan'ın sığınağının Batı Kanadı'nın altında olduğunu sanıyordum.", + "SUBTITLE_DCEMP_FLY_FORTOURISTS1319": "^2Çvş. Foley: ^7Hayır, o sadece turistler için. Bu gerçek olmalı. Açın şunu.", + "SUBTITLE_DCEMP_CPD_PLACEISHISTORY1320": "^2Çvş. Dunn: ^7Gerçek ya da değil dostum, burası tarih oldu. Umarım zamanında çıkmışlardır.", + "SUBTITLE_EST_GST_LETSGOLETSGO15": "^2Ghost: ^7Gidelim, gidelim!", + "SUBTITLE_EST_GST_AMBUSH21": "^2Ghost: ^7Pusu!", + "SUBTITLE_EST_GST_TARGETSLEFTSIDE24": "^2Ghost: ^7Hedefler! Sol taraf! Sol taraf!", + "SUBTITLE_EST_GST_MOREONRIGHT25": "^2Ghost: ^7Sağ tarafta daha fazlası var!", + "SUBTITLE_EST_SCR_PRESIGHTED26": "^2Scarecrow: ^7Bu bölgeyi havan ateşi için hazırlamışlar!", + "SUBTITLE_EST_GST_COUNTERATTACK27": "^2Ghost: ^7Dumana doğru karşı saldırı! İtin, itin, itin!", + "SUBTITLE_EST_GST_LOSEEMINSMOKE28": "^2Ghost: ^7Roach! Bir havan topu tarafından vurulacaksın! Onları dumanın içinde kaybet! Hadi, hadi, hadi!", + "SUBTITLE_EST_GST_HOSTCHOPPER31": "^2Ghost: ^7Düşman helikopteri güneyde!", + "SUBTITLE_EST_SNP1_TRUCKSLEAVING32": "^2Archer: ^7Hedef binadan ayrılan iki kamyon var!", + "SUBTITLE_EST_GST_TRUCKSGETAWAY33": "^2Ghost: ^7O kamyonların kaçmasına izin vermeyin!", + "SUBTITLE_EST_GST_BULLETPROOFED34": "^2Ghost: ^7Lanet olsun, bu kamyonlar kurşun geçirmez!", + "SUBTITLE_EST_GST_UPARMORED35": "^2Ghost: ^7Lanet olsun, bu kamyonlar zırhlı!", + "SUBTITLE_EST_SNP1_FIRINGJAVELIN36": "^2Archer: ^7Anlaşıldı! Roket ateşleniyor, tehlike yakın!", + "SUBTITLE_EST_GST_DANGERCLOSE37": "^2Ghost: ^7Bazuka, tehlike yakın! Yoldan geri çekilin!", + "SUBTITLE_EST_SNP1_TWOAWAY38": "^2Archer: ^7İki kişi uzakta!", + "SUBTITLE_EST_SNP1_NEUTRALIZED39": "^2Archer: ^7Hareketli araçlar etkisiz hâle getirildi.", + "SUBTITLE_EST_SNP1_DECOYS41": "^2Archer: ^7Bilginiz olsun, Makarov'u görmedik, tekrar ediyorum, görmedik ve evden başka kimse de çıkmadı. O kamyonlar tuzak olabilir. Tamam.", + "SUBTITLE_EST_GST_ADVANCINGONHOUSE42": "^2Ghost: ^7Anlaşıldı, şimdi eve doğru ilerliyoruz!", + "SUBTITLE_EST_GST_CLEARPERIMIETER43": "^2Ghost: ^7Çevreyi temizleyin!", + "SUBTITLE_EST_GST_BREACHNCLEAR44": "^2Ghost: ^7Güvenli eve girin ve temizleyin! Gidin! Gidin!", + "SUBTITLE_EST_SCR_MAINFLOOR51": "^2Scarecrow: ^7Ana kat temiz!", + "SUBTITLE_EST_GST_MAINFLOOR52": "^2Ghost: ^7Anlaşıldı, ana kat temiz!", + "SUBTITLE_EST_SCR_BASEMENT53": "^2Scarecrow: ^7Bodrum temiz!", + "SUBTITLE_EST_GST_BASEMENT54": "^2Ghost: ^7Anlaşıldı, bodrum temiz!", + "SUBTITLE_EST_SCR_TOPFLOOR55": "^2Scarecrow: ^7Üst kat temiz!", + "SUBTITLE_EST_GST_TOPFLOOR56": "^2Ghost: ^7Anlaşıldı, üst kat temiz!", + "SUBTITLE_EST_GST_OFFICECLEAR57": "^2Ghost: ^7Ofis temiz!", + "SUBTITLE_EST_GST_DININGROOMCLR58": "^2Ghost: ^7Yemek odası temiz!", + "SUBTITLE_EST_GST_CLEAR59": "^2Ghost: ^7Temiz!", + "SUBTITLE_EST_GST_LOCKEDROOMS511": "^2Ghost: ^7Roach, yukarı çık ve en üst kattaki kilitli odaları kontrol et. Kır ve temizle.", + "SUBTITLE_EST_SCR_GETUPSTAIRS512": "^2Scarecrow: ^7Bu bölgeyi kontrol altına aldım Roach. Yukarı çık ve en üst kattaki odaları kontrol et.", + "SUBTITLE_EST_GST_SITREP513": "^2Ghost: ^7Scarecrow, bana bir durum raporu ver.", + "SUBTITLE_EST_SCR_NOONESLEAVING514": "^2Scarecrow: ^7Kimse bodrumun önünden çıkmıyor.", + "SUBTITLE_EST_GST_CHECKBASEMENT515": "^2Ghost: ^7Roach, Korkuluk'la git ve bodrumda düşman hareketliliği olup olmadığını kontrol et. Gir ve temizle. Git.", + "SUBTITLE_EST_GST_THRUKITCHEN516": "^2Ghost: ^7Ozon, kimsenin mutfaktan çıkmadığından emin ol.", + "SUBTITLE_EST_OZN_ROGERTHAT517": "^2Ozone: ^7Anlaşıldı.", + "SUBTITLE_EST_SCR_GOTYOURBACK518": "^2Scarecrow: ^7Arkandayım, Roach.", + "SUBTITLE_EST_GST_REGROUP61": "^2Ghost: ^7Her yer temiz. Manga, benim için yeniden toplanın.", + "SUBTITLE_EST_GST_PHOTOS62": "^2Ghost: ^7Scarecrow, fotoğraflar.", + "SUBTITLE_EST_SCR_ROGERTHAT63": "^2Scarecrow: ^7Anlaşıldı.", + "SUBTITLE_EST_GST_NOSIGN64": "^2Ghost: ^7Shepherd, ben Ghost. Makarov'dan iz yok, tekrar ediyorum, Makarov'dan iz yok. Yüzbaşı Price, Afganistan'da şansınız yaver gitti mi?", + "SUBTITLE_EST_PRI_ATLEAST5066": "^2Yzb. Price: ^7Çok... burada en az elli kiralık silah var, ama Makarov'dan iz yok. Belki de istihbaratımız yanlıştı.", + "SUBTITLE_EST_GST_GOLDMINE67": "^2Ghost: ^7İstihbaratın kalitesi değişmek üzere. Bu güvenli ev tam bir altın madeni.", + "SUBTITLE_EST_SHP_EVERYTHING68": "^2Shepherd: ^7Anlaşıldı. Ghost, ekibin bir operasyon kitabı için toplayabildiğin her şeyi toplasın. İsimler, kişiler, yerler, her şey.", + "SUBTITLE_EST_GST_ALREADYONIT69": "^2Ghost: ^7Zaten üzerinde çalışıyoruz efendim. Makarov'un kaçacak yeri yok.", + "SUBTITLE_EST_SHP_ETA5MINS610": "^2Shepherd: ^7Fikir bu. Kurtarma ekibini getiriyorum, E.T.A. beş dakika. İstihbaratı al. Shepherd tamam.", + "SUBTITLE_EST_GST_STARTTRANSFER611": "^2Ghost: ^7Roach, Makarov'un bilgisayarına gir ve transferi başlat.", + "SUBTITLE_EST_GST_TAPINTONETWORK612": "^2Ghost: ^7Roach, Makarov'un ağına gir ve transferi başlat.", + "SUBTITLE_EST_GST_FILESOFF613": "^2Ghost: ^7Roach - DSM'yi Makarov'un bilgisayarına bağla.", + "SUBTITLE_EST_GST_CONNECTTONETWORK614": "^2Ghost: ^7Roach - DSM'yi Makarov'un ağına bağlayın.", + "SUBTITLE_EST_GST_REARSECURITY615": "^2Ghost: ^7Ozon, sen arka güvenliktesin. Ön taraf benim. Git.", + "SUBTITLE_EST_OZN_ONMYWAY616": "^2Ozone: ^7Yola çıkıyorum.", + "SUBTITLE_EST_GST_STARTDOWNLOAD617": "^2Ghost: ^7Roach, o dosyalar olmadan gitmiyoruz. Aktarımı başlat.", + "SUBTITLE_EST_SCR_VERYFUNNY618": "^2Scarecrow: ^7Çok komik Roach.", + "SUBTITLE_EST_PRI_SEARCHING619": "^2Yzb. Price: ^7Görev Gücü, ben Price. Makarov'un daha fazla adamı az önce mezarlığa geldi...", + "SUBTITLE_EST_PRI_GETTINGCLOSER620": "^2Yzb. Price: ^7Soap, beni koru. Şuradaki adamı yakalayacağım ve telsizini kullanarak onların iletişimine gireceğim.", + "SUBTITLE_EST_PRI_GOINGSILENT621": "^2Yzb. Price: ^7Ghost, birkaç dakikalığına sessizliğe bürünüyoruz. Rusya'da iyi şanslar. Price tamam.", + "SUBTITLE_EST_SNP1_MAINROAD71": "^2Archer: ^7Keskin Nişancı Ekibi Bir'den saldırı ekibine, kuzeybatı ve güneydoğudan yaklaşan düşman helikopterleri var, dikkatli olun.", + "SUBTITLE_EST_SNP1_60SECONDS72": "^2Archer: ^7En fazla 60 saniyemiz var, tamam.", + "SUBTITLE_EST_GST_WITHINTEL73": "^2Ghost: ^7Makarov'un adamları bu istihbaratla gitmemizi engellemek için ne gerekiyorsa yapacaklar. Transfer tamamlanana kadar DSM'yi korumalıyız.", + "SUBTITLE_EST_GST_WEAPONSCACHE74": "^2Ghost: ^7Silah zulalarını kullanın ve eğer kaldıysa mayınlarınızı yerleştirin. Savunma pozisyonları, gidelim!", + "SUBTITLE_EST_SNP1_15SECONDS75": "^2Archer: ^7Düşman helikopterleri 15 saniye içinde.", + "SUBTITLE_EST_GST_15SECONDS76": "^2Ghost: ^7Anlaşıldı, 15 saniye!", + "SUBTITLE_EST_SCR_INPOSITION77": "^2Scarecrow: ^7Yerimi aldım!", + "SUBTITLE_EST_OZN_READYENGAGE78": "^2Ozone: ^7Saldırıya hazırım!", + "SUBTITLE_EST_OZN_STOCKUP81": "^2Ozone: ^7Roach, bodrumda bir cephânelik var. Yapabiliyorken stok yapsan iyi olur.", + "SUBTITLE_EST_SNP1_FASTATTACK92": "^2Archer: ^7Düşman hızlı saldırı helikopterleri kuzeybatıdan geliyor.", + "SUBTITLE_EST_GST_HELOSNW93": "^2Ghost: ^7Anlaşıldı. Düşman helikopterleri kuzeybatıdan yaklaşıyor.", + "SUBTITLE_EST_SCR_FRONTLAWN94": "^2Scarecrow: ^7Ön bahçeyi korumalıyız!", + "SUBTITLE_EST_OZN_MAINWINDOWS95": "^2Ozone: ^7Ana pencerelere doğru ilerliyorum, birisinin benimkini çıkarması ve araba yolunu kapatması gerekiyor.", + "SUBTITLE_EST_GST_USECLAYMORES96": "^2Ghost: ^7Roach, mayınlarını garaj yolunda kullan ve eve doğru geri çekil!", + "SUBTITLE_EST_SNP1_MOVING109": "^2Archer: ^7Farklı bir görüş noktasına geçiyorum. Keskin nişancı desteği kırk beş saniye boyunca kullanılamayacak, beklemede kalın.", + "SUBTITLE_EST_SNP1_DISPLACING1010": "^2Archer: ^7Yer değiştiriyorum. Otuz saniye boyunca keskin nişancı desteğinden yoksun olacaksın, beklemede kal.", + "SUBTITLE_EST_SNP1_ADDITIONALHOSTILE111": "^2Archer: ^7Konumunuza doğru ilerleyen ilave düşman kuvvetleri görüyorum. Evin doğusundaki güneş panellerinden yaklaşıyorlar.", + "SUBTITLE_EST_GST_SOLARPANELSEAST112": "^2Ghost: ^7Evin doğusundaki güneş panellerinden içeri giriyorlar!", + "SUBTITLE_EST_SCR_COMETHRUTREES113": "^2Scarecrow: ^7Anlaşıldı, ağaçların arasından gelirken önlerini kesmeye çalışacağım.", + "SUBTITLE_EST_GST_EASTTRAIL114": "^2Ghost: ^7Varsa mayınlarınızı kullanın. Onları evin doğusundaki patikanın etrafına yerleştirin.", + "SUBTITLE_EST_SNP1_TROOPSWEST121": "^2Archer: ^7Evin batısına daha fazla asker bırakıyorlar!", + "SUBTITLE_EST_GST_BOATHOUSE122": "^2Ghost: ^7Kayıkhanenin yanında olmalılar! Batı yaklaşımını koruyun!", + "SUBTITLE_EST_OZN_249SANDRPGS123": "^2Ozone: ^7Yemek odası penceresinde 240'lar ve RPG'ler, ayrıca L86 makineli tüfekler var.", + "SUBTITLE_EST_GST_CUTEMDOWN124": "^2Ghost: ^7Anlaşıldı, ağaçların arasından çıktıklarında onları kesmek için kullanın!", + "SUBTITLE_EST_SNP1_BOATHOUSEWEST125": "^2Archer: ^7Kayıkhaneden batıya doğru yaklaşan düşmanlar var, tamam.", + "SUBTITLE_EST_GST_WESTSIDEOFHOUSE126": "^2Ghost: ^7Anlaşıldı, düşmanlar evin batı tarafından yaklaşıyor!", + "SUBTITLE_EST_SNP1_RPGTEAMNORTH141": "^2Archer: ^7Roketatar takımı kuzeye!", + "SUBTITLE_EST_GST_RPGTEAMNORTH142": "^2Ghost: ^7Anlaşıldı, RPG ekibi kuzeye!", + "SUBTITLE_EST_SNP1_RPGTEAMNE143": "^2Archer: ^7Roketatar takımı kuzeydoğudan yaklaşıyor!", + "SUBTITLE_EST_SCR_RPGTEAMNE144": "^2Scarecrow: ^7Manga! Roketatar takımı kuzeydoğudan yaklaşıyor!", + "SUBTITLE_EST_SNP1_RPGTEAMEAST145": "^2Archer: ^7Roketatar takımı doğudan yaklaşıyor!", + "SUBTITLE_EST_OZN_RPGTEAMEAST146": "^2Ozone: ^7Anlaşıldı, RPG takımı doğudan yaklaşıyor!", + "SUBTITLE_EST_SNP1_RPGTEAMSE147": "^2Archer: ^7Roketatar takımı güneydoğuya!", + "SUBTITLE_EST_GST_RPGTEAMSE148": "^2Ghost: ^7Anlaşıldı, RPG ekibi güneydoğuya!", + "SUBTITLE_EST_SNP1_RPGTEAMSOUTH149": "^2Archer: ^7Roketatar takımı güneyden yaklaşıyor!", + "SUBTITLE_EST_SCR_RPGTEAMSOUTH1410": "^2Scarecrow: ^7Anlaşıldı, RPG ekibi güneyden yaklaşıyor!", + "SUBTITLE_EST_SNP1_RPGTEAMSW1411": "^2Archer: ^7Roketatar takımı güneybatıdan geliyor!", + "SUBTITLE_EST_OZN_RPGTEAMSW1412": "^2Ozone: ^7Tamamdır! Roketatar takımı güneybatıdan yaklaşıyor!", + "SUBTITLE_EST_SNP1_RPGTEAMWEST1413": "^2Archer: ^7Roketatar timi batıdan yaklaşıyor!", + "SUBTITLE_EST_GST_RPGTEAMWEST1414": "^2Ghost: ^7Anlaşıldı! RPG ekibi batıdan yaklaşıyor!", + "SUBTITLE_EST_SNP1_RPGTEAMNW1415": "^2Archer: ^7Roket takımı, kuzeybatı!", + "SUBTITLE_EST_GST_RPGTEAMNW1416": "^2Ghost: ^7Manga! Kuzeybatıda bir RPG ekibimiz var!", + "SUBTITLE_EST_GST_STAYCLOSE151": "^2Ghost: ^7Roach! Eve yakın durun!", + "SUBTITLE_EST_GST_DONTSTRAY152": "^2Ghost: ^7Roach! Güvenli evden fazla uzaklaşmayın! Transferi korumamız gerek!", + "SUBTITLE_EST_GST_FALLBACK153": "^2Ghost: ^7Roach, hangi cehennemdesin?! Eve geri dönün! Çekilin!", + "SUBTITLE_EST_GST_TRYINGTOSTOP154": "^2Ghost: ^7Roach, güvenli eve geri çekil! Transferi durdurmaya çalışıyorlar!", + "SUBTITLE_EST_GST_LOSTTHEDSM155": "^2Ghost: ^7Burada onlardan çok fazla var! Roach! DSM'yi kaybettik, tekrar ediyorum kaybettik-", + "SUBTITLE_EST_GST_DESTROYEDTHEDSM156": "^2Ghost: ^7Roach! DSM'yi yok ettiler! Yok ettiler-", + "SUBTITLE_EST_SCR_WHATWASTHAT161": "^2Scarecrow: ^7Bu da neydi böyle?", + "SUBTITLE_EST_SNP1_HOSTILESSE162": "^2Archer: ^7Dikkatli olun, güneydoğudan gelen büyük bir düşman yoğunluğunuz var, az önce çevreyi aştılar!", + "SUBTITLE_EST_SNP1_THINEMOUT163": "^2Archer: ^7Çok yaklaşmadan önce onları seyreltmeye çalışacağım. Dürbünlü silahlara geçmenizi tavsiye ederim, tamam.", + "SUBTITLE_EST_GST_FIELDTOSE164": "^2Ghost: ^7Anlaşıldı! Herkes güneydoğudaki alanı korusun! Kımıldayın!", + "SUBTITLE_EST_OZN_EYESON165": "^2Ozone: ^7Gözüm üzerlerinde! İşte geliyorlar! Güneydoğudaki tarladalar!", + "SUBTITLE_EST_OZN_IMHIT171": "^2Ozone: ^7Vuruldum!", + "SUBTITLE_EST_SNP1_OZONEISDOWN172": "^2Archer: ^7Ozon düştü!", + "SUBTITLE_EST_SCR_IMHIT173": "^2Scarecrow: ^7Vuruldum!", + "SUBTITLE_EST_SNP1_SCARECROWDOWN174": "^2Archer: ^7Scarecrow düştü, tekrar ediyorum Korkuluk düştü!", + "SUBTITLE_EST_SCR_INSIDETHEHOUSE181": "^2Scarecrow: ^7Dikkatli olun, evin içinde hareket ediyorlar! Yardıma ihtiyacım var!", + "SUBTITLE_EST_SCR_NEEDSOMEHELP182": "^2Scarecrow: ^7Evin içindeler! Burada yardıma ihtiyacım var!", + "SUBTITLE_EST_SNP1_FIFTYMETERS183": "^2Archer: ^7Düşmanlar evin 50 metre yakınına kadar yaklaştı! İçerideler!", + "SUBTITLE_EST_GST_PROTECTTHEDSM184": "^2Ghost: ^7Anlaşıldı! Herkes geri çekilsin ve DSM'yi korusun!", + "SUBTITLE_EST_SNP1_CLEARFORNOW185": "^2Archer: ^7Tamam, şimdilik temizsiniz, eve çok yakın kimseyi görmüyorum.", + "SUBTITLE_EST_SCR_ONTHEWAY191": "^2Scarecrow: ^7Geliyorum!", + "SUBTITLE_EST_SCR_OSCARMIKE192": "^2Scarecrow: ^7Anlaşıldı, Oscar Mike!", + "SUBTITLE_EST_OZN_MOVING193": "^2Ozone: ^7Hareketli!", + "SUBTITLE_EST_OZN_IMONIT194": "^2Ozone: ^7Hallediyorum!", + "SUBTITLE_EST_SCR_ROGERTHAT2195": "^2Scarecrow: ^7Anlaşıldı!", + "SUBTITLE_EST_SCR_YOUGOTIT196": "^2Scarecrow: ^7Tamamdır!", + "SUBTITLE_EST_OZN_CONSIDERITDONE197": "^2Ozone: ^7Olmuş bilin.", + "SUBTITLE_EST_SNP1_ENEMYSIGHTED201": "^2Archer: ^7Düşman birlikleri görüldü, evin kuzeyindeki ormanda ilerliyorlar.", + "SUBTITLE_EST_GST_ONTHEDRIVEWAY202": "^2Ghost: ^7Anlaşıldı. Roach, eve giden yola birkaç mayın yerleştir! Hadi!", + "SUBTITLE_EST_GST_DSMCOMPLETE221": "^2Ghost: ^7Roach, transfer tamamlandı! Sen DSM'yi getirirken ben ana yaklaşımı koruyacağım! Hadi!", + "SUBTITLE_EST_GST_GETOUTTAHERE222": "^2Ghost: ^7Roach! Ben ön tarafı koruyorum! DSM'yi al! Buradan çıkmalıyız!", + "SUBTITLE_EST_SHP_ALMOSTATLZ223": "^2Shepherd: ^7Ben Shepherd. Neredeyse LZ'deyiz. Durumunuz nedir, tamam?", + "SUBTITLE_EST_GST_ONOURWAY224": "^2Ghost: ^7LZ'ye doğru gidiyoruz! Roach, gidelim!", + "SUBTITLE_EST_GST_KEEPMOVING234": "^2Ghost: ^7LZ'ye gidin! Devam edin!", + "SUBTITLE_EST_GST_GOGO235": "^2Ghost: ^7Gidin! Gidin!", + "SUBTITLE_EST_GST_ILLCOVERYOU236": "^2Ghost: ^7Seni koruyacağım! Yürü!", + "SUBTITLE_EST_GST_GETTOTHELZ241": "^2Ghost: ^7LZ'ye gitmeliyiz! Roach, hadi!", + "SUBTITLE_EST_GST_BRACKETING251": "^2Ghost: ^7Pozisyonumuzu havan toplarıyla kuşatıyorlar, ilerlemeye devam edin ama arkanızı kollayın!", + "SUBTITLE_EST_GST_GOTYOUCOVERED252": "^2Ghost: ^7Roach, seni koruyorum! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_EST_GST_REDSMOKE261": "^2Ghost: ^7Thunder Two-One, ağaç çizgisinde kırmızı duman patlattım! Hedefime saldırmak için hazır olun!", + "SUBTITLE_EST_GST_GOTYOUROACH263": "^2Ghost: ^7Seni yakaladım Roach, dayan!", + "SUBTITLE_EST_GST_HANGINTHERE264": "^2Ghost: ^7Roach, dayan!", + "SUBTITLE_EST_GST_CLEAREDHOT265": "^2Ghost: ^7Thunder Two-One, sıcak temizlendi!", + "SUBTITLE_EST_GST_COMEONGETUP271": "^2Ghost: ^7Hadi, ayağa kalk!", + "SUBTITLE_EST_GST_GETUPGETUP272": "^2Ghost: ^7Ayağa kalk! Kalkın! Kalkın! Neredeyse vardık!", + "SUBTITLE_EST_SHP_HAVETHEDSM291": "^2Shepherd: ^7DSM sende mi?", + "SUBTITLE_EST_GST_WEGOTIT292": "^2Ghost: ^7Aldık efendim!", + "SUBTITLE_EST_SHP_WELLDONE293": "^2Shepherd: ^7Aferin asker.", + "SUBTITLE_EST_SHP_LOOSEEND294": "^2Shepherd: ^7Güzel. Bir yarım kalmış iş daha azaldı.", + "SUBTITLE_EST_MCT_SPLITUP304": "^2Soap: ^7Price! Ayrılmalıyız yoksa ölürüz!", + "SUBTITLE_118": "^2ABD Askerleri: ^7(askerlerin tezahüratı walla)", + "SUBTITLE_FAVELA_CMT_READY2MOVE": "^2Yzb. MacTavish: ^7Ghost, plakalar eşleşti.", + "SUBTITLE_FAVELA_GST_GOOD2GO": "^2Ghost: ^7Anlaşıldı. Rojas'ın sağ kolundan bir iz var mı?", + "SUBTITLE_FAVELA_CMT_ROGERTHAT13": "^2Yzb. MacTavish: ^7Olumsuz. Şimdiden iki kez durdular - ondan iz yok.", + "SUBTITLE_FAVELA_CMT_INPOSITION14": "^2Yzb. MacTavish: ^7Bekle, yine durdular. Beklemede kalın.", + "SUBTITLE_FAVELA_CMT_INSIGHT15": "^2Yzb. MacTavish: ^7Kimlikleri tespit edildi! Bu adamlar her kimse, onu gördüklerine sevinmemişler...", + "SUBTITLE_FAVELA_CMT_NEEDHIMALIVE16": "^2Yzb. MacTavish: ^7Ghost, burada bir sorunumuz var!", + "SUBTITLE_FAVELA_CMT_GETDOWN17": "^2Yzb. MacTavish: ^7Yere yat, yere yat!", + "SUBTITLE_FAVELA_CMT_GETTINGAWAY21": "^2Yzb. MacTavish: ^7Kaçıyor! Roach gidelim, gidelim!", + "SUBTITLE_FAVELA_CMT_DRIVERSDEAD22": "^2Yzb. MacTavish: ^7Ghost, şoförümüz öldü! Yayan gidiyoruz! Bizimle Rio Oteli'nde buluş ve yapabiliyorsan önünü kes!", + "SUBTITLE_FAVELA_GST_ONMYWAY23": "^2Ghost: ^7Anlaşıldı, yoldayım!", + "SUBTITLE_FAVELA_GST_HESFAST31": "^2Ghost: ^7Ara sokağa girdi!", + "SUBTITLE_FAVELA_CMT_NONLETHAL32": "^2Yzb. MacTavish: ^7Sadece ölümcül olmayan indirmeler! Ona canlı ihtiyacımız var!", + "SUBTITLE_FAVELA_CMT_TAKESHOT33": "^2Yzb. MacTavish: ^7Roach - ateş et! Bacağına saldır!", + "SUBTITLE_FAVELA_CMT_HESDOWN34": "^2Yzb. MacTavish: ^7Yerde.", + "SUBTITLE_FAVELA_CMT_HIDINGINFAV41": "^2Yzb. MacTavish: ^7Roach, bu biraz zaman alacak. Meat ve Royce ile git ve Rojas'a dair bir iz var mı diye favelayı kontrol et - bu adamın gittiği yer orası.", + "SUBTITLE_FAVELA_RYC_LETSGO42": "^2Royce: ^7Hadi gidelim.", + "SUBTITLE_FAVELA_RYC_WATCHYOURBG51": "^2Royce: ^7Unutmayın - Gece konduda siviller var. Ateşinize dikkat edin.", + "SUBTITLE_FAVELA_RYC_WARNING54": "^2Royce: ^7Meat, şu sivilleri buradan çıkar.", + "SUBTITLE_FAVELA_MET_ROGERTHAT55": "^2Meat: ^7Anlaşıldı.", + "SUBTITLE_FAVELA_CMT_FULLBATTALION57": "^2Royce: ^7Bravo Altı, haberiniz olsun - aşağı köyde düşman milisleriyle çatışmaya girdik!", + "SUBTITLE_FAVELA_RYC_WITHYOU58": "^2Royce: ^7Roach! Seninleyim! Çatılara dikkat edin! Hadi!", + "SUBTITLE_FAVELA_CMT_DOINGOK510": "^2Yzb. MacTavish: ^7Royce, bana bir durum raporu ver, tamam!", + "SUBTITLE_FAVELA_RYC_NOSIGN511": "^2Royce: ^7Bir sürü milis var ama Rojas'tan iz yok, tamam!", + "SUBTITLE_FAVELA_CMT_KEEPSEARCHING512": "^2Yzb. MacTavish: ^7Anlaşıldı! Aramaya devam edin! Onu görürseniz bana haber verin! Dışarı!", + "SUBTITLE_FAVELA_RYC_MOVEUP513": "^2Royce: ^7Roach! İlerleyin! Hadi gidelim!", + "SUBTITLE_FAVELA_RYC_MEATISDOWN515": "^2Royce: ^7Meat düştü! Tekrar ediyorum, Meat düştü!", + "SUBTITLE_FAVELA_CMT_CANTAFFORD516": "^2Yzb. MacTavish: ^7Anlaşıldı! Devam edin, Rojas'ı kaybetmeyi göze alamayız!", + "SUBTITLE_FAVELA_RYC_IMDOWN518": "^2Royce: ^7Roach vuruldum!", + "SUBTITLE_FAVELA_RYC_ROACHISDOWN519": "^2Royce: ^7Bravo Altı, Roach yerde. Bunu tek başıma bitirmek zorundayım!", + "SUBTITLE_FAVELA_MET_ROACHISDOWN520": "^2Meat: ^7Roach düştü! Roach düştü! Sadece sen ve ben Royce!", + "SUBTITLE_FAVELA_CMT_DOYOUCOPY521": "^2Yzb. MacTavish: ^7Roach cevap ver! Roach duyuyor musun?! Roach!", + "SUBTITLE_FAVELA_CMT_ROACHISDOWN521": "^2Yzb. MacTavish: ^7Ghost, Roach düştü! Onu kaybettik!", + "SUBTITLE_FAVELA_CMT_LOSTROACH521": "^2Yzb. MacTavish: ^7Roach'u kaybettik! Rojas kaçacak!", + "SUBTITLE_FAVELA_CMT_CUTHIMOFF61": "^2Yzb. MacTavish: ^7Roach - Rojas'ın yerini bulduk! Gece kondunun üst katları boyunca batıya doğru gidiyor.", + "SUBTITLE_FAVELA_CMT_KEEPGOING62": "^2Yzb. MacTavish: ^7Bizim tarafımıza geri dönmesini engelleyeceğiz - devam edin ve önünü yukarıdan kesin!", + "SUBTITLE_FAVELA_CMT_NOTIME63": "^2Yzb. MacTavish: ^7Destek için zaman yok. Bunu kendi başınıza yapmak zorundasınız. İyi şanslar", + "SUBTITLE_FAVELA_CMT_WATCHROOFTOPS71": "^2Yzb. MacTavish: ^7Roach, çatılara dikkat et! Yükseklere yerleştirilmiş RPG'ler ve makineli tüfeklerle birkaç yakın temasımız oldu!", + "SUBTITLE_FAVELA_CMT_THEIRTERRITORY72": "^2Yzb. MacTavish: ^7Roach - burası onların bölgesi ve bunu iyi biliyorlar! Pusu pozisyonları için gözünüzü açık tutun ve köşelerinizi kontrol edin!", + "SUBTITLE_FAVELA_CMT_STILLTRACKING73": "^2Yzb. MacTavish: ^7Roach, burada milislerden ağır ateş altındayız ama ben hâlâ Rojas'ı takip ediyorum! Bir binaya girdi! Ghost, onu görüyor musun?", + "SUBTITLE_FAVELA_GST_DUFFELBAG74": "^2Ghost: ^7Anlaşıldı, siyah bir spor çantası taşıyarak çatıya tırmanıyor!", + "SUBTITLE_FAVELA_CMT_INTERCEPT75": "^2Yzb. MacTavish: ^7Bu onu yavaşlatır! Roach, geri dönmesini engelliyoruz! Önünü kesmek için ilerlemeye devam et! Hadi! Hadi! Yürüyün! Yürüyün!", + "SUBTITLE_FAVELA_GST_CUTTINGTHRU76": "^2Ghost: ^7Rojas'ı görüyorum! Pazarı kesiyor!", + "SUBTITLE_FAVELA_CMT_HEADFORROOFTOPS77": "^2Yzb. MacTavish: ^7Anlaşıldı! Çatılara yöneleceğim ve sağ taraftan önünü kesmeye çalışacağım! Batıya yönelmekten başka çaresi kalmayacak!", + "SUBTITLE_FAVELA_GST_WAYAROUND78": "^2Ghost: ^7Milislerden çok fazla ateş alıyorum, onu pazarın içinden takip edebileceğimi sanmıyorum! Başka bir yol bulmam gerekecek!", + "SUBTITLE_FAVELA_CMT_ANOTHERFENCE79": "^2Yzb. MacTavish: ^7Roach! Bir çitten daha atladı ve hâlâ Gece kondunun sizin tarafına doğru gidiyor! İlerlemeye devam et! Hadi! Hadi! Yürü! Yürü!", + "SUBTITLE_FAVELA_GST_HALFKLICK710": "^2Ghost: ^7Dikkatli olun, pazarın yaklaşık yarım kilometre doğusundayım, Rojas'ın sağ tarafımdaki çatılarda koştuğunu görebiliyorum!", + "SUBTITLE_FAVELA_GST_LEGSHOT712": "^2Ghost: ^7Efendim, Rojas görüş alanımda! Temiz bir bacak vuruşu yapabiliriz! Bu işi burada bitirebiliriz!", + "SUBTITLE_FAVELA_CMT_DONOTENGAGE713": "^2Yzb. MacTavish: ^7Olumsuz! Bunu riske atamayız! Saldırmayın!", + "SUBTITLE_FAVELA_GST_ROGERTHAT2714": "^2Ghost: ^7Kahretsin! Anlaşıldı!", + "SUBTITLE_FAVELA_CMT_YOURSIDE715": "^2Yzb. MacTavish: ^7Devam edin! Rojas hâlâ Gece kondunun sizin tarafına doğru gidiyor!", + "SUBTITLE_FAVELA_GST_PINYOUDOWN716": "^2Ghost: ^7Roach! Milislerin seni uzun süre sıkıştırmasına izin verme! Flaş bombalarını üzerlerinde kullan!", + "SUBTITLE_FAVELA_CMT_LOSTSIGHTAGAIN717": "^2Yzb. MacTavish: ^7Onu yine gözden kaybettim! Ghost, konuş benimle!", + "SUBTITLE_FAVELA_GST_ALLEYSBELOW718": "^2Ghost: ^7Peşindeyim! Aşağıdaki ara sokaklardan geri dönmeye çalışıyor!", + "SUBTITLE_FAVELA_CMT_STAYONHIM719": "^2Yzb. MacTavish: ^7Anlaşıldı! Peşinde kalın!", + "SUBTITLE_FAVELA_CMT_NOWHERETOGO720": "^2Yzb. MacTavish: ^7Roach! Yokuş yukarı devam et! Önünü kestim! Batıdaki çatılardan sizin bölgenize geçmekten başka gidecek yeri yok!", + "SUBTITLE_FAVELA_CMT_TRAPHIMUPHERE721": "^2Yzb. MacTavish: ^7Roach! Bölgeyi iyi biliyor ama onu burada tuzağa düşürebiliriz! Durmayın! Gidin! Gidin! Gidin!", + "SUBTITLE_FAVELA_GST_JUMPEDFENCE722": "^2Ghost: ^7Çitlerden atladı! Peşindeyim!", + "SUBTITLE_FAVELA_CMT_GOINGLEFT723": "^2Yzb. MacTavish: ^7Anlaşıldı! Sola doğru gidiyorum!", + "SUBTITLE_FAVELA_GST_WHEREISHE724": "^2Ghost: ^7Nerede o, nerede o?", + "SUBTITLE_FAVELA_CMT_SLIDINGROOFTOPS725": "^2Yzb. MacTavish: ^7Gördüm! Orada, teneke çatılardan aşağı kayıyor!", + "SUBTITLE_FAVELA_GST_ANOTHERLEGSHOT726": "^2Ghost: ^7Başka bir açık bacak atışım var!", + "SUBTITLE_FAVELA_CMT_CARRYHIMBACK727": "^2Yzb. MacTavish: ^7Olumsuz! Tüm bu milisler ensendeyken onu geri taşımak istemiyorsan olmaz! Ona zarar görmemiş olarak ihtiyacım var!", + "SUBTITLE_FAVELA_CMT_EYEOPEN728": "^2Yzb. MacTavish: ^7Anlaşıldı! Roach! Onu tepenin sizin tarafına yaklaştırıyoruz! Rojas için gözünüzü dört açın! Hâlâ çatılara doğru ilerliyor!", + "SUBTITLE_FAVELA_CMT_SPOTTEDFAUST91": "^2Yzb. MacTavish: ^7Roach! Rojas'ı gördüm, kaçmaya çalışıyor! Sana doğru geliyor!", + "SUBTITLE_FAVELA_CMT_UNHARMED92": "^2Yzb. MacTavish: ^7Ve onu vurmayın! Ona canlı ve zarar görmemiş olarak ihtiyacımız var!", + "SUBTITLE_FAVELA_CMT_CUTOFF93": "^2Yzb. MacTavish: ^7Roach, onu zirvede keseceğiz, o tarafa doğru itmeye devam et! Hadi! Hadi! Hadi! Hadi!", + "SUBTITLE_FAVELA_CMT_CORRALING94": "^2Yzb. MacTavish: ^7Onu tepeye doğru çekmeye devam edin! Zirvede önünü keseceğiz!", + "SUBTITLE_FAVELA_CMT_CLOSERTOYOURPART95": "^2Yzb. MacTavish: ^7Roach! Favela'nın sizin kısmına yaklaşıyor! Devam edin! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_FAVELA_CMT_MOTORCYCLE96": "^2Yzb. MacTavish: ^7Ghost motosiklete doğru gidiyor!", + "SUBTITLE_FAVELA_CMT_DONTSHOOTHIM99": "^2Yzb. MacTavish: ^7Güzel! Yine sağa kırıyor! Roach, onu görürsen sakın vurma! Ona zarar vermemeliyim!", + "SUBTITLE_FAVELA_CMT_ONTHEMOVE910": "^2Yzb. MacTavish: ^7Roach! Hareket hâlinde ve size doğru geliyor! Gidin! Gidin! Gidin!", + "SUBTITLE_FAVELA_CMT_BACKTOWARDS911": "^2Yzb. MacTavish: ^7Tamam, Rojas'ı görüyoruz - bekle! Ah, kahretsin! Size doğru geri dönüyor!", + "SUBTITLE_FAVELA_CMT_DOUBLEBACK912": "^2Yzb. MacTavish: ^7Roach, onu tepeye doğru itmeye devam et! Geri dönmesine izin verme!", + "SUBTITLE_FAVELA_CMT_FARRIGHT101": "^2Yzb. MacTavish: ^7Ghost, sağa doğru gidiyorum!", + "SUBTITLE_FAVELA_GST_ROGERTHAT102": "^2Ghost: ^7Anlaşıldı.", + "SUBTITLE_FAVELA_GST_GETAWAY103": "^2Ghost: ^7Kaçacak!", + "SUBTITLE_FAVELA_CMT_NOHESNOT104": "^2Yzb. MacTavish: ^7Hayır kaçmayacak.", + "SUBTITLE_FAVELA_CMT_GOTPACKAGE105": "^2Yzb. MacTavish: ^7Frontrunner, burası Bravo Altı. Paketi aldık. Tekrar ediyorum, paketi aldık.", + "SUBTITLE_FAVELA_GST_SENDCHOPPER111": "^2Ghost: ^7Komuta, kalkışa hazırız. Helikopteri gönderin. Koordinatları takip et-", + "SUBTITLE_FAVELA_GST_SKIESARECLEAR112": "^2Ghost: ^7Kahretsin! Gökyüzü açık. Helikopteri hemen gönderin.", + "SUBTITLE_FAVELA_GST_ONOUROWN113": "^2Ghost: ^7Komutanın kafası kıçında. Kendi başımızayız.", + "SUBTITLE_FAVESC_CMT_SURROUNDED16": "^2Yzb. MacTavish: ^7Nikolai! Etrafı milislerle çevrili bir gecekondunun tepesindeyiz! Helikopteri pazara getirin, anlaşıldı mı, tamam!", + "SUBTITLE_FAVESC_NKL_ONTHEWAY17": "^2Nikolai: ^7Tamam dostum, yoldayım!", + "SUBTITLE_FAVESC_CMT_LOCKANDLOAD18": "^2Yzb. MacTavish: ^7Herkes hazır olsun! Kilitlenin ve yükleyin!", + "SUBTITLE_FAVESC_GST_LETSDOTHIS19": "^2Ghost: ^7Hadi yapalım şu işi!", + "SUBTITLE_FAVESC_GST_SHACKONLEFT23": "^2Ghost: ^7Milisler soldaki barakadan çıkıyor!", + "SUBTITLE_FAVESC_CMT_THRUTHATGATE24": "^2Yzb. MacTavish: ^7Şu kapıdan geçin! Tahliye noktasına doğru ilerlemeye devam edin!", + "SUBTITLE_FAVESC_GST_ONROOFTOPS25": "^2Ghost: ^7Temas! Çatılarda ayaklı araçlar var, güneyden hızla yaklaşıyorlar!", + "SUBTITLE_FAVESC_GST_DEADAHEAD26": "^2Ghost: ^7Tangolar yer seviyesinde, tam önümüzde!", + "SUBTITLE_FAVESC_GST_SKINNIES27": "^2Ghost: ^7Saat 12 yönünde çatılarda daha fazla skinny var!", + "SUBTITLE_FAVESC_GST_LEFTFLANK28": "^2Ghost: ^7Sol kanadımıza doğru ilerliyorlar!", + "SUBTITLE_FAVESC_CMT_SHIFTFIRE29": "^2Yzb. MacTavish: ^7Sol tarafımızdaki çatılar! Ateş açın!", + "SUBTITLE_FAVESC_GST_LEFTLEFTLEFT210": "^2Ghost: ^7Sol sol sol! Şu tahta barakalarda!", + "SUBTITLE_FAVESC_CMT_RPGSEAST211": "^2Yzb. MacTavish: ^7RPG'ler doğuya!", + "SUBTITLE_FAVESC_GST_TOTHESOUTH212": "^2Ghost: ^7Güneydeki çatılarda RPG'ler var!", + "SUBTITLE_FAVESC_CMT_LOWFROMSE213": "^2Yzb. MacTavish: ^7Tangolar güneydoğudan alçaktan ilerliyor!", + "SUBTITLE_FAVESC_GST_ALOTOFEM214": "^2Ghost: ^7Lanet olsun, onlardan bir sürü var!", + "SUBTITLE_FAVESC_GST_TECHNICAL41": "^2Ghost: ^7Teknik güneyden geliyor!", + "SUBTITLE_FAVESC_CMT_TECHNICAL42": "^2Yzb. MacTavish: ^7Başka bir teknik var! Çıkarın onu!", + "SUBTITLE_FAVESC_CMT_THRUGATE51": "^2Yzb. MacTavish: ^7Helikoptere gitmeliyiz - pazar kapısından geçmeliyiz! Kımıldayın!", + "SUBTITLE_FAVESC_GST_GOGOGO52": "^2Ghost: ^7Gidin! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_FAVESC_GST_CHOPPERINBOUND61": "^2Ghost: ^7Helikopter geliyor!", + "SUBTITLE_FAVESC_NKL_MANYMILITIA62": "^2Nikolai: ^7Pazar bulunduğunuz yerden çok uzakta değil, ancak size doğru ilerleyen birçok milita görüyorum.", + "SUBTITLE_FAVESC_CMT_PUSHTHRUSTREETS71": "^2Yzb. MacTavish: ^7Gidelim, gidelim! Bu sokaklardan geçip pazara gitmeliyiz!", + "SUBTITLE_FAVESC_CMT_FLANKINGROUTES72": "^2Yzb. MacTavish: ^7Yan yollara dikkat edin!", + "SUBTITLE_FAVESC_CMT_LAYDOWNFIRE73": "^2Yzb. MacTavish: ^7Roach! Kavşağı biraz ateş altına alın!", + "SUBTITLE_FAVESC_CMT_ALLEYONLEFT74": "^2Yzb. MacTavish: ^7Dikkat! Soldaki sokak!", + "SUBTITLE_FAVESC_CMT_ALMOSTATMARKET75": "^2Yzb. MacTavish: ^7Devam edin! Neredeyse pazara geldik!", + "SUBTITLE_FAVESC_CMT_SPLITUP77": "^2Yzb. MacTavish: ^7Manga! Dağılın ve pazarı kesin! Kımıldayın!", + "SUBTITLE_FAVESC_GST_FIRINGBLIND78": "^2Ghost: ^7Saat 11 yönünde üstümüzde temas var, kör ateş!", + "SUBTITLE_FAVESC_CMT_SHACKONRIGHT79": "^2Yzb. MacTavish: ^7Tango sağdaki barakadan çıkıyor!", + "SUBTITLE_710": "^2Yzb. MacTavish: ^7Roach! Onları kuşatmak için sağdaki dondurmacıya girmenin bir yolunu bulmaya çalış!", + "SUBTITLE_711": "^2Yzb. MacTavish: ^7Roach! Soldaki sarı evlerden geç ve kavşağı kuşat!", + "SUBTITLE_FAVESC_CMT_THERESPAVELOW91": "^2Yzb. MacTavish: ^7Nikolai'nin Pave Low'u orada! Hadi gidelim!", + "SUBTITLE_FAVESC_CMT_IMMEDIATEDUSTOFF92": "^2Yzb. MacTavish: ^7Nikolai! Tahmini varış süresi 20 saniye! Ani toz duman için hazır olun!", + "SUBTITLE_FAVESC_NKL_NOTFASTENOUGH93": "^2Nikolai: ^7Bu yeterince hızlı olmayabilir! Daha fazla milisin pazara yaklaştığını görüyorum!", + "SUBTITLE_FAVESC_CMT_PICKUPPACE94": "^2Yzb. MacTavish: ^7Hızlanın! Hadi gidelim!", + "SUBTITLE_FAVESC_NKL_TOOHOT95": "^2Nikolai: ^7Çok sıcak! Bu inişten sağ çıkamayacağız!", + "SUBTITLE_FAVESC_CMT_WAVEOFF96": "^2Yzb. MacTavish: ^7Nikolai, el salla, el salla! Sizinle ikincil LZ'de buluşacağız! Gidin!", + "SUBTITLE_FAVESC_NKL_MEETYOUTHERE97": "^2Nikolai: ^7Pekâlâ, sizinle orada buluşuruz! İyi şanslar!", + "SUBTITLE_FAVESC_CMT_GETTOROOFTOPS101": "^2Yzb. MacTavish: ^7Haydi! Çatılara ulaşmalıyız, bu taraftan!", + "SUBTITLE_FAVESC_CMT_GETUPHERE102": "^2Yzb. MacTavish: ^7Roach! Çatılara çıkın, gidelim!", + "SUBTITLE_FAVESC_CMT_CLIMBUP103": "^2Yzb. MacTavish: ^7Roach! Buraya gel ve çatılara tırman!", + "SUBTITLE_FAVESC_CMT_CLIMBUPHERE104": "^2Yzb. MacTavish: ^7Roach! Buraya tırmanabilirsin!", + "SUBTITLE_FAVESC_CMT_LETSGOLETSGO111": "^2Yzb. MacTavish: ^7Gidelim, gidelim!", + "SUBTITLE_FAVESC_NKL_WHOLEVILLAGE112": "^2Nikolai: ^7Dostum, buradan bakınca bütün köy seni öldürmeye çalışıyor gibi görünüyor!", + "SUBTITLE_FAVESC_CMT_PICKUSUP113": "^2Yzb. MacTavish: ^7Bana bilmediğim bir şey söyle! Sadece bizi almaya hazır ol!", + "SUBTITLE_FAVESC_NKL_KEEPGOING114": "^2Nikolai: ^7Tamam, yakında sizi alacağım, devam edin!", + "SUBTITLE_FAVESC_GST_RUNOUTOFROOF115": "^2Ghost: ^7Çatıdaki yerimiz tükeniyor!", + "SUBTITLE_FAVESC_CMT_MAKEITGOGO116": "^2Yzb. MacTavish: ^7Başarabiliriz! Hadi, hadi, hadi!", + "SUBTITLE_FAVESC_CMT_WAKEUP122": "^2Yzb. MacTavish: ^7Roach! Roach! Uyan!", + "SUBTITLE_FAVESC_GST_COMINGFORYOU123": "^2Ghost: ^7Roach! Onları helikopterden görebiliyoruz! Senin için geliyorlar, düzinelercesi!", + "SUBTITLE_FAVESC_CMT_CIRCLINGAREA123": "^2Yzb. MacTavish: ^7Roach, bölgeyi dolaşıyoruz ama seni göremiyorum! Çatılara çıkmalısın!", + "SUBTITLE_FAVESC_CMT_TOOMANY124": "^2Yzb. MacTavish: ^7Roach! Onlardan çok fazla var! Oradan çıkın ve çatılara giden bir yol bulun! Yürüyün!", + "SUBTITLE_FAVESC_CMT_LOWONFUEL125": "^2Yzb. MacTavish: ^7Roach, yakıtımız azalıyor! Hangi cehennemdesin?!", + "SUBTITLE_FAVESC_CMT_RUNFORIT126": "^2Yzb. MacTavish: ^7Kaçın! Çatılara çıkın!", + "SUBTITLE_FAVESC_CMT_GETOUTTA127": "^2MacTavish: ^7Hadi Roach, neredeyse helikoptere vardık!", + "SUBTITLE_FAVESC_CMT_GETTOCHOPPER128": "^2MacTavish: ^7Roach, ne duruyorsun, gidelim!", + "SUBTITLE_FAVESC_CMT_WHATSHOLDUP129": "^2MacTavish: ^7Buradan çıkmalıyız, Roach, hadi!", + "SUBTITLE_FAVESC_CMT_MEETUSSOUTH131": "^2Yzb. MacTavish: ^7Roach! Seni görüyorum! Çatılardan aşağı atla ve bizimle güneyde buluş! Hadi!", + "SUBTITLE_FAVESC_CMT_HEADTORIGHT132": "^2Yzb. MacTavish: ^7Sağa doğru gidin!", + "SUBTITLE_FAVESC_CMT_KEEPMOVING133": "^2Yzb. MacTavish: ^7İlerlemeye devam edin! Sakın geri dönme! Yavaşlarsan ölürsün!", + "SUBTITLE_FAVESC_NKL_VERYLOW133": "^2Nikolai: ^7Benzin çok azaldı! Otuz saniye içinde ayrılmalıyım!", + "SUBTITLE_FAVESC_CMT_ONFUMES134": "^2Yzb. MacTavish: ^7Roach! Yakıtımız bitmek üzere! Otuz saniyen var! Koş!", + "SUBTITLE_FAVESC_CMT_LEFTTURNLEFT135": "^2Yzb. MacTavish: ^7Sola! Sola dön ve aşağı atla!", + "SUBTITLE_FAVESC_CMT_COMEON136": "^2Yzb. MacTavish: ^7Haydi!", + "SUBTITLE_FAVESC_CMT_JUMP137": "^2Yzb. MacTavish: ^7Atla!", + "SUBTITLE_FAVESC_CMT_GOTHIM138": "^2Yzb. MacTavish: ^7Nikolai! Onu yakaladık! Çıkar bizi buradan!", + "SUBTITLE_FAVESC_NKL_WHERETO139": "^2Nikolai: ^7Nereye, dostum?", + "SUBTITLE_1310": "^2Yzb. MacTavish: ^7Sadece bizi denizaltıya götür...", + "SUBTITLE_112_2": "^2Ghost: ^7Ruslar bu katliamın cevapsız kalmasına izin vermeyecekler. Kanlı olacak.", + "SUBTITLE_GULAG_RPT_30SEC11": "^2Yzb. MacTavish: ^7Otuz saniye.", + "SUBTITLE_GULAG_RPT_STBYENGAGE210": "^2Yzb. MacTavish: ^7Tüm keskin nişancılar, ben MacTavish, çatışmaya hazır olun.", + "SUBTITLE_GULAG_RPT_STABILIZE31": "^2Yzb. MacTavish: ^7Stabilize edin.", + "SUBTITLE_GULAG_LBP1_ROGER232": "^2Hornet İki-Bir: ^7Anlaşıldı.", + "SUBTITLE_GULAG_TCO_ONTARGET33": "^2Ghost: ^7Hedefte.", + "SUBTITLE_GULAG_RPT_CLEAREDENGAGE34": "^2Yzb. MacTavish: ^7Tüm keskin nişancılar - çatışmaya hazır.", + "SUBTITLE_GULAG_RPT_SHIFTRIGHT36": "^2Yzb. MacTavish: ^7Sağa kay.", + "SUBTITLE_GULAG_LBP1_SHIFTING37": "^2Hornet İki-Bir: ^7Vites değiştiriyorum.", + "SUBTITLE_GULAG_LBP1_READY39": "^2Hornet İki-Bir: ^7Hazır.", + "SUBTITLE_GULAG_WRM_ONTARGET310": "^2Solucan: ^7Hedefte.", + "SUBTITLE_GULAG_RPT_TAKEEMOUT318": "^2Yzb. MacTavish: ^7Çıkarın onları.", + "SUBTITLE_GULAG_CMT_SEEHOSTILES41": "^2Yzb. MacTavish: ^7Bir sonraki kulede dört düşman görüyorum!", + "SUBTITLE_GULAG_LBP1_HANGON42": "^2Hornet İki-Bir: ^7Dayanın!", + "SUBTITLE_GULAG_RPT_TOOCLOSE43": "^2Yzb. MacTavish: ^7Shepherd! O savaşçılara derhal ateşi kesmelerini söyle! Bu çok yakındı!", + "SUBTITLE_GULAG_HQR_MORETIME44": "^2Shepherd: ^7Sana biraz zaman kazandırmaya çalışacağım. Gulag'daki bir adam bu noktada Donanma için pek bir şey ifade etmiyor.", + "SUBTITLE_GULAG_GST_YANKS145": "^2Ghost: ^7Lanet Yankiler... Onların iyi adamlar olduğunu sanıyordum!", + "SUBTITLE_GULAG_GST_YANKS246": "^2Ghost: ^7Lanet olası Yankiler... Kimin tarafındalar ki?!", + "SUBTITLE_GULAG_RPT_CUTCHATTER47": "^2Yzb. MacTavish: ^7Ghost konuşmayı kes. Soğukkanlı kal.", + "SUBTITLE_GULAG_LBP1_GUNRUN63": "^2Hornet İki-Bir: ^7İki-Bir top atışı için pozisyon aldı.", + "SUBTITLE_GULAG_CMT_LASINGTARGET65": "^2Yzb. MacTavish: ^7Anlaşıldı İki-Bir, hedef ikinci katta!", + "SUBTITLE_GULAG_LBP1_GOTATALLY66": "^2Hornet İki-Bir: ^7İki-Bir kopyası, altı tangoda bir çetele var, sıcak geliyor.", + "SUBTITLE_GULAG_CMT_USEM20367": "^2Yzb. MacTavish: ^7Roach! Üçüncü katta düşmanlar var, M203'ünü kullan!", + "SUBTITLE_GULAG_CMT_UPAHEAD68": "^2Yzb. MacTavish: ^7Giriş ileride, ilerlemeye devam edin!", + "SUBTITLE_GULAG_CMT_GETOUT69": "^2Yzb. MacTavish: ^7İşte burası! İçeri giriyoruz, Mahkûm 627'yi alıyoruz ve çıkıyoruz!", + "SUBTITLE_GULAG_CMT_CHECKCORNERS610": "^2Yzb. MacTavish: ^7Köşelerinizi kontrol edin! Hadi gidelim!", + "SUBTITLE_GULAG_GST_CONTROLROOM71": "^2Ghost: ^7İleride kontrol odası var! Mahkûmu bulmak için kullanabilirim!", + "SUBTITLE_GULAG_CMT_TAPINTO72": "^2Ghost: ^7Sistemlerine girip mahkûmu arayacağım! Bu biraz zaman alacak!", + "SUBTITLE_GULAG_CMT_CELLDUTY73": "^2Yzb. MacTavish: ^7Anlaşıldı! Roach, hücre görevindeyiz! Beni takip et!", + "SUBTITLE_GULAG_GST_PATCHEDIN75": "^2Ghost: ^7Tamam, bağlandım. İlerlemenizi güvenlik kameralarından takip ediyorum.", + "SUBTITLE_GULAG_CMT_LOCATION77": "^2Yzb. MacTavish: ^7Anlaşıldı! Mahkûm 627'nin yerini biliyor musun?", + "SUBTITLE_GULAG_GST_JOBEASIER78": "^2Ghost: ^7Olumsuz, ama katınızdaki düşmanları izleyen bir projektörüm var. Bu işinizi kolaylaştıracaktır.", + "SUBTITLE_GULAG_CMT_STAYSHARP79": "^2Yzb. MacTavish: ^7Anlaşıldı! Dikkatli olun! Mahkûm bu hücrelerden birinde olabilir!", + "SUBTITLE_GULAG_CMT_SECDOOR717": "^2Yzb. MacTavish: ^7Ghost, bir güvenlik kapısına çarptık, aç onu!", + "SUBTITLE_GULAG_CMT_ANCIENT718": "^2Ghost: ^7Üzerinde çalışıyorum...bu donanım çok eski!", + "SUBTITLE_GULAG_CMT_WRONGDOOR719": "^2Yzb. MacTavish: ^7Ghost, yanlış kapıyı açtın!", + "SUBTITLE_GULAG_GST_STANDBY720": "^2Ghost: ^7Anlaşıldı, beklemede kalın...", + "SUBTITLE_GULAG_CMT_THATSBETTER721": "^2Yzb. MacTavish: ^7Bu daha iyi, gidelim!", + "SUBTITLE_GULAG_GST_THREETWO723": "^2Ghost: ^7Tamam - üç, iki içinde yandaki kapı -", + "SUBTITLE_GULAG_CMT_TALKTOME725": "^2Yzb. MacTavish: ^7Konuş benimle Ghost...bu hücreler terkedilmiş!", + "SUBTITLE_GULAG_GST_EASTWING726": "^2Ghost: ^7Anlaşıldı! Mahkûm 627 doğu kanadına nakledildi! Merkezdeki cephâneliğe doğru git - oraya giden en hızlı yol bu.", + "SUBTITLE_GULAG_CMT_ARMORYDOWNTHERE727": "^2Yzb. MacTavish: ^7Anlaşıldı! Takım, aşağıdaki cephâneliğe gidin! Yürüyün!", + "SUBTITLE_GULAG_CMT_SEEANYTHING728": "^2Yzb. MacTavish: ^7Hoşuna giden bir şey görüyor musun?", + "SUBTITLE_GULAG_GST_BADNEWS729": "^2Ghost: ^7Haberler kötü dostum. Konumunuza yaklaşan üç, hayır, dört düşman mangası izliyorum!", + "SUBTITLE_GULAG_CMT_HEARCOMING730": "^2Yzb. MacTavish: ^7Geldiklerini duyabiliyorum... Gidelim! Çok açıktayız!", + "SUBTITLE_GULAG_CMT_OPENDOOR731": "^2Yzb. MacTavish: ^7Ghost! Kapıyı aç!", + "SUBTITLE_GULAG_GST_RUNABYPASS732": "^2Ghost: ^7Lanet olsun, sert hattan kilitlemişler. Bir bypass yapmam gerekecek.", + "SUBTITLE_GULAG_CMT_TOOLATE733": "^2Yzb. MacTavish: ^7Çok geç! Çoktan geldiler!", + "SUBTITLE_GULAG_GST_GOTMORETANGOS734": "^2Ghost: ^7Dikkatli olun - size doğru gelen daha fazla tango var.", + "SUBTITLE_GULAG_CMT_MORECOVER735": "^2Yzb. MacTavish: ^7Daha fazla korumaya ihtiyacımız olacak - bir isyan kalkanı alın!", + "SUBTITLE_GULAG_CMT_PICKUPONE736": "^2Yzb. MacTavish: ^7Roach, şu isyan kalkanlarından birini al!", + "SUBTITLE_GULAG_CMT_OPENTHEDOOR737": "^2Yzb. MacTavish: ^7Kapıyı açın!", + "SUBTITLE_GULAG_GST_GOTIT738": "^2Ghost: ^7Neredeyse geldik! Yardımcı devre üzerinden yönlendiriliyor...", + "SUBTITLE_GULAG_CMT_GOTCOMPANY739": "^2Yzb. MacTavish: ^7Misafirimiz var!", + "SUBTITLE_GULAG_CMT_RIOTSHIELD740": "^2Yzb. MacTavish: ^7Bir isyan kalkanı kapın!", + "SUBTITLE_GULAG_GST_ALMOSTTHERE742": "^2Ghost: ^7Üzerinde çalışıyorum... Ana devre öldü! Beklemede kalın!", + "SUBTITLE_GULAG_CMT_USESHEILD743": "^2Yzb. MacTavish: ^7Ateşlerini çekmek için isyan kalkanını kullan!", + "SUBTITLE_GULAG_CMT_ILLDRAWFIRE744": "^2Yzb. MacTavish: ^7Ben isyan kalkanıyla ateşlerini çekeceğim, sen de onları hakla!", + "SUBTITLE_GULAG_GST_BYPASSFLOORS745": "^2Ghost: ^7Ben Ghost. Şu pencereden iple inerek alt katları atlamanı öneririm.", + "SUBTITLE_GULAG_CMT_ROACHFOLLOW746": "^2Yzb. MacTavish: ^7Anlaşıldı! Roach, beni takip et!", + "SUBTITLE_GULAG_GST_GOTIT2738_2": "^2Ghost: ^7Tamamdır!", + "SUBTITLE_GULAG_TF1_LASTFLOOR81": "^2TF-141 Asker: ^7Son kat temiz. En altta sizinle bağlantı kuracağız.", + "SUBTITLE_GULAG_TF1_CAPTAINLASTFLOOR82": "^2TF-141 Asker: ^7Yüzbaşı MacTavish, son kat temiz. En altta sizinle bağlantı kuracağız.", + "SUBTITLE_GULAG_GST_FEEDISDEAD83": "^2Ghost: ^7Hücre hapsindeki kamera yayını kesik. O bölümde elektrikler kesik olmalı.", + "SUBTITLE_GULAG_CMT_SWITCHNV84": "^2Yzb. MacTavish: ^7Anlaşıldı. Manga, gece görüşüne geçin.", + "SUBTITLE_GULAG_CMT_STRAGGLERS85": "^2Yzb. MacTavish: ^7Hücrelerde kaçak olup olmadığını kontrol edin.", + "SUBTITLE_GULAG_CMT_CALLOFF86": "^2Yzb. MacTavish: ^7Shepherd, bu da neydi böyle? Donanmaya ateşi kesmelerini söyle!", + "SUBTITLE_GULAG_HQR_WORKING87": "^2Shepherd: ^7Donanma şu anda konuşma havasında değil. Beklemede kalın.", + "SUBTITLE_GULAG_HQR_LOOSECANNON88": "^2Shepherd: ^7Bravo Altı - şimdilik ateşi kesmeyi kabul ettiler. Devam edin, sizi haberdar edeceğim", + "SUBTITLE_GULAG_GST_JUNCTIONA1291": "^2Ghost: ^7Yedek güç devrede. A-12 kavşağındaki geçidi açıyoruz - merdivenlerden aşağı inin ve servis tünellerine girin.", + "SUBTITLE_GULAG_CMT_GOGOGO192": "^2Yzb. MacTavish: ^7Hadi hadi hadi!", + "SUBTITLE_GULAG_GST_ONCAMERAS93": "^2Ghost: ^7Tamam, seni kameralarda görüyorum.", + "SUBTITLE_GULAG_GST_30FTONLEFT94": "^2Ghost: ^7Eski duş odası yaklaşık 30 metre ileride solunda. İçeri girmek için duvarı aşman gerekecek.", + "SUBTITLE_GULAG_CMT_PLANTBREACH95": "^2Yzb. MacTavish: ^7Roach - duvara patlayıcıyı yerleştir, kestirmeden gideceğiz.", + "SUBTITLE_GULAG_CMT_HURRYUP96": "^2Yzb. MacTavish: ^7Roach - kapıya değil! Patlayıcıyı şuradaki duvara yerleştir!", + "SUBTITLE_GULAG_CMT_FORGETTHATDOOR97": "^2Yzb. MacTavish: ^7Roach - kapıyı unut! Patlayıcıyı duvara yerleştir, kestirmeden gidiyoruz!", + "SUBTITLE_GULAG_CMT_SPREADOUT101": "^2Yzb. MacTavish: ^7Dağılın!", + "SUBTITLE_GULAG_CMT_HOSTILES2NDFLOOR102": "^2Yzb. MacTavish: ^7İkinci katta düşmanlar var! İndirin onları!", + "SUBTITLE_GULAG_CMT_KEEPMOVING103": "^2Yzb. MacTavish: ^7Devam edin!", + "SUBTITLE_GULAG_CMT_USELOCKERS104": "^2Yzb. MacTavish: ^7Siper almak için dolapları kullanın!", + "SUBTITLE_GULAG_CMT_HITFROMSIDE105": "^2Yzb. MacTavish: ^7İleride ağır saldırı birlikleri var! Onlara doğrudan saldırmayın! Hızlı hareket edin ve onları yandan vurun!", + "SUBTITLE_GULAG_CMT_COOKGRENADES106": "^2Yzb. MacTavish: ^7El bombalarını arkalarında patlayacak şekilde hazırla!", + "SUBTITLE_GULAG_CMT_HOLEINFLOOR111": "^2Yzb. MacTavish: ^7Duşların uzak tarafındaki zemindeki deliğe doğru gidiyorum! Beni takip edin! Hadi gidelim!", + "SUBTITLE_GULAG_CMT_WHICHWAY112": "^2Yzb. MacTavish: ^7Ghost, eski tünel sistemindeyiz, güney-güneybatıya gidiyoruz.", + "SUBTITLE_GULAG_GST_50METERS113": "^2Ghost: ^7Tamam. O tünel boyunca ilerlemeye devam et.", + "SUBTITLE_GULAG_CMT_STARTFIRING114": "^2Yzb. MacTavish: ^7Konuş benimle Ghost... O gemiler tekrar ateş etmeye başladığında burada olmak istemiyorum.", + "SUBTITLE_GULAG_GST_CISTERN115": "^2Ghost: ^7Devam et, neredeyse vardın.", + "SUBTITLE_GULAG_GST_8TANGOS116": "^2Ghost: ^7İki ısı izi tespit ediyorum - bunlardan biri Tutsak 627 olmalı.", + "SUBTITLE_GULAG_GST_8TANGOS2117": "^2Ghost: ^7Kuzeybatı duvarını aşarsan gardiyan iyileşmeden onu öldürmek için yeterli zamanın olur.", + "SUBTITLE_GULAG_CMT_HESWITHUS121": "^2Yzb. MacTavish: ^7Bırak onu!", + "SUBTITLE_GULAG_PRI_SOAP": "^2Yzb. Price: ^7Soap mu?", + "SUBTITLE_GULAG_CMT_BELONGSTOYOU": "^2Yzb. MacTavish: ^7Price? Bu size ait efendim.", + "SUBTITLE_GULAG_WRM_WHOSOAP123": "^2Worm: ^7Soap kim?", + "SUBTITLE_GULAG_CMT_GETOUTTAHEREMOVE125": "^2Yzb. MacTavish: ^7Hadi, buradan gitmeliyiz! Yürüyün! Kımıldayın!", + "SUBTITLE_GULAG_CMT_WEGOTCOMPANY127": "^2Yzb. MacTavish: ^7Misafirimiz var!", + "SUBTITLE_GULAG_CMT_NEEDMORETIME128": "^2Yzb. MacTavish: ^7Shepherd! Mahkûmu yakaladık ama henüz çıkmadık! Daha fazla zamana ihtiyacımız var!", + "SUBTITLE_GULAG_HQR_NOCANDO129": "^2Shepherd: ^7Donanma 'yapamayız' diyor. Hemen oradan çıkın.", + "SUBTITLE_GULAG_CMT_LETSGO1210": "^2Yzb. MacTavish: ^7Gidelim! Gidelim!", + "SUBTITLE_GULAG_CMT_READY2JUMP1211": "^2Yzb. MacTavish: ^7Helikopter orada! Atlamaya hazır olun!", + "SUBTITLE_GULAG_CMT_ANOTHERWAY1212": "^2Yzb. MacTavish: ^7Geri dön, geri dön! Başka bir çıkış yolu bulacağız!", + "SUBTITLE_GULAG_WRM_THISWAY1213": "^2Yzb. MacTavish: ^7Bu taraftan, bu taraftan!", + "SUBTITLE_GULAG_WRM_DEADEND1214": "^2Solucan: ^7Çıkmaz sokak!", + "SUBTITLE_GULAG_CMT_PRICE131": "^2Yzb. MacTavish: ^7Price?", + "SUBTITLE_GULAG_CMT_THISBELONGS132": "^2Yzb. MacTavish: ^7Bu size ait efendim.", + "SUBTITLE_GULAG_CMT_WHEREAREYOU134": "^2Yzb. MacTavish: ^7Altı-Dört, hangi cehennemdesin, tamam mı?!", + "SUBTITLE_GULAG_PLP_CANTSEE135": "^2Pave Low Pilot: ^7Bravo Altı, çok fazla duman var, seni göremiyorum, seni göremiyorum -", + "SUBTITLE_136": "^2Yzb. MacTavish: ^7Roach düştü!", + "SUBTITLE_137": "^2Yzb. MacTavish: ^7Roach!", + "SUBTITLE_GULAG_PRI_DOITFAST138": "^2Yzb. Price: ^7Soap ne yapacaksan çabuk yap!", + "SUBTITLE_GULAG_PLP_SEEFLARE139": "^2Pave Low Pilot: ^7Bravo Altı, işaret fişeğini görüyorum. SPIE teçhizatı yolda.", + "SUBTITLE_GULAG_PRI_LETSGO1310": "^2Yzb. Price: ^7Gidelim! Gidelim!", + "SUBTITLE_GULAG_CMT_HOOKUP21311": "^2Yzb. MacTavish: ^7Kancayı takın!", + "SUBTITLE_GULAG_CMT_GOGO1312": "^2Yzb. MacTavish: ^7Hadi, hadi!", + "SUBTITLE_INV_SIX_GOTBMP21": "^2Çvş. Foley: ^7Bir BTR'miz var! Çıkın, çıkın!", + "SUBTITLE_INV_SIX_TEAMTHISWAY22": "^2Çvş. Foley: ^7Takım, bu taraftan! Gidelim, gidelim!", + "SUBTITLE_INV_SIX_300MEAST23": "^2Çvş. Foley: ^7Raptor'u tespit ettim! 300 metre doğuda!", + "SUBTITLE_INV_SIX_PARATROOPER24": "^2Çvş. Foley: ^7Düşman paraşütçü çatıda!", + "SUBTITLE_INV_SIX_ENEMYPTROOP25": "^2Çvş. Foley: ^7Düşman paraşütçüsü 12 yönünde!", + "SUBTITLE_INV_SIX_RUSPTROOP26": "^2Çvş. Foley: ^7Rus paraşütçüleri saat 12 yönünde!", + "SUBTITLE_INV_SIX_REQAIRSUPPORT27": "^2Çvş. Foley: ^7Overlord, burası Avcı İki-Bir, hava desteği istiyoruz, tamam!", + "SUBTITLE_INV_HQR_ENGAGED28": "^2Overlord: ^7Avcı İki-Bir, tüm hava desteği çoktan devreye girdi.", + "SUBTITLE_INV_HQR_ENGAGED229": "^2Overlord: ^7Ek kara desteği konumunuza doğru ilerliyor ancak ağır bir direnişle karşılaştı, tamam.", + "SUBTITLE_INV_SIX_ONFOOT210": "^2Çvş. Foley: ^7Anlaşıldı Overlord.", + "SUBTITLE_INV_SIX_ONFOOT2211": "^2Çvş. Foley: ^7Haberiniz olsun, düşman zırhlılarıyla karşılaştık ve yaya olarak ilerliyoruz, tamam.", + "SUBTITLE_INV_HQR_GOODLUCK212": "^2Overlord: ^7Overlord herkesi duyuyor. İyi şanslar", + "SUBTITLE_INV_TCO_FOURSELVES213": "^2Çvş. Dunn: ^7Çavuş, karargâh az önce bize \"siktirin gidin\" mi dedi?", + "SUBTITLE_INV_SIX_PRETTYMUCH214": "^2Çvş. Foley: ^7Oldukça fazla, Onbaşı!", + "SUBTITLE_INV_SIX_HANGRIGHT31": "^2Çvş. Foley: ^7Ateş etmeyin! O BTR'ye saldırmayın - bizi ele geçirmediler!", + "SUBTITLE_INV_SIX_STAYBEHIND32": "^2Çvş. Foley: ^7Sağa dönün ve arkasında kalın!", + "SUBTITLE_INV_SIX_GRABRPG33": "^2Çvş. Foley: ^7Fark edildik! Ramirez, sis bombalarını kullan! Dunn, Morgan, onu koruyun!", + "SUBTITLE_INV_SIX_RPGSUPPLYDROP34": "^2Çvş. Foley: ^7Ramirez, erzak deposunda sis bombaları var! Hadi!", + "SUBTITLE_INV_SIX_THROWSEMTEX35": "^2Çvş. Foley: ^7Şu BTR'ye sis bombası atın!", + "SUBTITLE_INV_SIX_PICKUP36": "^2Çvş. Foley: ^7Erzak deposundan bir sis bombası al!", + "SUBTITLE_INV_SIX_GETSEMTEX37": "^2Çvş. Foley: ^7Takım, şu BTR'ye biraz sis bombası atın! Yürüyün!", + "SUBTITLE_INV_SIX_GETMORE38": "^2Çvş. Foley: ^7Ramirez erzak deposundan daha fazla sis bombası getir!", + "SUBTITLE_INV_SIX_DESTROY39": "^2Çvş. Foley: ^7Şu BTR'yi dumanla!", + "SUBTITLE_INV_SIX_NICEONE310": "^2Çvş. Foley: ^7Güzel. Şimdi herkes sağdaki sokağa girsin.", + "SUBTITLE_INV_SIX_COVEROFSMOKE311": "^2Çvş. Foley: ^7BTR'yi geçip ara sokağa girmek için dumanın örtüsünü kullanın!", + "SUBTITLE_INV_SIX_COMETOALLEY312": "^2Çvş. Foley: ^7Ramirez! Ara sokağa gel!", + "SUBTITLE_INV_SIX_VISCRASHSITE41": "^2Çvş. Foley: ^7Kaza alanından gelen dumanı gördüm. Raptor'un düştüğü yer orası!", + "SUBTITLE_INV_SIX_OUROBJECTIVE42": "^2Çvş. Foley: ^7Ekip, saat 12 yönünde düşen helikopter bizim hedefimiz.", + "SUBTITLE_INV_SIX_TAKEPOINT43": "^2Çvş. Foley: ^7Ramirez, nişan al - sağa doğru gidiyoruz.", + "SUBTITLE_INV_SIX_TRUCK1251": "^2Çvş. Foley: ^7Geliyor! Kamyon saat 12 yönünde!", + "SUBTITLE_INV_SIX_DONTENGAGEAPC61": "^2Çvş. Foley: ^7Takım, o BTR'ye saldırmayın - hedefimiz kaza alanı.", + "SUBTITLE_INV_SIX_GETBACKFROMAPC62": "^2Çvş. Foley: ^7Ramirez! O BTR'den geri çekilin!", + "SUBTITLE_INV_SIX_STAYWITHUS63": "^2Çvş. Foley: ^7Bizimle kal Ramirez!", + "SUBTITLE_INV_SIX_ONME64": "^2Çvş. Foley: ^7Benimle gel!", + "SUBTITLE_INV_SIX_GETOVERHERE65": "^2Çvş. Foley: ^7Buraya gel!", + "SUBTITLE_INV_SIX_GOGOGO66": "^2Çvş. Foley: ^7Hadi, hadi, hadi!", + "SUBTITLE_INV_SIX_CLOSEAIRSUPPORT67": "^2Çvş. Foley: ^7Tüm Avcı birimlerinin dikkatine, düşmanın AO'muzda faaliyet gösteren yakın hava desteği var.", + "SUBTITLE_INV_SIX_PURPLEBUILDING68": "^2Çvş. Foley: ^7Ateşinizi kontrol edin, ateşinizi kontrol edin! Dostlar saat 1 yönünde kahverengi binada.", + "SUBTITLE_INV_SIX_CRASHSITE69": "^2Çvş. Foley: ^7Ramirez, kaza alanındayız! Buraya gel!", + "SUBTITLE_INV_SIX_NORTHOFNATES610": "^2Çvş. Foley: ^7Kaza yeri Nate'in restoranının kuzey tarafında.", + "SUBTITLE_INV_SIX_GIMMESITREP71": "^2Çvş. Foley: ^7Asker! Bana bir durum raporu ver! Raptor nerede?", + "SUBTITLE_INV_SGW_MEATLOCKER72": "^2Er Wells: ^7Onu et dolabına taşıdık, pratik olarak kurşun geçirmez!", + "SUBTITLE_INV_SIX_STATUS73": "^2Çvş. Foley: ^7Durumu nedir?", + "SUBTITLE_INV_SGW_UNCONSCIOUS74": "^2Er Wells: ^7Hâlâ bilinci yerinde değil, doktorunuz var mı?", + "SUBTITLE_INV_SIX_WHATELSE75": "^2Çvş. Foley: ^7Onbaşı Dunn, kontrol edin! Başka ne var?", + "SUBTITLE_INV_SGW_SUPPLYDROP76": "^2Er Wells: ^7Çatıda bir M-5 nöbetçi silahı var!", + "SUBTITLE_INV_SIX_SENTRYGUNSOUTH77": "^2Çvş. Foley: ^7Ramirez - çatıya çık ve erzak teslimatını kontrol et!", + "SUBTITLE_INV_SIX_ANTITANK78": "^2Çvş. Foley: ^7Peki ya tanksavar silahları, hava desteği?", + "SUBTITLE_INV_SGW_ALLOUT79": "^2Er Wells: ^7Hepimiz bittik!", + "SUBTITLE_INV_SIX_ROGERTHAT710": "^2Çvş. Foley: ^7Anlaşıldı!", + "SUBTITLE_INV_SIX_LADDERINKITCHEN81": "^2Çvş. Foley: ^7Ramirez, mutfaktaki merdiveni kullan ve çatıya çık.", + "SUBTITLE_INV_SIX_GETTOROOF82": "^2Çvş. Foley: ^7Ramirez, ben Foley. Çatıya çık, mutfakta bir bakım merdiveni var.", + "SUBTITLE_INV_SIX_ONROOFYET83": "^2Çvş. Foley: ^7Ramirez, çatıya çıkmadın mı daha? Nöbetçi silahını çalıştır ve güneye doğrulttuğundan emin ol.", + "SUBTITLE_INV_SIX_HEADSUPLADIES91": "^2Çvş. Foley: ^7Dikkat bayanlar, güneyde kamyonlarımız var.", + "SUBTITLE_INV_SIX_2DOZEN92": "^2Çvş. Foley: ^7Güneyden geliyorlar! İki düzineden fazla ayaklı mobil!", + "SUBTITLE_INV_TCO_USINGSMOKE93": "^2Çvş. Dunn: ^7İlerleyişlerini gizlemek için duman kullanıyorlar!", + "SUBTITLE_INV_SIX_THERMALOPTICS94": "^2Çvş. Foley: ^7Manga, burası Avcı İki-Bir Gerçek. Elinizde varsa termal optiklere geçin.", + "SUBTITLE_INV_TCO_INCOMINGNORTH95": "^2Çvş. Dunn: ^7Geliyor, kuzey tarafı!", + "SUBTITLE_INV_TCO_CONTACTNORTH96": "^2Çvş. Dunn: ^7Kuzeyde temas var!", + "SUBTITLE_INV_TCO_INCOMINGSOUTH97": "^2Çvş. Dunn: ^7Geliyor, güney tarafı!", + "SUBTITLE_INV_TCO_CONTACTSOUTH98": "^2Çvş. Dunn: ^7Güneyde temas var!", + "SUBTITLE_INV_TCO_CONTACTNW99": "^2Çvş. Dunn: ^7Kuzeybatıda temas var!", + "SUBTITLE_INV_TCO_CONTACTSE910": "^2Çvş. Dunn: ^7Güneydoğu ile temas!", + "SUBTITLE_INV_TCO_INCOMINGHELO911": "^2Çvş. Dunn: ^7Gelen helikopter!", + "SUBTITLE_INV_SIX_SHIFTFIREN912": "^2Çvş. Foley: ^7Takım, ateşinizi kuzeye kaydırın.", + "SUBTITLE_INV_SIX_CONTACTSN913": "^2Çvş. Foley: ^7Takım, kuzeyde bağlantılarımız var.", + "SUBTITLE_INV_SIX_SHIFTFIREW914": "^2Çvş. Foley: ^7Takım, ateşinizi batıya kaydırın.", + "SUBTITLE_INV_SIX_CONTACTSW915": "^2Çvş. Foley: ^7Takım, batıya doğru temas kurun.", + "SUBTITLE_INV_TCO_SMOKESCRNTH916": "^2Çvş. Dunn: ^7Kuzeyde bir sis perdesi oluşturuyorlar.", + "SUBTITLE_INV_TCO_SMOKESCRWEST917": "^2Çvş. Dunn: ^7Batıda bir düşman sis perdesi var.", + "SUBTITLE_INV_SIX_SWITCHTHERMAL918": "^2Çvş. Foley: ^7Anlaşıldı. Varsa termal kameraya geç.", + "SUBTITLE_INV_SIX_ROOFBEHIND919": "^2Çvş. Foley: ^7Tangolar arkamızdaki çatıda!", + "SUBTITLE_INV_SIX_ENEMIESONROOF920": "^2Çvş. Foley: ^7Çevremiz ihlal edildi! Düşmanlar çatıda!", + "SUBTITLE_INV_SIX_INSIDEPERIM921": "^2Çvş. Foley: ^7Temas! Düşmanlar çatıda! Çevremizin içinde!", + "SUBTITLE_INV_SIX_TURNAROUND922": "^2Çvş. Foley: ^7Manga! Düşmanlar çatıda! Geri dönün!", + "SUBTITLE_INV_SIX_HADENOUGH923": "^2Çvş. Foley: ^7Ivan'ın canına tak etmiş gibi görünüyor.", + "SUBTITLE_INV_SIX_SITREPONRAPTOR924": "^2Çvş. Foley: ^7Onbaşı Dunn, Raptor hakkında durum raporu verin, tamam.", + "SUBTITLE_INV_TCO_SECUREANDSTABLE925": "^2Çvş. Dunn: ^7Raptor güvenli ve istikrarlı.", + "SUBTITLE_INV_SIX_CHECKAMMO927": "^2Çvş. Foley: ^7Anlaşıldı. Herkes silahlarını ve cephânesini kontrol etsin. Geri gelecekler.", + "SUBTITLE_INV_SIX_REGROUP928": "^2Çvş. Foley: ^7İyi işti takım. Burada toplanın.", + "SUBTITLE_INV_SIX_REGROUPINREST929": "^2Çvş. Foley: ^7Ramirez, restoranda yeniden toplanın.", + "SUBTITLE_INV_WRM_WHATWASTHAT101": "^2Çvş. Dunn: ^7Bu da neydi böyle?!", + "SUBTITLE_INV_SIX_GETOFFROOF102": "^2Çvş. Foley: ^7Manga! Çatıdan inin!", + "SUBTITLE_INV_SIX_OFFTHEROOF103": "^2Çvş. Foley: ^7Ramirez! Çatıdan... inin!", + "SUBTITLE_INV_SIX_GETOFFROOF2104": "^2Çvş. Foley: ^7Çatıdan in!", + "SUBTITLE_INV_SIX_GETOFFROOFNOW105": "^2Çvş. Foley: ^7Hemen çatıdan inin!", + "SUBTITLE_INV_TCO_HOWCOPY111": "^2Çvş. Dunn: ^7Çavuş Foley, ben Avcı İki-Bir-Delta - nasıl anlaşıldı?", + "SUBTITLE_INV_SIX_SOLIDCOPY112": "^2Çvş. Foley: ^7Anlaşıldı İki-Bir-Delta, devam et!", + "SUBTITLE_INV_TCO_UAVOP113": "^2Çvş. Dunn: ^7O füzeleri uzaktan kumanda eden bir düşman İHA operatörü görüyorum!", + "SUBTITLE_INV_TCO_UAVOP2114": "^2Çvş. Dunn: ^7Batıdaki lokantanın içinde, tamam!", + "SUBTITLE_INV_SIX_KILLTHATSOB115": "^2Çvş. Foley: ^7Ramirez! Oraya git ve o pisliği öldür!", + "SUBTITLE_INV_SIX_KILLTHATSOB2116": "^2Çvş. Foley: ^7Sana yardım etmesi için ekibin bir kısmını gönderiyorum! Gidin!", + "SUBTITLE_INV_TCO_COPIESALL117": "^2Çvş. Dunn: ^7İki-Bir-Delta anlaşıldı. Ramirez, sen benimlesin, gidelim.", + "SUBTITLE_INV_SIX_BMPSFROMNORTH118": "^2Çvş. Foley: ^7İki-Bir-Delta, kuzeyden iki BTR geliyor, haberiniz olsun.", + "SUBTITLE_INV_TCO_ROGERTHAT119": "^2Çvş. Dunn: ^7Anlaşıldı.", + "SUBTITLE_INV_SIX_BMPSPOTTEDYOU1110": "^2Çvş. Foley: ^7Siper alın! BTR seni gördü!", + "SUBTITLE_INV_SIX_BMPHASAVISUAL1111": "^2Çvş. Foley: ^7Yere yatın! BTR'lerden biri seni görüyor!", + "SUBTITLE_INV_SIX_BEHINDSOLID1112": "^2Çvş. Foley: ^7Sağlam bir şeyin arkasına geçin! O BTR seni görüş alanına aldı!", + "SUBTITLE_INV_SIX_BMPLOSTYOU1113": "^2Çvş. Foley: ^7BTR seni kaybetti! Hadi, hadi, hadi!", + "SUBTITLE_INV_SIX_BMPLOSTYOUMOVE1114": "^2Çvş. Foley: ^7BTR seni gözden kaybetti! Yürü!", + "SUBTITLE_INV_SIX_BMPLOSTYOUGO1115": "^2Çvş. Foley: ^7Pekâlâ, BTR seni kaybetti! Hadi, hadi, hadi!", + "SUBTITLE_INV_TCO_CONTROLRIG121": "^2Çvş. Dunn: ^7Ramirez - İHA için kontrol teçhizatını getir!", + "SUBTITLE_INV_TCO_PICKUPCONTROLRIG122": "^2Çvş. Dunn: ^7Ramirez - Ben seni korurum! Kontrol teçhizatını al!", + "SUBTITLE_INV_TCO_INCOMING123": "^2Çvş. Dunn: ^7Geliyor!", + "SUBTITLE_INV_TCO_BACKDOOR124": "^2Çvş. Dunn: ^7Arka kapı!", + "SUBTITLE_INV_SIX_WASTEBMPSNOW125": "^2Çvş. Foley: ^7Ramirez! Şu BTR'leri vurun! Şimdi!", + "SUBTITLE_INV_SIX_NEUTRALIZEARMOR126": "^2Çvş. Foley: ^7Ramirez, şu düşman zırhını etkisiz hâle getir.", + "SUBTITLE_INV_SIX_DESTROYAPCS127": "^2Çvş. Foley: ^7Şu BTR'leri yok edin!", + "SUBTITLE_INV_SIX_STILLONEBMP128": "^2Çvş. Foley: ^7Hâlâ bir BTR kaldı!", + "SUBTITLE_INV_SIX_WASTETHATBMPNOW129": "^2Çvş. Foley: ^7O BTR'yi şimdi harcayın!", + "SUBTITLE_INV_SIX_ONEMORE1210": "^2Çvş. Foley: ^7Hedef üzerinde iyi etki. Bu bir ölüm. Bir tane daha kaldı.", + "SUBTITLE_INV_SIX_FASTMOVERS131": "^2Çvş. Foley: ^7Düşman hızlı hareket ediyor! Siper alın!", + "SUBTITLE_INV_TCO_STILLTHERE132": "^2Çvş. Dunn: ^7Two-One-Actual hâlâ orada mısın?", + "SUBTITLE_INV_SIX_NEWPLAN133": "^2Çvş. Foley: ^7Anlaşıldı. Herkes dinlesin - yeni plân.", + "SUBTITLE_INV_SIX_SECUREBURGERTOWN134": "^2Çvş. Foley: ^7Ramirez! Takımını al ve Burger Kasabası'nın güvenliğini sağla! Raptor'u oraya taşıyacağız! Bu konum tehlikeye girdi!", + "SUBTITLE_INV_SIX_OVERWATCH135": "^2Çvş. Foley: ^7Onbaşı Dunn, Burger Kasabası'nın çatısına çık ve gözcülük yap! Ramirez, benimle yeniden toplanın! VIP'yi hareket ettirmeliyiz!", + "SUBTITLE_INV_TCO_REGROUPSQUAD136": "^2Çvş. Dunn: ^7Anlaşıldı, ben Oscar Mike! Ramirez, ekiple yeniden toplanın, hadi!", + "SUBTITLE_INV_SIX_RAMIREZONME137": "^2Çvş. Foley: ^7Ramirez, benimle gel! Takımla yeniden toplanın!", + "SUBTITLE_INV_SIX_BACKHERE138": "^2Çvş. Foley: ^7Ramirez! Onbaşı Dunn çatıyı kapattı! Sana burada ihtiyacımız var! Kımıldayın!", + "SUBTITLE_INV_SIX_LISTENUP139": "^2Çvş. Foley: ^7Herkes dinlesin! Raptor'u hemen götürüyoruz! Nates'in güney girişine yığınak yapın!", + "SUBTITLE_INV_SIX_ANOTHERPASS1310": "^2Çvş. Foley: ^7O hızlı taşıyıcılar başka bir geçiş yapmadan önce bu binadan çıkmamız gerekiyor.", + "SUBTITLE_INV_SIX_HOSTILESINBT1311": "^2Çvş. Foley: ^7Ramirez! Burger Town yakınlarında hâlâ düşmanlarımız var, harekete geçmeliyiz!", + "SUBTITLE_INV_SIX_WHATSHOLDUP1312": "^2Çvş. Foley: ^7Ramirez, Raptor'u hemen hareket ettirmeliyiz! O restoranı temizleyin!", + "SUBTITLE_INV_SIX_NEEDTOMOVE1313": "^2Çvş. Foley: ^7Ramirez, VIP'yi hemen götürmeliyiz! O restoranı boşaltın!", + "SUBTITLE_INV_SIX_LOCKANDLOAD141": "^2Çvş. Foley: ^7Ekip, haberiniz olsun, Raptor'u Nate's'ten Burger Town'a grup olarak taşıyacağız!", + "SUBTITLE_INV_SIX_ONTHREE142": "^2Çvş. Foley: ^7Üç deyince!", + "SUBTITLE_INV_TCO_HESDOWN143": "^2Çvş. Dunn: ^7Tango düştü.", + "SUBTITLE_INV_SIX_KEEPOFFME143": "^2Çvş. Foley: ^7Bu adamları benden uzak tutun!", + "SUBTITLE_INV_SIX_ONE144": "^2Çvş. Foley: ^7Bir!", + "SUBTITLE_INV_SIX_TWO145": "^2Çvş. Foley: ^7İki!", + "SUBTITLE_INV_SIX_GOTTHEPRESIDENT146": "^2Çvş. Foley: ^7Ekip, Burger Kasabası'nın et dolabına ulaştım. Raptor içeride ve güvende.", + "SUBTITLE_INV_SIX_THREE147": "^2Çvş. Foley: ^7Üç!", + "SUBTITLE_INV_SIX_GOTTHEPRESIDENT2148": "^2Çvş. Foley: ^7Kapı kapalı - siz Ivan'ı dışarıda tutun.", + "SUBTITLE_INV_SIX_GOGOGO2149": "SUBTITLE_INV_SIX_GOGOGO2149", + "SUBTITLE_INV_SIX_THEINFANTRY152": "^2Çvş. Foley: ^7Ramirez, düşmanlarımız var! Raptor'u korumak için Predator Drone kontrol teçhizatını kullan!", + "SUBTITLE_INV_SIX_THEINFANTRY2154": "^2Çvş. Foley: ^7Ramirez, uzaktan kumandalı Predator füzelerini kullan! Gelen piyadeler var! Onları Burgertown'dan uzak tutun!", + "SUBTITLE_INV_SIX_THATARMOR156": "^2Çvş. Foley: ^7Ramirez uzaktan kumandalı teçhizatını kullan ve düşman zırhına birkaç Predator Füzesi fırlat!", + "SUBTITLE_INV_HQR_BANKTONORTH161": "^2Overlord: ^7Dikkatli ol Avcı İki-Bir, kuzeydeki kıyıda bir düşman devriyesi var, tamam.", + "SUBTITLE_INV_HQR_FOOTMOBILES162": "^2Overlord: ^7Avcı İki-Bir, haberiniz olsun, on beşten fazla düşman yaya aracı bulunduğunuz yerin kuzeyine yaklaşıyor, tamam.", + "SUBTITLE_INV_HQR_SOUTHEAST163": "^2Overlord: ^7Avcı İki-Bir, Overlord. Tahminen yirmi düşman yaya aracı güneydoğudan size yaklaşıyor, tamam.", + "SUBTITLE_INV_HQR_VISUALSE164": "^2Overlord: ^7Avcı İki-Bir, Goliath Bir güneydoğudan gelen bir düşman devriyesi görüyor, tamam.", + "SUBTITLE_INV_HQR_TACOJOINT165": "^2Overlord: ^7Avcı İki-Bir, haberiniz olsun, taco lokantası yakınlarında çok sayıda düşman yaya aracı görüldü, tamam.", + "SUBTITLE_INV_HQR_ENEMYNORTH166": "^2Overlord: ^7Avcı İki-Bir, burası Gerçek Overlord, kuzeyinizde büyük bir düşman takviye grubu görüyoruz, tamam.", + "SUBTITLE_INV_HQR_NOVAGASSTATION167": "^2Overlord: ^7Avcı İki-Bir, Avcı Dört Nova benzin istasyonu yakınlarında düşman bir grup görüyor, tamam.", + "SUBTITLE_INV_HQR_DINERWEST168": "^2Overlord: ^7Avcı İki-Bir, on beşten fazla tango batıdaki lokantanın yanına yaklaşıyor, tamam.", + "SUBTITLE_INV_HQR_ENEMYWEST169": "^2Overlord: ^7Avcı İki-Bir, Goliath İki'den aktarıyorum, düşman takviye kuvvetleri batıdan yaklaşıyor, tamam.", + "SUBTITLE_INV_HQR_HELLFIREONLINE1611": "^2Overlord: ^7Avcı İki-Bir AGM füzesi devrede.", + "SUBTITLE_INV_HQR_HELLFIREONLINE21613": "^2Overlord: ^7AGM füzesi çevrimiçi.", + "SUBTITLE_INV_HQR_HELLFIREONLINE31615": "^2Overlord: ^7AGM füzesi devrede. Tekrar ediyorum, AGM füzesi devrede.", + "SUBTITLE_INV_HQR_HELLFIREOFFLINE1617": "^2Overlord: ^7AGM'ler çevrimdışı.", + "SUBTITLE_INV_HQR_HELLFIREDOWN1619": "^2Overlord: ^7AGM'ler düştü Avcı İki-Bir.", + "SUBTITLE_INV_HQR_PREDATOROFFLINE1620": "^2Overlord: ^7Predator drone'u çevrimdışı.", + "SUBTITLE_INV_HQR_PREDATOROFFLINE1621": "^2Overlord: ^7İHA çevrimdışı.", + "SUBTITLE_INV_HQR_PREDATOROFFLINE21622": "^2Overlord: ^7Predatör insansız hava aracı çevrimdışı.", + "SUBTITLE_INV_HQR_PREDATOROFFLINE21623": "^2Overlord: ^7İHA çevrimdışı.", + "SUBTITLE_INV_HQR_FIVENOTENKILLS1624": "^2Overlord: ^7Bu en az beş, hayır, on öldürme gibi görünüyor Avcı İki-Bir. Devam et.", + "SUBTITLE_INV_HQR_TENMORECONFIRMS1625": "^2Overlord: ^7Oh adamım. Bu en az on tane daha Avcı İki-Bir'i doğruluyor. İyi atıştı.", + "SUBTITLE_INV_HQR_TENPLUSKIA1626": "^2Overlord: ^7On artı KIA. İyi vuruş. İyi vuruş.", + "SUBTITLE_INV_HQR_FIVEPLUS1627": "^2Overlord: ^7Beş artı onaylanmış öldürme. İyi işti. Avcı İki-Bir.", + "SUBTITLE_INV_HQR_ANOTHER5PLUS1628": "^2Overlord: ^7Avcı İki-Bir, bir beş artı daha onaylandı.", + "SUBTITLE_INV_HQR_MORETHANFIVE1629": "^2Overlord: ^7İyi vuruş. Beşten fazla ölü var.", + "SUBTITLE_INV_HQR_YOUGOTEM1630": "^2Overlord: ^7Onları hakladın. İyi öldürdün.", + "SUBTITLE_INV_HQR_GOODKILLS1631": "^2Overlord: ^7İyi öldürmeler Avcı İki-Bir. İyi öldürmeler.", + "SUBTITLE_INV_HQR_DIRECTHIT1632": "^2Overlord: ^7Bu tam isabet Avcı İki-Bir, ateş etmeye devam et.", + "SUBTITLE_INV_HQR_HESDOWN1633": "^2Overlord: ^7Düştü.", + "SUBTITLE_INV_TCO_FIREDMISSILE172": "^2Ranger: ^7Birisi az önce Predator'ümüzü indirdi!", + "SUBTITLE_INV_TCO_UAVOFFLINE174": "^2Ranger: ^7Dikkatli olun, Predator çevrimdışı Tekrar ediyorum, Predator çevrimdışı!", + "SUBTITLE_INV_HQR_ENEMYHELO181": "^2Overlord: ^7Avcı İki-Bir, ben Overlord. Bölgenize doğru gelen bir çift düşman saldırı helikopteri görüyoruz, tamam.", + "SUBTITLE_INV_HQR_RELAYGOL1182": "^2Overlord: ^7Avcı İki-Bir, Goliath Bir'den aktarıyorum: Bölgenize yaklaşan bir düşman helikopteri var, tamam.", + "SUBTITLE_INV_TCO_EYESUP183": "^2Çvş. Dunn: ^7Gözler yukarı! Düşman savaş helikopteri yaklaşıyor!", + "SUBTITLE_INV_SIX_CONCENTRATEFIRE184": "^2Çvş. Foley: ^7Manga, savaş gemisine RPG fırlatın! İndirin onu!", + "SUBTITLE_INV_SIX_KEEPFIRING185": "^2Çvş. Foley: ^7Manga, RPG'niz varsa ateş etmeye devam edin! Onu indirmeliyiz!", + "SUBTITLE_INV_SIX_TAKEGUNSHIP186": "^2Çvş. Foley: ^7Manga! Konvoy gelmeden o savaş gemisini yok edin! Hadi! Hadi! Hadi! Hadi!", + "SUBTITLE_INV_SIX_ANTIAIRCRAFT187": "^2Çvş. Foley: ^7Takım, bir uçaksavar silahı bulun ve savaş gemisini yok edin!", + "SUBTITLE_INV_SIX_ANOTHERHELO188": "^2Çvş. Foley: ^7İkinci helikopter şimdi ortaya çıktı! İndirin onu!", + "SUBTITLE_INV_SIX_TAKEDOWN189": "^2Çvş. Foley: ^7Anlaşıldı Overlord. Takım! Helikopteri indirin! Hadi!", + "SUBTITLE_INV_HQR_CAPUNAVAIL1810": "^2Overlord: ^7Avcı İki-Bir, haberiniz olsun, düşman helikopteri bölgenize yaklaşıyor. CAP şu anda kullanılamıyor, iyi şanslar, tamam.", + "SUBTITLE_INV_SIX_BEFORECONVOY1811": "^2Çvş. Foley: ^7Herkes, konvoy gelmeden o helikopteri indirsin! Kımıldayın!", + "SUBTITLE_INV_TCO_ROOFOFNATES1812": "^2Çvş. Dunn: ^7Ramirez! Nate'in çatısında bir çift Stinger gördüm!", + "SUBTITLE_INV_TCO_ROOFOFNATES21813": "^2Çvş. Dunn: ^7O orospu çocuğunu indirmek için onları kullan! Hadi!", + "SUBTITLE_INV_TCO_KILLTHATHELO1814": "^2Çvş. Dunn: ^7Ramirez! Nate'in restoranının çatısında Stinger'lar var!", + "SUBTITLE_INV_TCO_KILLTHATHELO21815": "^2Çvş. Dunn: ^7Onları helikopteri öldürmek için kullan! Hadi! Hadi! Hadi! Hadi! Hadi! Hadi!", + "SUBTITLE_INV_SIX_CHECKTHEROOF1816": "^2Çvş. Dunn: ^7Ramirez! Nate'in restoranının çatısını kontrol et! Orada birkaç Stinger gördüm!", + "SUBTITLE_INV_SIX_SUPPLYDROPONROOF1817": "^2Çvş. Dunn: ^7Ramirez! Nate'in çatısındaki erzak deposunun yanında birkaç Stinger var!", + "SUBTITLE_INV_TCO_DISPATCHCHOPPER1818": "^2Çvş. Dunn: ^7Ramirez! Batıdaki lokantada bir Stinger füzesi gördüm!", + "SUBTITLE_INV_TCO_DISPATCHCHOPPER21819": "^2Çvş. Dunn: ^7Helikopteri yok etmek için kullan! Ben seni korurum! Git!", + "SUBTITLE_INV_TCO_INSIDEDINER1820": "^2Çvş. Dunn: ^7Batıdaki depoda bir Stinger füzesi var!", + "SUBTITLE_INV_TCO_INSIDEDINER21821": "^2Çvş. Dunn: ^7Lokantanın içinde! Seni koruyorum! Kımılda!", + "SUBTITLE_INV_TCO_NEXTTOSTATION1822": "^2Çvş. Dunn: ^7Batıdaki benzin istasyonunun yanında bir lokanta var! Stinger füzesi için orayı kontrol et!", + "SUBTITLE_INV_TCO_DINERUAV1823": "^2Çvş. Dunn: ^7İHA kontrol teçhizatını aldığımız lokantada bir Stinger füzesi gördüm!", + "SUBTITLE_INV_TCO_ROOFOFNATES1824": "^2Çvş. Foley: ^7Takım! Nate'in çatısında birkaç Stinger gördüm!", + "SUBTITLE_INV_TCO_ROOFOFNATES21825": "^2Çvş. Foley: ^7O orospu çocuğunu indirmek için onları kullanın! Hadi!", + "SUBTITLE_INV_TCO_KILLTHATHELO1826": "^2Çvş. Foley: ^7Nate'in restoranının çatısında Stinger'lar var!", + "SUBTITLE_INV_TCO_KILLTHATHELO21827": "^2Çvş. Foley: ^7Onları helikopteri öldürmek için kullan! Hadi! Hadi! Hadi! Hadi! Hadi!", + "SUBTITLE_INV_SIX_CHECKTHEROOF1828": "^2Çvş. Foley: ^7Nate'in restoranının çatısını kontrol edin! Orada birkaç Stinger gördüm!", + "SUBTITLE_INV_SIX_SUPPLYDROPONROOF1829": "^2Çvş. Foley: ^7Takım! Nate'in çatısındaki erzak deposunun yanında birkaç Stinger var!", + "SUBTITLE_INV_TCO_DISPATCHCHOPPER1830": "^2Çvş. Foley: ^7Takım! Batıdaki lokantada bir Stinger füzesi gördüm!", + "SUBTITLE_INV_TCO_DISPATCHCHOPPER21831": "^2Çvş. Foley: ^7Helikopteri yok etmek için kullan! Ben sizi korurum! Git!", + "SUBTITLE_INV_TCO_INSIDEDINER1832": "^2Çvş. Foley: ^7Batıdaki depoda bir Stinger füzesi var!", + "SUBTITLE_INV_TCO_INSIDEDINER21833": "^2Çvş. Foley: ^7Lokantanın içinde! Seni koruyorum! Kımılda!", + "SUBTITLE_INV_TCO_NEXTTOSTATION1834": "^2Çvş. Foley: ^7Batıdaki benzin istasyonunun yanında bir lokanta var! Stinger füzesi için orayı kontrol et!", + "SUBTITLE_INV_TCO_DINERUAV1835": "^2Çvş. Foley: ^7Predator Drone kontrol teçhizatını aldığımız lokantada bir Stinger füzesi gördüm!", + "SUBTITLE_INV_SIX_CONVOYSHERE191": "^2Çvş. Foley: ^7Konvoy burada! Herkes bana! Buradan defolup gidiyoruz! Gidelim, gidelim!", + "SUBTITLE_INV_SIX_SOUTHOFBTOWN192": "^2Çvş. Foley: ^7Ramirez! Konvoy Burger Kasabası'nın hemen güneyinde, buraya gel! Kımılda!", + "SUBTITLE_INV_TCO_BACKTOCONVOY193": "^2Çvş. Dunn: ^7Ramirez! Konvoya geri dönmeliyiz! Gidelim!", + "SUBTITLE_INV_SIX_FRIEDLYCONVOY194": "^2Çvş. Foley: ^7Dost konvoy Oscar Mike.", + "SUBTITLE_INV_HQR_SITREP195": "^2Overlord: ^7Avcı İki-Bir, ben Overlord, durum raporu ver.", + "SUBTITLE_INV_SIX_CARGOSECURE196": "^2Çvş. Foley: ^7Overlord, Avcı İki-Bir. Dikkat: değerli kargo güvende, tekrar ediyorum, değerli kargo güvende. Biz Oscar Mike'ız.", + "SUBTITLE_INV_HQR_GOODJOB197": "^2Overlord: ^7Overlord hepsini anladı. İyi işti", + "SUBTITLE_INV_FLY_2KCIVVIES198": "^2Çvş. Foley: ^7Ekip, Arcadia'da hâlâ 2000 sivil var! Orada aileniz varsa şanslı gününüzdesiniz - gidip hayatlarını kurtaracağız!", + "SUBTITLE_INV_SIX_NICEONETEAM201": "^2Çvş. Foley: ^7İyi işti! Helikopter düştü.", + "SUBTITLE_INV_SIX_NICEONEHELI202": "^2Çvş. Foley: ^7İyi işti takım!", + "SUBTITLE_119": "^2NORAD Karargâhı: ^7Sierra Delta durum raporu ver, tamam.", + "SUBTITLE_OILRIG_NSL_OUTTOGETHER41": "^2Yzb. MacTavish: ^2 ^7Yerini aldı. Onları birlikte çıkaralım. Başlayın.", + "SUBTITLE_OILRIG_NSL_SAMETIME42": "^2Yzb. MacTavish: ^7Onları aynı anda çıkaracağız... hareket hâlindeyken.", + "SUBTITLE_OILRIG_NSL_BOTHOUT43": "^2Yzb. MacTavish: ^7İkisini de çıkaracağız...sen giderken.", + "SUBTITLE_OILRIG_NSL_INPOSITION44": "^2Yzb. MacTavish: ^7Yerinde... hareket hâlinde.", + "SUBTITLE_OILRIG_NSL_SECT1ALPHA51": "^2Yzb. MacTavish: ^7Bölüm Bir-Alfa'da iki düşman vuruldu. İkinci bölüme geçiyoruz.", + "SUBTITLE_OILRIG_SBC_ROGERHTLSIX52": "^2Yardımcı Komutan: ^7Anlaşıldı, Hotel Altı.", + "SUBTITLE_OILRIG_NSL_READYWEAPONS53": "^2Yzb. MacTavish: ^7Silahları hazırlayın.", + "SUBTITLE_OILRIG_NSL_MOVEUP254": "^2Yzb. MacTavish: ^7İlerleyin.", + "SUBTITLE_OILRIG_NSL_KEEPITTIGHT55": "^2Yzb. MacTavish: ^7Sıkı durun millet.", + "SUBTITLE_OILRIG_NSL_EYESOPEN56": "^2Yzb. MacTavish: ^7Gözler açık. Sektörlerinize dikkat edin.", + "SUBTITLE_OILRIG_NSL_GETREADY57": "^2Yzb. MacTavish: ^7Hazır olun.", + "SUBTITLE_OILRIG_NS1_VISBYRAILING61": "^2Ghost: ^7Parmaklıklarda bir görüntü var.", + "SUBTITLE_OILRIG_NSL_SUPPWEAPONS62": "^2Yzb. MacTavish: ^7Çatışma serbest. Sadece bastırılmış silahlar.", + "SUBTITLE_OILRIG_SBC_CIVILHOSTAGES63": "^2Yardımcı Komutan: ^7Pozisyonunuzdaki sivil rehineler, ateşinize dikkat edin.", + "SUBTITLE_OILRIG_NSL_TM1TOBREACH64": "^2Yzb. MacTavish: ^7Anlaşıldı. Birinci Takım yarmak için hareket ediyor.", + "SUBTITLE_OILRIG_NSL_FRAMECHARGE65": "^2Yzb. MacTavish: ^7Kapıya bir çerçeve yükleyin. Odayı iki taraftan da vuracağız.", + "SUBTITLE_OILRIG_NSL_CHARGEONDOOR66": "^2Yzb. MacTavish: ^7Kapıya hücum edin. Her iki taraftan da gireceğiz.", + "SUBTITLE_OILRIG_NSL_BLOWDOORS67": "^2Yzb. MacTavish: ^7Kapıları patlatın. Her iki taraftan da vuracağız.", + "SUBTITLE_OILRIG_NSL_INTOPOSTION68": "^2Yzb. MacTavish: ^7Pozisyon alın.", + "SUBTITLE_OILRIG_NS1_INPOSITION69": "^2Ghost: ^7Pozisyon alın.", + "SUBTITLE_OILRIG_NS1_READYBREACH611": "^2Ghost: ^7İhlale hazır.", + "SUBTITLE_OILRIG_NS1_INPOSBREACH613": "^2Ghost: ^7İhlal için pozisyon alındı.", + "SUBTITLE_OILRIG_NS1_BREACHING615": "^2Ghost: ^7İhlal.", + "SUBTITLE_OILRIG_NS1_PLANTINGCHARGE617": "^2Ghost: ^7Dikim ücreti.", + "SUBTITLE_OILRIG_NS1_PLANTFRMCHARGE619": "^2Ghost: ^7Dikim çerçevesi şarjı.", + "SUBTITLE_OILRIG_NS1_WATCHFIELDFIRE621": "^2Ghost: ^7Ateş alanınıza dikkat edin.", + "SUBTITLE_OILRIG_NS2_CHECKTARGETS622": "^2Ghost: ^7Hedeflerinizi kontrol edin. Burada siviller var.", + "SUBTITLE_OILRIG_NS1_ONMARKGO623": "^2Ghost: ^7İşaretimle...git!", + "SUBTITLE_OILRIG_NS1_ONMYMARK624": "^2Ghost: ^7İşaretimle...", + "SUBTITLE_OILRIG_NS1_GO625": "^2Ghost: ^7Hadi!", + "SUBTITLE_OILRIG_NS1_BREACHWATCHFIRE629": "^2Ghost: ^7İhlal. Ateşinize dikkat edin.", + "SUBTITLE_OILRIG_NS2_BREACHCHECKTARG630": "^2Ghost: ^7İhlal. Hedeflerinizi kontrol edin.", + "SUBTITLE_OILRIG_NS1_WERECLEAR631": "^2Ghost: ^7Temiziz.", + "SUBTITLE_OILRIG_NSL_WERECLEAR631": "^2Yzb. MacTavish: ^7Temiziz.", + "SUBTITLE_OILRIG_NS1_ROOMCLEAR632": "^2Ghost: ^7Oda temiz.", + "SUBTITLE_OILRIG_NSL_ROOMCLEAR632": "^2Yzb. MacTavish: ^7Oda temiz.", + "SUBTITLE_OILRIG_NS1_CLEAR633": "^2Ghost: ^7Temiz.", + "SUBTITLE_OILRIG_NSL_CLEAR633": "^2Yzb. MacTavish: ^7Temiz.", + "SUBTITLE_OILRIG_NSL_PRECIOUSCARGO637": "^2Yzb. MacTavish: ^7Değerli kargo Two-Echo bölümünde emniyete alındı.", + "SUBTITLE_OILRIG_NSL_HOSTSEC638": "^2Yzb. MacTavish: ^7Rehineler Two-Echo bölümünde emniyete alındı.", + "SUBTITLE_OILRIG_NSL_PACKSEC639": "^2Yzb. MacTavish: ^7İki-Echo bölümündeki paketler emniyete alındı.", + "SUBTITLE_OILRIG_SBC_SECANDEVAC71": "^2Yardımcı Komutan: ^7Anlaşıldı Hotel Altı, Takım İki güvenliğini sağlayacak ve tahliye edecek, üst tarafı aramaya devam edin.", + "SUBTITLE_OILRIG_SBC_SECANDEVAC72": "^2Yardımcı Komutan: ^7Anlaşıldı Hotel Altı, Takım İki güvenliği sağlayacak ve tahliye edecek, yukarı çıkın ve sivillerin geri kalanını bulun.", + "SUBTITLE_OILRIG_NS2_GETTOPSIDE73": "^2Robot: ^7Üst tarafa çıkın, bu bölgeyi hallettik.", + "SUBTITLE_OILRIG_NS2_GETMOVING74": "^2Robot: ^7Roach, yukarı çık, bu bölge güvenli.", + "SUBTITLE_OILRIG_NS2_REGROUPTOPSIDE75": "^2Zach: ^7Bu rehineleri hallettik. Ekibin geri kalanıyla üst tarafta yeniden toplanın.", + "SUBTITLE_OILRIG_NS2_MOVEUP76": "^2Zach: ^7Bu bölgeyi hallettik. Ekibinizle birlikte Güverte 2'ye çıkın.", + "SUBTITLE_OILRIG_NSL_ALLTEAMSMOVE77": "^2Yzb. MacTavish: ^7Tüm takımlar dışarı çıksın.", + "SUBTITLE_OILRIG_NSL_OSCARMDECK278": "^2Yzb. MacTavish: ^7Hadi gidelim. Biz Oscar Mike - Güverte 2'ye gidiyoruz.", + "SUBTITLE_OILRIG_NSL_WATCHSECTORS79": "^2Yzb. MacTavish: ^7Güverte 2'ye çıkın ve sektörlerinize dikkat edin.", + "SUBTITLE_OILRIG_NSL_DECK2710": "^2Yzb. MacTavish: ^7Güverte 2'ye ilerliyoruz.", + "SUBTITLE_OILRIG_NSL_MOVEUPSTAIRS711": "^2Yzb. MacTavish: ^7Tamam, yukarı çıkın. Kontrol - Güverte 2'ye ilerliyoruz.", + "SUBTITLE_OILRIG_NSL_LETSMOVE712": "^2Yzb. MacTavish: ^7Gidelim - üst güvertelerde daha fazla rehinemiz var.", + "SUBTITLE_OILRIG_NSL_SPLITUP713": "^2Yzb. MacTavish: ^7Ayrılın. Bu koridorlardan yanlara doğru ilerleyebiliriz.", + "SUBTITLE_OILRIG_SBC_LOWPROFILE81": "^2Yardımcı Komutan: ^7Düşman helikopteri çevrede devriye geziyor. Dikkat çekmeyin, Hotel Altı.", + "SUBTITLE_OILRIG_NSL_ROGERTHAT82": "^2Yzb. MacTavish: ^7Anlaşıldı.", + "SUBTITLE_OILRIG_NS1_HELOAPPROACH83": "^2Ghost: ^7Helikopter yaklaşıyor. Eğilin.", + "SUBTITLE_OILRIG_NS2_HELOGETDOWN84": "^2Ghost: ^7Düşman helikopteri. Yere yatın.", + "SUBTITLE_OILRIG_NS1_CHOPPERINBOUND85": "^2Ghost: ^7Helikopter geliyor, alçakta kal.", + "SUBTITLE_OILRIG_NSL_GETOUTTASIGHT86": "^2Yzb. MacTavish: ^2 ^7Düşman helikopteri, görüş alanından çıkın.", + "SUBTITLE_OILRIG_NSL_OKMOVE87": "^2Yzb. MacTavish: ^7Tamam, hareket edin.", + "SUBTITLE_OILRIG_NSL_MOVE88": "^2Yzb. MacTavish: ^7Yürüyün.", + "SUBTITLE_OILRIG_NSL_ALLCLEARMOVE89": "^2Yzb. MacTavish: ^7Her yer temiz, ilerleyin.", + "SUBTITLE_OILRIG_NSL_BEENSPOTTED810": "^2Yzb. MacTavish: ^7Tespit edildik.", + "SUBTITLE_OILRIG_NSL_COMPROMISED811": "^2Yzb. MacTavish: ^7Gizliliğimiz ihlal edildi.", + "SUBTITLE_OILRIG_NSL_DETECTED812": "^2Yzb. MacTavish: ^7Tespit edildik.", + "SUBTITLE_OILRIG_SBC_HOSTATPOSITION91": "^2Yardımcı Komutan: ^7Hotel Altı, bulunduğunuz yerde daha fazla rehine var.", + "SUBTITLE_OILRIG_NSL_COPYTHAT92": "^2Yzb. MacTavish: ^7Anlaşıldı.", + "SUBTITLE_OILRIG_NSL_STRONGHOLDSEC93": "^2Yzb. MacTavish: ^7Kontrol - tüm Güverte İki rehineleri emniyete alındı.", + "SUBTITLE_OILRIG_NS1_HAVECOMPANY94": "^2Ghost: ^7Düşman telsizi....Sanırım bir misafirimiz olacak efendim...", + "SUBTITLE_OILRIG_NSL_GOINGLOUD97": "^2Yzb. MacTavish: ^7B planı için hazırlanın. Cesetlerin üzerine C4 yerleştirin, hadi.", + "SUBTITLE_OILRIG_NSL_PLANTC498": "^2Yzb. MacTavish: ^7Cesetlerin üzerine C4 yerleştirin. Devriye her an burada olabilir.", + "SUBTITLE_OILRIG_NSL_DONTHAVETIME99": "^2Yzb. MacTavish: ^7Cesetlere hemen C4 yerleştirin. Fazla zamanımız yok.", + "SUBTITLE_OILRIG_NS1_FORASURPRISE910": "^2Ghost: ^7Şarjörler yerleştirildi. Cesetleri bulduklarında büyük bir sürprizle karşılaşacaklar.", + "SUBTITLE_OILRIG_NS2_C4PLACED911": "^2Ghost: ^7C4 yerleştirildi, efendim.", + "SUBTITLE_OILRIG_NSL_AMBUSHTHEM912": "^2Yzb. MacTavish: ^7Yüksek bir yere çıkın. Cesetleri bulduklarında onları pusuya düşüreceğiz.", + "SUBTITLE_OILRIG_NSL_INVESTIGATE913": "^2Yzb. MacTavish: ^7Yüksek bir yere çıkın. Araştırmaya geldiklerinde onları pusuya düşüreceğiz.", + "SUBTITLE_OILRIG_NSL_ELEVATEDPOSWAIT914": "^2Yzb. MacTavish: ^7Bir pusu kurmalıyız. Yüksek bir yere çıkın ve bekleyin.", + "SUBTITLE_OILRIG_NSL_HOLDFIRE915": "^2Yzb. MacTavish: ^7Devriye orada. Onlar yaklaşana kadar ateş etmeyin.", + "SUBTITLE_OILRIG_NSL_STANDBY1916": "^2Yzb. MacTavish: ^7Beklemede....", + "SUBTITLE_OILRIG_NSL_DOIT919": "^2Yzb. MacTavish: ^7B planı. Yap şunu.", + "SUBTITLE_OILRIG_NSL_COVERBLOWN101": "^2Yzb. MacTavish: ^7Kontrol, burası Hotel Altı. Kimliğimiz açığa çıktı.", + "SUBTITLE_OILRIG_SBC_POSSIBLEEXPL102": "^2Yardımcı Komutan: ^7Anlaşıldı, istihbarat hâlâ üst katta rehineler ve olası patlayıcılar olduğunu gösteriyor.", + "SUBTITLE_OILRIG_SBC_SECTHATLOC103": "^2Yardımcı Komutan: ^7SAM bölgelerini ele geçirmek için takviye göndermeden önce ekibinizin o bölgeyi güvence altına alması gerekiyor, tamam.", + "SUBTITLE_OILRIG_NSL_COPYTHAT2104": "^2Yzb. MacTavish: ^7Anlaşıldı, üzerinde çalışıyoruz. Tamam.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD4111": "^2Yzb. MacTavish: ^7Helikopter tarafından parçalanıyoruz. RPG ya da roket bul ve onu indir.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD5112": "^2Yzb. MacTavish: ^7O helikopteri etkisiz hâle getirmeliyiz. Ağır silahlara dikkat edin ve onları etkisiz hâle getirin.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD6113": "^2Yzb. MacTavish: ^7O helikopteri düşürün, bizi kıstırdı!", + "SUBTITLE_OILRIG_NS3_LBNEUTRALIZED114": "^2Ghost: ^7Düşman helikopteri etkisiz hâle getirildi.", + "SUBTITLE_OILRIG_NS1_GETDOWN115": "^2Ghost: ^7Düşman helikopteri! Yere yatın, yere yatın!", + "SUBTITLE_OILRIG_NS2_ENEMYHELO116": "^2Ghost: ^7Düşman helikopteri! Siper alın!", + "SUBTITLE_OILRIG_NS1_ATTACKHELI117": "^2Ghost: ^7Saldırı helikopteri saat 12 yönünde, siper alın!", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD1119": "^2Yzb. MacTavish: ^7O kuşu indirmek için biraz ağır mühimmat bul.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD21111": "^2Yzb. MacTavish: ^7Helikopteri indir. Roket arayın.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD31112": "^2Yzb. MacTavish: ^7Helikopter bizi sıkıştırıyor. Roketlerle hallet onu.", + "SUBTITLE_OILRIG_NS2_FIREAT41113": "^2Ghost: ^7AT4 ateşleniyor.", + "SUBTITLE_OILRIG_NS3_FIREMISSILE1114": "^2Ghost: ^7Füze ateşleniyor.", + "SUBTITLE_OILRIG_NS2_CLEARSHOT1115": "^2Ghost: ^7Net bir atış yapamıyorum.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD71116": "^2Yzb. MacTavish: ^7Şu helikopteri indir, ağır silahlarını kullan.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD81117": "^2Yzb. MacTavish: ^7O helikopter bizi öldürüyor, indirin onu.", + "SUBTITLE_OILRIG_NSL_TAKEOUTBIRD91118": "^2Yzb. MacTavish: ^7O helikoptere ağır silahlarla ateş açılmasını istiyorum.", + "SUBTITLE_OILRIG_NS3_NICESHOT121": "^2Ghost: ^7O helikopter tarih oldu. İyi atıştı.", + "SUBTITLE_OILRIG_NS2_NICEWORK122": "^2Ghost: ^7İyi işti.", + "SUBTITLE_OILRIG_NS2_GOODSHOT123": "^2Ghost: ^7Düşman helikopteri düştü. İyi atış.", + "SUBTITLE_OILRIG_NS2_TACOMAN124": "^2Ghost: ^7Güzel atış, Roach.", + "SUBTITLE_OILRIG_NS3_TACOMAN125": "^2Ghost: ^7İyi atış Roach.", + "SUBTITLE_OILRIG_SBC_GETTOLZ131": "^2Sub Commander: ^7Hotel Altı, alt güvertedeki rehineler Takım İki tarafından çıkarılıyor. Geri kalanları emniyete almak için en kısa sürede üst güverteye ilerleyin, tamam.", + "SUBTITLE_OILRIG_NSL_CALLFOREXFIL132": "^2Yzb. MacTavish: ^7Anlaşıldı. LZ Bravo'da tahliye için çağrı yapacağız.", + "SUBTITLE_OILRIG_NSL_CENTCOM133": "^2Yzb. MacTavish: ^7CentCom, denizcileri gönderebilmek için en kısa sürede üst güverteyi almamızı istiyor. Yürüyün.", + "SUBTITLE_OILRIG_NSL_CLOCKSTICKING134": "^2Yzb. MacTavish: ^7Zaman geçiyor. Denizcileri çağırmadan önce üst güverteye çıkmalı ve kalan rehineleri kurtarmalıyız.", + "SUBTITLE_OILRIG_NSL_RESCUETHEMSELVES135": "^2Yzb. MacTavish: ^7Gidelim! O rehineler kendi kendilerini kurtarmayacaklar.", + "SUBTITLE_OILRIG_NSL_OUTFLANK141": "^2Yzb. MacTavish: ^7Dağılın ve onları kuşatın.", + "SUBTITLE_OILRIG_NS3_AIMFUELTANKS151": "^2Ghost: ^7Yakıt tanklarına nişan alın.", + "SUBTITLE_OILRIG_NS2_SHOOTTANKS152": "^2Ghost: ^7Yakıt tanklarını vurun.", + "SUBTITLE_OILRIG_NS3_AIMFUELSTORAGE153": "^2Ghost: ^7Yakıt depolama tanklarına nişan al.", + "SUBTITLE_OILRIG_NSL_FIREFUELSTORAGE154": "^2Yzb. MacTavish: ^7Yakıt depolarını ateşe ver.", + "SUBTITLE_OILRIG_NS2_POPSMOKE161": "^2Ghost: ^7Duman çıkarıyorlar.", + "SUBTITLE_OILRIG_NS2_SMOKESCREEN162": "^2Ghost: ^7Sis perdesi.", + "SUBTITLE_OILRIG_NSL_SEETHRUSMOKE163": "^2Yzb. MacTavish: ^7Tüm ekiplerin dikkatine: Bu adamlar bir adım önde - dumanın arkasını görmek için termal optik kullanıyorlar.", + "SUBTITLE_OILRIG_NS3_ENEMPOP164": "^2Ghost: ^7Düşman duman çıkarıyor.", + "SUBTITLE_OILRIG_NSL_GETTARGET165": "^2Yzb. MacTavish: ^7Bu adamların termal optikleri var. Dumandan uzak durun.", + "SUBTITLE_OILRIG_NS3_SMOKESCREEN166": "^2Ghost: ^7Sis perdesi oluşturuyorlar.", + "SUBTITLE_OILRIG_NS2_HOSTPOPSMOKE167": "^2Ghost: ^7Düşmanlar duman çıkarıyor.", + "SUBTITLE_OILRIG_NSL_PICKOFF171": "^2Yzb. MacTavish: ^7Termal nişangahınız varsa, şimdi iyi bir zaman olabilir!", + "SUBTITLE_OILRIG_NS3_SWITCHING172": "^2Ghost: ^7Düşmanlar termal optik kullanıyor... Termal dürbüne geçiyorum...", + "SUBTITLE_OILRIG_SBC_HOSTCONFIRMED181": "^2Yardımcı Komutan: ^7Hotel Altı, bilginize, bulunduğunuz yerde olası patlayıcılarla birlikte rehineler olduğu doğrulandı, tamam.", + "SUBTITLE_OILRIG_NSL_BEHINDDOORS182": "^2Yzb. MacTavish: ^7Anlaşıldı. Tüm ekipler ateşinizi kontrol edin - bu kapıların arkasında ne olduğunu bilmiyoruz.", + "SUBTITLE_OILRIG_NSL_ALLHOSTSEC191": "^2Yzb. MacTavish: ^7Kontrol, tüm rehinelerin güvenliği sağlandı. Tekrar ediyorum, tüm rehineler güvende. LZ Bravo'ya ilerliyoruz, tamam.", + "SUBTITLE_OILRIG_SBC_PHASE2192": "^2Yardımcı Komutan: ^7İyi iş, Hotel Altı. Deniz takviye birlikleri, FÜZE alanlarını sökmek için bölgeye giriyor. Ekibinizi operasyonun ikinci aşaması için hazırlayın", + "SUBTITLE_21": "^2Ghost: ^7Önce iyi haber: Dünya harika durumda.", + "SUBTITLE_22": "^2Ghost: ^7Rusya'da bir iç savaş var, hükümete sadık olanlar Ultranasyonalist isyancılara karşı ve 15000 nükleer bomba tehlikede.", + "SUBTITLE_23": "^2Yzb. Price: ^7Ofiste sıradan bir gün daha.", + "SUBTITLE_24": "^2Ghost: ^7Khaled Al-Asad. Şu anda Orta Doğu'nun en güçlü ikinci adamı. Söylentilere göre, orada en tepede olmak için gerekli minerallere sahip. İstihbaratın gözü onun üzerinde.", + "SUBTITLE_25": "^2Yzb. Price: ^7Peki ya kötü haber?", + "SUBTITLE_26": "^2Ghost: ^7Bugün bize yeni katılan bir adamımız var. Adı Soap.", + "SUBTITLE_27": "^2Ghost: ^7FNG efendim.", + "SUBTITLE_28": "^2Ghost: ^7Üzerine gitmeyin efendim, Alay'daki ilk günü.", + "SUBTITLE_29": "^2Yzb. Price: ^7Pekâlâ... Soap ne biçim bir isim öyle? Senin gibi bir kukla seçmeleri nasıl geçti?", + "SUBTITLE_31": "^2Ghost: ^7Yüzbaşı Price, Al-Asad az önce Başkan Al-Fulani'yi ulusal televizyonda idam etti.", + "SUBTITLE_32": "^2Yzb. Price: ^7Amerikalıların Al-Asad için planları var ve Al-Fulani için bir şey yapmak için çok geç. Ancak üç saatten kısa bir süre içinde kod adı Nikolai Rusya'da idam edilecek.", + "SUBTITLE_33": "^2Ghost: ^7Nikolai, efendim?", + "SUBTITLE_34": "^2Yzb. Price: ^7Nikolai, Ultranationalist kampındaki muhbirimiz. Kargo gemisi operasyonuyla ilgili istihbaratı o sağladı.", + "SUBTITLE_35": "^2Yzb. Price: ^7Nikolai şu anda cehennemde. Onu dışarı çıkaracağız...", + "SUBTITLE_36": "^2Yzb. Price: ^7Biz arkadaşlarımıza bakarız. Hadi gidelim.", + "SUBTITLE_37": "^2Yzb. Price: ^7Sadıklar ha? Bunlar iyi Ruslar mı yoksa kötü Ruslar mı?", + "SUBTITLE_38": "^2Ghost: ^7Onu dövmeliyiz efendim.", + "SUBTITLE_39": "^2Nikolai: ^7Ne istiyorsunuz? Kimsiniz siz? Özel Kuvvetler mi?", + "SUBTITLE_310": "^2Yzb. Price: ^7Bu o.", + "SUBTITLE_311": "^2Ghost: ^7Nikolai - iyi misin? Yürüyebilir misin?", + "SUBTITLE_312": "^2Nikolai: ^7Evet...ve hâlâ savaşabilirim. Beni buradan çıkardığın için teşekkür ederim.", + "SUBTITLE_313": "^2Nikolai: ^7Amerikalılar çoktan El-Esad'a saldırdı mı?", + "SUBTITLE_314": "^2Nikolai: ^7Amerikalılar hata yapıyor. El-Esad'ı asla canlı ele geçiremeyecekler.", + "SUBTITLE_41": "^2Nikolai: ^7O adam bir korkak, Yüzbaşı Price. Al-Asad asla kendini feda etmez.", + "SUBTITLE_42": "^2Nikolai: ^7Azerbaycan'da Al-Asad'ın geçmişte kullandığı bir güvenli ev var. Sana koordinatları gönderiyorum.", + "SUBTITLE_51": "^2Yzb. Price: ^7Delta 1 X-Ray, bir füze fırlatıldı, tekrar ediyorum bir füze fırlatıldı -", + "SUBTITLE_ROADKILL_SHP_ONTHELINE11": "^2Shepherd: ^7Kalk Er Allen!", + "SUBTITLE_ROADKILL_SHP_ONTHELINE11_2": "^2Shepherd: ^7Korucular önden! Yürüyün!", + "SUBTITLE_ROADKILL_FLY_WERESWIMMING12": "^2Çvş. Foley: ^7Avcı İki! Roketatar takımlarına baskı yapmaya devam edin! Eğer o köprücü vurulursa, yüzeriz, hooah?", + "SUBTITLE_ROADKILL_FLY_YOURM20313": "^2Çvş. Foley: ^7Allen! M203'e geç!", + "SUBTITLE_ROADKILL_FLY_ACROSSRIVER14": "^2Çvş. Foley: ^7Nehrin karşısındakilere birkaç mermi at!", + "SUBTITLE_ROADKILL_FLY_10OCLOCKHIGH15": "^2Çvş. Foley: ^7Köprüde, saat 10 yönünde! Birden fazla hedef var, indir onları!", + "SUBTITLE_ROADKILL_FLY_ONTHEBRIDGE16": "^2Çvş. Foley: ^7Köprünün üstünde!", + "SUBTITLE_ROADKILL_CPD_FARSIDE17": "^2Çvş. Dunn: ^7Köprünün yukarısında, uzak tarafta!", + "SUBTITLE_ROADKILL_CPD_BRIDGELAYER18": "^2Çvş. Dunn: ^7Köprü mevzisine gidiyorlar!", + "SUBTITLE_ROADKILL_AR1_10OCLOCK19": "^2Ranger: ^7Köprü üzerindeler, saat 10 yönünde!", + "SUBTITLE_ROADKILL_FLY_MAKINGAPUSH111": "^2Çvş. Foley: ^7Yukarıdalar! Köprüye doğru ilerliyorlar! Onları geri püskürtün!", + "SUBTITLE_ROADKILL_FLY_KEEPHITTING112": "^2Çvş. Foley: ^7Geri çekiliyorlar, vurmaya devam edin!", + "SUBTITLE_ROADKILL_FLY_BRIDGECOMPLETE113": "^2Çvş. Foley: ^7Avcı İki! Köprü tamamlandı, biz Oscar Mike'ız! Dışarı çıkın!", + "SUBTITLE_ROADKILL_FLY_KNOCKITOFF222": "^2Çvş. Foley: ^7Kesin şunu! Avcı İki, biz Oscar Mike'ız! Dışarı çıkın!", + "SUBTITLE_ROADKILL_SHP_TAKETOWN223": "^2Shepherd: ^7Allen, düşman zırhını indirmekte iyi iş çıkardın. Şimdi oraya gidip şu kasabayı alalım.", + "SUBTITLE_ROADKILL_CPD_MOVINOUT31": "^2Çvş. Dunn: ^7Gidiyoruz!", + "SUBTITLE_ROADKILL_AR3_BACKINVEHICLE33": "^2Ranger: ^7Gidelim, gidelim! Kıçını araca geri sok.", + "SUBTITLE_ROADKILL_FLY_MOVINGOUT38": "^2Çvş. Foley: ^7Şimdi gidiyoruz!", + "SUBTITLE_ROADKILL_FLY_MOUNTUP39": "^2Çvş. Foley: ^7Atlara binin!", + "SUBTITLE_ROADKILL_FLY_COMEONGETIN310": "^2Ranger: ^7Allen, atla!", + "SUBTITLE_ROADKILL_FLY_HOLDINGUPLINE311": "^2Ranger: ^7Allen, içeri gir, sırayı bekletiyorsun!", + "SUBTITLE_ROADKILL_FLY_HURRYUP312": "^2Ranger: ^7Acele et asker!", + "SUBTITLE_ROADKILL_FLY_MOVELETSGO313": "^2Çvş. Foley: ^7Allen, kaldır kıçını, gidelim!", + "SUBTITLE_ROADKILL_AR1_10SECONDS48": "^2Ranger: ^710 saniye!", + "SUBTITLE_ROADKILL_AR3_DANGERCLOSE415": "^2Ranger: ^7Hey, bu tehlike görev gücü için yakın değil mi?", + "SUBTITLE_ROADKILL_CPD_SINCEWHEN416": "^2Çvş. Dunn: ^7Hadi ama, Shepherd ne zamandan beri yakın tehlikeyi önemsiyor?", + "SUBTITLE_ROADKILL_CPD_OSCARMIKE427": "^2Çvş. Dunn: ^7Pekâlâ, biz Oscar Mike'ız!", + "SUBTITLE_ROADKILL_AR3_ONTHEMOVE428": "^2Ranger: ^7Harekete geçiyoruz!", + "SUBTITLE_ROADKILL_FLY_EYEOUTFORCIV53": "^2Çvş. Foley: ^7Tüm Avcı İki galipleri, sivillere dikkat edin, önce onlar ateş etmedikçe çatışmaya girme iznimiz yok.", + "SUBTITLE_ROADKILL_FLY_SCANROOFTOPS54": "^2Çvş. Foley: ^7Çatıları düşmanlar için tarayın. Soğukkanlı kalın.", + "SUBTITLE_ROADKILL_CPD_SEEANYTHING55": "^2Ranger: ^7Bir şey görüyor musun?", + "SUBTITLE_ROADKILL_CPD_PLACEISDEAD56": "^2Çvş. Dunn: ^7Hiçbir şey yok dostum. Burası ölü bir yer.", + "SUBTITLE_ROADKILL_FLY_CROSSSTREETELIZ58": "^2Çvş. Foley: ^7Overlord, Avcı İki-Bir. Harvey tünelini geçiyoruz, Elizabeth caddesindeyiz.", + "SUBTITLE_ROADKILL_HQR_CAUTION59": "^2Overlord: ^7Anlaşıldı, Avcı İki-Bir, dikkatli ilerleyin.", + "SUBTITLE_ROADKILL_CPD_WILDWEST510": "^2Çvş. Dunn: ^7Pekâlâ, soğukkanlı olun çocuklar, burası Vahşi Batı.", + "SUBTITLE_ROADKILL_AR3_ROGERTHAT511": "^2Ranger: ^7Anlaşıldı.", + "SUBTITLE_ROADKILL_FLY_WATCHALLEYS512": "^2Çvş. Dunn: ^7Şu sokaklara dikkat et.", + "SUBTITLE_ROADKILL_AR3_COVERING513": "^2Ranger: ^7Koruyorum.", + "SUBTITLE_ROADKILL_AR1_PROBABLEMILITIA514": "^2Avcı İki-Üç: ^7Üç yaya arabası, saat 12 yönünde balkon. Muhtemelen milisler.", + "SUBTITLE_ROADKILL_FLY_ARETHEYARMED515": "^2Çvş. Foley: ^7Silahları var mı?", + "SUBTITLE_ROADKILL_AR1_WATCHINGUS516": "^2Avcı iki-üç: ^7Olumsuz, sadece bizi izliyorlar.", + "SUBTITLE_ROADKILL_CPD_SCOUTINGUS517": "^2Çvş. Dunn: ^7Bahse girerim bizi izliyorlar.", + "SUBTITLE_ROADKILL_FLY_DOESNTMEAN518": "^2Ranger: ^7Eh, ama bu onları vurabileceğimiz anlamına gelmez.", + "SUBTITLE_ROADKILL_FLY_NOTHINGTHERE519": "^2Çvş. Dunn: ^7Allen, neye ateş ediyorsun, orada hiçbir şey yok! Ateşi kesin!", + "SUBTITLE_ROADKILL_FLY_CEASEFIRE520": "^2Çvş. Dunn: ^7Allen! Ateşi kesin! Ateşi kesin!", + "SUBTITLE_ROADKILL_AR2_SEEEM71": "^2Ranger: ^7Onları görebiliyor musun? Onları görebiliyor musun?", + "SUBTITLE_ROADKILL_CPD_DONTSEEJACK72": "^2Çvş. Dunn: ^7Hiçbir şey göremiyorum!", + "SUBTITLE_ROADKILL_FLY_PREPENG73": "^2Çvş. Foley: ^7Tüm Avcı birlikleri, ben Çavuş Foley. Çatışmaya hazırlanın, birçok yönden keskin nişancı ateşi alıyoruz.", + "SUBTITLE_ROADKILL_CPD_GOININ74": "^2Çvş. Dunn: ^7Çatışmaya hazırlanın! İçeri giriyoruz!", + "SUBTITLE_ROADKILL_AR1_SPINEMUP75": "^2Ranger: ^7İşte bu kadar! Döndürün onları!", + "SUBTITLE_ROADKILL_CPD_WALATMNT78": "^2Çvş. Dunn: ^7Harekete dikkat edin!", + "SUBTITLE_ROADKILL_CPD_LIGHTEMUP713": "^2Çvş. Dunn: ^7İşte oradalar, yakın onları!", + "SUBTITLE_ROADKILL_CPD_BACKUP714": "^2Çvş. Dunn: ^7Onlardan çok fazla var! Geri çekilin! Geri çekilin!", + "SUBTITLE_ROADKILL_CPD_OUTTAHERE715": "^2Çvş. Dunn: ^7Çıkar bizi buradan! Sür!", + "SUBTITLE_ROADKILL_FLY_STRUNGOUT83": "^2Çvş. Foley: ^7Yavaşla, yoruluyoruz!", + "SUBTITLE_ROADKILL_CPD_KEEPMOVING84": "^2Çvş. Dunn: ^7Devam edin!", + "SUBTITLE_ROADKILL_AR2_SHOTUP85": "^2Avcı İki-Üç: ^7Avcı İki-Bir, ben Avcı İki-Üç, Haggerty kötü yaralandı ve çok ateş altındayız, neredesiniz?", + "SUBTITLE_ROADKILL_FLY_HANGTIGHT86": "^2Çvş. Foley: ^7Anlaşıldı Avcı İki-Üç! Sıkı durun! Size doğru geliyoruz, tamam!", + "SUBTITLE_ROADKILL_AR2_SOLIDCOPY87": "^2Avcı İki-Üç: ^7Avcı İki-Üç Anlaşıldı!", + "SUBTITLE_ROADKILL_AR3_GOINGON88": "^2Overlord: ^7Avcı İki-Bir, Overlord. Orada neler oluyor, tamam?", + "SUBTITLE_ROADKILL_FLY_TOOKFIRE89": "^2Çvş. Foley: ^7Overlord, ateş aldık ve Avcı İki-Üç'ten ayrıldık! Geri dönmeye çalışıyoruz, tamam!", + "SUBTITLE_ROADKILL_AR3_SOLIDCOPY810": "^2Overlord: ^7Anlaşıldı 2-1. Overlord tamam.", + "SUBTITLE_ROADKILL_CPD_CUTOFF811": "^2Çvş. Dunn: ^7Yolumuz kesildi!", + "SUBTITLE_ROADKILL_FLY_PUSHTHROUGH812": "^2Çvş. Foley: ^7İtin!", + "SUBTITLE_ROADKILL_FLY_RPGTOPFLOOR813": "^2Çvş. Foley: ^7ROKETATAR! En üst kat! Tam önümüzde!", + "SUBTITLE_ROADKILL_FLY_GETOFFSTREET91": "^2Çvş. Foley: ^7Caddeden çıkmamız gerek!", + "SUBTITLE_ROADKILL_FLY_EVERYBODYOK92": "^2Çvş. Foley: ^7Herkes iyi mi?", + "SUBTITLE_ROADKILL_CPD_MOVINAROUNDUP96": "^2Çvş. Dunn: ^7Üst katta dolaşıyorlar!", + "SUBTITLE_ROADKILL_FLY_EYESONSCHOOL97": "^2Çvş. Foley: ^7Avcı İki-Bir'den Avcı İki-Üç'e, okulu görüyorum, tamam!", + "SUBTITLE_ROADKILL_FLY_SECURETOPFLOOR97": "^2Çvş. Foley: ^7Pencerelerden uzaklaşın ve üst katı emniyete alın! Çekilin! Yürüyün! Yürüyün!", + "SUBTITLE_ROADKILL_AR3_INEFFECTIVE98": "^2Avcı İki-Üç: ^7İki-Bir, burada etkisiz durumdayız! Okuldan yoğun ateş altındayız, yardım edebilir misiniz, tamam?!", + "SUBTITLE_ROADKILL_FLY_KEEPITTOGETHER99": "^2Çvş. Foley: ^7Birlikte kalın İki-üç! Yoldayız! İki-Bir tamam!", + "SUBTITLE_ROADKILL_FLY_PRESSUREOFF910": "^2Çvş. Foley: ^7Devam edin! Avcı İki-Üç'ün üzerindeki baskıyı kaldırmalıyız!", + "SUBTITLE_ROADKILL_FLY_GETFLASHBANG911": "^2Çvş. Foley: ^7Oraya bir flashbang getirin!", + "SUBTITLE_ROADKILL_CPD_FRONTOFSCHOOL912": "^2Çvş. Dunn: ^7Hedefler, okulun önü! İndirin onları!", + "SUBTITLE_ROADKILL_FLY_FOLLOWME913": "^2Çvş. Foley: ^7Manga, benimle gelin, gidelim!", + "SUBTITLE_ROADKILL_FLY_FALLINGBACK913": "^2Çvş. Foley: ^7Okula geri dönüyorlar!", + "SUBTITLE_ROADKILL_CPD_CLASSONRIGHT914": "^2Çvş. Dunn: ^7Dikkat et! Bazıları sağdaki sınıfa girdi!", + "SUBTITLE_ROADKILL_CPD_CLEAR915": "^2Çvş. Dunn: ^7Temiz!", + "SUBTITLE_ROADKILL_CPD_2COMINOUT916": "^2Çvş. Dunn: ^7İki kişi geliyor!", + "SUBTITLE_ROADKILL_CPD_3COMINOUT917": "^2Çvş. Dunn: ^7Üç kişi geliyor!", + "SUBTITLE_ROADKILL_FLY_INTHESCHOOL918": "^2Çvş. Foley: ^7Avcı İki-Üç, Avcı İki-Bir, okuldayız. Ağır direniş.", + "SUBTITLE_ROADKILL_SHP_COPYTHAT21919": "^2Avcı İki-Üç: ^7Anlaşıldı Avcı İki-Bir.", + "SUBTITLE_ROADKILL_CPD_HISTORYCLASS920": "^2Çvş. Dunn: ^7Evet, şimdi tarih dersini kesiyorum.", + "SUBTITLE_ROADKILL_FLY_ROGERTHAT921": "^2Çvş. Foley: ^7Anlaşıldı.", + "SUBTITLE_ROADKILL_FLY_SAWONE922": "^2Çvş. Foley: ^7Sanırım bir tanesinin sınıfa girdiğini gördüm.", + "SUBTITLE_ROADKILL_SHP_THANKSFORASSIST101": "^2Avcı İki-Üç: ^7Avcı İki-Bir, ben Avcı İki-Üç, yardımınız için teşekkürler! Gidiyoruz, tamam!", + "SUBTITLE_ROADKILL_FLY_ALLTHEWAYSIR102": "^2Çvş. Foley: ^7Anlaşıldı İki-Üç.", + "SUBTITLE_ROADKILL_SHP_ALLTHEWAY103": "^2Avcı İki-Üç: ^7Diğer tarafta görüşürüz Avcı İki-Bir, İki-Üç dışarı.", + "SUBTITLE_ROADKILL_FLY_TOGOLIATH111": "^2Çvş. Foley: ^7Avcı İki-Bir'den Overlord'a.", + "SUBTITLE_ROADKILL_AR3_SENDTRAFFIC112": "^2Overlord (Karargâh Telsizi): ^7Avcı İki-Bir Actual burası Overlord, trafik gönderin.", + "SUBTITLE_ROADKILL_FLY_SCHOOLSECURE113": "^2Çvş. Foley: ^7Okul güvende ve düşmanlar bölgeden çekiliyor. Şu an sadece temizlik yapıyoruz.", + "SUBTITLE_ROADKILL_AR3_RALLYPOINT114": "^2Overlord (Karargâh Telsizi): ^7Birebir kopya Avcı İki-Bir, toplanma noktasına dikkatle ilerleyin. EPW'ler hâlâ bölgede olabilir. Tamam.", + "SUBTITLE_ROADKILL_FLY_THANKSFORTIP115": "^2Çvş. Foley: ^7Anlaşıldı Overlord, ipucu için teşekkürler. Tamam.", + "SUBTITLE_ROADKILL_FLY_WATCHSTRAGGLERS116": "^2Çvş. Foley: ^7Manga, düşman kaçaklarına dikkat edin! Toplanma noktasına gidelim!", + "SUBTITLE_ROADKILL_FLY_LASTOFEM117": "^2Çvş. Foley: ^7Temiz!", + "SUBTITLE_ROADKILL_SHP_SHOCKTRAUMA121": "^2Shepherd: ^7Yaralıları şok travma ünitesine götürün! Helikopterimi kullanın!", + "SUBTITLE_ROADKILL_SHP_GOODWORK122": "^2Shepherd: ^7Beyler, kasabayı ele geçirmekte iyi iş çıkardınız.", + "SUBTITLE_ROADKILL_SHP_SPECIALOP123": "^2Shepherd: ^7Er Allen, bundan sonra emirleri benden alacaksın. Helikopterde sana bilgi vereceğim. Hadi gidelim.", + "SUBTITLE_SO_CHOP_INV_HP1_LZ2HOT11": "^2Gunslinger-One: ^7Silahşör Bir'den yere, birincil LZ çok sıcak! Yakın alanımızda 10'dan fazla düşman var ve yerde kalamayız, tamam!", + "SUBTITLE_SO_CHOP_INV_HP1_ENGHOST12": "^2Gunslinger-One: ^7Kara kuvvetleri, ikincil çıkarma noktasında birleşeceğiz. Doğudaki Nate's Sports Bar'ın çatısına gidin.", + "SUBTITLE_SO_CHOP_INV_HP1_GUNNER12": "^2Gunslinger-One: ^7Nişancı, düşmanlara saldırabilirsin. Yerdeki dostlara dikkat et, tamam.", + "SUBTITLE_SO_CHOP_INV_HP1_FINDCOVER13": "^2Gunslinger-One: ^7Gunslinger-One'dan kara kuvvetlerine, biraz siper bulun! Sokağın sonundaki barikatın arkasında bir müfreze büyüklüğünde düşman grubu izliyoruz, tamam!", + "SUBTITLE_SO_CHOP_INV_HP1_BY_BARRICADE14": "^2Gunslinger-One: ^7Tehlike yakın kara kuvvetleri, yaklaşıyoruz! Nişancı, barikatın yanındaki düşmanlara saldırabilirsin.", + "SUBTITLE_SO_CHOP_INV_HP1_GOODEFFECT15": "^2Gunslinger-One: ^7Hedefte iyi etki, Nişancı - dur, bekle!", + "SUBTITLE_SO_CHOP_INV_HP1_RPGS16": "^2Gunslinger-One: ^7Kara kuvvetlerinin dikkatine, bölgede RPG'ler var, tamam. Bir saniye içinde buraya saldırı için geri dönüyoruz.", + "SUBTITLE_SO_CHOP_INV_HP1_LIGHTEMUP17": "^2Gunslinger-One: ^7Gunslinger-One'dan yere, saldırıya başlıyoruz, tamam. Nişancı, ateşle.", + "SUBTITLE_SO_CHOP_INV_HP1_GUNS18": "^2Gunslinger-One: ^7Anlaşıldı, sıcak temizlendi.", + "SUBTITLE_SO_CHOP_INV_HP1_REPOSITION19": "^2Gunslinger-One: ^7Gunslinger-One'dan yere, bulunduğunuz yere doğru yeniden konumlanıyoruz, tamam.", + "SUBTITLE_SO_CHOP_INV_HP1_BA_TRUCKS110": "^2Gunslinger-One: ^7Gunslinger-One'dan yere, bilginize, güneydoğudan gelen bir düşman kamyon konvoyunu takip ediyoruz, onları halletmemize izin vermenizi tavsiye ederiz, tamam.", + "SUBTITLE_SO_CHOP_INV_HP1_WESEEYOU111": "^2Gunslinger-One: ^7Gunslinger-One'dan yere, sizi görüyoruz! Çatıdaki konumunuzu koruyun, yoldayız!", + "SUBTITLE_SO_CHOP_INV_HP1_LETSGO112": "^2Gunslinger-One: ^7Kara kuvvetleri, gidelim, gidelim! Çatıdayız ve tahliye için bağlantı kurmaya hazırız!", + "SUBTITLE_SO_CHOP_INV_HP1_PACE113": "^2Gunslinger-One: ^7Kara kuvvetleri, hızlanın, burada ördek gibi oturuyoruz!", + "SUBTITLE_SO_CHOP_INV_HP1_LINKUP114": "^2Gunslinger-One: ^7Kara kuvvetleri, Nate's Sports Bar'ın çatısında birleşin!", + "SUBTITLE_SO_CHOP_INV_HP1_MEETUS115": "^2Gunslinger-One: ^7Silahşör Bir'den yere, bizimle Nate'in Spor Barı'nın çatısında buluşun!", + "SUBTITLE_SO_CHOP_INV_HP1_GETTOROOF116": "^2Gunslinger-One: ^7Kara kuvvetleri, Nate'in Spor Barı'nın çatısına gidin!", + "SUBTITLE_SO_CHOP_INV_HP1_FRIENDLY_01117": "^2Gunslinger-One: ^7Topçu, ateşine dikkat et - bu bir dost!", + "SUBTITLE_SO_CHOP_INV_HP1_FRIENDLY_02120": "^2Gunslinger-One: ^7Topçu, bu dost ateşi! Nişanını kontrol et!", + "SUBTITLE_SO_CHOP_INV_HP1_FRIENDLY_03121": "^2Gunslinger-One: ^7Orada bir dost var, Nişancı! Odaklan!", + "SUBTITLE_SO_CHOP_INV_HP1_INTOCHOPPER_01122": "^2Gunslinger-One: ^7Çabuk, düşmanlar geliyor, helikoptere binin!", + "SUBTITLE_SO_CHOP_INV_HP1_INTOCHOPPER_02123": "^2Gunslinger-One: ^7Helikoptere binin!", + "SUBTITLE_SO_CHOP_INV_HP1_INTOCHOPPER_03124": "^2Gunslinger-One: ^7Kolay hedefiz, helikoptere binin!", + "SUBTITLE_SO_DEF_INV_BMPSPOTTEDYOU11": "^2Overlord: ^7Düşman BTR'si seni görüyor Avcı İki-Bir, siper almanı öneriyorum, tamam.", + "SUBTITLE_SO_DEF_INV_BMPSPOTTEDYOU12": "^2Overlord: ^7Avcı İki-Bir, düşman BTR'sinin sizi hedef aldığını bildirin, tamam.", + "SUBTITLE_SO_DEF_INV_NICEONE13": "^2Overlord: ^7Güzeldi, tamam.", + "SUBTITLE_SO_DEF_INV_THERMALOPTICS14": "^2Overlord: ^7Avcı İki-Bir, Overlord. Termal optiğe geçmenizi öneririm, tamam.", + "SUBTITLE_SO_DEF_INV_STINGERDINER15": "^2Overlord: ^7Avcı İki-Bir, AT4 roketleri batıdaki lokantada, tamam.", + "SUBTITLE_SO_DEF_INV_STINGERDINER16": "^2Overlord: ^7Avcı İki-Bir, istihbarata göre batıda bir AT4 roketi deposu var, tamam.", + "SUBTITLE_SO_DEF_INV_STINGERNATES17": "^2Overlord: ^7Burası Overlord Actual, AT4 roketleri Nate'in restoranının çatısındaki erzak deposunda, tamam.", + "SUBTITLE_SO_DEF_INV_STINGERNATES18": "^2Overlord: ^7Avcı İki-Bir, Nate'in restoranının çatısında AT4 roketleri olup olmadığını kontrol et, tamam.", + "SUBTITLE_SO_DEF_INV_MOBILESOUTH19": "^2Overlord: ^7Dikkatli ol Avcı İki-Bir, güneydeki Burger Kasabası'nın yanında düşman ayaklı mobilleri var, tamam.", + "SUBTITLE_SO_DEF_INV_ATTACKSOUTH110": "^2Overlord: ^7Avcı İki-Bir, Overlord, güneyden potansiyel saldırganlara dikkat edin, tamam.", + "SUBTITLE_SO_DEF_INV_HOSTILESOUTH111": "^2Overlord: ^7Avcı İki-Bir, Avcı Dört Burger Kasabası yakınlarında büyük bir düşman grubu tespit etti, tamam.", + "SUBTITLE_SO_DEF_INV_DRONESPOTTED112": "^2Overlord: ^7Avcı İki-Bir, düşman Predator drone'u sizi tespit etti, siper almanızı öneririm, tamam.", + "SUBTITLE_SO_DEF_INV_DRONENOTICE113": "^2Overlord: ^7Avcı İki-Bir, düşman insansız hava aracı sizi fark etti, tamam.", + "SUBTITLE_SO_DEF_INV_DRONETARGET114": "^2Overlord: ^7Avcı İki-Bir, düşman insansız hava aracı seni hedef alıyor, siper al, tamam.", + "SUBTITLE_SO_DEF_INV_DRONEDIRECT115": "^2Overlord: ^7Düşman insansız hava aracı doğrudan senin pozisyonuna ateş ediyor Avcı İki-Bir, tamam.", + "SUBTITLE_INV_HQR_ENEMYNORTH116": "^2Overlord: ^7Avcı İki-Bir, burası Gerçek Overlord, kuzeyinizde büyük bir düşman takviye grubu görüyoruz, tamam.", + "SUBTITLE_SO_DWNLD_STK_EXPLICITAUTH11": "^2Stryker Topçusu: ^7Tüm Avcı birimleri, Porsuk Bir sizin açık izniniz olmadan hedeflere saldırmayacak.", + "SUBTITLE_SO_DWNLD_STK_DESIGNATED12": "^2Stryker Nişancısı: ^7Avcı İki-Bir, tekrar ediyorum, Porsuk Bir sizin belirlemediğiniz hedeflere saldırmaya yetkili değildir.", + "SUBTITLE_SO_DWNLD_STK_CANTFIRE13": "^2Stryker Nişancısı: ^7Avcı İki-Bir, sizin izniniz olmadan düşmanlara ateş edemeyiz!", + "SUBTITLE_SO_DWNLD_HQR_LAPTOPS21": "^2Overlord: ^7AO'nuzda yüksek değerli bilgiler içeren birkaç sağlamlaştırılmış dizüstü bilgisayar var.", + "SUBTITLE_SO_DWNLD_HQR_DOWNLOADDATA22": "^2Overlord: ^7Dizüstü bilgisayarların her birinden verileri indirin, ardından ayıklama için Stryker'a geri dönün.", + "SUBTITLE_SO_DWNLD_STK_TENFOOTMOBILES31": "^2Stryker Nişancısı: ^7Avcı İki-Bir, doğudan 10'dan fazla ayaklı araç yaklaşıyor!", + "SUBTITLE_SO_DWNLD_STK_BROWNMANSION32": "^2Stryker Nişancısı: ^7Batıda hareketlilik var, açık kahverengi malikaneden geliyorlar!", + "SUBTITLE_SO_DWNLD_STK_ACROSSSTREET33": "^2Stryker Nişancısı: ^7Düşmanlar caddenin karşısında görüldü, sizin pozisyonunuza doğru ilerliyorlar!", + "SUBTITLE_SO_DWNLD_STK_GOTMOVEMENT34": "^2Stryker Nişancısı: ^7Avcı İki-Bir, bulunduğunuz yerin hemen dışında hareketlilik var!", + "SUBTITLE_SO_DWNLD_HQR_WIRELESSLYDISRUPT41": "^2Overlord: ^7Avcı İki-Bir, bölgede veri aktarımını kablosuz olarak bozabilecek düşmanlar var.", + "SUBTITLE_SO_DWNLD_HQR_RESTARTMANUALLY42": "^2Overlord: ^7Avcı İki-Bir, indirme işlemi yarıda kesildi! Veri aktarımını elle yeniden başlatman gerekecek.", + "SUBTITLE_SO_DWNLD_HQR_GETBACKRESTART43": "^2Overlord: ^7Avcı İki-Bir, düşmanlar indirmeyi yarıda kesti! Oraya geri dön ve aktarımı manuel olarak devam ettir!", + "SUBTITLE_SO_DWNLD_HQR_GOFINDTHEM51": "^2Overlord: ^7İyi iş, Avcı İki-Bir. İstihbaratımız bölgede iki dizüstü bilgisayar daha olduğunu gösteriyor - git onları bul ve verilerini al.", + "SUBTITLE_SO_DWNLD_HQR_ONELAPTOP52": "^2Overlord: ^7Soğukkanlılığını koru Avcı İki-Bir, bir dizüstü bilgisayar kaldı.", + "SUBTITLE_SO_DWNLD_HQR_PULLINGYOUOUT53": "^2Overlord: ^7İyi iş, Avcı İki-Bir. Şimdi Stryker'a geri dön, seni bölgeden çıkarıyoruz.", + "SUBTITLE_SO_DWNLD_HQR_EXTRACTION54": "^2Overlord: ^7Avcı İki-Bir, çıkarma için Stryker'a geri dön!", + "SUBTITLE_SO_DWNLD_HQR_COMPLETEMISSION55": "^2Overlord: ^7Avcı İki-Bir, görevini tamamlamak için Stryker'a dön!", + "SUBTITLE_SO_ESC_AIR_AMBUSH_WARNING": "^2Ghost: ^7Buradaki düşmanlar pusuda bekliyor... bu yüzden dikkatli ol.", + "SUBTITLE_SO_HID_GHIL_GOODNIGHT11": "^2Ghost: ^7İyi geceler", + "SUBTITLE_SO_HID_GHIL_BEAUTIFUL12": "^2Ghost: ^7Güzel", + "SUBTITLE_SO_HID_GHIL_PERFECT13": "^2Ghost: ^7Mükemmel", + "SUBTITLE_SO_HID_GHIL_TANGO_DOWN14": "^2Ghost: ^7Tango aşağı", + "SUBTITLE_SO_HID_GHIL_HESDOWN15": "^2Ghost: ^7O düştü", + "SUBTITLE_SO_HID_GHIL_NEUTRALIZED16": "^2Ghost: ^7Hedef etkisiz hâle getirildi", + "SUBTITLE_SO_HID_GHIL_SLOPPY17": "^2Ghost: ^7Özensiz çalışma", + "SUBTITLE_SO_HID_GHIL_NOISY18": "^2Ghost: ^7Çok gürültülü", + "SUBTITLE_SO_HID_GHIL_DO_BETTER19": "^2Ghost: ^7Daha iyisini yapabilirsin", + "SUBTITLE_SO_HID_GHIL_RAD_WARNING110": "^2Ghost: ^7Dikkatli olun. Radyasyon ceplerini işaretleyen direklere dikkat edin. Eğer çok fazla emersen... ölürsün.", + "SUBTITLE_SO_HID_GHIL_SNIPER_HINT111": "^2Ghost: ^7Eğer bir keskin nişancı gördüğünü düşünüyorsan, o bölgeyi izle ve hata yapmasını bekle.", + "SUBTITLE_SO_HID_GHIL_PATROL_HINT112": "^2Ghost: ^7Sabırlı ol. Devriye gezen düşman düzenlerini izleyin. Onları hızlı ve sessizce indirecek bir zaman bul.", + "SUBTITLE_SO_HID_GHIL_DOUBLE_KILL": "^2Ghost: ^7Çifte öldürme... mükemmel.", + "SUBTITLE_SO_HID_GHIL_TRIPLE_KILL": "^2Ghost: ^7Üçlü öldürme... çok etkileyici!", + "SUBTITLE_SO_ROOF_CONT_DEF_POS11": "SUBTITLE_SO_ROOF_CONT_DEF_POS11", + "SUBTITLE_SO_ROOF_CONT_PRED_DRONE12": "^2Yzb. MacTavish: ^7Predator Drone Kontrol Teçhizatını al.", + "SUBTITLE_SO_ROOF_CONT_PRED_DRONE13": "^2Yzb. MacTavish: ^7Predator Drone Kontrol Teçhizatını al.", + "SUBTITLE_SO_TRAINER_MISSEDTARGET11": "^2Korucu 1: ^7Bir hedefi kaçırdın, geri dön ve onu vur.", + "SUBTITLE_SO_TRAINER_GOBACK12": "^2Korucu 1: ^7Bir hedefi kaçırdın, aşağı atlamadan önce geri dön!", + "SUBTITLE_SO_TRAINER_LASTAREA13": "^2Korucu 1: ^7Son bölgede bazı hedefler bıraktın, git onları al.", + "SUBTITLE_SO_TRAINER_TRYITAGAIN14": "^2Korucu 1: ^7Bir hedefi kaçırdın, tekrar dene.", + "SUBTITLE_SO_TRAINER_TOOMANYCIV15": "^2Korucu 1: ^7Çok fazla sivili vurdun, tekrar dene.", + "SUBTITLE_SO_TF_1_PLYR_PREP11": "^2Ghost: ^7Hadi yapalım şunu.", + "SUBTITLE_SO_TF_1_PLYR_PREP12": "^2Ghost: ^7Hazır olun.", + "SUBTITLE_SO_TF_1_TIME_GENERIC13": "^2Ghost: ^7Zamanımız tükeniyor!", + "SUBTITLE_SO_TF_1_TIME_GENERIC14": "^2Ghost: ^7Saat işliyor...", + "SUBTITLE_SO_TF_1_TIME_GENERIC15": "^2Ghost: ^7Fazla zaman kalmadı!", + "SUBTITLE_SO_TF_1_TIME_HURRY16": "^2Ghost: ^7Zaman tükeniyor! Hadi! Hadi! Git! Git! Hadi! Hadi!", + "SUBTITLE_SO_TF_1_TIME_HURRY17": "^2Ghost: ^7Zamanımız tükenmek üzere! Yürüyün! Yürüyün!", + "SUBTITLE_SO_TF_1_TIME_HURRY18": "^2Ghost: ^7Zaman neredeyse doldu! Bu çok yakın olacak!", + "SUBTITLE_SO_TF_1_FAIL_GENERIC19": "^2Ghost: ^7Görev başarısız oldu. Bir dahaki sefere onları yakalayacağız.", + "SUBTITLE_SO_TF_1_FAIL_GENERIC110": "^2Ghost: ^7Bu bir felaketti! Tekrar deneyelim.", + "SUBTITLE_SO_TF_1_FAIL_GENERIC111": "^2Ghost: ^7Lanet olsun, az önce kıçımıza tekmeyi yedik.", + "SUBTITLE_SO_TF_1_FAIL_GENERIC112": "^2Ghost: ^7Stratejimizi yeniden düşünmeliyiz. Tekrar deneyelim.", + "SUBTITLE_SO_TF_1_FAIL_TIME113": "^2Ghost: ^7Zamanımız tükendi. Gözünü saatten ayırma.", + "SUBTITLE_SO_TF_1_FAIL_TIME114": "^2Ghost: ^7Çok yavaşsın dostum. Bir dahaki sefere saate dikkat et, tamam mı?", + "SUBTITLE_SO_TF_1_FAIL_BLEEDOUT115": "^2Ghost: ^7Takım olarak kazanırız, takım olarak kaybederiz. Anladın mı?", + "SUBTITLE_SO_TF_1_FAIL_BLEEDOUT116": "^2Ghost: ^7Bakın, biz bir takım olarak çalışıyoruz. Kimse geride kalmayacak!", + "SUBTITLE_SO_TF_1_SUCCESS_GENERIC117": "^2Ghost: ^7Bu iş böyle yapılır.", + "SUBTITLE_SO_TF_1_SUCCESS_JERK118": "^2Ghost: ^7Fena değil ama daha iyilerini de gördüm.", + "SUBTITLE_SO_TF_1_SUCCESS_GENERIC119": "^2Ghost: ^7İyi işti takım.", + "SUBTITLE_SO_TF_1_SUCCESS_GENERIC120": "^2Ghost: ^7Görev tamamlandı.", + "SUBTITLE_SO_TF_1_TIME_STATUS_LATE121": "^2Ghost: ^7Az kaldı, hızlanmamız gerek.", + "SUBTITLE_SO_TF_1_TIME_STATUS_LATE122": "^2Ghost: ^7Geride kalıyorsun, acele et yoksa başaramayacaksın.", + "SUBTITLE_SO_TF_1_TIME_STATUS_LATE123": "^2Ghost: ^7Zamana dikkat et, çok yavaş ilerliyorsun.", + "SUBTITLE_SO_TF_1_TIME_STATUS_GOOD124": "^2Ghost: ^7Şimdiye kadarki en iyi zamanını geçiyorsun.", + "SUBTITLE_SO_TF_1_TIME_STATUS_GOOD125": "^2Ghost: ^7En iyi zamanını geçme hızında, hadi hadi.", + "SUBTITLE_SO_TF_1_TIME_STATUS_GOOD126": "^2Ghost: ^7Bu şekilde devam edersen yeni bir rekor olacak.", + "SUBTITLE_SO_TF_1_PROGRESS_HALF127": "^2Ghost: ^7Yolu yarıladık.", + "SUBTITLE_SO_TF_1_PROGRESS_HALF128": "^2Ghost: ^7Yolu yarıladın.", + "SUBTITLE_SO_TF_1_PROGRESS_HALF129": "^2Ghost: ^7Yarısına geldin...", + "SUBTITLE_SO_TF_1_PROGRESS_QUARTER130": "^2Ghost: ^7Yaklaşıyorsun, durma.", + "SUBTITLE_SO_TF_1_PROGRESS_QUARTER131": "^2Ghost: ^7Neredeyse bitti, odaklan.", + "SUBTITLE_SO_TF_1_PROGRESS_QUARTER132": "^2Ghost: ^7Çok az kaldı, devam et.", + "SUBTITLE_SO_TF_1_PROGRESS_5MORE133": "^2Ghost: ^75 tane daha.", + "SUBTITLE_SO_TF_1_PROGRESS_5MORE134": "^2Ghost: ^75 kaldı.", + "SUBTITLE_SO_TF_1_PROGRESS_5MORE135": "^2Ghost: ^75 kaldı", + "SUBTITLE_SO_TF_1_PROGRESS_4MORE136": "^2Ghost: ^74 tane daha.", + "SUBTITLE_SO_TF_1_PROGRESS_4MORE137": "^2Ghost: ^74 tane kaldı.", + "SUBTITLE_SO_TF_1_PROGRESS_4MORE138": "^2Ghost: ^74 kaldı", + "SUBTITLE_SO_TF_1_PROGRESS_3MORE139": "^2Ghost: ^73 tane daha.", + "SUBTITLE_SO_TF_1_PROGRESS_3MORE140": "^2Ghost: ^73 tane kaldı.", + "SUBTITLE_SO_TF_1_PROGRESS_3MORE141": "^2Ghost: ^73 tane kaldı", + "SUBTITLE_SO_TF_1_PROGRESS_2MORE142": "^2Ghost: ^72 tane daha.", + "SUBTITLE_SO_TF_1_PROGRESS_2MORE143": "^2Ghost: ^72 kaldı.", + "SUBTITLE_SO_TF_1_PROGRESS_2MORE144": "^2Ghost: ^72 kaldı", + "SUBTITLE_SO_TF_1_PROGRESS_1MORE145": "^2Ghost: ^71 tane daha.", + "SUBTITLE_SO_TF_1_PROGRESS_1MORE146": "^2Ghost: ^71 tane kaldı.", + "SUBTITLE_SO_TF_1_PROGRESS_1MORE147": "^2Ghost: ^71 tane kaldı", + "SUBTITLE_SO_TF_1_CIV_KILL_WARNING148": "^2Ghost: ^7Ateşinize dikkat edin, sivillerden kaçının!", + "SUBTITLE_SO_TF_1_CIV_KILL_WARNING149": "^2Ghost: ^7Sivil kayıplar kabul edilemez!", + "SUBTITLE_SO_TF_1_CIV_KILL_WARNING150": "^2Ghost: ^7Dikkatli olun, masum sivilleri öldürüyorsunuz!", + "SUBTITLE_SO_TF_1_SUCCESS_BEST151": "^2Ghost: ^7İyi iş çıkardın, önceki en iyi dereceni geçtin.", + "SUBTITLE_SO_TF_1_SUCCESS_BEST152": "^2Ghost: ^7Yeni bir kişisel rekor, harika iş.", + "SUBTITLE_SO_TF_1_SUCCESS_BEST153": "^2Ghost: ^7Önceki en iyi dereceni geçtin, böyle devam et.", + "SUBTITLE_SO_TF_1_SUCCESS_BEST154": "^2Ghost: ^7Mükemmel iş, yeni bir kişisel en iyi.", + "SUBTITLE_SO_TF_1_SUCCESS_JERK155": "^2Ghost: ^7Aferin, ama daha iyisini yapabilirsin.", + "SUBTITLE_SO_TF_1_SUCCESS_JERK156": "^2Ghost: ^7En iyisi değil ama başardın.", + "SUBTITLE_SO_TF_1_PROGRESS_3QUARTER157": "^2Ghost: ^7Bir çeyrek kaldı, devam et.", + "SUBTITLE_SO_TF_1_PROGRESS_3QUARTER158": "^2Ghost: ^7Yolun çeyreği, durma.", + "SUBTITLE_SO_TF_1_PROGRESS_3QUARTER159": "^2Ghost: ^7İyi ilerleme, devam et.", + "SUBTITLE_SO_TF_1_UNSUPPRESS_WARNING160": "^2Ghost: ^7Düşman silahlarını alma konusunda dikkatli ol. Bastırılmamış ateşli silahlar çok dikkat çekecektir.", + "SUBTITLE_SO_TF_1_TIME_STATUS_HALF129_1": "^2Ghost: ^7Zamanınızın yarısı kaldı - odaklanın.", + "SUBTITLE_SO_TF_1_TIME_STATUS_HALF129_2": "^2Ghost: ^7Zamanının yarısını kullandın - tetikte ol.", + "SUBTITLE_SO_TF_1_TIME_STATUS_HALF129_3": "^2Ghost: ^7Zamanının sadece yarısı kaldı - devam et.", + "SUBTITLE_SO_TF_1_PLYR_PREP_TIMED129_5": "^2Ghost: ^7Gözünü saatten ayırma. Bu süreli bir görev.", + "SUBTITLE_SO_TF_1_PLYR_PREP_TIMED129_6": "^2Ghost: ^7Bu görevde sınırlı zamanınız var - iyi şanslar.", + "SUBTITLE_AC130_FCO_BACKONTHOSE21": "^2AC-130 FCO: ^7O adamlara geri dön.", + "SUBTITLE_AC130_FCO_CLEAREDTOENGAGE22": "^2AC-130 FCO: ^7Düşman personeline müdahale izni verildi.", + "SUBTITLE_AC130_FCO_CONFIRMED23": "^2AC-130 FCO: ^7Onaylandı, araç etkisiz hâle getirildi.", + "SUBTITLE_AC130_FCO_CROSSINGFIELD24": "^2AC-130 FCO: ^7Düşmanlar alanı geçiyor.", + "SUBTITLE_AC130_FCO_DIRECTHIT25": "^2AC-130 FCO: ^7Doğrudan isabet.", + "SUBTITLE_AC130_FCO_DIRECTHITS26": "^2AC-130 FCO: ^7Evet, tam isabet.", + "SUBTITLE_AC130_FCO_DOVEONGROUND27": "^2AC-130 FCO: ^7Evet, sadece yere daldı.", + "SUBTITLE_AC130_FCO_DOWNSTILLMOVING28": "^2AC-130 FCO: ^7Adam yerde ama hâlâ hareket ediyor.", + "SUBTITLE_AC130_FCO_ENEMYONROAD29": "^2AC-130 FCO: ^7Düşman personeli yolda.", + "SUBTITLE_AC130_FCO_FULLTANK210": "^2AC-130 FCO: ^7Kahretsin, benzin deposu dolu olmalı.", + "SUBTITLE_AC130_FCO_GETPERSON211": "^2AC-130 FCO: ^7Şu kişiyi yakalayın.", + "SUBTITLE_AC130_FCO_GETTHATGUY212": "^2AC-130 FCO: ^7Yakalayın şu adamı.", + "SUBTITLE_AC130_FCO_GETTINBACKUP213": "^2AC-130 FCO: ^7Tekrar ayağa kalkıyor.", + "SUBTITLE_AC130_FCO_GETVEHICLE214": "^2AC-130 FCO: ^7Mürettebat, hareket hâlindeki aracı alın.", + "SUBTITLE_AC130_FCO_GONNAGETHIM215": "^2AC-130 FCO: ^7Bu adamı yakalayacak mısın?", + "SUBTITLE_AC130_FCO_GOODKILL216": "^2AC-130 FCO: ^7İyi öldürdün. İyi öldürdün.", + "SUBTITLE_AC130_FCO_GOTARUNNER217": "^2AC-130 FCO: ^7Burada bir kaçağımız var.", + "SUBTITLE_AC130_FCO_GUYBYCAR218": "^2AC-130 FCO: ^7Şu arabanın yanında bir adam var.", + "SUBTITLE_AC130_FCO_GUYBYTRUCK219": "^2AC-130 FCO: ^7Şu kamyonun yanında bir tane var.", + "SUBTITLE_AC130_FCO_GUYMOVIN220": "^2AC-130 FCO: ^7Anlaşıldı, adam hareket ediyor.", + "SUBTITLE_AC130_FCO_GUYRUNNIN221": "^2AC-130 FCO: ^7Koşan bir adamımız var.", + "SUBTITLE_AC130_FCO_HEADINFORDITCH222": "^2AC-130 FCO: ^7Evet, hendeğe doğru gidiyor.", + "SUBTITLE_AC130_FCO_HOTDAMN1223": "^2AC-130 TV Operatörü: ^7Lanet olsun!", + "SUBTITLE_AC130_FCO_HOTDAMN2224": "^2AC-130 TV Operatörü: ^7Oooh, sıcak lanet!", + "SUBTITLE_AC130_FCO_HOTDAMN3225": "SUBTITLE_AC130_FCO_HOTDAMN3225", + "SUBTITLE_AC130_FCO_ISEEPIECES226": "^2AC-130 FCO: ^7Evet, iyi öldürdün. Aşağıda bir sürü küçük parça görüyorum.", + "SUBTITLE_AC130_FCO_KABOOM227": "^2AC-130 FCO: ^7Ka-boom.", + "SUBTITLE_AC130_FCO_KNOCKEDWIND228": "^2AC-130 FCO: ^7Muhtemelen nefesi kesilmiştir.", + "SUBTITLE_AC130_FCO_LIGHTEMUP229": "^2AC-130 FCO: ^7Ateşleyin çocuklar.", + "SUBTITLE_AC130_FCO_MOREENEMY230": "^2AC-130 FCO: ^7Daha fazla düşman personeli.", + "SUBTITLE_AC130_FCO_MOVINGAGAIN231": "^2AC-130 FCO: ^7Tamam, tekrar hareket ediyor.", + "SUBTITLE_AC130_FCO_MOVINGVEHICLE232": "^2AC-130 FCO: ^7Burada hareket eden bir araç var.", + "SUBTITLE_AC130_FCO_NAILBYBUILDING1233": "^2AC-130 FCO: ^7Şu adamları binanın yanına çivileyin.", + "SUBTITLE_AC130_FCO_NAILTHOSEGUYS234": "^2AC-130 FCO: ^7Şu adamları çivileyin.", + "SUBTITLE_AC130_FCO_NICE235": "^2AC-130 FCO: ^7Güzel.", + "SUBTITLE_AC130_FCO_OKYOUGOTHIM236": "^2AC-130 FCO: ^7Tamam, onu yakaladın. Diğer adamların yanına dön.", + "SUBTITLE_AC130_FCO_OOPSIEDAISY237": "^2AC-130 FCO: ^7Whoops.", + "SUBTITLE_AC130_FCO_OUTOFCHURCH238": "^2AC-130 FCO: ^7Kiliseden kaçan silahlı personel var.", + "SUBTITLE_AC130_FCO_PERSONNELTHERE239": "^2AC-130 FCO: ^7Personel tam orada.", + "SUBTITLE_AC130_FCO_RIGHTONTARGET240": "^2AC-130 FCO: ^7Evet, tam isabetti.", + "SUBTITLE_AC130_FCO_RIGHTTHERE241": "^2AC-130 FCO: ^7Tam orada... takip.", + "SUBTITLE_AC130_FCO_STILLMOVING242": "^2AC-130 FCO: ^7Hâlâ hareket ediyor.", + "SUBTITLE_AC130_FCO_TAKEHIMOUT243": "^2AC-130 FCO: ^7Evet, indir onu.", + "SUBTITLE_AC130_FCO_THATSAHIT244": "^2AC-130 FCO: ^7Bu bir vuruş.", + "SUBTITLE_AC130_FCO_TRACKING245": "^2AC-130 FCO: ^7Takip ediliyor.", + "SUBTITLE_AC130_FCO_VEHICLEONMOVE246": "^2AC-130 FCO: ^7Aşağıda hareket eden bir araç var.", + "SUBTITLE_AC130_FCO_WITHIN2FEET247": "^2AC-130 FCO: ^7Pekâlâ, adamı yakaladınız. Ona bir metre kadar yaklaşmış olabilir.", + "SUBTITLE_AC130_FCO_YEPSTILLMOVING248": "^2AC-130 FCO: ^7Evet, adam hâlâ hareket ediyor.", + "SUBTITLE_AC130_FCO_YOUGOTHIM249": "^2AC-130 FCO: ^7Onu yakaladınız.", + "SUBTITLE_AC130_FCO_YOUGOTHIM2250": "^2AC-130 FCO: ^7Onu yakaladınız!", + "SUBTITLE_AC130_GNR_GUNREADY1251": "^2AC-130 Nişancısı: ^7Silah hazır!", + "SUBTITLE_AC130_GNR_SHOT1252": "^2AC-130 Nişancısı: ^7Atış!", + "SUBTITLE_AC130__SECONDARIES1253": "^2AC-130 igator: ^7İkinciler.", + "SUBTITLE_AC130_PLT_AZIMUTHSWEEP254": "^2AC-130 Pilotu: ^7Azimut tarama açısını yeniden kalibre edin. Yükseklik taramasını ayarlayın.", + "SUBTITLE_AC130_PLT_CLEANUP255": "^2AC-130 Pilot: ^7Sinyali temizleyin.", + "SUBTITLE_AC130_PLT_CLEAREDTOENGAGE256": "^2AC-130 Pilot: ^7Bunların hepsine müdahale etmek için izin verildi.", + "SUBTITLE_AC130_PLT_CLEARTOENGAGE257": "^2AC-130 Pilotu: ^7Anlaşıldı. Hareket hâlindeki araca ve etrafta gördüğünüz tüm personele müdahale etme izniniz var.", + "SUBTITLE_AC130_PLT_COPYSMOKE258": "^2AC-130 Pilotu: ^7Anlaşıldı, dumanlayın.", + "SUBTITLE_AC130_PLT_ENGVEHICLE259": "^2AC-130 Pilotu: ^7Hareket hâlindeki araca müdahale etme izniniz verildi.", + "SUBTITLE_AC130_PLT_GOTTAHURT260": "^2AC-130 Pilotu: ^7Ooo bu acıtmış olmalı.", + "SUBTITLE_AC130_PLT_ROLLININ261": "^2AC-130 Pilotu: ^7Geliyor.", + "SUBTITLE_AC130_PLT_SCANRANGE262": "^2AC-130 Pilotu: ^7Tarama aralığını ayarlayın.", + "SUBTITLE_AC130_PLT_TARGETRESET263": "^2AC-130 Pilot: ^7Hedef sıfırlama.", + "SUBTITLE_AC130_PLT_YEAHCLEARED264": "^2AC-130 Pilot: ^7Evet, angajman için izin verildi.", + "SUBTITLE_AC130__COVERBYWALL1265": "^2AC-130 TV Operatörü: ^7Duvarın yanında siper alıyorlar.", + "SUBTITLE_AC130__DIRECTSECONDARY1266": "^2AC-130 TV Operatörü: ^7Doğrudan ikincil.", + "SUBTITLE_AC130__DIRECTSECONDARY2267": "^2AC-130 TV Operatörü: ^7İkincil.", + "SUBTITLE_AC130__WHOA1268": "^2AC-130 TV Operatörü: ^7Woah!", + "SUBTITLE_AC130_FCO_FIRINGTOCLOSE271": "^2AC-130 FCO: ^7Ateşinizi kontrol edin, dostunuza ateş ediyorsunuz - yanıp sönen flaşa dikkat edin - o bizim adamımız!", + "SUBTITLE_AC130_FCO_FIRINGTOCLOSE272": "^2AC-130 FCO: ^7Dostumuza çok yakın ateş ediyorsunuz, tekrar ediyorum, dostumuza çok yakın ateş ediyorsunuz. Kızılötesi flaşa dikkat edin.", + "SUBTITLE_AC130_FCO_FIRINGTOCLOSE273": "^2AC-130 FCO: ^7Dikkatli olun! Neredeyse adamımızı öldürüyordun!", + "SUBTITLE_TRAIN_FLY_DEMONSTRATION13": "^2Çvş. Foley: ^7Er Allen, siz yerlilere nasıl yapıldığını göstermek için hızlı bir silah gösterisi yapacak.", + "SUBTITLE_TRAIN_FLY_NOOFFENSE15": "^2Çvş. Foley: ^7Alınma ama çoğunuzun kalçadan ateş ettiğini ve mermileri poligonun her tarafına püskürttüğünüzü görüyorum.", + "SUBTITLE_TRAIN_FLY_MAKESYOULOOK17": "^2Çvş. Foley: ^7Sonunda hiçbir şeyi vuramıyorsunuz ve bu sizi aptal gibi gösteriyor.", + "SUBTITLE_TRAIN_FLY_SHOWEM19": "^2Çvş. Foley: ^7Er Allen, onlara neden bahsettiğimi göster.", + "SUBTITLE_TRAIN_FLY_FIREATTARGETS111": "^2Çvş. Foley: ^7Masadaki silahı al ve arkandaki hedeflere ateş et.", + "SUBTITLE_TRAIN_FLY_TURNAROUND112": "^2Çvş. Foley: ^7Arkanı dön ve hedeflere ateş et.", + "SUBTITLE_TRAIN_FLY_GRABTHATWEAPON114": "^2Çvş. Foley: ^7Er Allen, masanın üstündeki silahı al ve arkandaki hedeflere ateş et.", + "SUBTITLE_TRAIN_FLY_COMEONALLEN115": "^2Çvş. Foley: ^7Hadi, Allen. Programa uy. O silahı al ve arkandaki hedeflere ateş et.", + "SUBTITLE_TRAIN_FLY_DONTAIMDOWN116": "^2Çvş. Foley: ^7Henüz nişan alma. Burada bir şey anlatmaya çalışıyorum. Sadece kalçadan ateş et.", + "SUBTITLE_TRAIN_FLY_TRYAFEW117": "^2Çvş. Foley: ^7Birkaç tane daha deneyelim.", + "SUBTITLE_TRAIN_FLY_FIREFROMTHEHIP118": "^2Çvş. Foley: ^7Kalçadan, asker. Tıpkı filmlerdeki gibi.", + "SUBTITLE_TRAIN_FLY_PAYATTENTION121": "^2Çvş. Foley: ^7Herkes dikkatini versin. Cephâneniz bittiğinde şarjör değiştirmeyi unutmamalısınız.", + "SUBTITLE_TRAIN_FLY_RELOAD122": "^2Çvş. Foley: ^7Silahını yeniden doldur, asker.", + "SUBTITLE_TRAIN_FLY_WAITINGFOR123": "^2Çvş. Foley: ^7Ne bekliyorsun? Silahını doldur.", + "SUBTITLE_TRAIN_FLY_SPRAYEDBULLETS31": "^2Çvş. Foley: ^7Ne demek istediğimi anladın mı? Her yere kurşun yağdırdı.", + "SUBTITLE_TRAIN_FLY_PICKYOURTARGETS33": "^2Çvş. Foley: ^7Sabit bir duruştan nişan alarak hedeflerinizi seçmelisiniz.", + "SUBTITLE_TRAIN_FLY_HOWTHERANGERS35": "^2Çvş. Foley: ^7Er Allen, buradaki arkadaşlarımıza Korucu'ların bir hedefi nasıl indirdiğini göster.", + "SUBTITLE_TRAIN_FLY_CROUCHFIRST37": "^2Çvş. Foley: ^7Önce çömel, sonra nişan al ve hedefe nişan al.", + "SUBTITLE_TRAIN_FLY_BEFOREENGAGING39": "^2Çvş. Foley: ^7Er Allen, hedefe nişan almadan önce nişan al.", + "SUBTITLE_TRAIN_FLY_DONTFORGET310": "^2Çvş. Foley: ^7Nişan almayı unutma, Er.", + "SUBTITLE_TRAIN_FLY_CROUCHINGSTANCE311": "^2Çvş. Foley: ^7Allen, çömelme pozisyonu al ve nişan al.", + "SUBTITLE_TRAIN_FLY_CROUCHED312": "^2Çvş. Foley: ^7Çömelmişken ateş etmeni istiyorum, asker.", + "SUBTITLE_TRAIN_FLY_GOTTAAIM313": "^2Çvş. Foley: ^7Hepsi bu kadar. Hedeflerinin yere düşmesini mi istiyorsun? Nişan almalısın.", + "SUBTITLE_TRAIN_FLY_ACCURACY41": "^2Çvş. Foley: ^7Yere çömelirseniz ya da yüzüstü yatarsanız isabet oranınız artacaktır.", + "SUBTITLE_TRAIN_FLY_WILLDEMONSTRATE43": "^2Çvş. Foley: ^7Er Allen neden bahsettiğimi gösterecek.", + "SUBTITLE_TRAIN_FLY_GOPRONE45": "^2Çvş. Foley: ^7Er Allen, yüzüstü yat ve birkaç hedefi daha vur.", + "SUBTITLE_TRAIN_FLY_FIREFROMPRONE47": "^2Çvş. Foley: ^7Yüzüstü pozisyondan ateş et, Er.", + "SUBTITLE_TRAIN_FLY_NEEDYOUTOFIRE48": "^2Çvş. Foley: ^7Er, yüzüstü pozisyonda ateş etmeni istiyorum.", + "SUBTITLE_TRAIN_FLY_SWITCHING51": "^2Çvş. Foley: ^7Nişangâhını aşağıya çevirmek hedefler arasında hızlıca geçiş yapmak için de işe yarar.", + "SUBTITLE_TRAIN_FLY_POPINANDOUT53": "^2Çvş. Foley: ^7Nişangahınızı aşağıya doğrultun, sonra yeni hedefler almak için içeri girip çıkın.", + "SUBTITLE_TRAIN_FLY_SHOWEMPRIVATE55": "^2Çvş. Foley: ^7Göster onlara asker.", + "SUBTITLE_TRAIN_FLY_IFTARGETCLOSE56": "^2Çvş. Foley: ^7Eğer hedefiniz nişan aldığınız yere yakınsa, nişangahınızı aşağı doğru tutarak hedefe hızlıca ulaşabilirsiniz.", + "SUBTITLE_TRAIN_FLY_TOOSLOW58": "^2Çvş. Foley: ^7Bu çok yavaştı. Yeni hedeflere yönelmek için nişan almanız ve nişanınızı hızlıca bırakmanız gerekir", + "SUBTITLE_TRAIN_FLY_SPEEDITUP59": "^2Çvş. Foley: ^7Tekrar yap. Hızlıca nişan alıp nişanınızı bırakarak yeni bir hedefe geçebilirsiniz.", + "SUBTITLE_TRAIN_FLY_ACQUIRENEW510": "^2Çvş. Foley: ^7Çok yavaş. Er Allen, yeni hedeflere hızlıca nişan alıp nişan almaktan vazgeçmelisin.", + "SUBTITLE_TRAIN_FLY_POPPINGINANDOUT511": "^2Çvş. Foley: ^7Tekrar yap ve hızlandır. Bu adamlara nişangahınızı hızlıca açıp kapatarak yeni hedefleri nasıl yakalayacaklarını gösterin.", + "SUBTITLE_TRAIN_FLY_NOTSNAPPING512": "^2Çvş. Foley: ^7Er Allen, hedeflerinize hızlıca nişan almıyorsunuz. Yeni hedeflere yönelmek için nişangahı hızlıca açıp bırakman gerekiyor.", + "SUBTITLE_TRAIN_FLY_AIMTOSNAP513": "^2Çvş. Foley: ^7Er Allen, yeni hedefe nişan almak için nişan al.", + "SUBTITLE_TRAIN_FLY_FORGETTOAIM514": "^2Çvş. Foley: ^7Nişan almayı unutma.", + "SUBTITLE_TRAIN_FLY_FROMTHEHIP515": "^2Çvş. Foley: ^7Kalçadan ateş ediyorsun, asker. Nişangahını aşağıya çevirerek hedefe nişan al.", + "SUBTITLE_TRAIN_FLY_NOTAIMINGPROP516": "^2Çvş. Foley: ^7Düzgün nişan almıyorsun, Er. Nişangahını indirerek hedefe nişan al.", + "SUBTITLE_TRAIN_FLY_DOINGITWRONG517": "^2Çvş. Foley: ^7Er Allen, yanlış yapıyorsun. Yeni hedeflere nişan almak için hızlıca nişan al ve bırak.", + "SUBTITLE_TRAIN_FLY_HOWYOUDOIT518": "^2Çvş. Foley: ^7İşte böyle yapacaksın. Hedeflerinizi hızlı ve kontrollü bir şekilde vurmak istiyorsunuz.", + "SUBTITLE_TRAIN_FLY_LIGHTCOVER61": "^2Çvş. Foley: ^7Şimdi eğer hedefiniz hafif bir siperin arkasındaysa, bazı silahların hedefinizi delip geçebileceğini ve vurabileceğini unutmayın.", + "SUBTITLE_TRAIN_FLY_THEPRIVATEHERE63": "^2Çvş. Foley: ^7Er burada gösterecek.", + "SUBTITLE_TRAIN_FLY_WOODPANEL65": "^2Çvş. Foley: ^7Er, hedefi ahşap panelden vur.", + "SUBTITLE_TRAIN_FLY_ALLENWOODPANEL66": "^2Çvş. Foley: ^7Er Allen, hedefi ahşap panelden vur.", + "SUBTITLE_TRAIN_FLY_TOSSAFRAG71": "^2Çvş. Foley: ^7Son olarak, parça tesirli el bombasının nasıl atılacağını bilmen gerekiyor.", + "SUBTITLE_TRAIN_FLY_PICKUPFRAG73": "^2Çvş. Foley: ^7Er Allen, masadan birkaç parça el bombası al.", + "SUBTITLE_TRAIN_FLY_GRENADEDOWNRANGE74": "^2Çvş. Foley: ^7Birden fazla hedefi aynı anda vurmak için el bombasını menzile at.", + "SUBTITLE_TRAIN_FLY_THROWAGRENADE76": "^2Çvş. Foley: ^7Er, bir el bombası at ve şu hedefleri yok et.", + "SUBTITLE_TRAIN_FLY_LETSGOTHROW77": "^2Çvş. Foley: ^7Asker, gidelim. Hedeflere bir el bombası atın!", + "SUBTITLE_TRAIN_FLY_NOTGOODENOUGH78": "^2Çvş. Foley: ^7Bu yeterince iyi değil, asker. El bombasını hedefe daha yakın bir yere atmalısın.", + "SUBTITLE_TRAIN_FLY_YOUREARANGER79": "^2Çvş. Foley: ^7Sen bir korucusun, asker. El bombasını hedefe bundan daha fazla yaklaştırabileceğini biliyorum, ha?", + "SUBTITLE_TRAIN_FLY_GOOD710": "^2Çvş. Foley: ^7Güzel.", + "SUBTITLE_TRAIN_FLY_FRAGSTENDTOROLL711": "^2Çvş. Foley: ^7Parçaların eğimli yüzeylerde yuvarlanma eğiliminde olduğunu unutmayın. Bu yüzden bir tanesini tepeye fırlatmadan önce iki kez düşünün.", + "SUBTITLE_TRAIN_FLY_LETSGOPICKUP713": "^2Çvş. Foley: ^7Gidelim, asker. Masadan bazı parça tesirli el bombalarını al.", + "SUBTITLE_TRAIN_FLY_GRABFRAGS714": "^2Çvş. Foley: ^7Masadan birkaç parça al, Asker", + "SUBTITLE_TRAIN_FLY_NEEDTOPICKUP715": "^2Çvş. Foley: ^7Er Allen, bu gösteriyi tamamlamak için masadan bazı parçalar almanız gerekiyor", + "SUBTITLE_TRAIN_FLY_THANKSFORHELP81": "^2Çvş. Foley: ^7Pekâlâ, yardımın için teşekkürler, Er Allen. Şimdi Çukur'a git... General Shepherd seni koşarken görmek istiyor.", + "SUBTITLE_TRAIN_FLY_GOFIRST82": "^2Çvş. Foley: ^7Pekâlâ, ilk kim başlamak ister? Şimdiye kadar ne öğrendiğinizi gösterin.", + "SUBTITLE_TRAIN_CPD_WELCOMEBACK91": "^2Çvş. Dunn: ^7Hey asker. Çukur'a tekrar hoş geldin.", + "SUBTITLE_TRAIN_CPD_SPECIALOP92": "^2Çvş. Dunn: ^7General Shepherd'ın özel bir operasyon için birliğimizden bir nişancıyı çekmek istediğini duydum. Her neyse, yukarıda gözlem altında.", + "SUBTITLE_TRAIN_CPD_GRABAPISTOL93": "^2Çvş. Dunn: ^7Devam et ve bir tabanca kap.", + "SUBTITLE_TRAIN_CPD_ALREADYHAVE94": "^2Çvş. Dunn: ^7TAMAM. Yani zaten bir silahınız var.", + "SUBTITLE_TRAIN_CPD_TRYSWITCHING95": "^2Çvş. Dunn: ^7Bana bir iyilik yap ve yan silahına geçmeyi dene.", + "SUBTITLE_TRAIN_CPD_SWITCHTORIFLE96": "^2Çvş. Dunn: ^7Pekâlâ, tüfeğine geçmeyi dene.", + "SUBTITLE_TRAIN_CPD_SWITCHTOSIDEARM97": "^2Çvş. Dunn: ^7Güzel. Şimdi tekrar tabancana geç.", + "SUBTITLE_TRAIN_CPD_ALWAYSFASTER98": "^2Çvş. Dunn: ^7Ne kadar hızlı olduğunu gördün mü? Unutma... tabancana geçmek her zaman yeniden doldurmaktan daha hızlıdır.", + "SUBTITLE_TRAIN_CPD_TIMERSTARTS99": "^2Çvş. Dunn: ^7Tamam, içeri girin. İlk hedef patladığında zamanlayıcı başlar.", + "SUBTITLE_TRAIN_CPD_ANYWEAPON910": "^2Çvş. Dunn: ^7Tamam, istediğiniz silahı alın ve içeri girin. İlk hedef patlar patlamaz zamanlayıcı başlar.", + "SUBTITLE_TRAIN_CPD_SMILEFORCAMERAS911": "^2Çvş. Dunn: ^7Kameralara gülümseyin ve ıskalamayın... Shepherd izliyor olacak. En iyi atıcı prima-donna takımına katılacak... eğer senin olayın buysa.", + "SUBTITLE_TRAIN_CPD_DONTMISS912": "^2Çvş. Dunn: ^7Kameralara gülümse ve ıskalama... Shepherd ve diğer rütbeliler özel bir operasyon için nişancı arıyorlar.", + "SUBTITLE_TRAIN_CPD_DONTHAVEALLDAY917": "^2Çvş. Dunn: ^7Tamam, Er Allen, bütün gün bekleyemeyiz. Çukura gir.", + "SUBTITLE_TRAIN_CPD_BOTHINTROUBLE918": "^2Çvş. Dunn: ^7İkimizin de General'le başını belaya sokacaksın. Çukura gir ve kursu tamamla, dostum.", + "SUBTITLE_TRAIN_CPD_WATCHOUT101": "^2Çvş. Dunn: ^7Sivillere dikkat edin.", + "SUBTITLE_TRAIN_CPD_WATCHOUT101_1": "^2Çvş. Dunn: ^7Hey, sivillere dikkat et.", + "SUBTITLE_TRAIN_CPD_AWWKILLED102": "^2Çvş. Dunn: ^7Bir sivili öldürdün. Hadi, Allen!", + "SUBTITLE_TRAIN_CPD_AWWKILLED102_2": "^2Çvş. Dunn: ^7Hadi ama, bir sivili öldürdün. Gidelim, Allen!", + "SUBTITLE_TRAIN_CPD_ACIVILIAN103": "^2Çvş. Dunn: ^7O bir sivildi, Asker.", + "SUBTITLE_TRAIN_CPD_MELEE104": "^2Çvş. Dunn: ^7Bıçağınla yakın dövüş!", + "SUBTITLE_TRAIN_CPD_CROUCH105": "^2Çvş. Dunn: ^7Engelin altına çömel ve ilerlemeye devam et!", + "SUBTITLE_TRAIN_CPD_CLEARTHEAREA106": "^2Çvş. Dunn: ^7Alanı temizleyin!", + "SUBTITLE_TRAIN_CPD_TOPFLOOR107": "^2Çvş. Dunn: ^7Üst kat pencerelerinde düşmanlar var!", + "SUBTITLE_TRAIN_CPD_JUMPDOWN108": "^2Çvş. Dunn: ^7Bölge temizlendi! Aşağı atlayın!", + "SUBTITLE_TRAIN_CPD_SPRINT109": "^2Çvş. Dunn: ^7Çıkışa doğru koş! Saat işliyor!", + "SUBTITLE_TRAIN_CPD_CLEARFIRSTGOGOGO1010": "^2Çvş. Dunn: ^7İlk bölgeyi temizle. Hadi! Hadi! Gidin! Gidin! Git! Git!", + "SUBTITLE_TRAIN_CPD_AREACLEARED1011": "^2Çvş. Dunn: ^7Bölge temizlendi! Binaya girin!", + "SUBTITLE_TRAIN_CPD_MISSEDSOME1012": "^2Çvş. Dunn: ^7Bazı hedefleri ıskaladınız, ilerlemeye devam edin.", + "SUBTITLE_TRAIN_CPD_LEFTTARGETS1013": "^2Çvş. Dunn: ^7Son bölgede hedefleri bıraktın, sadece ilerlemeye devam et.", + "SUBTITLE_TRAIN_CPD_TIMEDCOURSE1014": "^2Çvş. Dunn: ^7İlerleyin! Bu zamanlı bir parkur!", + "SUBTITLE_TRAIN_CPD_UPTHESTAIRS1015": "^2Çvş. Dunn: ^7Merdivenlerden yukarı!", + "SUBTITLE_TRAIN_CPD_LASTAREAMOVE1016": "^2Çvş. Dunn: ^7Son bölge! Yürüyün! Yürüyün!", + "SUBTITLE_TRAIN_CPD_NEEDTOUSEKNIFE1017": "^2Çvş. Dunn: ^7Bıçağını kullanmalısın, Allen.", + "SUBTITLE_TRAIN_CPD_NOBULLETS1018": "^2Çvş. Dunn: ^7Kurşun yok asker, hedef için bıçağını kullan.", + "SUBTITLE_TRAIN_CPD_MELEETHATTARGET1019": "^2Çvş. Dunn: ^7O hedefe yakın dövüş, Asker.", + "SUBTITLE_TRAIN_CPD_USEYOURKNIFE1020": "^2Çvş. Dunn: ^7Bıçağını kullan!", + "SUBTITLE_TRAIN_CPD_STOPFIRINGFROMHIP1021": "^2Çvş. Dunn: ^7Kalçadan ateş etmeyi kes! Nişan al!", + "SUBTITLE_TRAIN_CPD_AIMSIGHTSPRIVATE1022": "^2Çvş. Dunn: ^7Nişan al, asker!", + "SUBTITLE_TRAIN_CPD_NEEDTOAIM1024": "^2Çvş. Dunn: ^7Nişan almalısın, Allen!", + "SUBTITLE_TRAIN_CPD_NEEDTOSPRINT1025": "^2Çvş. Dunn: ^7Parkuru tamamlamak için koşman gerekiyor. Kırmızı daireye geri dön ve tekrar dene.", + "SUBTITLE_TRAIN_CPD_DIDNTSPRINT1026": "^2Çvş. Dunn: ^7Koşmadın asker. Kırmızı daireye geri dön ve çıkışa doğru koş.", + "SUBTITLE_TRAIN_CPD_GOBACKANDSPRINT1027": "^2Çvş. Dunn: ^7Koşman gerek asker. Kırmızı daireye geri dön ve sonuna kadar koş.", + "SUBTITLE_TRAIN_CPD_CANTFINISHSPRINT1028": "^2Çvş. Dunn: ^7Koşmadan bitiremezsin, Allen. Kırmızı daireye geri dön ve sonuna kadar koş.", + "SUBTITLE_TRAIN_CPD_MOVINGFORWARDGO1029": "^2Çvş. Dunn: ^7İlerlemeye devam et! Koş! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_TRAIN_CPD_RUNNINGOUTOFTIME1030": "^2Çvş. Dunn: ^7Çekilin! Yürüyün! Zamanınız tükeniyor!", + "SUBTITLE_TRAIN_CPD_TIMEDCOURSE21031": "^2Çvş. Dunn: ^7Gidelim! İlerleyin! Bu süreli bir parkur, Private", + "SUBTITLE_TRAIN_CPD_SPRINTTOEXIT1032": "^2Çvş. Dunn: ^7Gidin! Çıkışa doğru koş!", + "SUBTITLE_TRAIN_CPD_MOVESPRINT1033": "^2Çvş. Dunn: ^7Yürü! Koş, asker!", + "SUBTITLE_TRAIN_CPD_SPRINTALLENGOGOGO1034": "^2Çvş. Dunn: ^7Sprint, Allen! Koş! Koş! Koş! Koş!", + "SUBTITLE_TRAIN_CPD_NOWSPRINT1035": "^2Çvş. Dunn: ^7Şimdi çıkışa doğru koş! Yürüyün! Yürü! Yürü! Yürü! Yürü!", + "SUBTITLE_TRAIN_CPD_MOVINGFORWARD1113": "^2Çvş. Dunn: ^7İlerlemeye devam edin!", + "SUBTITLE_TRAIN_CPD_LONGANDCIVILIANS121": "^2Çvş. Dunn: ^7Yeterince iyi değil, Allen. Çok uzun sürdü ve çok fazla sivil öldürdün. Tekrar git.", + "SUBTITLE_TRAIN_CPD_LONGANDCIVILIANS121_1": "^2Çvş. Dunn: ^7Bu yeterli değil, Allen. Çok uzun sürdü, çok fazla sivil öldürdün. Tekrar dene.", + "SUBTITLE_TRAIN_CPD_TARGETSWITHKNIFE122": "^2Çvş. Dunn: ^7Bıçağınla çok fazla hedef öldürdün. Tekrar dene, bu sefer mermilerle.", + "SUBTITLE_TRAIN_CPD_LONGANDTARGETS123": "^2Çvş. Dunn: ^7Yeterince iyi değil, Allen. Çok uzun sürdü ve çok fazla hedefi ıskaladın. Tekrar dene.", + "SUBTITLE_TRAIN_CPD_TARGETS124": "^2Çvş. Dunn: ^7Yeterince iyi değil, Allen. Çok fazla hedefi ıskaladın. Tekrar dene.", + "SUBTITLE_TRAIN_CPD_CIVILIANS125": "^2Çvş. Dunn: ^7Yeterince iyi değil, Allen. Çok fazla sivili öldürdün. Tekrar dene.", + "SUBTITLE_TRAIN_CPD_CIVILIANS125_1": "^2Çvş. Dunn: ^7Bu yeterince iyi değil, Allen. Çok fazla sivil öldürdün. Oraya tekrar gir.", + "SUBTITLE_TRAIN_CPD_SLOPPY126": "^2Çvş. Dunn: ^7Tamam, fena değil. Yine de biraz özensizleşiyorsun gibi görünüyor.", + "SUBTITLE_TRAIN_CPD_ALRGIHTIGUESS127": "^2Çvş. Dunn: ^7Evet, fena değildi sanırım. Yine de ciddi bir cilaya ihtiyacın var.", + "SUBTITLE_TRAIN_CPD_GOODENOUGH128": "^2Çvş. Dunn: ^7Yeterince iyiydi, ama biraz özensizleşiyorsun.", + "SUBTITLE_TRAIN_CPD_ROUGHEDGES129": "^2Çvş. Dunn: ^7Pekâlâ, daha kötülerini de gördüm. Yine de birkaç pürüzün var.", + "SUBTITLE_TRAIN_CPD_WASNTHORRIBLE1210": "^2Çvş. Dunn: ^7Tamam, korkunç değildi ama harika da değildi.", + "SUBTITLE_TRAIN_CPD_LOOKOK1211": "^2Çvş. Dunn: ^7Orada iyi görünüyordun, ama hâlâ biraz çalışmaya ihtiyacın var.", + "SUBTITLE_TRAIN_CPD_STILLGOTIT1212": "^2Çvş. Dunn: ^7Bu iyiydi dostum, çok iyiydi. Sende hâlâ iş var.", + "SUBTITLE_TRAIN_CPD_VERYNICE1213": "^2Çvş. Dunn: ^7Tamam, şimdi bu güzeldi. Gerçek bir profesyonel gibi koştun.", + "SUBTITLE_TRAIN_CPD_JUSTSWITCH1214": "^2Çvş. Dunn: ^7Sadece diğer silahına geç! Yeniden doldurmaktan daha hızlı!", + "SUBTITLE_TRAIN_CPD_PRETTYGOOD1215": "^2Çvş. Dunn: ^7İşte bu çok iyiydi. İyi iş, Allen.", + "SUBTITLE_TRAIN_CPD_VERYIMPRESSIVE1216": "^2Çvş. Dunn: ^7Çok etkileyiciydi, dostum! O parkuru kendi kaltağın yaptın!", + "SUBTITLE_TRAIN_CPD_AMAZINGWORK1217": "^2Çvş. Dunn: ^7Harika iş, dostum. Tamam, işte Çukur böyle yönetilir.", + "SUBTITLE_TRAIN_CPD_RUNAGAIN1218": "^2Çvş. Dunn: ^7Tamam, yukarı çıkın ve ekibinizle yeniden toplanın ya da geri dönüp parkuru tekrar çalıştırabilirsiniz.", + "SUBTITLE_TRAIN_CPD_HEADUPSTAIRS1219": "^2Çvş. Dunn: ^7Pekâlâ. Yukarı çıkıp diğerleriyle yeniden toplanın.", + "SUBTITLE_TRAIN_CPD_ANOTHERGO1220": "^2Çvş. Dunn: ^7Pekâlâ. Geri dön ve bir kez daha dene.", + "SUBTITLE_TRAIN_CPD_JUMPTHEDITCH1220": "^2Çvş. Dunn: ^7Hendekten atla!", + "SUBTITLE_TRAIN_CPD_NEEDTORUNAGAIN1221": "^2Çvş. Dunn: ^7Çok yavaş. Tekrar çalıştırmalısın asker.", + "SUBTITLE_TRAIN_HQR_HEADEDOUT131": "^2Overlord: ^7Tüm Avcı birimleri, galiplerinizin yanına gidin. Biz çıkıyoruz.", + "SUBTITLE_TRAIN_AR1_TRAPPED132": "^2Er Walden: ^7BCT Bir nehrin karşısında kırmızı bölgede sıkışıp kaldı! Teması kaybettik!", + "SUBTITLE_TRAIN_AR2_BLEWTHEBRIDGE133": "^2Çvş. Arnett: ^7Lanet köprüyü havaya uçurdular! Gitmeliyiz!", + "SUBTITLE_TRAIN_FLY_MOVINGOUT134": "^2Çvş. Foley: ^7Herkes araçlarına binsin! Gidiyoruz!", + "SUBTITLE_DCBURN_CPD_OPTICSONUS": "^2Çvş. Dunn: ^7Üzerimizde optikler var...keskin nişancılar, RPG ekipleri ve ağır silah ateşi, tüm zeminler...saat 12 yönünde pozisyonumuzun batısında!", + "SUBTITLE_DCBURN_CPD_CAPITOLBUILD": "^2Çvş. Dunn: ^7Bu lanet Kongre Binasıydı dostum.", + "SUBTITLE_DCBURN_AR2_LEAVEBEHIND": "^2Atlas İki-Beş: ^7Burası Atlas İki-Beş, LZ Bir! Motorlar yüzde otuzda! Daha fazla insan taşıyamam! Bazılarını geride bırakmak zorundayız!!", + "SUBTITLE_DCBURN_MCY_HANGON": "^2Çvş. Foley: ^7Onbaşı, dayan!", + "SUBTITLE_DCBURN_MCY_TALKTOME": "^2Çvş. Foley: ^7Sean, konuş benimle!", + "SUBTITLE_DCBURN_HQR_UNCOVERENGAGE": "^2Overlord: ^7Tüm çağrı işaretleri, LZ yoğun ateş altında. Düşman mevzilerini ortaya çıkarın ve potansiyel hedeflere saldırın.", + "SUBTITLE_DCBURN_AR4_WATCH3": "^2Er Sean: ^7Ben iyiyim! Kendinize dikkat edin!", + "SUBTITLE_DCBURN_HQR_ORDERIRENE": "^2Overlord: ^7Overlord'nden tüm birimlere, tahliye emri April, tekrar ediyorum, tahliye emri April. Herkes oradan çıksın.", + "SUBTITLE_DCBURN_AR1_LINCOLNMEMORIAL": "^2Delta Four-One: ^7Burası Delta Dört-Bir, Lincoln Anıtı'ndayız. Ağır ateş altındayız, bulunduğumuz yere silahlı saldırı ve hava saldırısı talep ediyoruz. Elinizde ne varsa gönderin! Kırık ok, kırık ok!!!", + "SUBTITLE_DCBURN_AR4_CENTCOM": "^2Ranger: ^7Mystic Two-One, CENTCOM az önce Potomac'ın doğusundaki tüm tahliye alanlarının terk edilmesi emrini verdi. Kaldır kıçını oradan!", + "SUBTITLE_DCBURN_HQR_URGENTSURGICALS": "^2Overlord: ^7Atlas İki-Altı şu anda uzakta. Kalan tüm tahliye birimleri, üçüncü seviye tahliye protokollerini uygulayın. Sadece acil ameliyatlar.", + "SUBTITLE_DCBURN_AR1_WEARELEAVING": "^2Ranger: ^7Adamlarınızı hemen nakil aracına bindirin, gidiyoruz!", + "SUBTITLE_DCBURN_AR4_WEAREGOINGDOWN": "^2Atlas Bir-Bir: ^7Burası Atlas One-One, Dupont Circle'ın iki tık batısına inen sivil araç! Biz-", + "SUBTITLE_DCBURN_AR5_TRIPLEA": "^2Ranger: ^7Az önce Atlas İki-Üç'ü Capitol Binası'ndaki üçlü A'ya kaybettik!", + "SUBTITLE_DCBURN_AR2_BACKINSEATS": "^2Ranger: ^7Sivilleri yerlerine oturtun!", + "SUBTITLE_DCBURN_HQR_FIRSTWAVE": "^2Overlord: ^7İlk sivil nakliye dalgası gitti. Reaver İki, ikinci aşama tahliyeye devam edin. Sadece acil personel.", + "SUBTITLE_DCBURN_HQR_FALLBACKNOW": "^2Overlord: ^7Atlas İki-Üç, İki-Dört ve İki-Beş uzaklaştı. LZ 4'teki kara birimleri, şimdi geri çekilin.", + "SUBTITLE_DCBURN_AR3_GOTTATOUCHDOWN": "^2Ranger: ^7Büyük bir hidrolik sızıntı var! MSR'yi zar zor aşacağız! İnmemiz gerek-", + "SUBTITLE_OILRIG_SBC_DRYDOCK": "^2Sub Commander: ^7USS Chicago gerçek kuru havuz sığınağına. Gidiyoruz.", + "SUBTITLE_OILRIG_SBO_FULLPRESSURE": "^2Denizaltı Subayı: ^7DDS hangarını su bastı. Tam basınç.", + "SUBTITLE_OILRIG_SBC_DEPLOYMENT": "^2Yardımcı Komutan: ^7Konuşlandırmaya başlayın.", + "SUBTITLE_OILRIG_SBO_TM1AWAY": "^2Alt Subay: ^7Takım Bir SDV uzakta.", + "SUBTITLE_OILRIG_SBO_ZEROONENINER": "^2Yardımcı Subay: ^7Hotel Altı, Sıfır-Bir-Dokuz'u taşıyor.", + "SUBTITLE_OILRIG_SBC_USSDALLAS": "^2Yardımcı Komutan: ^7USS Dallas, Takım İki'yi konuşlandırıyor. RV hedefte.", + "SUBTITLE_OILRIG_SBO_DEPTH20": "^2Denizaltı Subayı: ^7Hotel Altı 20 metre derinlikte.", + "SUBTITLE_OILRIG_SBC_TM2OBJECTIVE": "^2Denizaltı Komutanı: ^7İkinci Takım hedefte.", + "SUBTITLE_OILRIG_RMV_GOPLAT": "^2Punisher: ^7Avcı İki-İki, burası Punisher Actual. GOPLAT güvende. Tüm EOD ekipleri iniş için hazır.", + "SUBTITLE_OILRIG_GM1_COPIES": "^2Avcı İki-İki: ^7Anlaşıldı Punisher, Avcı İki-İki herkesi duyuyor.", + "SUBTITLE_OILRIG_F15_TWOF15S": "^2Phoenix One-One: ^7Punisher burası Phoenix One-One, iki F-15'ten oluşan uçuş SEAD görevi için 257221 numaralı bölgeye gidiyor, durum raporu talep ediyoruz.", + "SUBTITLE_OILRIG_RMV_BLUESKY": "^2Punisher: ^7Phoenix One-One, Punisher. Mavi gökyüzü, tekrar ediyorum mavi gökyüzü. İki-Dört-Sıfır rotasına gelin ve hedef bölgeye doğru devam edin. İyi avlar. Tamam.", + "SUBTITLE_OILRIG_F15_COPIES": "^2Phoenix One-One: ^7Anka Bir-Bir anlaşıldı. Tamam.", + "SUBTITLE_OILRIG_RMV_LOCALAIRSPACE": "^2Punisher: ^7Punisher'dan 255202 numaralı grid civarındaki tüm uçuşlara, yerel hava sahası güvenlidir. Tekrar ediyorum, yerel hava sahası güvenlidir. Kasım-İki Rotası boyunca hedef bölgeye doğru ilerleyin.", + "SUBTITLE_OILRIG_GM1_HUNTERACTUAL": "^2Avcı İki-İki: ^7Punisher, bu Hunter Actual. Avcı İki-İki ana güvertenin güneybatı köşesindeki FÜZE bölgesini emniyete almak için hareket ediyor. Avcı İki-Üç patlayıcıları etkisiz hâle getirmek için vinç binasına doğru ilerliyor.", + "SUBTITLE_OILRIG_RMV_STANDBY": "^2Punisher: ^7Punisher herkesi duyuyor. İki-İki'yi görüyoruz. Güneybatı FÜZE bölgesine varıyorlar... beklemede... beklemede... Bölge güvenli, tekrar ediyorum bölge güvenli.", + "SUBTITLE_OILRIG_RMV_SAMSITESNEUT": "^2Punisher: ^7Punisher'dan tüm saldırı ekiplerine - tüm FÜZE sahâlârı etkisiz hâle getirildi, tekrar ediyorum, tüm FÜZE sahâlârı etkisiz hâle getirildi. Mavi gökyüzü yürürlükte.", + "SUBTITLE_GULAG_HRP1_ANGELSONE": "^2Jester One-One: ^7Hornet İki-Bir, burası Jester Bir-Bir, iki F-15 uçuşu, bölüm için dört HARM, SEAD için beklemede.", + "SUBTITLE_GULAG_LBP1_GOGETEM": "^2Hornet İki-Bir: ^7Anlaşıldı Jester. Git hakla onları.", + "SUBTITLE_GULAG_FP1_NICEDAY": "^2Jester Bir-Bir: ^7Hornet İki-Bir, tüm yol temizlendi. İyi şanslar", + "SUBTITLE_GULAG_LBP1_DEPLOYED": "^2Hornet İki-Bir: ^7Birinci Takım konuşlandı. Bekleme düzenine geçiyoruz.", + "SUBTITLE_GULAG_LBP3_SNIPERCOVER": "^2Hornet İki-Üç: ^7Beş-Üç, keskin nişancı koruması sağlamak için baş üstü düzenine geçiyor, tamam.", + "SUBTITLE_GULAG_TF1_CELLCLEAR": "^2TF-141 Asker: ^7Hücre temiz.", + "SUBTITLE_GULAG_TF1_CELL4DCLEAR": "^2TF-141 Asker: ^7Hücre 4D temiz.", + "SUBTITLE_GULAG_PRI_YES": "^2Yzb. Price: ^7Yeeeeeah!", + "SUBTITLE_GULAG_HQR_GETOUT": "^2Shepherd: ^7Bravo Altı'nın dikkatine, bombardımana erken başladılar - hemen oradan çıkın!", + "SUBTITLE_GULAG_LBP1_2NDWAVE": "^2Hornet İki-Bir: ^7İkinci dalga geliyor. Beklemede kalın.", + "SUBTITLE_GULAG_LBP1_10FT": "^2Hornet İki-Bir: ^7On feet.", + "SUBTITLE_GULAG_LBP1_TOUCHDOWN": "^2Hornet İki-Bir: ^7İki-Bir hedefe iniyor.", + "SUBTITLE_AFCAVES_SCHQ_GOAHEAD": "^1Gölge Bölüğü Karargâhı: ^7Devam et Alfa?", + "SUBTITLE_AFCAVES_SC1_RIVERBEDCLEAR": "^1Gölge Bölüğü: ^7Nehir yatağı temiz, tamam.", + "SUBTITLE_AFCAVES_SCHQ_BRAVO": "^1Gölge Bölüğü Karargâhı: ^7Bravo mu?", + "SUBTITLE_AFCAVES_SC2_CATWALKCLEAR": "^1Gölge Bölüğü: ^7Podyum temiz... Görüş %100, tamam.", + "SUBTITLE_AFCAVES_SCHQ_ZULU": "^1Gölge Bölüğü Karargâhı: ^7Zulu?", + "SUBTITLE_AFCAVES_SC3_SANDSTORM": "^1Gölge Bölüğü: ^7Kum Fırtınası. Şu anda görecek pek bir şey yok, tamam.", + "SUBTITLE_AFCAVES_SC1_STARTINGPATROL": "^1Gölge Bölüğü: ^7...uh, devriyemize kanyon boyunca doğudan başlıyoruz, kuzey tarafı erişim yolu, tamam.", + "SUBTITLE_AFCAVES_SCHQ_FINISHSWEEP": "^1Gölge Bölüğü Karargâhı: ^7Anlaşıldı, Öğrenci Dört. Taramanızı bitirin ve içeri girin. Zulu ekibi yolda şiddetli bir kum fırtınası olduğunu bildirdi. Oksit dışarı.", + "SUBTITLE_AFCAVES_SCHQ_D4WHATSYOURSTATUS": "^1Gölge Bölüğü Karargâhı: ^7Öğrenci Dört, Oksit. Durumunuz nedir, tamam?", + "SUBTITLE_AFCAVES_SCHQ_D4DOYOUCOPY": "^1Gölge Bölüğü Karargâhı: ^7Mürit Dört, Oksit, duyuyor musunuz, tamam?", + "SUBTITLE_AFCAVES_SCHQ_BADTRANSMITTER": "^1Gölge Bölüğü Karargâhı: ^7Hey, kuzey sırt yolundaki Disciple Four'dan bir şey alamıyorum. Kötü bir verici olabilir.", + "SUBTITLE_EST_SNP1_INPOSITION": "^2Archer: ^7Keskin nişancılar yerlerini aldı.", + "SUBTITLE_EST_GST_ENGAGEONSIGHT": "^2Ghost: ^7Saldırı timi, gidin. Makarov'u gördüğünüz yerde vurun.", + "SUBTITLE_EST_SLD2_SOLIDCOPY": "^2Ozone: ^7Anlaşıldı.", + "SUBTITLE_EST_TF1_AMBUSH": "^2Scarecrow: ^7Pusu!", + "SUBTITLE_EST_TF2_AMBUSH": "^2Ozone: ^7Pusu!", + "SUBTITLE_EST_HP2_WATCHFORSNIPERS": "^2Görev Gücü Pilotu: ^7Altın Kartal yerde. Termalde keskin nişancılara dikkat edin, tamam.", + "SUBTITLE_EST_GST_NO": "^2Ghost: ^7Hayır!", + "SUBTITLE_EST_PRI_UNDERATTACK": "^2Price: ^7Ghost, cevap ver, ben Price! Mezarlıkta Shepherd'ın adamları tarafından saldırıya uğradık! Soap, sol kanadı tut! Shepherd'a güvenmeyin - Tekrar söylüyorum, Shepherd'a güvenmeyin! Soap yere yat!", + "SUBTITLE_DCBURN_HQR_DOYOUCOPY": "^2Overlord: ^7Hançer İki-Bir, ben Overlord. Duyuyor musun, tamam?", + "SUBTITLE_DCBURN_HQR_HOWCOPY": "^2Overlord: ^7Hançer İki-Bir, burası Overlord, nasıl anlaşıldı?", + "SUBTITLE_CONT_CMT_BARELYSEE": "^2Soap: ^7Price, uydu yayınımda Roach'un paraşütünü zar zor görebiliyorum. Çok fazla parazit var. Onu görüyor musun, tamam?", + "SUBTITLE_CONT_GST_WHATWAIT": "^2Ghost: ^7Ne...? Bekle...bekle, Price - hayır!", + "SUBTITLE_CONT_GST_CODEBLACK": "^2Ghost: ^7Nükleer bir füze fırlatıldı, füze havada - füze havada! Siyah kod - siyah kod!", + "SUBTITLE_ARCADIA_FLY_HEAVYLOSSES": "^2Çvş. Foley: ^7Avcı İki-Bir, burası Avcı İki-Bir Gerçek. Tahliye helikopterlerimiz yerden açılan ateşle ağır kayıplar veriyor!", + "SUBTITLE_FAVESC_GST_CLOSINGIN": "^2Ghost: ^7Efendim, milisler yaklaşıyor! Neredeyse iki yüz kişi, önden ve arkadan!", + "SUBTITLE_FAVESC_CMT_FIGHTOURWAY": "^2Yzb. MacTavish: ^7LZ'ye ulaşmak için savaşmamız gerekecek! Hadi gidelim!", + "SUBTITLE_FAVESC_GST_WHATABOUTROJAS": "^2Ghost: ^7Rojas ne olacak?", + "SUBTITLE_FAVESC_CMT_TAKEOVER": "^2Yzb. MacTavish: ^7Sokaklar onun icabına bakacak.", + "SUBTITLE_FAVESC_GST_WORKSFORME": "^2Ghost: ^7Bana uyar.", + "SUBTITLE_ROADKILL_CPD_AIRSTRIKE": "^2Hunter Two-One: ^7Savaş Lordu, Savaş Lordu, burası Avcı İki-Bir, 252171 numaralı bölgeye hava saldırısı talep ediyorum! Hedef beyaz, on iki katlı bir apartman binası, tamam!", + "SUBTITLE_ROADKILL_AUC_ONTHELINE": "^2Savaş Lordu: ^7Avcı İki-Bir, burası Savaş Lordu, Anlaşıldı, Şeytan Bir-Bir var, iki F-15'ten oluşan uçuş, hatta, aktarma için beklemede.", + "SUBTITLE_ROADKILL_FP1_DEVIL11": "^2Devil One-One: ^7Avcı İki-Bir burası Şeytan Bir-Bir, iki F-15 uçuşu, istasyonda zaman, bir-beş dakika, üç-Sierra'da bekleme, kuzeybatı, Knife bekleme alanı, iki JDAM ve iki HARM taşıyor, tamam.", + "SUBTITLE_ROADKILL_FP1_STANDINGBY": "^2Devil One-One: ^7Beklemedeyiz.", + "SUBTITLE_ROADKILL_CPD_LEVELBUILDING": "^2Avcı İki-Bir: ^7Şeytan Bir-Bir, hedef 252171 numaralı karede bulunan beyaz, on iki katlı bir apartman binası. O binanın seviyesini yükseltmeni istiyorum, nasıl kopyalayabilirim?", + "SUBTITLE_ROADKILL_FP1_TARGETACQUIRED": "^2Şeytan Bir-Bir: ^7Anlaşıldı Avcı İki-Bir. Şimdi geliyorum. Hedef ele geçirildi.", + "SUBTITLE_ROADKILL_CPD_NOTSTOPPIN": "^2Ranger: ^7Dostum, eğer iki dolar bırakacaksan şimdi yap çünkü o arabayı bir kere çalıştırdım mı durmam!", + "SUBTITLE_ROADKILL_CPD_NOTSTOPPIN_B": "^2Ranger: ^7Hey dostum, kablo döşemen gerekiyorsa şimdi yap çünkü o arabayı bir kez çalıştırdım mı durmam!", + "SUBTITLE_ROADKILL_CPD_NOTSTOPPIN_C": "^2Ranger: ^7Hey, eğer bir çivi düşüreceksen şimdi yap dostum, çünkü o arabayı bir kez çalıştırırsam durmam hooah!", + "SUBTITLE_ROADKILL_AR3_10SECONDS": "^2Ranger: ^7On saniye!", + "SUBTITLE_ROADKILL_AR1_WHICHBUILDING": "^2Ranger: ^7Hangi bina efendim?", + "SUBTITLE_ROADKILL_AR2_TALLONE": "^2Ranger: ^7Saat 1 yönündeki uzun bina.", + "SUBTITLE_ROADKILL_AR3_HEYDAWG": "^2Ranger: ^7Hey, hangi bina?", + "SUBTITLE_ROADKILL_AR4_WHICHONE": "^2Ranger: ^7Saat bir yönündeki, uzun olan - hey Dave, hangisi o? Soldaki mi yoksa sağdaki mi?", + "SUBTITLE_ROADKILL_FLY_BREAKINGAWAY": "^2Ranger: ^7Avcı İki kaçıyor.", + "SUBTITLE_ROADKILL_HQR_COPYHUNTER2": "^2Overlord: ^7Anlaşıldı Avcı İki.", + "SUBTITLE_DCEMP_FP1_ABORTABORT": "^2Savaş Pilotu: ^7Whiskey Otel'de karşı işaret tespit edildi! İptal iptal!", + "SUBTITLE_DCEMP_FP2_ABORTMISSION": "^2Savaş Pilotu: ^7Bir karşı işaret aldık! Görev iptal!", + "SUBTITLE_DCEMP_FP3_ROLLINGOUT": "^2Savaş Pilotu: ^7Silah bırakma iptal ediliyor! Çıkıyoruz!", + "SUBTITLE_ROADKILL_CPD_CLASSONRIGHT_B": "^2Çvş. Dunn: ^7Dikkat et! Sınıf sağda!", + "SUBTITLE_ROADKILL_CPD_CLASSONRIGHT_C": "^2Çvş. Dunn: ^7Dikkat et! Sağdaki sınıf!", + "SUBTITLE_TRAIN_CPD_PUTUSIN": "^2Çvş. Dunn: ^7Neden önce bizi sokmadıklarını anlamıyorum Allen.", + "SUBTITLE_TRAIN_CPD_SOCOMBRASS": "^2Çvş. Dunn: ^7Korucu'ların SF ve Delta'nın yapamayacağı pek bir şey yok ama neyse dostum. SOCOM'un üst düzey yetkilileri böyle işte.", + "SUBTITLE_TRAIN_CPD_REALACTION": "^2Çvş. Dunn: ^7Ve tüm o lanet olası engelleme pozisyonları. Seals ve D-boys'a bebek bakıcılığı yapmak yerine ne zaman gerçek bir aksiyon göreceğiz, hooah?", + "SUBTITLE_ROADKILL_INTRO_RPG": "^2Ranger: ^7RPG!!!", + "SUBTITLE_TRAIN_FLY_WELCOME": "^2Çvş. Foley: ^7Atış Poligonu 101'e hoş geldiniz.", + "SUBTITLE_FAVELA_GST_NOHESNOT": "^2Ghost: ^7Hayır, değil!", + "SUBTITLE_ROADKILL_AR4_ONEONTHELEFT": "^2Ranger: ^7Soldaki.", + "CLIFFHANGER_OBJ_FUEL_STATION": "Yakıt istasyonuna patlayıcı yerleştir.", + "CLIFFHANGER_OBJ_C4": "Yakıt tanklarına patlayıcı yerleştir.", + "CLIFFHANGER_OBJ_C4_MIG": "MiG-29 Jet Savaş Uçağına patlayıcı yerleştir.", + "CLIFFHANGER_HINT_PRONE": "Yüzüstü gitmek için ^3[{goprone}]^7 tuşuna basın.", + "CLIFFHANGER_OBJ_PACKAGE": "'Paketi' geri al.", + "CLIFFHANGER_OBJ_FOLLOW": "Yüzbaşı MacTavish'i takip et.", + "CLIFFHANGER_OBJ_BASE": "Üsse girmenin bir yolunu bul.", + "CLIFFHANGER_OBJ_FIND_FUEL": "Yakıt tankerlerini bul.", + "CLIFFHANGER_OBJ_STEALTH": "Tespit edildiniz. Şimdi olanları ortadan kaldırın.", + "CLIFFHANGER_FAIL_STEALTH_COUNT": "Çok fazla düşmanı alarma geçirdin.", + "CLIFFHANGER_FAIL_STEALTH_TIME": "Çok uzun sürdü, alarm verildi.", + "CLIFFHANGER_FAIL_PRICE_DEAD": "Yüzbaşı MacTavish'i ölüme terk ettiniz.", + "CLIFFHANGER_MISSION_ABORT": "Yüzbaşı MacTavish görevi iptal etti.", + "CLIFFHANGER_USE_SATELITE_PC": "ACS'yi geri almak için ^3&&1^7 tuşuna basın.", + "CLIFFHANGER_USE_SATELITE": "ACS'yi almak için ^3&&1^7 tuşuna basılı tutun.", + "CLIFFHANGER_OBJ_USE_SATELITE": "Veri Depolama Modülünü Uydudan Çıkarın.", + "CLIFFHANGER_OBJ_GOTO_HANGER": "Uyduya git.", + "CLIFFHANGER_OBJ_SNOWMOBILE": "Bir kar motosikleti bul.", + "CLIFFHANGER_OBJ_EXTRACT": "Çıkarma noktasına git.", + "CLIFFHANGER_OBJ_EVACUATE": "Yüzbaşı MacTavish ile kaç.", + "CLIFFHANGER_ACTIVATE_HEARTBEAT": "Kalp atışı sensörünü etkinleştirmek için ^3[{weapnext}]^7 tuşuna basın.", + "CLIFFHANGER_SWITCH_HEARTBEAT": "Kalp atışı sensörünü etkinleştirmek için^3 [{+actionslot 3}] ^7 düğmesine basın.", + "CLIFFHANGER_OBJ_MACRO_ACS": "ACS modülünü kurtarın.", + "CLIFFHANGER_OBJ_COMPUTER": "ACS modülünü geri alın.", + "CLIFFHANGER_PRICE_DIED": "Yüzbaşı MacTavish infaz edildi.", + "CLIFFHANGER_RUN_OVER": "Yüzbaşı MacTavish ezildi.", + "CLIFFHANGER_BOARD_PRESS": "Binmek için ^3&&1^7 tuşuna basın.", + "CLIFFHANGER_BOARD": "Binmek için ^3&&1^7 tuşuna basılı tutun.", + "CLIFFHANGER_MAKES_FIRST_JUMP": "Kimse ilk atlayışı yapamaz...", + "CLIFFHANGER_GREATEST_GLORY": "En büyük zaferimiz hiç düşmemek değil, her düştüğümüzde ayağa kalkmaktır.", + "CLIFFHANGER_GREATEST_GLORY_AUTHOR": "- Konfüçyüs", + "CLIFFHANGER_FALLING_ROCKS": "Düşen kayalar, dedi tabela. Öyle mi?", + "CLIFFHANGER_GREAT_CHASM": "Hayat yolunda ilerlerken büyük bir uçurum göreceksiniz. Atlayın. Düşündüğünüz kadar geniş değildir.", + "CLIFFHANGER_GREAT_CHASM_AUTHOR": "- Kızılderili atasözü", + "CLIFFHANGER_JUMP_HIGH": "Yüksek atlamak isteyen uzun bir koşu yapmalıdır.", + "CLIFFHANGER_JUMP_HIGH_AUTHOR": "- Danimarka atasözü", + "CLIFFHANGER_JUMP_UP": "Yukarı zıplarsın, ama yine de aşağı inersin.", + "CLIFFHANGER_JUMP_UP_AUTHOR": "- Martiniquais atasözü", + "CLIFFHANGER_THOUGH_A_TREE": "Bir ağaç ne kadar yükselirse yükselsin, düşen yapraklar toprağa geri döner.", + "CLIFFHANGER_THOUGH_A_TREE_AUTHOR": "- Malaya atasözü", + "CLIFFHANGER_FALLING_HURTS": "Düşmek en az alçaktan uçanları incitir.", + "CLIFFHANGER_FALLING_HURTS_AUTHOR": "- Çin atasözü", + "CLIFFHANGER_MAN_FALLING_DOWN": "Yere düşen bir adam durumun ciddiyetini anlar.", + "CLIFFHANGER_HUMPTY_DUMPTY": "Humpty Dumpty'nin de harika bir düşüşü vardı.", + "CLIFFHANGER_IF_YOU_FALL": "Eğer düşersen, orada olacağım.", + "CLIFFHANGER_IF_YOU_FALL_AUTHOR": "- Zemin", + "CLIFFHANGER_HOLD_ON_TIGHT": "Canını kurtarmak için dayan.", + "CLIFFHANGER_LEFT_ICEPICK": "Hold \u0012 to swing your left icepick.", + "CLIFFHANGER_RIGHT_ICEPICK": "Hold \u0013 to swing your right icepick.", + "CLIFFHANGER_LEFT_ICEPICK_PC": "^3[{+attack}]^7sol buz kıracağını savurmak için tut.", + "CLIFFHANGER_RIGHT_ICEPICK_PC": "Sağ buz kırıcınızı savurmak için ^3[{+ads}]^7 tuşuna basılı tutun.", + "CLIFFHANGER_HOW_TO_CLIMB": "Buza yaklaşın ve tırmanmak için ^3[{+attack}]^7 tuşuna basılı tutun.", + "CLIFFHANGER_LINE1": "\"Uçurumun Kenarında\"", + "CLIFFHANGER_LINE2": "2. Gün - 07:35:[{FAKE_INTRO_SECONDS:32}]", + "CLIFFHANGER_LINE3": "Çavuş Gary 'Roach' Sanderson", + "CLIFFHANGER_LINE4": "Görev Gücü 141", + "CLIFFHANGER_LINE5": "Tian Shan Sıradağları, Kazakistan", + "CLIFFHANGER_E3_INTEREST_OF_TIME": "Zaman açısından..", + "CLIFFHANGER_E3_NOT_AS_PLANNED": "İşler her zaman planlandığı gibi gitmez.", + "CLIFFHANGER_HOW_TO_CLIMB_PC": "Buza yaklaşın ve tırmanmak için ^3[{+ads}]^7tuşlarını basılı tutun.", + "SPEECH_SAY_AND_ONE_OF_THE_FOLLOWING": "\"Advanced Warfare\", \"A W\" veya \"Call of Duty\" ve aşağıdakilerden birini söyleyin:", + "SPEECH_SHOW_MENU": "Menüyü Göster", + "SPEECH_PAUSE": "Duraklat", + "SPEECH_UNPAUSE": "Duraklatmayı Kaldır", + "SPEECH_NEXT": "Sonraki", + "SPEECH_PREVIOUS": "Önceki", + "SPEECH_FRAG": "Frag", + "SPEECH_CONTACT": "İletişim", + "SPEECH_SMART": "Akıllı", + "SPEECH_THREAT": "Tehdit", + "SPEECH_FLASH": "Flaş", + "SPEECH_EMP": "EMP", + "SPEECH_SURVIVAL": "Hayatta Kalma", + "CGAME_NOSPECTATORVOICECHAT": "Seyirci olarak sesli sohbet yapamazsınız.", + "CGAME_SPECTATOR": "İZLEYİCİ", + "CGAME_COMPLAINTFILED": "Şikayetiniz dosyalanmıştır", + "CGAME_COMPLAINTDISMISSED": "Şikayet reddedildi", + "CGAME_COMPLAINTSERVERHOST": "Sunucu Ana Bilgisayarı hakkında şikayette bulunulamaz", + "CGAME_SERVERHOSTTEAMKILLED": "Sunucu Sahibi tarafından takım hâlinde öldürüldünüz", + "CGAME_COMPLAINTTEAMKILLFILE": "Takım öldürme suçundan &&1 hakkında şikayette bulunun?", + "CGAME_PRESSYESNO": "EVET için '&&1' veya Hayır için '&&2' tuşuna basın", + "CGAME_VOTE": "OY VER", + "CGAME_YES": "EVET", + "CGAME_NO": "HAYIR", + "CGAME_FOLLOWING": "İZLEYİCİ", + "CGAME_YOUKILLED": "&&1'i öldürdün", + "CGAME_TEAMMATE": "TAKIM ARKADAŞI", + "CGAME_UNKNOWN": "Bilinmiyor", + "CGAME_MISSIONOBJECTIVES": "GÖREV HEDEFLERİ", + "CGAME_MISSIONOBJECTIVES_NONE": "HEDEF YOK", + "CGAME_PAUSED": "DURAKLATILDI", + "CGAME_PLAYERRENAMES": "olarak yeniden adlandırıldı", + "CGAME_CONNECTIONINTERUPTED": "Bağlantı Kesildi", + "CGAME_SB_PLAYER": "&&1", + "CGAME_SB_PLAYERS": "CGAME_SB_PLAYERS", + "CGAME_SPECTATORS": "Seyirciler", + "CGAME_SB_SCORE": "Skor", + "CGAME_SB_DEATHS": "Ölümler", + "CGAME_SB_PING": "Ping", + "CGAME_FOR": "için", + "CGAME_DIED": "Öldü", + "CGAME_MELEE": "yakın dövüş", + "CGAME_SUICIDE": "İntihar", + "CGAME_FALLING": "düşmek", + "CGAME_CRUSH": "ezmek", + "CGAME_DROWN": "boğulmak", + "CGAME_SLIME": "balçık", + "CGAME_WAITINGFORSERVERLOAD": "Sunucunun yeni haritayı yüklemesi bekleniyor", + "CGAME_HEAD_SHOT": "kafa vuruşu", + "CGAME_PRONE_BLOCKED": "Eğimli Engellenmiş", + "CGAME_PRONE_BLOCKED_WEAPON": "Bu silahla yüzüstü yatamazsınız.", + "CGAME_HEALTH": "Sağlık", + "CGAME_THIS_WEAPON_HAS_NO_ALTERNATE": "Bu silahın geçiş yapılabilecek alternatif bir modu yoktur.", + "CGAME_YOUWEREKILLED": "&&1 tarafından öldürüldü", + "CGAME_NOW_SAVING": "Kaydediliyor...", + "CGAME_CONTINUE_SAVING": "KAYDET VE ÇIK", + "CGAME_SAVE_WARNING": "Şimdi kaydederseniz, son kontrol noktanızdan bu yana kaydettiğiniz tüm ilerlemeyi kaybedersiniz. \n\nKaydetmeye devam edeyim mi?", + "CGAME_RESTART_WARNING": "Şimdi yeniden başlatırsanız, bu görevde kaydettiğiniz tüm ilerlemeyi kaybedersiniz\n\nYeniden başlatmaya devam edelim mi?", + "CGAME_SAVE_VICTORY": "Oyun ilerlemenizi kaydetmek ister misiniz?", + "CGAME_SB_KILLS": "Öldürmeler", + "CGAME_SB_ASSISTS": "Asistler", + "CGAME_SB_TAGS": "Etiketler", + "CGAME_OBJECTIVE_BELOW": "Aşağıdaki Hedef", + "CGAME_OBJECTIVE_ABOVE": "Yukarıdaki Amaç", + "CGAME_SAVINGREPLAY": "&&1 tekrar oynatmayı kaydetme\n &&2 -> &&3", + "CGAME_OBJECTIVE_FOLLOWTEXT_DEFAULT": "Takip Et", + "CGAME_LISTENSERVER": "Dinleme Sunucusu", + "PLATFORM_WARNING_AUTOSAVE": "Bu oyun belirli noktalarda verileri otomatik olarak kaydeder. 'Kaydediliyor...' mesajı göründüğünde gücü kapatmayın.", + "PLATFORM_FOLLOWPREVIOUSPLAYER": "- Önceki oyuncuyu takip etmek için^3 &&1 ^7tuşuna basın", + "PLATFORM_FOLLOWSTOP": "- İzlemeyi durdurmak için^3 &&1 ^7tuşuna basın", + "PLATFORM_LOWER_RAISE_CAM": "^3&&1^7 Kamerayı İndir\\Yükselt ^3&&2^7", + "PLATFORM_LOWER_RAISE_CAM_GAMEPAD": "\u0012 Lower\\Raise Camera \u0013", + "PLATFORM_STANCEHINT_JUMP": "Atlamak için^3 &&1 ^7tuşuna basın", + "PLATFORM_STANCEHINT_STAND": "Durmak için^3 &&1 ^7tuşuna basın", + "PLATFORM_STANCEHINT_CROUCH": "Çömelmek için^3 &&1 ^7tuşuna basın", + "PLATFORM_STANCEHINT_PRONE": "Yüzüstü gitmek için^3 &&1 ^7tuşuna basın", + "PLATFORM_SWAPWEAPONSGAMEPAD": "3 &&1 ^7 için basılı tutun", + "PLATFORM_SWAPWEAPONS": "Değiştirmek için^3 &&1 ^7 tuşuna basın -", + "PLATFORM_MANTLE_IF_JUMP": "Geçmek için^3 &&1 ^7 tuşuna basılı tutun.", + "PLATFORM_MANTLE": "Geçmek için^3 &&1 ^7tuşuna basın.", + "PLATFORM_CHANGE_ZOOM": "Yakınlaştırmak için^3 &&1 ^7tuşlarına tıklayın", + "PLATFORM_HYBRID_TOGGLE": "Melezi değiştirmek için &&1 tuşuna basın", + "PLATFORM_THERMAL_TOGGLE": "Termiği değiştirmek için &&1 tuşuna basın", + "PLATFORM_HOLD_BREATH": "Sabit tutmak için ^3 &&1 ^7 tuşuna basılı tutun.", + "PLATFORM_PICKUPNEWWEAPONGAMEPAD": "Almak için ^3 &&1 ^7 tuşuna basılı tutun-", + "PLATFORM_PICKUPNEWWEAPON": "Almak için^3 &&1 ^7 tuşuna basın-", + "PLATFORM_THROWBACKGRENADE": "^3&&1 ^7ile geri at", + "PLATFORM_USEAION30CAL": "30 kalibreye el koymak için USE^3 &&1 ^7 tuşuna basın", + "PLATFORM_PRESS_TO_SKIP_CAPS": "GEÇ^3 [{+activate}] ^7", + "PLATFORM_HOLD_TO_SKIP": "Hold \u0001 to skip", + "PLATFORM_PRESS_TO_SKIP": "Geçmek için^3 [{+activate}] ^7tuşuna basın", + "PLATFORM_PRESS_TO_SPAWN": "Ortaya çıkmak için^3 [{+activate}] ^7 tuşuna basın", + "PLATFORM_PRESS_TO_RESPAWN_CAPS": "YENİDEN DOĞMA\n^3 [{+activate}] ^7", + "PLATFORM_HINT_HOLD_CROUCH_COVER": "Siperin arkasına çömelmek için ^3[{+movedown}]^7 tuşunu basılı tutun.", + "PLATFORM_HINT_CROUCH_TOGGLE_COVER_PC": "Siperin arkasına çömelmek için ^3[{+togglecrouch}]^7 tuşuna basın.", + "PLATFORM_HINT_CROUCH_TOGGLE_PC": "Çömelmek için ^3[{+togglecrouch}]^7tuşuna basın.", + "PLATFORM_HINT_HOLD_CROUCH": "Çömelmek için ^3[{+movedown}]^7tuşunu basılı tutun.", + "PLATFORM_PRESS_TO_RESPAWN": "^3 tuşuna basın: [{+activate}] ^7yeniden doğmak için", + "PLATFORM_HOLD_TO_USE_GAMEPAD": "^3[{+activate}]^7kullanmak için tutun", + "PLATFORM_HOLD_TO_USE_MINIGUN": "^3[{+activate}]^7M134 Minigun kullanmak için basılı tutun", + "PLATFORM_HOLD_TO_USE_M249SAW": "^3[{+activate}]^7M249 SAW kullanmak için basılı tutun", + "PLATFORM_HOLD_TO_USE_M2BROWNING": "^3[{+activate}]^7M2 Browning kullanmak için basılı tutun", + "PLATFORM_HOLD_TO_DROP": "Bırakmak için ^3[{+activate}]^7tuşuna basın", + "PLATFORM_HOLD_TO_PLANT_EXPLOSIVES": "Hold^3 &&1 ^7patlayıcı yerleştirmek için", + "PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES": "Hold^3 &&1 ^7patlayıcıları etkisiz hâle getirmek için", + "PLATFORM_EOG_PRESS_ESC": "3 ESC ^7to^2 Sınıf Oluştur ^7ve daha fazlası için basın", + "PLATFORM_SAVE_AND_QUIT": "KAYDET VE ÇIK", + "PLATFORM_QUIT": "ÇIKIŞ", + "PLATFORM_BACK": "Geri", + "PLATFORM_YES": "Evet", + "PLATFORM_NO": "Hayır", + "PLATFORM_RELOAD": "ŞARJÖR DEĞİŞTİR", + "PLATFORM_LOW_AMMO_NO_RELOAD": "DÜŞÜK CEPHÂNE", + "PLATFORM_PICK_UP_STOPPING_POWER": "Durdurma Gücünü almak için^3 &&1 ^7tuşuna basın", + "PLATFORM_PICK_UP_JUGGERNAUT": "Juggernaut'u almak için^3 &&1 ^7tuşuna basın", + "PLATFORM_PICK_UP_DOUBLE_TAP": "Çift Dokunuşu almak için^3 &&1 ^7tuşuna basın", + "PLATFORM_PICK_UP_LAST_STAND": "Last Stand'i almak için^3 &&1 ^7tuşuna basın", + "PLATFORM_PICK_UP_MARTYRDOM": "Şehitliği almak için^3 &&1 ^7tuşuna basın", + "PLATFORM_PICK_UP_SLEIGHT_OF_HAND": "Sleight of Hand'i almak için^3 &&1 ^7tuşuna basın", + "PLATFORM_PLAY_ONLINE": "Çevrimiçi Oyna", + "PLATFORM_ONLINE_PLAY_DOWNLOAD": "Tam oyun indirme işlemi tamamlanana kadar Çevrimiçi Oyun kullanılamaz.\n", + "PLATFORM_PLAY_ONLINE_DESC": "Call of Duty®'de çevrimiçi oynayın: Modern Warfare® 2 Campaign Remastered çok oyunculu modunda çevrimiçi oynayın.", + "PLATFORM_NOMOTD": "Call of Duty® almak için çevrimiçi olun: Modern Warfare® 2 Campaign Remastered haberleri ve güncellemeleri için çevrimiçi olun", + "PLATFORM_NOMOTD_MP": "Call of Duty®'ye hoş geldiniz: Modern Warfare® 2 Campaign Remastered Multiplayer'a hoş geldiniz.", + "PLATFORM_FOLLOWNEXTPLAYER": "- Sonraki oyuncuyu takip etmek için^3 &&1 ^7tuşuna basın", + "PLATFORM_LOCSEL_DIR_CONTROLS": "Yönü ayarlamak için [Sağ Fare] tuşunu basılı tutun", + "PLATFORM_LOCSEL_POSITION_CONTROLS": "Bir hedef seçmek için fareyi kullanın", + "PLATFORM_PRESS_TO_SET_AIRSTRIKE": "Hava Saldırısı konumunu ayarlamak için Ateş'e basın", + "PLATFORM_COWARDS_WAY_OUT": "Hold^3 [{+activate}] ^7Korkağın çıkış yolu", + "PLATFORM_DISCONNECTED_FROM_SERVER": "Sunucu bağlantısı kesildi", + "PLATFORM_STATSREADERROR": "İstatistik verileri okunurken bir hata oluştu. İstatistikleriniz sıfırlandı.", + "PLATFORM_NOTSIGNEDINTOPROFILE": "Henüz bir profil seçmediniz.", + "PLATFORM_UNEXPECTEDDOWNLOADMESSAGE": "Beklenmeyen www indirme mesajı.", + "PLATFORM_DOWNLOADDISCONNECTED": "İstemci dosyaları indirmek için düştü.", + "PLATFORM_PRESS_TO_SAFESPAWN": "[{+frag}] Güvenli Doğuş", + "PLATFORM_RESUPPLY": "[{+activate}] İkmal", + "PLATFORM_GET_SENTRY": "[{+activate}]Nöbetçi", + "PLATFORM_GET_AUTO_SHOT": "[{+activate}]Auto_Shot", + "PLATFORM_GET_THUMPER": "[{+activate}]Thumper", + "PLATFORM_GET_RANDOM": "[{+aktifleştir}] Rastgele Öğe", + "PLATFORM_VEH_BOOST": "[Uzay] Güçlendirme", + "PLATFORM_VEH_BRAKE": "[S] Ters", + "PLATFORM_VEH_FIRE": "[Sol Fare] Ateş", + "PLATFORM_VEH_THROTTLE": "[W] Gaz Kelebeği", + "PLATFORM_GET_KIT": "[{+activate}] Yeni kit", + "PLATFORM_REVIVE": "[{+activate}] Oyuncuyu canlandır", + "PLATFORM_USEONLINESTATS_TRUE": "IwNet Kilit Açar: Açık", + "PLATFORM_USEONLINESTATS_FALSE": "IwNet Kilit Açar: Kapalı", + "PLATFORM_FIND_GAME": "Oyun Bul", + "PLATFORM_DESC_FIND_GAME": "Bir oyun modu seçin ve hızlıca çevrimiçi bir oyuna katılın.", + "PLATFORM_DESC_FIND_GAME_LOCKED": "Sadece parti sahibi oyun bulabilir.", + "PLATFORM_BACK_CAPS": "Geri ^2ESC^7", + "PLATFORM_DETONATE": "Patlatmak için [{+activate}] tuşuna basın", + "PLATFORM_GET_KILLSTREAK": "[{+activate}] Killstreak", + "PLATFORM_USE_BUTTONMOVE_TO_POSITION": "Konumlandırmak için fareyi kullanın", + "PLATFORM_USE_BUTTONLOOK_TO_AIM": "Nişan almak için ^3[Sağ Fare]^7tuşlarını basılı tutun", + "PLATFORM_PRESS_BUTTON_TO_CONFIRM_TARGET": "Hedefi onaylamak için ^3[Sol Fare]^7tuşuna basın", + "PLATFORM_PLAY_ONLINE_CAPS": "OYUN", + "PLATFORM_SYSTEM_LINK": "LAN PARTİSİ", + "PLATFORM_SYSTEM_LINK_CAPS": "PLATFORM_SYSTEM_LINK_CAPS", + "PLATFORM_SYSTEM_LINK_DESC": "Yerel bir ağ üzerinden özel maçlar.", + "PLATFORM_FIND_GAME_CAPS": "OYUN BUL", + "PLATFORM_SYSTEM_LINK_TITLE": "PLATFORM_SYSTEM_LINK_TITLE", + "PLATFORM_GAME_SUMMARY_CAPS": "OYUN ÖZETİ ^0- ^3F1^7", + "PLATFORM_PREDATOR_MISSILE_AIM": "Yönlendirme", + "PLATFORM_PREDATOR_MISSILE_AIM_GPAD": "Dümen", + "PLATFORM_PREDATOR_MISSILE_BOOST": "[{+attack}] Güçlendirme", + "PLATFORM_CONTINUE_CAPS": "DEVAM", + "PLATFORM_CLOSE_CAPS": "KAPAT", + "PLATFORM_PRESS_TO_COPYCAT": "Basın^3 [^7 Sınıflarını çal!", + "PLATFORM_ACCEPT_INVITE": "Daveti Kabul Et", + "PLATFORM_OFFENSIVE_NO_PENALTY": "(Oyunu tamamlama açısından cezalandırılmayacaksınız.)", + "PLATFORM_DYK_IW5_MSG1": "Yükseltilmiş Avantajların kilidini açmak için Avantaj mücadelelerini tamamlayın.", + "PLATFORM_DYK_IW5_MSG2": "Ölmeden art arda öldürmeler yaparak Saldırı ve Uzman Killstreak Ödülleri kazanın.", + "PLATFORM_DYK_IW5_MSG3": "Silahınızı oyuncuları öldürmek, ekipmanları yok etmek ve öldürme noktalarını havaya uçurmak için kullanarak silah XP'si kazanın.", + "PLATFORM_DYK_IW5_MSG4": "Bazı killstreak ödülleri kontrol edilebilir ancak sizi yerde savunmasız bırakır.", + "PLATFORM_DYK_IW5_MSG5": "Kışladaki tüm Ödüllerinize göz atın.", + "PLATFORM_DYK_IW5_MSG6": "Düşman teçhizatını ve bakım paketi tuzaklarını tespit etmek için Sitrep Avantajını kullanın.", + "PLATFORM_DYK_IW5_MSG7": "Parça tesirli el bombalarını Zıplayan Betty, Fırlatma Bıçağı ve diğer Ölümcül ekipmanlarla değiştirin.", + "PLATFORM_DYK_IW5_MSG8": "Deathstreak'ler işler yolunda gitmediğinde size destek verir.", + "PLATFORM_DYK_IW5_MSG9": "Mermiler İsyan Kalkanlarından sekebilir ve öldürebilir!", + "PLATFORM_DYK_IW5_MSG10": "Kazandığınız Unvanları ve Amblemleri göstermek için Çağrı İşaretinizi düzenleyin.", + "PLATFORM_DYK_IW5_MSG11": "Daha ayrıntılı bilgi için Oyun Özetinde sola ve sağa kaydırın.", + "PLATFORM_DYK_IW5_MSG12": "Kazandığınız Unvanlar ve Amblemler Prestij Moduna girdikten sonra sıfırlanmaz.", + "PLATFORM_DYK_IW5_MSG13": "Oyunun ortasında kapatmanız Maç Bonusunuzu kaybetmenize neden olur.", + "PLATFORM_DYK_IW5_MSG14": "Bakım Paketi, rastgele bir killstreak ödülü veren bir airdrop'tur.", + "PLATFORM_DYK_IW5_MSG15": "Taktiksel Ekleme, bir sonraki yeniden doğuşunuzun nerede olacağını gösteren bir işaret fişeğidir.", + "PLATFORM_DYK_IW5_MSG16": "Düşmanın Taktiksel Yerleştirmesini önlemek için kırmızı işaret fişeklerini yok edin.", + "PLATFORM_DYK_IW5_MSG17": "Semtex düşmanınıza yapışacaktır.", + "PLATFORM_DYK_IW5_MSG18": "Patlama Kalkanı Avantajı patlamalara karşı direncinizi artırır.", + "PLATFORM_DYK_IW5_MSG19": "Ağır Kalkanınız sırtınızdayken bile mermileri engeller.", + "PLATFORM_DYK_IW5_MSG20": "Kalp Atışı Sensörü eklentisi yakınlardaki düşmanları tespit eder.", + "PLATFORM_DYK_IW5_MSG21": "Suikastçı Avantajı sizi termal görüş, İHA, Taşınabilir Radar ve Kalp Atışı Sensörlerine karşı görünmez yapar.", + "PLATFORM_DYK_IW5_MSG22": "Hardline, killstreak ödüllerinin 1 daha az öldürme gerektirmesini sağlar.", + "PLATFORM_DYK_IW5_MSG23": "Son Duruş'tayken sürünebilirsiniz.", + "PLATFORM_DYK_IW5_MSG24": "Keşif, tüm patlayıcı hasarlarınızın düşmanlarınızı mini haritaya boyamasını sağlayarak onları bulmayı kolaylaştırır.", + "PLATFORM_DYK_IW5_MSG25": "Juiced Deathstreak, yeniden doğduğunuzda size sınırlı bir hız artışı sağlar.", + "PLATFORM_DYK_IW5_MSG26": "Maksimum etki için İsyan Kalkanınızı doğrudan size ateş eden kişiye doğrultun.", + "PLATFORM_DYK_IW5_MSG27": "Taretler, üzerlerinde Flaş Bombaları veya Sersemletici Bombalar kullanılarak geçici olarak devre dışı bırakılabilir.", + "PLATFORM_DYK_IW5_MSG28": "Avcı Füzesi, yukarıdan ateşlenen bir füzeyi kontrol etmenizi sağlar.", + "PLATFORM_DYK_IW5_MSG29": "Ayaklarınızı korumak ve maksimum koruma elde etmek için İsyan Kalkanı ile çömelin.", + "PLATFORM_DYK_IW5_MSG30": "Killstreak Ödüllerinin kilidi seçtiğiniz sırayla açılır.", + "PLATFORM_DYK_IW5_MSG31": "Rakibinize üstünlük sağlamak için silahınızın seviyesini yükselterek silah Yeterliliklerinin kilidini açın.", + "PLATFORM_DYK_IW5_MSG32": "Varsayılan Sınıflar, daha sonraki seviyelerde açılacak öğeleri içerir ve size gelecek şeylerin bir önizlemesini sunar.", + "PLATFORM_DYK_IW5_MSG33": "Çöpçü Avantajı, cephânenizi düşen düşmanlardan alarak yeniden doldurmanızı sağlar.", + "PLATFORM_DYK_IW5_MSG34": "Revenge Deathstreak ile sizi öldüren son düşmanı görün.", + "PLATFORM_DYK_IW5_MSG35": "Tabancalar için Taktik Bıçak eklentisi yakın dövüşünüzü hızlandırır.", + "PLATFORM_DYK_IW5_MSG36": "Eklentiler silah Yeterliliği, birincil silahınızda 2 eklentiye sahip olmanızı sağlar.", + "PLATFORM_DYK_IW5_MSG37": "Bir Son Durak kan kaybından kurtulursanız tekrar ayağa kalkarsınız.", + "PLATFORM_DYK_IW5_MSG38": "Airdrop sandıklarından elde edilen Öldürme Sayısı Ödülleri, Öldürme Sayısı sayınıza dahil edilmez.", + "PLATFORM_DYK_IW5_MSG39": "Akimbo silahlar size daha fazla ateş gücü verir ancak nişan alma yeteneğinizi kısıtlar.", + "PLATFORM_DYK_IW5_MSG40": "Ölü Adamın Eli ile rakibinize bir C4 sürprizi yapın.", + "PLATFORM_DYK_IW5_MSG41": "Karşınıza çıkabilecek her türlü duruma hazır olmak için her sınıfı kendi Saldırı Paketi ile özelleştirin.", + "PLATFORM_DYK_IW5_MSG42": "Saldırı Saldırı Paketi öğeleri, bir sonrakini kazanmak için öldürmeleri zincirleyecek.", + "PLATFORM_DYK_IW5_MSG43": "Bir takım oyuncusu olun, mürettebatınız için birkaç Balistik Yelek atın.", + "PLATFORM_DYK_IW5_MSG44": "Boşluk Noktaları, geri dönüş öldürmesi için gereken ekstra hasarı verir.", + "PLATFORM_DYK_IW5_MSG45": "Tüm Juggernaut'lar birbirine benzemez.", + "PLATFORM_DYK_IW5_MSG46": "I.M.S.'in çaldığını duyduğunuzda artık çok geçtir.", + "PLATFORM_DYK_IW5_MSG47": "Savaş sırasında daha fazla Avantaja ihtiyacınız olduğunu düşünüyorsanız, Uzman Saldırı Paketini kullanmalısınız.", + "PLATFORM_DYK_IW5_MSG48": "Takımınızı desteklemeyi, saldırıda olmayı veya yalnız bir silah olmayı seviyor musunuz? Saldırı Paketleri size seçim şansı verir.", + "PLATFORM_DYK_IW5_MSG49": "Kör Göz Avantajı sizi hava desteği ve nöbetçilere karşı güvende tutar.", + "PLATFORM_DYK_IW5_MSG50": "Boğazlarına bir füze tıktığınızda Juggernaut'lar o kadar da sert değildir.", + "PLATFORM_DYK_IW5_MSG51": "Düşmana saldırırken hızlanmak için Takipçi Avantajını kullanın.", + "PLATFORM_DYK_IW5_MSG52": "Destek Saldırısı Paketi, öldüğünüzde öldürme hızınızı sıfırlamaz.", + "PLATFORM_DYK_IW5_MSG53": "Üç killstreak yuvanız ve başka yollarla elde ettiğiniz diğer killstreak'leri saklamak için fazladan bir yuvanız vardır.", + "PLATFORM_DYK_IW5_MSG54": "Ekstra killstreak yuvanız birikir, bu yüzden onları kaybetme konusunda endişelenmenize gerek yoktur.", + "PLATFORM_DYK_IW5_MSG55": "Killstreak'leriniz arasında yukarı ve aşağı kaydırın ve şu anda istediğinizi kullanın.", + "PLATFORM_CALL_NUKE": "Nükleer Saldırı için ^3&&1^7tuşlarını basılı tutun.", + "PLATFORM_CHANGE_PROFILE_CAPS": "PROFİL DEĞİŞTİR", + "PLATFORM_UNLOCK_KILLSTREAK": "Killstreak kilidini açmak için tıklayın.", + "PLATFORM_VIEW_CHALLENGES": "^3F2^0-^7 Zorlukları Görüntüle", + "PLATFORM_STEAM_AUTH_DENIED": "Steam yetkilendirmesi başarısız oldu.", + "PLATFORM_STEAM_KICK_CHEAT": "Hile tespit edildi.", + "PLATFORM_STEAM_CONNECT_FAIL": "Steam bağlantısı başarısız oldu.", + "PLATFORM_VIEW_CHALLENGE_DETAILS": "^3F2^0-^7 Mücadele Detayları", + "PLATFORM_STEAM_JOIN_FAIL": "Steam lobisine katılamadı.", + "PLATFORM_JOIN_FRIEND_FAILED": "Arkadaşının oyununa katılamadı.", + "PLATFORM_NO_FRIENDS": "Steam arkadaşınız yok", + "PLATFORM_POPUP_CONNECTION": "Çevrimiçi Hizmetlere Bağlanma", + "PLATFORM_STEAM_OFFLINE": "Oynamak için Çevrimiçi modda Steam'de oturum açmış olmalısınız.", + "PLATFORM_STEAM_DISCONNECTED": "Steam bağlantısı kesildi.", + "PLATFORM_HINT_MOVEONTRUCK": "Kamyon üzerinde hareket etmek için hareket tuşuna basın.", + "PLATFORM_INVITE": "Davetiye Gönder", + "PLATFORM_INVITE_NOT_CONNECTED": "Eşleştirme Sunucusuna bağlı değil.", + "PLATFORM_INVITE_SYSTEM_ERROR": "Oyun daveti gönderilemedi. Lütfen daha sonra tekrar deneyin.", + "PLATFORM_JOIN_SESSION_LOST": "Davet edildiğiniz oyun oturumu artık geçerli değil.", + "PLATFORM_JOIN": "Oyuncuya Katıl", + "PLATFORM_INVITE_TO_PARTY": "Partiye davet et", + "PLATFORM_INVITE_TO_GAME": "Oyuna davet et", + "PLATFORM_FRIENDS_ONLINE_VAULT_BROWSE": "Arkadaşınızın Çevrimiçi Kasasını Görüntüleyin", + "PLATFORM_SYSTEM_ERROR": "Sistem Hatası", + "PLATFORM_CHALLENGE_BLADE_BUTTON": "^3F1^7", + "PLATFORM_NAVBAR_BUTTON_FOCUSED_SELECTBUTTON": "", + "PLATFORM_BACK_BUTTON": "^2ESC^7", + "PLATFORM_SHOW_GROUPS": "Grupları Göster", + "PLATFORM_DEMO_DVR_TOGGLE_CONTROLS_HUD": "^3F1^7 Kontrolleri Değiştir", + "PLATFORM_DEMO_DVR_CHANGE_CAMERA": "^3F2^7", + "PLATFORM_DEMO_DVR_JUMP_BACK": "^3LA^7", + "PLATFORM_DEMO_DVR_JUMP_FORWARD": "^3RA^7", + "PLATFORM_DEMO_DVR_SLOW_MOTION": "^3DN^7", + "PLATFORM_DEMO_DVR_FAST_MOTION": "^3UP^7", + "PLATFORM_DEMO_DVR_PLAY": "^3SPACE^7", + "PLATFORM_DEMO_DVR_RECORD": "^3R^7", + "PLATFORM_DEMO_DVR_TAKE_SCREENSHOT": "^3F3^7", + "PLATFORM_DEMO_DVR_SWITCH_PLAYERS": "&&1 \\ &&2 Oyuncu Değiştir", + "PLATFORM_DEMO_DVR_SWITCH_PLAYER_PREV": "^3L-Click^7", + "PLATFORM_DEMO_DVR_SWITCH_PLAYER_NEXT": "^3R-Click^7", + "PLATFORM_CHANGE_FILTER_CAPS": "FİLTRE DEĞİŞTİR", + "PLATFORM_TOP_OF_LIST_CAPS": "LİSTENİN BAŞI", + "PLATFORM_DEMO_PREVIEW_CLIP": "ÖN İZLEME KLİPSİ", + "PLATFORM_DEMO_CLEAR_ALL_SEGMENTS": "TÜM SEGMENTLERI TEMIZLE", + "PLATFORM_DEMO_MOVE_SEGMENT_LEFT": "SEGMENTI SOLA TAŞI", + "PLATFORM_DEMO_MOVE_SEGMENT_RIGHT": "SEGMENTI SAĞA TAŞI", + "PLATFORM_DEMO_PLACE_SEGMENT": "YER SEGMENTİ", + "PLATFORM_DEMO_PREVIEW_SEGMENT": "ÖNIZLEME BÖLÜMÜ", + "PLATFORM_DEMO_DELETE_SEGMENT": "SEGMENTİ SİL", + "PLATFORM_MW3_BACK": "Geri ^0- ^3ESC^7", + "PLATFORM_FILTER": "Filtre", + "PLATFORM_TOP": "Üst", + "PLATFORM_PAGE_UP": "Sayfa Yukarı", + "PLATFORM_PAGE_DOWN": "Sayfa Aşağı", + "PLATFORM_DLCSEARCH_TOGGLE_OFF": "DLC ^2F1^7'yi etkinleştirin:", + "PLATFORM_DLCSEARCH_TOGGLE_ON": "DLC ^2F1^7'yi devre dışı bırakın:", + "PLATFORM_DEMO_DVR_FREECAMERA_CHANGE_HEIGHT": "&&1 \\ &&2 Yüksekliği Değiştir", + "PLATFORM_OPTIONS_COLOR_BLIND_ASSIST_DESC": "Oyuncu adları için Renk Körü Yardımını etkinleştirin veya devre dışı bırakın.", + "PLATFORM_READING_SAVE_DEVICE": "HDD OKUMA", + "PLATFORM_FACEBOOK_LEGAL2": "Facebook hesabınıza giriş yaparak, Activision'ın Call of Duty®: Modern Warfare® 2 Campaign Remastered bilgilerinizi, Steam kullanıcı adınız da dahil olmak üzere, adınız da dahil olmak üzere Facebook hesap bilgilerinizle ilişkilendirmesini ve görüntülemesini kabul etmiş olursunuz.", + "PLATFORM_FB_NEXT_PAGE": "Sonraki Sayfa", + "PLATFORM_FB_PREV_PAGE": "Önceki Sayfa", + "PLATFORM_DEMO_CONTROLS_JUMP_BACK": "Geri Zıpla", + "PLATFORM_DEMO_CONTROLS_JUMP_BACK_KEY": "^3Left Arrow^7", + "PLATFORM_DEMO_CONTROLS_JUMP_FORWARD": "İleri Zıpla", + "PLATFORM_DEMO_CONTROLS_JUMP_FORWARD_KEY": "^3Right Arrow^7", + "PLATFORM_DEMO_CONTROLS_PREVIOUS_PLAYER": "Önceki Oyuncu", + "PLATFORM_DEMO_CONTROLS_PREVIOUS_PLAYER_KEY": "^3Sol Tıklama^7", + "PLATFORM_DEMO_CONTROLS_NEXT_PLAYER": "Sonraki Oyuncu", + "PLATFORM_DEMO_CONTROLS_NEXT_PLAYER_KEY": "^3Sağ Tıklama^7", + "PLATFORM_DEMO_CONTROLS_INCREASE_PLAYBACK_SPEED": "Hız + 0.1x", + "PLATFORM_DEMO_CONTROLS_INCREASE_PLAYBACK_SPEED_KEY": "^3Yukarı Ok^7", + "PLATFORM_DEMO_CONTROLS_DECREASE_PLAYBACK_SPEED": "Hız - 0.1x", + "PLATFORM_DEMO_CONTROLS_DECREASE_PLAYBACK_SPEED_KEY": "^3Down Arrow^7", + "PLATFORM_DEMO_CONTROLS_SWITCH_CAMERA": "Kamera Değiştir", + "PLATFORM_DEMO_CONTROLS_SWITCH_CAMERA_KEY": "PLATFORM_DEMO_CONTROLS_SWITCH_CAMERA_KEY", + "PLATFORM_DEMO_CONTROLS_SCREENSHOT": "Ekran Görüntüsü Alın", + "PLATFORM_DEMO_CONTROLS_SCREENSHOT_KEY": "PLATFORM_DEMO_CONTROLS_SCREENSHOT_KEY", + "PLATFORM_DEMO_CONTROLS_RECORD": "Başlat/Durdur Kaydı", + "PLATFORM_DEMO_CONTROLS_RECORD_KEY": "PLATFORM_DEMO_CONTROLS_RECORD_KEY", + "PLATFORM_DEMO_CONTROLS_PLAY": "Oynat / Duraklat", + "PLATFORM_DEMO_CONTROLS_PLAY_KEY": "^3Space^7", + "PLATFORM_DEMO_CONTROLS_SPEED_1X": "Hız + 1.0x", + "PLATFORM_DEMO_CONTROLS_SPEED_1X_KEY": "^3F5^7", + "PLATFORM_DEMO_CONTROLS_SPEED_NEG1X": "Hız - 1.0x", + "PLATFORM_DEMO_CONTROLS_SPEED_NEG1X_KEY": "^3F4^7", + "PLATFORM_DEMO_CONTROL_OPTIONS": "Tiyatro Kontrolleri", + "PLATFORM_KICKEDFROMPARTY": "Partiden atıldınız.", + "PLATFORM_BACK_SHORTCUT": "PLATFORM_BACK_SHORTCUT", + "PLATFORM_FRIENDS_SHORTCUT": "Arkadaşlar ^2F^7", + "PLATFORM_GAMESUMMARY_SHORTCUT": "Oyun Özeti ^2G^7", + "PLATFORM_LEADERBOARDS_SHORTCUT": "Lider Tabloları ^2Sağ Fare^7/^2F1^7", + "PLATFORM_REFRESH_SHORTCUT": "Yenile ^2F1^7", + "PLATFORM_SAVETOVAULT_SHORTCUT": "Kasaya Kaydet ^2Sağ Fare^7/^2F1^7", + "PLATFORM_REMOVELASTGUN_SHORTCUT": "Son Silahı Kaldır ^2F1^7", + "PLATFORM_SAVESETTINGS_SHORTCUT": "Ayarları Kaydet ^2F1^7", + "PLATFORM_RESTRICT_SHORTCUT": "Kısıtla ^2Sağ Fare^7/^2F1^7", + "PLATFORM_RULES_TOGGLE_ROTATION_ON": "Harita Döndürmeyi Etkinleştir ^2F1^7", + "PLATFORM_RULES_TOGGLE_ROTATION_OFF": "Harita Döndürmeyi Devre Dışı Bırak ^2F1^7", + "PLATFORM_CLEAR_KILLSTREAKS": "Killstreak'leri Temizle ^2X^7", + "PLATFORM_CHALLENGES_SHORTCUT": "Mücadeleler ^2F1^7", + "PLATFORM_SSAO": "EKRAN ALANI ORTAM OKLÜZYONU", + "PLATFORM_MDAO": "ORTA MESAFE ORTAM OKLÜZYONU", + "PLATFORM_MOTIONBLUR": "HAREKET BULANIKLIĞI", + "PLATFORM_FOV": "FOV", + "PLATFORM_ONLINEVAULT_MUSTLOGIN": "Çevrimiçi Kasayı görüntülemek için internete bağlı olmanız gerekir.", + "PLATFORM_NOGUEST": "Call of Duty®'deki Lan Party oyunları için konuk hesapları desteklenmez: Modern Warfare® 2 Campaign Remastered'da Lan Party oyunları için desteklenmez.", + "PLATFORM_JOIN_WRONG_EXE_MP": "Bu arkadaş şu anda çok oyunculu oyun oynuyor. Bu oyuncuya katılmak için çok oyunculu oyun modunu başlatmalısınız.", + "PLATFORM_JOIN_WRONG_EXE_SP": "Bu arkadaş şu anda tek oyunculu oynuyor. Bu oyuncuya katılmak için ana menüye dönmelisin.", + "PLATFORM_PAGE_BUTTONS": "PLATFORM_PAGE_BUTTONS", + "PLATFORM_FILTER_SHORTCUT": "Filtre ^2F1^7", + "PLATFORM_PAGE_UP_SHORTCUT": "Sayfa Yukarı ^2PGUP^7", + "PLATFORM_PAGE_DOWN_SHORTCUT": "Aşağı Sayfa ^2PGDN^7", + "PLATFORM_TOP_SHORTCUT": "Üst ^2HOME^7", + "PLATFORM_MELEEZOOM": "Yakınlaştır/Değiştir", + "PLATFORM_MELEEZOOM_DESC": "Yakın dövüş saldırısı ve Yakınlaştırmayı Değiştir için tuş bağını ayarlayın.", + "PLATFORM_REMOTE_UAV_ASCEND": "^3[{+gostand}]^7 Yüksel", + "PLATFORM_THEATER_RECORDING": "Tiyatro Kaydı", + "PLATFORM_THEATER_RECORDING_DESC": "Tiyatro demo kaydını etkinleştirin veya devre dışı bırakın.", + "PLATFORM_REMOTE_UAV_DESCEND": "Descend ^3[{+sprint}]^7", + "PLATFORM_HIGH_QUALITY": "Yüksek Kalite", + "PLATFORM_LOW_QUALITY": "Düşük Kalite", + "PLATFORM_VOTE_YES": "Oyunuz Evet", + "PLATFORM_VOTE_NO": "Oy Hayır", + "PLATFORM_MISSINGMAP": "Bu haritaya sahip değilsiniz veya hasar görmüş. Bu haritayı Steam üzerinden harita paketlerini indirerek edinebilirsiniz.", + "PLATFORM_BOTTOM_SHORTCUT": "Alt ^2END^7", + "PLATFORM_DLCSEARCH_BUTTON": "PLATFORM_DLCSEARCH_BUTTON", + "PLATFORM_PLAYLIST_REQUIRES_DLC": "Bu oynatma listesi, sahip olmadığınız bir harita paketi gerektirir. Harita paketlerini Steam'den indirebilirsiniz.", + "PLATFORM_COOP_REQUIRES_DLC": "Bu ortak sunucu, sahip olmadığınız bir harita paketi gerektirir. Harita paketlerini Steam'den indirebilirsiniz.", + "PLATFORM_DLC_GO_TO_STORE": "Yeni oyun içeriği satın almak için Mağaza'yı başlatın?", + "PLATFORM_STORE_DESC": "İndirilebilir oyun içeriği satın alın.", + "PLATFORM_RENAME_CHARACTER": "^3 &&1 ^7 Yeniden Adlandır", + "PLATFORM_DELETE_CHARACTER": "^3 &&1 ^7 Sil", + "PLATFORM_P2PAUTH_BAD_HOST": "Kötü ana bilgisayar nedeniyle bağlantı kesildi.", + "PLATFORM_P2PAUTH_BAD_CLIENT": "Hatalı istemci nedeniyle bağlantı kesildi.", + "PLATFORM_P2PAUTH_BAD_SELF": "VAC zaman aşımı nedeniyle bağlantı kesildi.", + "PLATFORM_P2PAUTH_BAD_SELF_INVALID_TICKET": "VAC nedeniyle bağlantı kesildi.", + "PLATFORM_P2PAUTH_INVALID_PLAYER": "Hesabınız VAC tarafından yasaklandı ve çevrimiçi oynayamıyor.", + "PLATFORM_RELOAD_GAMEPAD": "\u0003 Reload", + "PLATFORM_USE_BUTTONMOVE_TO_POSITION_GAMEPAD": "Use \u0010 to position", + "PLATFORM_USE_BUTTONLOOK_TO_AIM_GAMEPAD": "Use \u0011 to aim", + "PLATFORM_PRESS_BUTTON_TO_CONFIRM_TARGET_GAMEPAD": "Press \u0001 to confirm target", + "PLATFORM_PRESS_TO_TEAMSPAWN": "[{weapnext}] Spawn on your partner!", + "PLATFORM_EMBLEM_EDIT_DONE": "(B)Done", + "PLATFORM_EMBLEM_TOGGLE_FLIP": "(<)Flip", + "PLATFORM_EMBLEM_TOGGLE_OUTLINE": "(>)Toggle Outline/Full", + "PLATFORM_HOLD_TO_HACK_DROP_POD": "Hold^3 &&1 ^7to hack drop pod", + "PLATFORM_BACK_BUTTON_GAMEPAD": "\u0002", + "PLATFORM_CHALLENGE_BLADE_BUTTON_GAMEPAD": "\u0003", + "PLATFORM_Y_BUTTON_GAMEPAD": "\u0004", + "PLATFORM_DEMO_DVR_JUMP_FORWARD_GAMEPAD": "\u0013", + "PLATFORM_DEMO_DVR_JUMP_BACK_GAMEPAD": "\u0012", + "PLATFORM_FB_NEXT_PAGE_BUTTON_GAMEPAD": "\u0006", + "PLATFORM_FB_PREV_PAGE_BUTTON_GAMEPAD": "\u0005", + "PLATFORM_PAGE_UP_BUTTON_GAMEPAD": "\u0014", + "PLATFORM_PAGE_DOWN_BUTTON_GAMEPAD": "\u0015", + "PLATFORM_RIGHT_STICK_GAMEPAD": "\u0011", + "PLATFORM_LEFT_STICK_GAMEPAD": "\u0010", + "PLATFORM_CONTROLLER_DISCONNECTED": "Lütfen kontrol cihazını tekrar bağla.", + "PLATFORM_LOW_AMMO_NO_RELOAD_CAPS": "PLATFORM_LOW_AMMO_NO_RELOAD_CAPS", + "PLATFORM_RELOAD_CAPS": "ŞARJÖR DEĞİŞTİR", + "PLATFORM_RELOAD_GAMEPAD_CAPS": "\u0003 RELOAD", + "PLATFORM_KB_PRIMARY_BUTTON": "GİRİŞ", + "PLATFORM_KB_SECONDARY_BUTTON": "ESC", + "PLATFORM_KB_ALT1_BUTTON": "F2", + "PLATFORM_KB_ALT2_BUTTON": "F1", + "PLATFORM_KB_RIGHT_TRIGGER_BUTTON": "E", + "PLATFORM_KB_LEFT_TRIGGER_BUTTON": "Q", + "PLATFORM_KB_RIGHT_SHOULDER_BUTTON": "D", + "PLATFORM_KB_LEFT_SHOULDER_BUTTON": "A", + "PLATFORM_KB_DPAD_UP_BUTTON": "UP", + "PLATFORM_KB_BACK_BUTTON": "TAB", + "PLATFORM_KB_DPAD_DOWN_BUTTON": "DOWN", + "PLATFORM_KB_INS": "INS", + "PLATFORM_KB_DEL": "DEL", + "PLATFORM_KB_START_BUTTON": "SPACE", + "PLATFORM_KB_HOME_BUTTON": "HOME", + "PLATFORM_KB_END_BUTTON": "END", + "PLATFORM_THIRDPERSON_GAMEPAD": "\u0004 Third Person", + "PLATFORM_SCOREBOARD_GAMEPAD": "&&1 Puan\n", + "PLATFORM_MP_OPEN_MENU_GAMEPAD": "&&1 Menü\n", + "PLATFORM_MP_OPEN_MENU": "^3&&1^7- Menü\n", + "PLATFORM_SCOREBOARD": "^3&&1^7- Puan\n", + "PLATFORM_THIRDPERSON": "^3&&1^7- Üçüncü Şahıs", + "PLATFORM_FOLLOW_LOADING_GAMEPAD": "Sıradaki oyuncu yükleniyor...", + "PLATFORM_FOLLOWSTOP_GAMEPAD": "\u0004 Stop following", + "PLATFORM_FOLLOWNEXTPLAYER_GAMEPAD": "\u0001 Next", + "PLATFORM_FOLLOWPREVIOUSPLAYER_GAMEPAD": "\u0002 Previous", + "PLATFORM_FOLLOW_LOADING": "PLATFORM_FOLLOW_LOADING", + "PLATFORM_FIRSTPERSON": "^3&&1^7 - Birinci Şahıs", + "PLATFORM_FIRSTPERSON_GAMEPAD": "\u0004 First Person", + "PLATFORM_NAME1": "İsim: &&1", + "PLATFORM_NAME": "İsim", + "PLATFORM_FOV_OPTION_SUB": "Oyunun görüş alanını ayarlar. \nFOV'u minimum ayarın üzerine çıkarmak daha düşük kare hızına ve bazı grafik sorunlarına neden olabilir.", + "PLATFORM_MEDIUM_QUALITY": "Orta Kalite", + "PLATFORM_HBAO": "HBAO+", + "PLATFORM_KB_MOUSE_PRIMARY_BUTTON": "GİRİŞ/TIKLA", + "PLATFORM_ASPECT_RATIO_DESCRIPTION": "Monitörün fiziksel en boy oranı. Görüntülendiği monitörden farklı olan oyun çözünürlüğünün en boy oranını telafi eder. Nadiren manuel olarak ayarlanması gerekir. Yalnızca Tam Ekran'da kullanılabilir.", + "PLATFORM_SUPERSAMPLING_DESCRIPTION": "Örtüşmeyi azaltmak için daha fazla piksel işleyin, görüntü doğruluğunu artırır.", + "PLATFORM_SCREEN_REFRESH_RATE_DESCRIPTION": "Ekran ne sıklıkta işlenirse işlensin, daha yüksek Hz daha yumuşak hareketle sonuçlanır.\nSadece Tam Ekran'da kullanılabilir.", + "PLATFORM_SYNC_EVERY_FRAME_DESCRIPTION": "Bir sonraki işlenen görüntüyü görüntülemeden önce monitör yenilenene kadar bekler.\nSadece Tam Ekran'da kullanılabilir.", + "PLATFORM_IMAGE_QUALITY_DESCRIPTION": "3B sahne oluşturma çözünürlüğü. Daha yavaş ekran kartlarında performansı artırmak için azaltın. Sürümüne izin vermek için 'Native Render Resolution' devre dışı bırakılmalıdır.\n", + "PLATFORM_ANISOTROPIC_FILTERING_DESCRIPTION": "Açılı bakıldığında yüzeylerin doku kalitesini artırır.", + "PLATFORM_DOF_DESCRIPTION": "Kamera lensini simüle eder, odak dışı bölgeler bulanık görünür.", + "PLATFORM_SSAO_DESCRIPTION": "Dolaylı aydınlatmada küçük ölçekli yumuşak gölgeleme sağlar.", + "PLATFORM_MDAO_DESCRIPTION": "Karakterler ve araçlar için dolaylı aydınlatmanın yumuşak gölgelenmesini sağlar.", + "PLATFORM_MOTIONBLUR_DESCRIPTION": "Hareketli nesnelerin bulanıklaşmasını simüle eder.", + "PLATFORM_RAGDOLL_DESC": "Karakterlerin ölümünde Ragdoll özelliğini etkinleştirin.", + "PLATFORM_BULLET_IMPACTS_DESCRIPTION": "Yüzeyler üzerindeki mermi etkilerini oluşturun.", + "PLATFORM_SHADOWS_DESCRIPTION": "Doğrudan aydınlatmanın gölgelenmesini sağlar.", + "PLATFORM_SHADOW_MAP_RESOLUTION_DESCRIPTION": "Daha yüksek çözünürlük daha keskin, daha yüksek kaliteli gölgeler sağlar.", + "PLATFORM_CACHED_SUN_SHADOWS_DESCRIPTION": "Ek video belleği gerektiren önceden hesaplanmış güneş ışığı gölgesi oluşturma.\n\nUYARI: Çok yoğun bellek kullanımı. Yalnızca en az 4 GB video belleğine sahip ekran kartları için önerilir. Bulanık dokulara neden olan doku akışı sorunları yaşıyorsanız lütfen devre dışı bırakın.", + "PLATFORM_CACHED_SPOT_SHADOWS_DESCRIPTION": "Önemli ölçüde ek video belleği gerektiren önceden hesaplanmış spot ışığı gölge oluşturma.\n\nUYARI: Çok yoğun bellek kullanımı. Yalnızca en az 4 GB video belleğine sahip ekran kartları için önerilir. Bulanık dokulara neden olan doku akışı sorunları yaşıyorsanız lütfen devre dışı bırakın.", + "PLATFORM_TEXTURE_QUALITY_DESCRIPTION": "Otomatik olarak ayarlanırsa, oyun donanımınız için uygun doku çözünürlüklerini seçecektir", + "PLATFORM_TEXTURE_RESOLUTION_DESCRIPTION": "Daha yüksek çözünürlük yüzeylerde daha fazla renk ayrıntısı sağlar.", + "PLATFORM_NORMAL_MAP_RESOLUTION_DESCRIPTION": "Daha yüksek çözünürlük, engebeli yüzeylerde daha fazla aydınlatma varyasyonuna neden olur.", + "PLATFORM_SPECULAR_MAP_RESOLUTION_DESCRIPTION": "Daha yüksek çözünürlük, engebeli yüzeylerde daha fazla parlaklık varyasyonuna neden olur.", + "PLATFORM_SUBSURFACE_SCATTERING_DESCRIPTION": "Yarı saydam malzemeler aracılığıyla ışık taşınımının simülasyonu.", + "PLATFORM_POST_AA_DESCRIPTION": "Örtüşmeyi azaltmak için işlem sonrası efekti. SMAA T2x ve Filmic SMAA T2x, performansın önemli ölçüde düşmesine neden olacağından NVIDIA SLI® veya AMD Crossfire™ sistemleri için önerilmez.", + "PLATFORM_DEPTH_PREPASS_DESCRIPTION": "Opak yüzeylerin ek işlenmesi. MDAO ve yüzey altı saçılması için gereklidir.", + "PLATFORM_FXAA": "FXAA", + "PLATFORM_SMAA_1X": "SMAA 1x", + "PLATFORM_SMAA_T2X": "SMAA T2x", + "PLATFORM_FILMIC_SMAA_1X": "Filmik SMAA 1x", + "PLATFORM_FILMIC_SMAA_T2X": "Filmik SMAA T2x", + "PLATFORM_EMBLEM_MOVE_LAYER_KBM": "Amblemi taşımak için sol tıklayın + sürükleyin", + "PLATFORM_EMBLEM_SCALE_LAYER_KBM": "Amblemin ölçeğini değiştirmek için sol tıklama + sağ tıklama + sürükleme", + "PLATFORM_EMBLEM_ROTATE_LAYER_KBM": "Amblemi döndürmek için sağ tıklayın + sürükleyin", + "PLATFORM_EMBLEM_LAYER_DOWN_KBM": "Katmanı aşağı taşı", + "PLATFORM_EMBLEM_LAYER_UP_KBM": "Katmanı yukarı taşı", + "PLATFORM_EMBLEM_UNIFORM_SCALE_LAYER_KBM": "Sabit ölçeklendirme için fare tekerleği", + "PLATFORM_EMBLEM_OPACITY_KBM": "A veya D", + "PLATFORM_MOUSE_WHEEL": "MOUSEWHEEL", + "PLATFORM_CAC_CHANGE_WEAPON": "Silah Değiştir", + "PLATFORM_DLIGHT_FORCE_LIMIT_DESCRIPTION": "Bir sahnede görülebilen maksimum dinamik ışık sayısı.", + "PLATFORM_MONITOR_ASPECT_RATIO": "MONİTÖR EN BOY ORANI", + "PLATFORM_SHADER_PRELOAD_DESCRIPTION": "Oynanıştan önce gölgelendiricileri önceden yükleyin. Oyun sırasında olası takılmaları ortadan kaldırmak için daha uzun seviye yüklemesine neden olur.", + "PLATFORM_SHADER_PRELOAD_AFTER_CINEMATIC_DESCRIPTION": "Seviye yükleme sinematiği sırasında gölgelendirici ön yüklemesi gerçekleştirin. Yükleme sürelerini azaltır ancak sinematikler sırasında takılma yaratabilir.", + "PLATFORM_FILL_MEMORY_TEXTURES_DESCRIPTION": "Kalan ekran kartı belleğini dokularla doldurun.\n\nGenel performansı artırır, ancak diğer grafik yoğun programlarla etkileşime girebilir.", + "PLATFORM_SAVE": "- Sonraki oyuncuyu takip etmek için^3 &&1 ^7 tuşuna basın", + "PLATFORM_USEFLAK88": "Flak 88 silahını kullanmak için USE^3 &&1 ^7tuşuna basın", + "PLATFORM_USEFLAKVIERLING": "Flak Vierling'i kullanmak için USE^3 &&1 ^7tuşuna basın", + "PLATFORM_USEAIONMG42": "MG42'ye el koymak için USE^3 &&1 ^7tuşuna basın", + "PLATFORM_TANK_BINOCULARS": "Uzaktaki hedefleri görmek için dürbününüzü kullanmak üzere^3 &&1 ^7tuşuna basın.", + "PLATFORM_HOLD_1_TO_TURN_THE_BASE": "Tankın tabanını taretle aynı hizaya getirmek için^3 &&1 ^7tuşlarını basılı tutun.", + "PLATFORM_PRESS_1_TO_USE_YOUR_BINOCULARS": "Dürbününüzü kullanmak için^3 &&1 ^7tuşuna basın.", + "PLATFORM_WHILE_LOOKING_THROUGH": "Dürbünden bakarken topçu çağırmak için USE^3 &&1 ^7tuşuna basın.", + "PLATFORM_DYK_MSG1": "XP kazanın! Öldürme, mücadeleleri tamamlama ve Dereceli sunuculardaki maçları tamamlama karşılığında deneyim puanı (XP) kazanırsınız.", + "PLATFORM_DYK_MSG2": "Seviye atlayın! XP kazandıkça terfiler, açılabilirler ve yeni mücadeleler kazanırsınız.", + "PLATFORM_DYK_MSG3": "Silahınızı özelleştirin! Sınıf Oluştur'da silahlarınıza bir kamuflaj deseni veya eklenti ekleyebilirsiniz.", + "PLATFORM_DYK_MSG4": "Kendi sınıfınızı tasarlayın! Bir Sınıf Oluştur, silahlarınızı ve avantajlarınızı seçmenize ve ardından sınıfı istediğiniz gibi adlandırmanıza olanak tanır.", + "PLATFORM_DYK_MSG5": "Takım çalışmasını kullanın! Bir düşmana hasar verirseniz ancak başka biri öldürürse, asist puanı kazanırsınız.", + "PLATFORM_DYK_MSG6": "Sertleşin. Hardcore modları hud'ınızı kaldırır ve silahları daha da ölümcül hâle getirir.", + "PLATFORM_DYK_MSG7": "Özel oyunlar! Sıralamasız oyunlar, özel kurallarla herhangi bir oyun modunu oynayabilir.", + "PLATFORM_DYK_MSG8": "Mücadeleler ödüllendirici. Silah mücadeleleri, Sınıf Oluştur'da kullanılmak üzere eklentilerin ve kamuflaj desenlerinin kilidini açar.", + "PLATFORM_DYK_MSG9": "Daha fazla XP kazanın! Rütbe ve Mücadeleler bölümünde bulunan Mücadeleleri tamamladığınızda ekstra XP bonusları kazanırsınız.", + "PLATFORM_DYK_MSG10": "Dinleyin... Kulak Misafiri avantajı ile düşman takımın sesli sohbetini duyabilirsiniz.", + "PLATFORM_DYK_MSG11": "Dikkatli olun... Bomba Ekibi avantajı ile mayın ve C4 gibi düşman patlayıcı cihazlarını tespit edebilirsiniz.", + "PLATFORM_DYK_MSG12": "Durun! Tabancanızı çekin ve Son Direniş avantajıyla ölmeden önce birkaç öldürme elde etmek için son bir çaba gösterin.", + "PLATFORM_DYK_MSG13": "Hava desteğinizi birleştirin! Nokta atışı isabetli bir halı bombası için hava saldırısı ile birlikte radarı alın.", + "PLATFORM_DYK_MSG14": "Helikopter düştü! Birincil silahınızla düşman helikopterlerine ateş etmekten korkmayın. Bir roketten daha az hasar verebilir ama kesinlikle can yakar.", + "PLATFORM_DYK_MSG15": "Düşmanı bulun! Radar almak düşmanları GPS'inizde kırmızı noktalar olarak gösterir. Düşmanın konumunu bilmek büyük bir avantajdır.", + "PLATFORM_DYK_MSG17": "Bayraklarınızı savunun! Domination oyun modunda, işaretli hedefleri tutmak takımınıza puan kazandırır. Ne kadar çok hedefi tutarsanız, o kadar çok puan kazanırsınız.", + "PLATFORM_DYK_MSG18": "Köşelere dikkat edin! Arama ve İmha oyununu oynarken dikkatli olun - öldüğünüzde yeniden doğmazsınız.", + "PLATFORM_DYK_MSG19": "Bombaya eşlik edin! Sabotaj'da bomba taşıyıcısını koruyun. Düşman hedefine ulaşmak için takım çalışması gerekir.", + "PLATFORM_DYK_MSG20": "Radar çağırın! Ölmeden arka arkaya 3 öldürme yaparak kendiniz ve takımınız için radar kazanabilirsiniz.", + "PLATFORM_DYK_MSG21": "Hava saldırısı çağırın! Ölmeden arka arkaya 5 öldürme yapın ve seçtiğiniz pozisyona bir hava saldırısı çağırabilirsiniz.", + "PLATFORM_DYK_MSG22": "Helikopter çağırın! Ölmeden arka arkaya 7 öldürme yaparak helikopter hava desteği kazanabilirsiniz.", + "PLATFORM_DYK_MSG23": "Temellere dönüş... Old School oyun modlarında sınıf yoktur. Herkes aynı silahlarla başlar ve seviye içinde yeni silahlar ve avantajlar edinmek zorundadır.", + "PLATFORM_DYK_MSG24": "Atışlarınızı seçin! Susturucu olmadan bir silahı ateşlediğinizde, düşmanlarınızın pusulasında kırmızı bir nokta olarak görünürsünüz.", + "PLATFORM_DYK_MSG25": "Sessiz olun... Susturucu kullanmak atışlarınızı düşman pusulasında kırmızı bir nokta olarak göstermez, ancak silahınızın menzili azalır.", + "PLATFORM_DYK_MSG26": "Gizlilik teknolojisi. İHA Karıştırıcı avantajını kullanmak, düşman pusulasında kırmızı bir nokta olarak görünmenizi engeller.", + "PLATFORM_DYK_MSG27": "Tüfeğe monte edilmiş bir bomba atardan çıkan el bombalarının ateşlenmeden önce hareket etmesi gerekir. Düşmanınıza isabet ederlerse hasar verirler, ancak yalnızca belli bir mesafede patlarlar.", + "PLATFORM_DYK_MSG28": "Kendi oyun modunuzu oluşturun! Kendi sunucunuzu başlatın ve oyun modu ayarlarını istediğiniz gibi değiştirin.", + "PLATFORM_DYK_MSG29": "Takım çalışmasıyla hükmet! Hakimiyet bayrakları, birden fazla takım arkadaşının birlikte ele geçirmesiyle daha hızlı ele geçirilir.", + "PLATFORM_DYK_MSG30": "Bıçağını kullan! Hızlı ve aşağılayıcı bir öldürme için bıçağınızla düşmana yakınlaşın.", + "PLATFORM_DYK_MSG31": "Daha hızlı koş! Sprint tuşuna basmak kısa bir süreliğine daha hızlı koşmanızı sağlar, ancak silahınızı kullanamazsınız.", + "PLATFORM_DYK_MSG32": "Nefesinizi tutun! Daha fazla isabet için dürbünlü silahlarla nefesinizi tutun.", + "PLATFORM_DYK_MSG33": "El bombalarını geri at! Yakınınızda bir el bombası olduğunda el bombasını geri atma simgesini arayın. Düşmanın el bombalarını geri atabilirsiniz.", + "PLATFORM_DYK_MSG34": "Duvarların içinden ateş edin! Farklı silahlar, daha az hasarla birçok farklı yüzeyden ateş edebilir.", + "PLATFORM_DYK_MSG35": "Envanterinizi kullanın! El bombası fırlatıcıları, RPG'ler, kil mayınları ve C4 gibi öğeler envanterinizde saklanır.", + "PLATFORM_DYK_MSG36": "Patlayıcı kısayolu! Başka bir silah kullanırken atılan C4'ü patlatmak için kullanım tuşuna iki kez dokunun.", + "PLATFORM_PRESS_START_BUTTON": "Press \u0001", + "PLATFORM_PRESS_START_PC": "SİNNERCLOWN ÇEVİRİ sunar\n\nTürkçe Çeviri\nNarayanna", + "PLATFORM_OPTIONS_HORIZONTAL_SENSITIVITY_DESC": "Kumandanızın çubuklarının yatay hassasiyetini ayarlayın.", + "PLATFORM_OPTIONS_VIBRATION_DESC": "Titreşim işlevini etkinleştirin veya devre dışı bırakın.", + "PLATFORM_HOLD_TO_SKIP_KEYBOARD": "Geçmek için ^3ENTER^7 tuşunu basılı tutun\n", + "PLATFORM_OPTIONS_VERTICAL_SENSITIVITY_DESC": "Kumandanızın çubuklarının dikey hassasiyetini ayarlayın.", + "PLATFORM_NO_FRIENDS_XBOXLIVE": "Xbox Live arkadaşınız yok", + "PLATFORM_MISSINGMAP_XBOXLIVE": "Bu haritaya sahip değilsiniz, hasar görmüş veya oyun tam olarak yüklenmemiş. Harita paketlerini Xbox Store'dan indirerek bu haritayı alabilirsiniz.", + "PLATFORM_PLAYLIST_REQUIRES_DLC_XBOXLIVE": "Bu çalma listesi, sahip olmadığınız bir harita paketi gerektirir. Harita paketlerini Xbox Store'dan indirebilirsiniz.", + "PLATFORM_COOP_REQUIRES_DLC_XBOXLIVE": "Bu kümes sahibi, sahip olmadığınız bir harita paketi gerektirir. Harita paketlerini Xbox Store'dan indirebilirsiniz.", + "PLATFORM_EULA_1": "YALNIZCA KUZEY AMERİKA'DA İKAMET EDENLER İÇİN ÖNEMLİ uyarı: BU anlaşma, aşağıdaki BÖLÜM 16'DA ayrıntılı OLARAK açıklandığı ÜZERE BAĞLAYICI TAHKİME VE TOPLU dava HAKLARINDAN FERAGATE TABİDİR. \n\nSYAZILIM LİSANSI VE HİZMET SÖZLEŞMESİ\n\nBu yazılım PROGRAMININ (ve tüm GÜNCELLEMELERİN), bununla ilişkili tüm ÇEVRİMİÇİ HİZMETLERİN veya indirmelerin, ilgili çevre birimleri (topluca ”Çevre Birimi” olarak anılacaktır) için yazılımın (ürün yazılımı dahil), ilgili MEDYANIN, basılı materyallerin ve belgelerin (topluca \"Çevre Birimi\" olarak anılacaktır) kullanılması, \"Program“) BU YAZILIM LİSANSI VE HİZMET SÖZLEŞMESİNE (”Sözleşme\") TABİDİR. YETKİ ALANINIZDA REŞİT DEĞİLSENİZ VEYA HANGİSİ DAHA BÜYÜKSE on SEKİZ (18) YAŞINDAYSANIZ, LÜTFEN programı kullanmadan ÖNCE EBEVEYNİNİZDEN VEYA vasinizden bu sözleşmeyi sizin adınıza OKUMASINI VE kabul etmesini İSTEYİN. BU PAKETİ AÇARAK, PROGRAMI İNDİREREK, YÜKLEYEREK VEYA KULLANARAK VEYA \"KABUL ETMEK İÇİN TIKLAYARAK\", PROGRAMI NEREDEN EDİNİP KULLANDIĞINIZA bağlı OLARAK BÖLÜM 17'DE (\"Activision\") BELİRTİLEN ACTİVİSİON TÜZEL KİŞİLİĞİ İLE BU SÖZLEŞMENİN şartlarını kabul ETMİŞ OLURSUNUZ. BU şartları kabul etmiyorsanız, programı kurmanıza, kopyalamanıza veya kullanmanıza izin verilmez. BU şartları reddetmek İÇİN, BU şartları ”KABUL etmek için tıklamamalı\" VEYA programı YÜKLEMEMELİ, kopyalamamalı veya kullanmamalısınız. \n\nSADECE KUZEY AMERİKA'DA İKAMET EDENLER İÇİN: BU SÖZLEŞMEYİ REDDEDERSENİZ, ÇEVRE BİRİMİNİZİ VE PROGRAMINIZI İADE EDEBİLİR VE satın aldığınız tarihten SONRAKİ OTUZ (30) GÜN İÇİNDE ÇEVRE BİRİMİNİZ VE PROGRAMINIZ İÇİN GERİ ÖDEME TALEBİNDE BULUNABİLİRSİNİZ. . ACTİVİSİON'IN GİZLİLİK POLİTİKASI ŞU ADRESTE MEVCUTTUR: SİZİN TARAFINIZDAN KABUL EDİLEN VE KABUL EDİLEN “ANLAŞMA” nın BİR PARÇASI OLARAK KABUL EDİLECEKTİR VE BU ŞARTLAR BURADA REFERANS OLARAK DAHİL EDİLMİŞTİR. KUZEY AMERİKA dışındaki SAKİNLER İÇİN: SİZ (VEYA VARSA EBEVEYNİNİZ VEYA VASİNİZ) BU SÖZLEŞMEYİ kabul ETMİYORSANIZ, PROGRAMI VEYA HERHANGİ BİR BÖLÜMÜNÜ KULLANMAMALI VEYA BUNLARA ERİŞMEMELİSİNİZ. \"KABUL ETMEK İÇİN TIKLAYARAK“, ON SEKİZ (18) YAŞINI DOLDURMUŞ VEYA YASAL VASİSİ BU SÖZLEŞMEYİ KABUL ETMİŞ VE KABUL ETMİŞ BİR ”GERÇEK KİŞİ\" OLDUĞUNUZU BEYAN VE GARANTİ EDERSİNİZ. BU sözleşmeyi reddederseniz, PROGRAMLA İLGİLİ İADE HAKLARINIZ, PROGRAMI satın aldığınız ÜLKEDEKİ YASAL HAKLARINIZA TABİDİR. LÜTFEN ZİYARET EDİN . \n\nEXBÖLÜM 16 (TAHKİM VE TOPLU DAVADAN FERAGAT) HARİÇ OLMAK ÜZERE ACTİVİSİON, BU SÖZLEŞMEYİ DX_1p İLE sınırlama olmaksızın herhangi bir zamanda herhangi bir yolla değiştirme hakkını saklı tutar: DEĞİŞİKLİKLER VE / VEYA ^2 SÖZLEŞMEYİ “KABUL etmek İÇİN TIKLAMANIZI” GEREKTİRİR VE programı kullanmaya DEVAM ETMENİZ DEĞİŞİKLİKLERİ KABUL ETTİĞİNİZ ANLAMINA GELİR. SÖZLEŞMEDE GELECEKTE YAPILACAK HERHANGİ BİR DEĞİŞİKLİK SİZİN İÇİN KABUL EDİLEMEZ İSE VEYA BU SÖZLEŞMEYE ARTIK UYMAMANIZA neden OLUYORSA, PROGRAMI FESHETMELİ VE HEMEN kullanmayı BIRAKMALISINIZ. GELECEKTE YAPILACAK DEĞİŞİKLİKLER ”KABUL ETMEK İÇİN TIKLA\" SÖZLEŞMESİ OLARAK UYGULANIRSA, DEĞİŞTİRİLEN SÖZLEŞMEYİ OLUMLU OLARAK KABUL ETMEDİĞİNİZ SÜRECE PROGRAMI KULLANMAYA DEVAM EDEMEYEBİLİRSİNİZ.\n\n1. HİZMETLER VE EK HİZMET şartları: ÇEVRİMİÇİ VEYA ÇOK OYUNCULU BİLEŞENLER VEYA GÜNCELLENMİŞ ÖZELLİKLER DAHİL OLMAK ÜZERE PROGRAMIN BELİRLİ ÖZELLİKLERİNİN KULLANILMASI, EK HİZMET şartlarının ONAYLANMASINI GEREKTİREBİLİR. GEÇERLİ ÖZELLİKLERİN SİZE SUNULDUĞU TARİHTE SİZE BU EK HİZMET ŞARTLARI SAĞLANACAKTIR. EK HİZMET ŞARTLARI'NI KABUL ETMİYORSANIZ, EK HİZMET ŞARTLARI'NA TABİ OLAN EK ÖZELLİKLERE ERİŞEMEYEBİLİR VEYA BUNLARI KULLANAMAYABİLİRSİNİZ. \n", + "PLATFORM_EULA_2": "2. Sınırlı kullanım LİSANSI: Activision, herhangi bir sistem gereksinimine tabi olarak, Programın yazılım bileşen (ler)inin bir kopyasını yalnızca kişisel kullanımınız için kurmanız ve kullanmanız için size münhasır olmayan, devredilemez, sınırlı hak ve lisans verir. Özel olarak verilmeyen tüm haklar Activision tarafından saklıdır. Program kullanımınız için lisanslıdır, satılmamıştır. Lisansınız Programda herhangi bir unvan veya mülkiyet hakkı vermez ve Programdaki herhangi bir hakkın satışı olarak yorumlanmamalıdır. Bu Sözleşme, söz konusu düzeltme eki veya güncellemeye ek koşullar eşlik etmediği sürece, Program için alabileceğiniz düzeltme ekleri veya güncellemeler için de geçerli olacaktır. BU sözleşme tarafından size verilen lisans dışında, çevrimiçi hesaplar, HERHANGİ BİR SANAL PARA BİRİMİ VEYA mallar dahil ancak bunlarla sınırlı OLMAMAK üzere, sağlanan herhangi BİR ÜRÜN VEYA hizmet içeriğinde (aşağıda tanımlandığı gibi) mülkiyet VEYA mülk menfaatine sahip olmayacağınızı kabul EDER VE kabul EDERSİNİZ. ve ayrıca, bu sözleşmeyi kabul ettiğinizi VE kabul ettiğinizi kabul edersiniz. YÜRÜRLÜKTEKİ YASALARIN izin verdiği en geniş ÖLÇÜDE, bu tür ÜRÜN VE HİZMETLERLE sağlanan İÇERİKTEKİ VE İÇERİKTEKİ TÜM HAKLAR SONSUZA DEK ACTİVİSİON'A aittir VE ACTİVİSİON'IN yararınadır.\n\\ NKUZEY AMERİKA dışında yaşayanlar için: Şüpheden kaçınmak için, bölüm 2'deki hiçbir şey, haklı olarak satın aldığınız Programı içeren fiziksel medyayı satma ve aktarma hakkınızı sınırlayamaz.\n\n3. LİSANS koşulları: Bu lisans aşağıdaki sınırlamalara tabidir (\"Lisans Sınırlamaları\"). Programın Lisans Sınırlamalarını ihlal eden herhangi bir kullanımı, lisansınızın derhal feshedilmesine neden olur ve Programın sürekli kullanımı, Activision'ın telif haklarının ve Programdaki ve Programdaki diğer hakların ihlali anlamına gelir. Aşağıdakilerden hiçbirini yapmayacağınızı veya bunlara izin vermeyeceğinizi kabul edersiniz: ^1 Programı ticari olarak kullanmak; ^2 herhangi bir sistem gereksinimine tabi olarak, Programı aynı anda birden fazla sistemde kullanmak; (3) Programın tamamını veya tamamını kopyalar. (4) yukarıdaki fıkrayı (3) sınırlamaksızın, Programın kendisi kurulum sırasında bir kopyasını oluşturmadıkça veya Programı yetkili bir Activision çevrimiçi satıcısından indirmediğiniz sürece Programı bir sabit sürücüye veya başka bir depolama aygıtına kopyalayın; (5) Programı, Program işlevselliğine dahil olanlar dışında herhangi bir çevrimiçi kullanım dahil olmak üzere bir ağ, çok kullanıcılı düzenleme veya uzaktan erişim düzenlemesinde kullanmak; (6) Programı satmak, kiralamak, kiralamak, lisanslamak, dağıtmak veya başka bir şekilde aktarmak; ^7yürürlükteki yasalara tabi olarak, tersine mühendislik, programdaki yazılımın ve diğer tescilli teknolojinin tamamen veya kısmen kaynak kodunu türetir, değiştirir, derlemesini oluşturur, parçalara ayırır veya türev çalışmalar oluşturur; (8) çevrimdışı, çevrimiçi veya çok oyunculu oyun modlarında avantaj elde etmek için yetkisiz yazılım programları oluşturun, geliştirin, değiştirin, dağıtın veya kullanın; bu tür davranışlar Activision'ın takdirine bağlı olarak yaptırıma tabi olacaktır; (9) üzerinde veya içinde bulunan mülkiyet bildirimlerini veya etiketleri kaldırın, devre dışı bırakın veya atlayın (10) Amerika Birleşik Devletleri hükümetinin yürürlükteki herhangi bir yasa veya yönetmeliğine aykırı olarak Programı ihraç etmek veya yeniden ihraç etmek. Activision tarafından açıkça izin verilmeyen ve yürürlükteki yerel yasalara tabi olarak, ÇEVRE BİRİMİNDEKİ VEYA herhangi bir bölümündeki yazılımın PROGRAM dışındaki herhangi bir yazılım ÜRÜNÜ ile birleştirilmesine, dahil edilmesine veya kullanılmasına izin vermemeyi kabul edersiniz. BU SÖZLEŞME kapsamında size verilen TÜM HAKLAR (YAZILIMI ÇEVRE BİRİMİNDE kullanımınız DAHİL), BU PARAGRAFIN herhangi BİR ŞARTINI İHLAL ETMENİZ VEYA ÇEVRE BİRİMİNDE BU SÖZLEŞME tarafından açıkça izin verilmeyen herhangi BİR yazılımla HERHANGİ BİR ŞEY YAPMANIZ DURUMUNDA DERHAL SONA ERECEKTİR. Programı kullanırken aşağıdaki eylemlerden hiçbirini yapmamayı kabul edersiniz: (A) başka bir katılımcıyı, kullanıcıyı veya başka bir kişi veya kuruluşu taciz etmek, tehdit etmek, utandırmak veya sıkıntı veya rahatsızlığa neden olmak; (B) Activision'ın aşağıdakileri yapmayı düşündüğü herhangi bir ugc'yi (Bölüm 14'te tanımlandığı şekilde) iletmek: yıkıcı, yasa dışı, zararlı, tehdit edici, taciz edici, taciz edici, küçük düşürücü, kaba, müstehcen, nefret dolu veya ırksal, cinsel, etnik veya başka şekilde sakıncalı olmak; (C) Activision dahil ancak bunlarla sınırlı olmamak üzere herhangi bir kişi veya kuruluşu taklit etmek; (D) normal Program işlevselliğini bozmak veya başka bir şekilde diğer katılımcıları ve / veya genel Program deneyimini olumsuz yönde etkileyecek şekilde hareket etmek; (E) herhangi bir istenmeyen reklam, tanıtım materyali veya diğer herhangi bir talep biçimini yayınlamak veya iletmek; (F) yürürlükteki herhangi bir yasa, yönetmelik veya yönetmeliği kasıtlı veya kasıtsız olarak ihlal etmek. programı kullanırken veya Programa erişirken anlaşma yapmak; (G) Aynı içeriğe sahip birden fazla gönderi yayınlamak (ör. \"Spam\"); veya (H) herhangi bir fikri mülkiyet hakkı dahil ancak bunlarla sınırlı olmamak üzere herhangi bir kişi veya kuruluşun gizliliğini ihlal etmek veya herhangi bir hakkını ihlal etmek veya ihlal etmek.kendi yetki alanlarında reşit olmayan veya 18 yaşın altındaki çocukların ebeveynleri ve velileri, hangisi daha büyükse, bu tür kullanımlara sizin tarafınızdan izin verilip verilmediğine bakılmaksızın, Programın çocuğunuz tarafından tüm kullanımlarından sizin sorumlu olacağınızı kabul eder.\n", + "PLATFORM_EULA_3": "4. MÜLKİYET: Programdaki ve Programdaki tüm mülkiyet hakları, mülkiyet hakları ve fikri mülkiyet hakları Activision'a, Activision'ın bağlı kuruluşlarına veya Activision'ın lisans verenlerine aittir. Program, Amerika Birleşik Devletleri'nin telif hakkı yasaları, uluslararası telif hakkı anlaşmaları, sözleşmeler ve diğer yasalarla korunmaktadır. Program belirli lisanslı materyaller içerebilir ve Activision'ın lisans verenleri bu Sözleşmenin ihlali durumunda haklarını koruyabilir. AKSİNE HERHANGİ BİR ŞEYE RAĞMEN, BİR ACTİVİSİON SİSTEMİNDE DEPOLANAN VEYA BARINDIRILAN HERHANGİ BİR HESAPTA MÜLKİYETİNİZ VEYA BAŞKA BİR MÜLK MENFAATİNİZ OLMAYACAĞINI kabul EDER VE KABUL EDERSİNİZ VE AYRICA BU HESAPLARDAKİ VE HESAPLARDAKİ TÜM HAKLARIN SONSUZA DEK ACTİVİSİON'A ait OLDUĞUNU VE ACTİVİSİON'IN yararına OLACAĞINI KABUL EDER VE kabul EDERSİNİZ. ACTİVİSİON, BU HESAPLARDAN HERHANGİ BİRİNİ SİZE BİLDİRİMDE BULUNARAK VEYA BULUNMAKSIZIN herhangi BİR NEDENLE VEYA HERHANGİ BİR NEDENLE herhangi BİR ZAMANDA ASKIYA ALABİLİR, FESHEDEBİLİR, DEĞİŞTİREBİLİR VEYA SİLEBİLİR. \n\n5. YAMALAR VE GÜNCELLEMELER: Activision, Programı kullanmaya devam edebilmeniz için Programa yüklenmesi gereken zorunlu yamaları, güncellemeleri ve değişiklikleri dağıtabilir veya sağlayabilir. Activision, size haber vermeden Programı uzaktan güncelleyebilir ve bu tür düzeltme eklerini, güncelleştirmeleri ve değişiklikleri dağıtmak ve uygulamak için Activision'a onay vermiş olursunuz. Bu tür yamalar, güncellemeler ve değişiklikler için geniş bant internet gereklidir. Tüm geniş bant erişim ve kullanım ücretlerinden siz sorumlusunuz. \n\n6. Sınırlı donanım garantisi (yalnızca KUZEY AMERİKA VE AVUSTRALYA'DA ikamet edenler): \\ n \\ n6 (A) Activision, bu Programın orijinal tüketici alıcısına, bu Programın depolandığı fiziksel ortamın ve herhangi bir fiziksel aksesuarın (birlikte “Mallar”) malzeme ve işçilik hatalarından arınmış olacağını garanti eder satın alma tarihinden itibaren 90 gün boyunca. Mallar orijinal satın alma tarihinden itibaren 90 gün içinde kusurlu bulunursa, Activision, Mallar hâlâ üretildiği sürece, Programı aldıktan sonra (posta ücreti ödenmiş, satın alma tarihinin kanıtı ile birlikte) geçerli 90 günlük süre içinde geçerli kusurlu Malları ücretsiz olarak değiştirmeyi kabul eder activision tarafından. Mallar artık mevcut değilse, Activision eşit veya daha yüksek değere sahip benzer malların yerini alma hakkını saklı tutar. Bu garanti, orijinal olarak Activision tarafından sağlanan Ürünlerle sınırlıdır ve normal aşınma ve yıpranma için geçerli değildir. Kusurun kötüye kullanım, kötü muamele veya ihmal yoluyla ortaya çıkması durumunda bu garanti geçerli olmayacak ve geçersiz olacaktır. Tüzük tarafından öngörülen zımni garantiler, yukarıda açıklanan 90 günlük süre ile açıkça sınırlıdır. BURADA BELİRTİLENLER DIŞINDA, BU GARANTİ, AÇIK VEYA ZIMNİ DİĞER TÜM GARANTİLERİN YERİNE GEÇER.\n\nkuzey Amerika'da ikamet edenler için: Garanti değişimi veya diğer müşteri hizmetleri talepleri hakkında bilgi için . Bir değiştirme uygunsa, iade etmeniz gerekecektir: ^1 orijinal Mallar; ^2 tarihli satış makbuzunuzun bir kopyası; (3) adınız ve iade adresiniz; (4) karşılaştığınız kusur ve sorun (lar) ın bir açıklaması; ve (5) Müşteri Desteği tarafından size verilen olay / RMA numarası. Amerika Birleşik Devletleri'nde şu adrese gönderin: Garanti Değiştirmeleri, Activision Publishing, Inc., 100 N. Sepulveda Bulvarı. Süit 900, El Segundo, CA 90245; amerika Birleşik Devletleri dışında lütfen ziyaret edin .\n\navustralya sakinleri için: Bu garanti, Avustralya Tüketici Yasası uyarınca, bu oyun paketinde size sağlanan Mallarla ilgili sahip olabileceğiniz diğer hak ve çözüm yollarına ek olarak sağlanır. Mallar, Avustralya Tüketici Yasası kapsamında hariç tutulamayacak garantilerle birlikte gelir. Makul olarak öngörülebilir diğer kayıp veya hasarlar için büyük bir arıza ve tazminat için değiştirme veya geri ödeme hakkınız vardır. Ayrıca, Malların kabul edilebilir kalitede olmaması ve arızanın büyük bir arıza anlamına gelmemesi durumunda Malların onarılmasını veya değiştirilmesini sağlama hakkınız vardır. Lütfen 1300 748 995 numaralı telefondan Activision ile iletişime geçin veya e-posta gönderin ausupport@activision.com veya posta Posta Kutusu 544 Pyrmont NSW 2009 Avustralya Bu oyun paketinde size sağlanan Ürünlerle ilgili bir sorununuz varsa. Değiştirme veya onarım gerekiyorsa, Activision size işlem hakkında talimat verecektir. İşlemin bir parçası olarak, sizden: ^1 fiziksel ortamı (örneğin, CD-ROM/ DVD/Blu-ray Disk /kartuş (kılavuz veya kasa dahil değil)) koruyucu ambalajda göndermeniz istenebilir; ^2 aksesuar; (3) tarihli satış makbuzunuzun fotokopisi; (4) adınız ve iade adresiniz yazılı veya açıkça basılmış; (5) kusuru, karşılaştığınız sorun (lar) ı ve yazılımı çalıştırdığınız sistemi açıklayan kısa bir not; ve (6) Müşteri Desteği tarafından size verilen olay numarası. Ayrıca bir çek veya havale göndermeniz gerekebilir, ancak talebinizin geçerli olduğu tespit edilirse bu tutarın iadesine hak kazanabilirsiniz. Müşteri Desteği tarafından aksi belirtilmedikçe, lütfen değiştirilecek öğeleri (kayıtlı posta önerilir) Sınırlı Fiziksel Ortam / Çevre Birimi Garanti Değiştirmeleri, Activision Blizzard Australia Pty Ltd, PO Box 544 Pyrmont NSW 2009 Avustralya'ya gönderin. Aşağıdaki Zararların Sınırlandırılması maddesi hükümleri, yalnızca 2010 Rekabet ve Tüketici Yasası'nın (Cth) izin verdiği ölçüde geçerlidir.\n\n6(B). Sınırlı donanım garantisi (yalnızca KUZEY AMERİKA VE AVUSTRALYA dışındaki tüm ülkelerde ikamet edenler): Programın garantisi, her zaman geçerli olacak bir tüketici olarak yasal haklarınıza uygun olarak sağlanır. Activision'ın Programın Avrupa Birliği'nde ve Kuzey Amerika ve Avustralya dışındaki diğer ülkelerde değiştirilmesine ilişkin prosedürleri veya diğer müşteri hizmetleri talepleri hakkında bilgi için lütfen aşağıdakileri kontrol edin: . \\Activision Blizzard Avustralya Pty Ltd, Posta Kutusu 544 Pyrmont NSW 2009 Avustralya . Aşağıdaki Zararların Sınırlandırılması maddesi hükümleri, yalnızca 2010 Rekabet ve Tüketici Yasası'nın (Cth) izin verdiği ölçüde geçerlidir.\n\n6(B). Sınırlı donanım garantisi (yalnızca KUZEY AMERİKA VE AVUSTRALYA dışındaki tüm ülkelerde ikamet edenler): Programın garantisi, her zaman geçerli olacak bir tüketici olarak yasal haklarınıza uygun olarak sağlanır. Activision'ın Programın Avrupa Birliği'nde ve Kuzey Amerika ve Avustralya dışındaki diğer ülkelerde değiştirilmesine ilişkin prosedürleri veya diğer müşteri hizmetleri talepleri hakkında bilgi için lütfen aşağıdakileri kontrol edin: http://support.activision.com\n", + "PLATFORM_EULA_4": "7. ZARARLARIN sınırlandırılması \n\n7 (A) KUZEY AMERİKA'DA ikamet edenler için: \n\nACTİVİSİON, mülkiyete verilen zararlar, bilgisayar arızası veya arızası dahil olmak üzere programın bulundurulması, kullanılması veya arızalanmasından kaynaklanan özel, tesadüfi veya sonuç olarak ortaya çıkan zararlardan sorumlu olmayacaktır. ve izin verdiği ölçüde YASAYA GÖRE, KİŞİSEL YARALANMALARDAN KAYNAKLANAN ZARARLAR, ACTİVİSİON'A BU ZARARLARIN OLASILIĞI BİLDİRİLMİŞ OLSA BİLE. ACTİVİSİON'IN SORUMLULUĞU, PROGRAMI KULLANMA LİSANSI İÇİN ÖDENEN GERÇEK FİYATI AŞMAYACAKTIR. BAZI EYALETLER / ÜLKELER, ZIMNİ BİR GARANTİNİN ne KADAR SÜRECEĞİ VE / VEYA zararların HARİÇ tutulması VEYA sınırlandırılması KONUSUNDA sınırlamalara izin vermediğinden, yukarıdaki sınırlamalar VE / VEYA İSTİSNALAR SİZİN İÇİN GEÇERLİ OLMAYABİLİR. BU GARANTİ SİZE BELİRLİ YASAL HAKLAR VERİR VE YARGI YETKİSİNDEN YARGI YETKİSİNE DEĞİŞEN BAŞKA HAKLARINIZ DA OLABİLİR.\n\n7 (B) KUZEY AMERİKA dışındaki SAKİNLER İÇİN: \n\\ NBU SÖZLEŞMEDEKİ hiçbir şey ACTİVİSİON'IN SİZE KARŞI SORUMLULUĞUNU SINIRLAMAZ VEYA HARİÇ TUTMAZ: \\ n- İHMALİMİZDEN KAYNAKLANAN ÖLÜM VEYA KİŞİSEL YARALANMA İÇİN; \\ n- HİLELİ YANLIŞ BEYAN İÇİN; VEYA \\ n- İKAMET ETTİĞİNİZ YARGI YETKİSİ YASALARINA GÖRE SINIRLANDIRILAMAYACAK VEYA HARİÇ TUTULAMAYACAK DİĞER HERHANGİ BİR SORUMLULUK İÇİN.BUNA bağlı olarak, ACTİVİSİON hiçbir durumda herhangi bir ticari kayıptan size karşı sorumlu tutulamaz VE ACTİVİSİON'IN maruz kaldığınız kayıplardan DOLAYI sahip olduğu herhangi bir SORUMLULUK, makul bir şekilde öngörülebilir olan kayıplarla kesinlikle sınırlıdır VE toplamda aşağıdakilerden daha fazlasını aşmayacaktır: PROGRAM İÇİN tarafınızdan ödenen TOPLAM BEDEL SORUMLULUĞUN ORTAYA ÇIKTIĞI TARİHTEN İTİBAREN ÖNCEKİ 12 AY BOYUNCA (ARTI HİZMET İÇİN ÖDENMİŞ İÇERİK); VEYA MEVCUT DÖVİZ KURU ALTINDA 500 GBP £ VEYA EŞDEĞERİ TUTARIN TOPLAMI.\n\n8. FESİH: Activision'ın diğer haklarına halel getirmeksizin, hüküm ve koşullarına uymamanız durumunda bu Sözleşme otomatik olarak feshedilecektir. Bu nedenle fesih durumunda, Programın tüm kopyalarını ve tüm bileşen parçalarını imha etmeniz gerekir. Ayrıca, Programın herhangi bir kurulumunu kalıcı olarak silerek ve elinizdeki veya kontrolünüzdeki Programın tüm kopyalarını imha ederek Sözleşmeyi istediğiniz zaman feshedebilirsiniz. Aşağıdaki hükümler bu sözleşmenin sona ermesinden sonra da geçerli olacaktır: LİSANS koşulları (BÖLÜM 3), MÜLKİYET (BÖLÜM 4), sınırlı donanım garantisi (BÖLÜM 6A VE 6B), hasarların sınırlandırılması (BÖLÜM 7A VE 7B), FESİH (BÖLÜM 8), TAZMİNAT (BÖLÜM 10), HİZMET sağlanan içerik (BÖLÜM 11), BULUNABİLİRLİK (BÖLÜM 12), ERİŞİM (BÖLÜM 13), BAĞLAYICI TAHKİM VE TOPLU DAVADAN FERAGAT (BÖLÜM 16), YARGI YETKİSİ VE YÜRÜRLÜKTEKİ HUKUK (BÖLÜM 17) VE ÇEŞİTLİ (BÖLÜM 18).\n\n9. Kuzey Amerika'da yaşayanlar için - ABD. DEVLET tarafından kısıtlanmış haklar: Program tamamen özel olarak geliştirilmiştir ve \"Ticari Bilgisayar Yazılımı\" veya \"kısıtlanmış bilgisayar yazılımı\" olarak sağlanmaktadır.\" ABD Hükümeti veya bir ABD Hükümeti alt yüklenicisi tarafından kullanılması, çoğaltılması veya ifşa edilmesi, DFARS 252.227-7013'teki Teknik Veri ve Bilgisayar Yazılımı maddelerindeki Hakların (ii) bendi (c) ^1 (ii) bendinde veya (c) ^1 ve ^2 bendinde belirtilen kısıtlamalara tabidir.: ticari Bilgisayar Yazılımı Kısıtlı Haklar hükümlerinin FAR 52.227-19'da geçerli olduğu şekilde. Yüklenici / Üretici Activision Publishing, Inc.'dir., 3100 Okyanus Parkı Bulvarı, Santa Monica, Kaliforniya 90405.\n\n10. Kuzey Amerika'da yaşayanlar için TAZMİNAT: Activision'ı, ortaklarını, bağlı kuruluşlarını, lisans verenlerini, yüklenicilerini, memurlarını, direktörlerini, çalışanlarını ve temsilcilerini, bu Sözleşmeyi ihlal etmenizden ve / veya eylemlerinizden doğrudan veya dolaylı olarak kaynaklanan tüm zarar, ziyan ve masraflardan tazmin etmeyi, savunmayı ve korumayı kabul edersiniz. ve / veya acenteleriniz ve acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz, acenteleriniz bu Sözleşmenin şartlarına uygun olarak Programı kullanmadaki ihmaller. \n\n11. HİZMET tarafından sağlanan içerik: \"Hizmet Tarafından Sağlanan içerik\", size sağlanan tüm sanal materyallerden, bilgilerden ve içerikten oluşur (örneğin, kilitlenebilir içerik, hesaplar, istatistikler, sanal varlıklar, sanal para birimleri, kodlar, başarılar, sanal ödüller, krediler, erişim, şovlar, jetonlar, madeni paralar, güçlendirmeler ve özelleştirmeler) ek içerik elde etmek için \"kazanmanız\", \"öğütmeniz\", \"satın almanız\" ve / veya \"satın almanız\" gereken Çevrimiçi Hizmetler de dahil olmak üzere Programı kullanımınızla bağlantılı olarak. \n\nprogram, oyun içinde veya oyunla bağlantılı olarak Hizmet Tarafından Sağlanan içeriği “kazanmanıza”, “öğütmenize”, \"satın almanıza\" veya \"satın almanıza\" izin verebilirken, aslında Hizmet Tarafından Sağlanan İçeriğe ve Hizmet Tarafından Sağlanan Herhangi bir İçeriğin Priceına sahip değilsiniz veya bunlarla ilgili herhangi bir mülk menfaatiniz yok gerçek para biriminin veya eşdeğerinin herhangi bir kredi bakiyesine atıfta bulunmaz. Yazılı olarak aksi belirtilmediği sürece, aldığınız Hizmet Tarafından Sağlanan herhangi bir İçerik, burada belirtildiği şekilde size lisanslanmıştır ve Hizmet Tarafından Sağlanan herhangi bir İçerik üzerinde mülkiyet hakkınız olmayacaktır. Uygun olduğu durumlarda, Hizmet Tarafından Sağlanan Diğer İçerikler dışında, Hizmet Tarafından Sağlanan Herhangi bir İçeriği satamaz, ödünç veremez, kiralayamaz, takas edemez veya başka bir şekilde aktaramazsınız. “Gerçek” para için sanal para birimi veya bu öğelerin değişimi veya Program dışındaki değer için sanal para birimi dahil ancak bunlarla sınırlı olmamak üzere Sağlanan Hizmet içeriğinin satışı yasaktır. Hizmet Tarafından Sağlanan içerik, değişiklikten önce Hizmet Tarafından Sağlanan İçeriği “kullanmamış” veya “tüketmemiş” olsanız bile, Activision tarafından değiştirilebilir, kaldırılabilir, silinebilir veya durdurulabilir (örneğin, bu Sözleşmenin feshi ve/veya Bölüm 8'de belirtildiği şekilde Program için çevrimiçi desteğin sona ermesi üzerine), kaldırma, silme veya durdurma. Yukarıdakileri sınırlamaksızın, Hizmet Tarafından Sağlanan İçerik sanal paralar, puanlar veya diğer sanal para birimlerini (“Sanal Para Birimi”) içerebilir. Sanal Para Birimi satın alarak veya başka bir şekilde satın alarak, Hizmet Tarafından Sağlanan diğer içeriğe erişmek ve bunlardan birini seçmek için sınırlı bir lisans (geçerli yasalar tarafından aksi belirtilmedikçe Activision tarafından herhangi bir zamanda iptal edilebilir) elde edersiniz. Sanal Para Biriminin parasal değeri yoktur ve herhangi bir türde para birimi veya mülk teşkil etmez. Sanal Para Birimi, yalnızca Hizmet Tarafından Sağlanan diğer içerikler için kullanılabilir. Geçerli yerel yasalara tabi olarak, Sanal Para Birimi iade edilmez. Kullanılmayan herhangi bir Sanal Para Birimi için Sağlanan Hizmet içeriği ve kullanılmayan Sanal Para Birimi değiştirilemez gibi bir geri ödeme veya başka bir tazminat alma hakkınız yoktur. Activision, Program aracılığıyla sunulan Hizmet İçeriği ve Sanal Para Biriminin Pricelandırmasını istediği zaman revize edebilir. Activision, herhangi bir zamanda satın alınabilecek Hizmet Tarafından Sağlanan Toplam İçerik veya Sanal Para Birimini sınırlayabilir ve/veya hesabınızda tutulabilecek Hizmet Tarafından Sağlanan Toplam İçerik veya Sanal Para Birimini toplu olarak sınırlayabilir. Program aracılığıyla yalnızca Activision'dan veya yetkili ortaklarımızdan Hizmet Tarafından Sağlanan İçeriği veya Sanal Para Birimini satın almanıza izin verilir ve başka hiçbir şekilde satın almanıza izin verilmez. Activision, Hizmet Tarafından Sağlanan İçeriği ve / veya Sanal Para Birimini edinme taleplerinizi reddetme hakkını saklı tutar. Hizmet Tarafından Sağlanan içeriğin ve/veya Sanal Para Biriminin edinilmesi, kullanılması veya Hizmete erişimiyle ilgili geçerli vergilerin ödenmesinden yalnızca sizin sorumlu olacağınızı kabul edersiniz.\n\\ ngerçek para ile ödeme yapmanızı gerektirecek, miktarı Programda belirtilecek olan Hizmet Tarafından Sağlanan içerik (satın almayı seçerseniz) olabilir. Hizmet Tarafından Sağlanan tüm içerik, gerçek parayla satın aldığınızda hemen kullanıma sunulacak ve bunun böyle olduğunu ve satın alma işleminiz tamamlandıktan sonra fikrinizi değiştirme ve iptal etme hakkınızın olmayacağını (bazen 'soğuma' hakkı olarak da bilinir) kabul edersiniz. Platformunuza bağlı olarak, satın alınan Hizmet Tarafından Sağlanan herhangi bir içerik, platform sağlayıcınızdan satın alınacak ve bu satın alma, ilgili Hizmet Şartlarına ve Kullanıcı Sözleşmesine tabi olacaktır. Öğeden öğeye farklılık gösterebileceğinden lütfen her satın alma için kullanım haklarını kontrol edin. Aksi belirtilmedikçe, herhangi bir oyun içi mağazada bulunan içerik, oyunla aynı yaş derecesine sahiptir.\n", + "PLATFORM_EULA_5": "12. KULLANILABİLİRLİK: \n\n12(A) Kuzey Amerika'da ikamet edenler için: Activision, Programla ilişkili herhangi bir çevrimiçi hizmetin, oynatmanın veya özelliğin (toplu olarak “Çevrimiçi Hizmetler” olarak anılacaktır) veya Hizmet Tarafından Sağlanan İçeriğin her zaman veya herhangi bir zamanda kullanılabileceğini veya Activision'ın kullanıma devam edeceğini garanti etmez. belirli bir süre için Çevrimiçi Hizmetler veya Hizmet Tarafından Sağlanan içerik sunun. Activision, size bildirimde bulunmaksızın Çevrimiçi Hizmetleri veya Hizmet Tarafından Sağlanan İçeriği değiştirebilir ve güncelleyebilir. Activision, Çevrimiçi Hizmetlerin kullanılabilirliği konusunda hiçbir garanti veya beyanda bulunmaz ve Çevrimiçi Hizmetleri, zaman içinde Çevrimiçi Hizmeti kullanmaya devam eden sınırlı sayıda kullanıcı nedeniyle ekonomik nedenlerle Çevrimiçi Bir Hizmeti durdurmak da dahil olmak üzere, kendi takdirine bağlı olarak önceden haber vermeksizin değiştirme veya durdurma hakkını saklı tutar. AKSİNE HERHANGİ BİR ŞEYE RAĞMEN, ÇEVRİMİÇİ HİZMETLERİN SİZE bildirimde bulunmaksızın TAMAMEN VEYA kısmen ACTİVİSİON'IN takdirine bağlı OLARAK FESHEDİLEBİLECEĞİNİ VE ÇEVRİMİÇİ HİZMETLERİN FESHEDİLMESİYLE bağlantılı olarak, SİZE lisanslanan HİZMET tarafından sağlanan tüm İÇERİKLERİN FESHEDİLEBİLECEĞİNİ kabul VE taahhüt EDERSİNİZ. ÇEVRİMİÇİ HİZMETLERİN SONA ERMESİ VE SAĞLANAN HİZMET İÇERİĞİNİN VEYA BAŞKA BİR ŞEKİLDE KAYBEDİLMESİ İLE İLGİLİ HER TÜRLÜ KAYIP RİSKİNİ ÜSTLENİRSİNİZ. \n\n12(B) Kuzey Amerika dışındaki sakinler için: Bir sonraki cümleye tabi olarak Activision, Sağlanan herhangi bir Çevrimiçi Hizmetin veya Hizmet İçeriğinin her zaman veya herhangi bir zamanda kullanılabilir veya hatasız olacağını garanti etmez. Activision, Programın, gerçek parayla ödenmiş herhangi bir Hizmet Tarafından Sağlanan İçeriğe ek olarak, satın alma noktasında sağladığı açıklamaya büyük ölçüde uyacağını ve tatmin edici kalitede olacağını garanti eder (ayrıca, bunlar aracılığıyla sağlanan ilgili hizmetler makul özen ve beceriyle sağlanacaktır). Activision, size bildirimde bulunmaksızın Çevrimiçi Hizmetleri veya Hizmet Tarafından Sağlanan İçeriği değiştirebilir ve güncelleyebilir (bu tür değişikliklerin, Programın işlevselliğinde veya gerçek parayla ödenmiş Hizmet Tarafından Sağlanan herhangi bir İçeriğin önemli ölçüde bozulmasına neden olmaması koşuluyla). Activision, ücretsiz olan Çevrimiçi Hizmetlerin ve / veya Hizmet Tarafından Sağlanan İçeriğin kullanılabilirliği konusunda hiçbir garanti veya beyanda bulunmaz (ör. gerçek para ile ödenmez) ve zaman içinde sınırlı sayıda kullanıcının bunları kullanmaya devam etmesi nedeniyle ekonomik nedenlerle de dahil olmak üzere, size bildirimde bulunmaksızın kendi takdirine bağlı olarak bunları değiştirme veya durdurma hakkını saklı tutar. Activision, makul kontrolü dışındaki olaylardan kaynaklanan yükümlülüklerinin yerine getirilmemesi veya yerine getirilmesindeki gecikmelerden sorumlu veya yükümlü değildir. Bu koşullar, Program veya Hizmet Tarafından Sağlanan İçeriğin işlevselliğinde maddi bozulmaya neden olursa, bunları indirmek, kullanmak veya bunlara erişmek için herhangi bir ödeme yapma yükümlülüğünüz bu süre boyunca askıya alınacaktır. Activision, size makul bir bildirimde bulunulması hâlinde tamamen kendi takdirine bağlı olarak gerçek parayla ödenen Çevrimiçi Hizmetleri ve / veya Hizmet Tarafından Sağlanan İçeriği değiştirme veya durdurma hakkına sahiptir. Bu tür Çevrimiçi Hizmetler ve / veya Hizmet Tarafından Sağlanan İçerik için garanti, tüketici olarak her zaman geçerli olacak yasal haklarınıza uygun olarak sağlanır. Activision'ın zararlarla ilgili sınırlamasıyla ilgili olarak lütfen Bölüm 7'ye bakın, ancak bu paragraftaki hiçbir şey yasal haklarınızı etkilemeyecektir. \n\n13. ERİŞİM: PROGRAMI VE hizmetleri kullanmak İÇİN MARUZ kaldığınız üçüncü taraf masraflarından yalnızca SİZ SORUMLUSUNUZ. Programa erişmek ve Programı kullanmak için gereken ekipmanı, interneti veya diğer bağlantı ücretlerini kendi maliyet ve masraflarınızla sağlayacağınızı kabul ve taahhüt edersiniz. Activision, Programa tüm sistemlerde, denetleyicilerde veya cihazlarda, belirli bir İnternet veya başka bir bağlantı sağlayıcısı aracılığıyla veya tüm bölgelerde erişilebileceğine veya kullanılabileceğine dair hiçbir garanti vermez. Program, üçüncü taraf hizmetleri ve içeriğiyle bütünleştirilebilir, bütünleştirilebilir veya bunlarla bağlantılı olarak sağlanabilir. Activision bu üçüncü taraf hizmetleri ve içeriği kontrol etmez. Söz konusu üçüncü taraf hizmetleri ve içeriği için geçerli olan kullanım koşulları sözleşmelerini ve gizlilik politikalarını okumalısınız. \n\n14. Kullanıcı tarafından OLUŞTURULAN içerik: Program, sizin ve diğer kullanıcıların kullanıcı tarafından oluşturulan içeriği paylaşabileceği araçlar içerebilir (”UGC\"). Yürürlükteki yasaların izin verdiği en geniş ölçüde, Activision'a otomatik olarak verdiğiniz (veya bu hakların sahibinin açıkça vermiş olduğunu beyan ve garanti ettiğiniz) herhangi bir ugc'yi göndererek, kullanmak, çoğaltmak, değiştirmek, uyarlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, yayınlamak, bu tür ugc'lerden çeviri yapın, alt lisans alın, türev çalışmalar oluşturun ve dağıtın veya bu tür UGC içeriğini şu anda evrende bilinen veya daha sonra geliştirilen herhangi bir forma, ortama veya teknolojiye dahil edin, ve Activision'ın ugc'yi ticari veya başka herhangi bir amaç için tazminatsız (ancak yürürlükteki yerel mevzuata tabi), bildirimde bulunmaksızın veya atfetmeksizin sınırsız kullanma hakkına sahip olacağını kabul edin. Activision'a veya onun ortaklarına, bağlı kuruluşlarına, bağlı kuruluşlarına veya lisans sahiplerine, ugc'nizde sahip olabileceğiniz ahlaki veya benzer haklardan feragat eder ve bunlara karşı çıkmamayı kabul edersiniz. Program, diğer kullanıcıların ugc'nize erişmesine ve kullanmasına izin verdiği ölçüde, bu tür kullanıcılara, ugc'nizi Program üzerinde veya Program aracılığıyla başka bir bildirimde bulunmaksızın kullanma, kopyalama, değiştirme, görüntüleme, gerçekleştirme, bunlardan türev çalışmalar oluşturma ve başka şekilde iletme ve dağıtma hakkı da verirsiniz. , size atıf veya tazminat. Programa yalnızca kendi ugc'nizi yükleyebilirsiniz; başkasının ugc'sini yüklemeyin. Activision, yalnızca Activision'ın takdirine bağlı olarak herhangi bir nedenle ugc'yi kaldırma, engelleme, düzenleme, taşıma veya devre dışı bırakma hakkını saklı tutar (ancak hiçbir yükümlülüğü yoktur). Activision, diğer kullanıcılar tarafından gönderilen veya gönderilen görüş, görüş, tavsiye veya önerilerden sorumlu değildir ve bunları onaylamaz veya garanti etmez. \n\\ nkuzey Amerika dışındaki tüm ülkelerde yaşayanlar için: Programın kullanıcıları ugc'yi kendi riskleri altında oluşturur, yükler, indirir ve kullanır. Programımız aracılığıyla ugc'nizi diğer kullanıcılara yüklerseniz veya kullanıma sunarsanız, ugc'nizi kontrol etmiyoruz, izlemiyoruz, onaylamıyoruz veya sahiplenmiyoruz ve yukarıdaki lisansa tabi olarak bu tür ugc'yi barındırmamız ve kullanıma sunmamız için bizi görevlendiriyorsunuz. \n\n Herhangi bir ugc'nin içeriğiyle ilgili şikayetler aşağıdaki adrese gönderilmelidir: legalaffairs@activision.com ve şikayete yol açan belirli UGC'NİN ayrıntılarını içermelidir.\n\n15. Kuzey Amerika'da yaşayanlar için-- TELİF hakkı bildirimi: \n\nprogramda ve/ veya ugc'de görünen herhangi bir içeriğin telif hakkı ihlali oluşturacak şekilde kopyalandığını düşünüyorsanız, lütfen aşağıdaki bilgileri aşağıda adı geçen telif hakkı temsilcisine iletin. Telif hakkı ihlali bildiriminiz Dijital Binyıl Telif Hakkı Yasası'na (\"DMCA\") uygun olmalıdır. 17 U.S.C.'yi incelemeniz önerilir. § 512 (c) (3) veya bir bildirim göndermeden önce bir avukata danışın. Telif hakkı ihlali bildiriminde bulunmak için, aşağıda listelenen adrese aşağıdakileri içeren yazılı bir iletişim göndermeniz gerekir: (a) adınız, adresiniz, telefon numaranız ve e-posta adresiniz; (b) ihlal edildiğini iddia ettiğiniz telif hakkıyla korunan eserin bir açıklaması; (c) telif hakkıyla korunan eserin bir açıklaması; (c) telif hakkıyla korunan eserin bir açıklaması; (c) telif hakkıyla korunan eserin bir açıklaması; (c) telif hakkıyla korunan eserin bir açıklaması; (c) telif hakkıyla korunan eserin bir açıklaması; (c) telif hakkıyla korunan eserin bir açıklaması; ihlal ettiği iddia edilen materyalin bulunduğu yerin tam URL'si veya açıklaması; (d) ihtilaflı kullanımın telif hakkı sahibi, temsilcisi veya yasa tarafından yetkilendirilmediğine dair iyi niyetli bir inancınız olduğuna dair tarafınızdan yapılan bir beyan; (e) telif hakkı menfaatinin sahibi adına hareket etmeye yetkili kişinin elektronik veya fiziki imzası; ve (f) yalan beyanda bulunma cezası altında, bildiriminizdeki yukarıdaki bilgilerin doğru olduğunu ve telif hakkı sahibi olduğunuzu veya telif hakkı sahibi adına hareket etmeye yetkili olduğunuzu beyan etmeniz.\n\nCopyright Aracısı\nActivision Publishing, Inc.\n3100 Ocean Park Bulvarı\nSanta Monica, Kaliforniya 90405 \\ nAttn: Activision iş ve Hukuk işleri \nFax: (310) 255-2152 \\ nE-Posta: legalaffairs@activision.com \\ n\\ nmalzemenin veya faaliyetin ihlal edici olduğunu bilerek yanlış beyan ederseniz, dmca'nın zararlardan (masraflar ve avukat ücretleri dahil) sorumlu olabileceğinizi belirttiğini lütfen unutmayın. Telif hakkı ihlali bildiriminizde sağlanan bilgilerin, ihlal ettiği iddia edilen materyalden sorumlu kişiye verilebileceğini lütfen unutmayın.\n", + "PLATFORM_EULA_6": "16. Kuzey Amerika'da ikamet edenler için -- BAĞLAYICI TAHKİM VE TOPLU DAVADAN FERAGAT:\n\nBU bölümü dikkatlice okuyun. MAHKEMEDE DAVA AÇMA HAKKINIZ DA DAHİL OLMAK ÜZERE YASAL HAKLARINIZI ÖNEMLİ ÖLÇÜDE ETKİLEYEBİLİR.\n\\ nBu bağlayıcı TAHKİM VE TOPLU DAVADAN FERAGAT hükümleri, Amerika Birleşik Devletleri'nde ikamet ediyorsanız ve / veya Programı satın aldıysanız ve kullanıyorsanız sizin için geçerlidir. Bu hükümler, Programa Amerika Birleşik Devletleri dışından ikamet ediyorsanız ve / veya Programı satın aldıysanız ve kullanıyorsanız sizin için de geçerli olabilir. Ayrıntılar için aşağıdaki yargı yetkisine VE yürürlükteki yasalara bakın.\n\nİnitial Uyuşmazlık Çözümü: Activision'ın Müşteri Destek departmanına şu adresten ulaşılabilir: programla ilgili endişelerinizi gidermek için. Endişelerin çoğu, müşterilerimizin memnuniyeti için bu şekilde hızla çözülür. Taraflar, herhangi bir anlaşmazlığı, iddiayı, soruyu veya anlaşmazlığı, dava veya tahkim başlatan taraflardan birinin ön koşulu olacak istişare ve iyi niyetli müzakereler yoluyla doğrudan çözmek için ellerinden gelen çabayı göstereceklerdir.bağlayıcı Tahkim: Taraflar, yukarıdaki fıkra uyarınca gayri resmi uyuşmazlık çözümünün takip edildiği tarihten itibaren 30 günlük bir süre içinde üzerinde anlaşmaya varılmazsa, taraflardan her ikisi de, aşağıda belirtilen şartlara tabi olarak, talepleri resmi olarak çözmenin tek yolu olarak bağlayıcı tahkim başlatabilir. Özellikle, bu Sözleşmeden kaynaklanan veya bu Sözleşmeyle ilgili tüm iddialar (yorumlanması, oluşturulması, ifası ve ihlali dahil), tarafların birbirleriyle olan ilişkileri ve / veya Programı kullanımınız, JAMS tarafından Kapsamlı Tahkim Kuralları hükümlerine uygun olarak yönetilen bağlayıcı tahkim yoluyla kesin olarak karara bağlanacaktır. veya Kolaylaştırılmış Tahkim Kuralları, uygun şekilde, sınıf eylemlerini düzenleyen veya bunlara izin veren herhangi bir kural veya prosedür hariç. Bu tahkim hükmü, eyaletler arası ticareti içeren bir işlem uyarınca yapılır ve Federal Tahkim Yasası (\"FAA\"), bu Sözleşmede yer alan diğer herhangi bir yasa hükmü seçimine bakılmaksızın, bu Sözleşmenin yorumlanması, uygulanabilirliği, uygulanabilirliği ve oluşumu için geçerli olacaktır. Hakem, herhangi bir federal, eyalet veya yerel mahkeme veya kurum değil, bu Sözleşmenin yorumlanması, uygulanabilirliği, uygulanabilirliği veya oluşumundan kaynaklanan veya bunlarla ilgili tüm anlaşmazlıkları çözme konusunda münhasır yetkiye sahip olacaktır. , bu Sözleşmenin tamamının veya herhangi bir bölümünün geçersiz veya geçersiz olduğuna dair herhangi bir iddia dahil ancak bunlarla sınırlı olmamak üzere veya bir talebin tahkime tabi olup olmadığı. Hakem, bir mahkemede hukuka göre veya hakkaniyete uygun olarak sağlanabilecek her türlü yardımı verme yetkisine sahip olacaktır. Hakemin kararı taraflar için bağlayıcı olacaktır ve yetkili yargı yetkisine sahip herhangi bir mahkemede karar olarak verilebilir. \n\n Tahkime ilişkin JAMS Kurallarına şu adresten erişilebilir: veya (800) 352-5267 numaralı telefondan jams'i arayarak. Tahkim ücretleriniz ve hakem tazminatı payınız JAMS Kapsamlı Tahkim Kurallarına tabi olacaktır, ancak JAMS Toplu Dava Prosedürlerini ve geçerli olduğu ölçüde, tahkim dosyalama ücretlerine ilişkin o zamanki sınır dahil olmak üzere Tüketici Asgari Standartlarını içermeyecektir. Tahkim için dosyalama ücretinin dava açma maliyetini aştığı ölçüde, Activision ek ücreti ödeyecektir. Taraflar, bu zorunlu hükmün yokluğunda mahkemede dava açma ve jürili yargılama hakkına sahip olacaklarını anlarlar. Ayrıca, bazı durumlarda tahkim masraflarının dava masraflarını aşabileceğini ve keşif hakkının tahkimde mahkemeden daha sınırlı olabileceğini anlarlar.\n\nkonum: Amerika Birleşik Devletleri'nde ikamet ediyorsanız, tahkim, Amerika Birleşik Devletleri'nde sizin için uygun olan herhangi bir makul yerde gerçekleşecektir. Amerika Birleşik Devletleri dışında ikamet edenler için, Kaliforniya, Los Angeles County'de tahkim başlatılacaktır ve siz ve Activision, tahkimi zorlamak, tahkimi bekleyen yargılamaları sürdürmek veya onaylamak, değiştirmek, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, onaylamak, hakem tarafından girilen ödülü boşaltın veya karara bağlayın.\n \\ nSınıf Davasından Feragat: Taraflar ayrıca, herhangi bir tahkimin bir sınıf davası veya başka bir temsili dava olarak değil, yalnızca bireysel kapasitelerinde yürütüleceğini kabul ederler, taraflar, toplu dava açma veya sınıf bazında yardım talep etme haklarından açıkça feragat ederler. SİZ VE ACTİVİSİON, HER BİRİNİN, İDDİA EDİLEN HERHANGİ BİR SINIF VEYA TEMSİLCİ DAVASINDA DAVACI VEYA SINIF ÜYESİ OLARAK DEĞİL, YALNIZCA SİZİN VEYA KENDİ SIFATIYLA DİĞERİNE KARŞI TALEPTE BULUNABİLECEĞİNİ KABUL EDERSİNİZ. Herhangi bir mahkeme veya hakem, bu fıkrada belirtilen toplu davadan feragatin herhangi bir nedenle geçersiz veya uygulanamaz olduğuna veya tahkimin sınıf bazında ilerleyebileceğine karar verirse, yukarıda belirtilen tahkim hükmü tamamen geçersiz sayılır ve taraflar kabul etmemiş sayılır anlaşmazlıkları tahkim etmek.\n\nException - Fikri Mülkiyet Davaları ve Küçük Talepler Mahkemesi Talepleri: Tarafların tüm anlaşmazlıkları tahkim yoluyla çözme kararına bakılmaksızın, taraflardan herhangi biri eyalet veya federal mahkemede yalnızca patent ihlali veya geçersizlik, telif hakkı ihlali, ahlaki haklar ihlali, ticari marka ihlali ve / veya ticari sır kötüye kullanımı iddialarında bulunan bir dava açabilir. , ancak, açıklık için, bu Sözleşme kapsamındaki Program için size verilen lisansla ilgili iddialar değil. Her iki taraf da, o mahkemenin yargı yetkisi kapsamındaki anlaşmazlıklar veya talepler için küçük talep mahkemesinde yardım isteyebilir.\n\n30 Günlük Vazgeçme Hakkı: Vazgeçme kararınıza ilişkin yazılı bildirim göndererek yukarıdaki \"Bağlayıcı Tahkim\", \"Konum\" ve \"Toplu Davadan Feragat\" paragraflarında belirtilen tahkim ve toplu davadan feragat hükümlerine bağlı kalmamaya ve vazgeçme hakkınız vardır-şu adrese gidin: Activision Publishing, Inc., 3100 Okyanus Parkı Bulvarı, Santa Monica, CA 90405-3032, Dikkat: Yasal. Bildirim, Programı satın aldıktan sonraki 30 gün içinde gönderilmelidir (veya satın alma yapılmadıysa, Programa ilk eriştiğiniz veya Programı kullandığınız tarihten itibaren 30 gün içinde ve bu şartları kabul ederseniz); aksi takdirde, anlaşmazlıkları bu paragrafların şartlarına uygun olarak tahkim etmekle yükümlüsünüzdür. Bu tahkim hükümlerinden vazgeçerseniz, Activision da bunlara bağlı olmayacaktır. \n\nBu Bölümdeki Değişiklikler: Activision, bu Bölümdeki herhangi bir değişiklik hakkında 60 günlük bildirim sağlayacaktır. Değişiklikler 60. günde yürürlüğe girecek ve ileriye dönük olarak yalnızca 60. günden sonra ortaya çıkacak talepler için geçerli olacaktır.\n", + "PLATFORM_EULA_7": "17. Yargı yetkisi VE yürürlükteki YASALAR \nprogram, bu Sözleşmenin şartlarına tabi olarak kullanıma sunulmuştur. Programı şu adresten satın aldıysanız ve kullanıyorsanız: \nA. Amerika Birleşik Devletleri, Meksika veya Kanada'da ikamet edenler için Activision Publishing, Inc. ile sözleşme yapıyorsunuz demektir., 3100 Ocean Park Bulvarı, Santa Monica, CA 90405-3032 ve bu Sözleşmeden doğan tüm iddialar (yorumlama, ihlal iddiaları ve diğer tüm iddialar (tüketicinin korunması, haksız rekabet ve haksız fiil iddiaları dahil) dahil), çatışmaya atıfta bulunulmaksızın Delaware Eyaleti yasalarına tabi olacaktır kanun ilkeleri. Herhangi bir mahkeme veya hakem, yukarıda belirtilen “Toplu Davadan Feragat” paragrafının herhangi bir nedenle geçersiz veya uygulanamaz olduğunu veya bir tahkimin sınıf bazında ilerleyebileceğini belirlerse, bu Sözleşmeden doğan tüm talepler (yorumlama, ihlal talepleri ve diğer tüm talepler (tüketici talepleri dahil) dahil). koruma, haksız rekabet ve haksız fiil iddiaları)) bu Sözleşmeye tabi olan Programı aldığınız veya satın aldığınız sırada vatandaşı olduğunuz devletin yasalarına göre kararlaştırılacaktır. Buna ek olarak, yukarıda bağlayıcı TAHKİM ve toplu dava FERAGATNAMESİNDE açıklanan tahkim anlaşmasının istisnalarına tabi olan veya başka bir şekilde tahkim edilemez olduğuna karar verilen herhangi bir iddiayı çözmek için siz ve biz Los Angeles County, California'daki eyalet veya federal mahkemelerin münhasır yargı yetkisine ve yerine geri dönülmez bir şekilde rıza gösteririz.nB. Avrupa Birliği'nde ikamet edenler için Activision Blizzard International B.V. ile sözleşme yapıyorsunuz demektir. daha önce Beechavenue 131, 1119RB Schiphol-Rijk, Hollanda'dan Cooperatie Activision Blizzard International UA olarak bilinen ve İngiltere ve Galler yasaları, bu Anlaşmanın yorumlanmasını yönetir ve yasalar çatışması ilkelerine atıfta bulunmaksızın ihlal iddialarına uygulanır. Tüketiciyi koruma yasaları, haksız rekabet yasaları ve haksız fiille ilgili iddialar da dahil olmak üzere diğer tüm iddialar, Programı edindiğiniz ve kullandığınız Avrupa Birliği ülkesinin yasalarına (örneğin, Birleşik Krallık, Fransa Cumhuriyeti veya Federal Almanya Cumhuriyeti) tabi olacaktır. Buna ek olarak, yargı yetkisi ile ilgili olarak, Programı edindiğiniz ve kullandığınız ülkenin mahkemelerini (örneğin, Birleşik Krallık, Fransa Cumhuriyeti veya Federal Almanya Cumhuriyeti) veya alternatif olarak İngiltere ve Galler mahkemelerini veya diğer mahkemeleri seçebilirsiniz. brüksel Yönetmeliği EC 44/2001. NC. Avustralya veya Japonya'da ikamet edenler için Activision Blizzard International B.V. ile sözleşme yapıyorsunuz demektir. daha önce Beechavenue 131, 1119RB Schiphol-Rijk, Hollanda'dan Cooperatie Activision Blizzard International UA olarak bilinen ve Avustralya yasaları, bu Anlaşmanın yorumlanmasını yönetir ve yasalar çatışması ilkelerine atıfta bulunmaksızın ihlal iddialarına uygulanır. Tüketiciyi koruma yasaları, haksız rekabet yasaları ve haksız fiille ilgili iddialar da dahil olmak üzere diğer tüm iddialar, Programı edindiğiniz ve kullandığınız ülkenin yasalarına (Avustralya veya Japonya olmak üzere) tabi olacaktır. Yürürlükteki yasaların izin verdiği ölçüde, Avustralya, Yeni Güney Galler mahkemelerinin yargı yetkisini kabul edersiniz. nD. Dünyanın geri kalanında ikamet edenler için, bu Programı yukarıdaki A, B ve C bölümlerinde listelenenler dışındaki ülkelerden satın aldıysanız ve kullanıyorsanız, bunu kendi inisiyatifinizle yaparsınız ve yerel yasalar geçerliyse ve geçerli olduğu ölçüde yerel yasalara uymaktan siz sorumlusunuz. yürürlükteki yasaların izin verdiği ölçüde, Programı kullanımınızdan kaynaklanan her türlü iddia, kayıp, yaralanma, hasar veya masraftan Activision'ı açıkça tazmin edin ve zararsız tutun. Activision tarafından Programın veya Programın yukarıdaki A, B ve C bölümlerinde listelenen ülkeler dışında herhangi bir kullanımının yürürlükteki herhangi bir yerel yasaya uygun olduğuna dair hiçbir garanti veya beyanda bulunulmaz. Ayrıca, Programı kullanımınız ve Programdan veya bu Sözleşmeden kaynaklanan veya bunlarla ilgili tüm talepler, yürürlükteki yasalar uyarınca izin verildiği ölçüde, yasalar çatışması ilkelerine atıfta bulunmaksızın İngiltere ve Galler yasalarına tabi olacak ve İngiltere ve Galler mahkemelerinin yargı yetkisine rıza göstereceksiniz.Amerika Birleşik Devletleri dışındaki herhangi bir kullanıcının Amerika Birleşik Devletleri içindeki yasal işlemlere başlama ve / veya katılma hakkı varsa, yürürlükteki yasaların izin verdiği en geniş ölçüde, daha sonra bu kullanıcı, yukarıdaki BAĞLAYICI TAHKİM VE TOPLU DAVADAN FERAGAT hükümlerine bağlı kalmayı kabul eder.\n \n18. ÇEŞİTLİ: Bu Sözleşme, taraflar arasındaki bu lisansla ilgili tam sözleşmedir ve aralarındaki önceki tüm sözleşmelerin ve beyanların yerini alır. Bu Sözleşmenin herhangi bir hükmünün uygulanamaz olduğuna karar verilirse, yürürlükteki hüküm, yalnızca uygulanabilir hâle getirmek için gerekli olduğu ölçüde yeniden düzenlenecek ve burada açıkça aksi belirtilmedikçe, bu Sözleşmenin geri kalan hükümleri etkilenmeyecektir.\n", + "PLATFORM_EULA_8": "19. EK KOŞULLAR- ALMANYA\n\naşağıdaki Bölümler, Almanya'da ikamet edenler için yukarıdaki ilgili Bölümlerin yerini alır ve bunların yerini alır:\n\nşartların Değiştirilmesi: Zaman zaman, Activision'ın bu Sözleşmeyi, örneğin yeni ürün veya hizmetleri yansıtmak veya bunlara dahil etmek, kullanıcıların veya kullanıcıların güvenliğini artırmak için değiştirmesi gerekebilir. yasadaki değişiklikler yüzünden. Activision bu Sözleşmede böyle bir değişiklik yaparsa, bu değişikliklerin yürürlüğe girmesinden en geç otuz (30) takvim günü önce belirli değişiklikleri size önceden bildiririz ve bu değişiklikleri kabul etmiş sayılırsınız (i) bu değişikliklere itirazınızı otuz gün içinde bize bildirmediğiniz sürece (30) tarafımızdan bildirim alındığı andan itibaren takvim günleri veya (ii) değişiklikler yürürlüğe girdikten sonra Programı kullanırsanız. Bildirimde, itiraz hakkınız, geçerli bildirim süresi ve itiraz etmemenizin hukuki sonuçları hakkında sizi bilgilendireceğiz.\n\\ nBu Sözleşmenin en son sürümü her zaman web sitemizde mevcut olacaktır, bu nedenle Programı her kullandığınızda bu Sözleşmedeki güncellemeleri kontrol etmenizi öneririz. Sözleşmedeki değişiklikler tahakkuk eden haklarınızı etkilemeyecek, bu Sözleşme kapsamında sizinle aramızdaki sözleşme dengesini önemli ölçüde bozmayacak ve geriye dönük bir etkisi olmayacaktır.\n\nService Tarafından Sağlanan içerik: Yukarıdakilere ek olarak, Almanya'da ikamet edenler için aşağıdaki Cayma Hakkı geçerli olacaktır.Eğer bir tüketici iseniz (örn. ağırlıklı olarak ticareti, işi veya mesleği dışında olan amaçlar için yasal bir işleme giren gerçek bir kişi), bundan sonra belirtildiği şekilde cayma hakkınız olacaktır.\n\n Cayma hakkının kullanılmasına ilişkin bilgiler\n\n Cayma Hakkı\n\n Herhangi bir sebep göstermeksizin 14 takvim günü içinde herhangi bir Satın Alma Sözleşmesinden cayma hakkına sahipsiniz. Para çekme süresi, Satın Alma Sözleşmesinin imzalandığı günden itibaren 14 takvim gününden sonra sona erecektir. Cayma hakkını kullanmak için bizi bilgilendirmelisiniz (Beechavenue 131, 1119RB Schiphol-Rijk, Hollanda'dan Activision Blizzard International B.V. iletişim bilgileri şu adresten edinilebilir www.support.activision.com - -#include "interface.hpp" - -namespace gsc -{ - std::unique_ptr compiler() - { - auto compiler = std::make_unique(); - compiler->mode(xsk::gsc::build::prod); - return compiler; - } - - std::unique_ptr decompiler() - { - return std::make_unique(); - } - - std::unique_ptr assembler() - { - return std::make_unique(); - } - - std::unique_ptr disassembler() - { - return std::make_unique(); - } -} diff --git a/deps/extra/gsc-tool/interface.hpp b/deps/extra/gsc-tool/interface.hpp deleted file mode 100644 index 133e6ae2..00000000 --- a/deps/extra/gsc-tool/interface.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace gsc -{ - std::unique_ptr compiler(); - std::unique_ptr decompiler(); - std::unique_ptr assembler(); - std::unique_ptr disassembler(); -} diff --git a/deps/gsc-tool b/deps/gsc-tool new file mode 160000 index 00000000..8b03229a --- /dev/null +++ b/deps/gsc-tool @@ -0,0 +1 @@ +Subproject commit 8b03229a190b85a3073ef9c36b0a70ee147c8935 diff --git a/deps/gsc-tool-h2 b/deps/gsc-tool-h2 deleted file mode 160000 index c86b0b53..00000000 --- a/deps/gsc-tool-h2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c86b0b53921e91a300359f0f4da38e103641ef5a diff --git a/deps/json b/deps/json index b2306145..0457de21 160000 --- a/deps/json +++ b/deps/json @@ -1 +1 @@ -Subproject commit b2306145e1789368e6f261680e8dc007e91cc986 +Subproject commit 0457de21cffb298c22b629e538036bfeb96130b7 diff --git a/deps/libtomcrypt b/deps/libtomcrypt index 2a1b2846..7e863d21 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit 2a1b284677a51f587ab7cd9d97395e0c0c93a447 +Subproject commit 7e863d21429f94ed6a720e24499a12a3f852bb31 diff --git a/deps/libtommath b/deps/libtommath index 03de03de..8314bde5 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 03de03dee753442d4b23166982514639c4ccbc39 +Subproject commit 8314bde5e5c8e5d9331460130a9d1066e324f091 diff --git a/deps/lua b/deps/lua index cf08915d..e288c5a9 160000 --- a/deps/lua +++ b/deps/lua @@ -1 +1 @@ -Subproject commit cf08915d62e338c987b71c078b148490510e9fe7 +Subproject commit e288c5a91883793d14ed9e9d93464f6ee0b08915 diff --git a/deps/minhook b/deps/minhook index 49d03ad1..f5485b84 160000 --- a/deps/minhook +++ b/deps/minhook @@ -1 +1 @@ -Subproject commit 49d03ad118cf7f6768c79a8f187e14b8f2a07f94 +Subproject commit f5485b8454544c2f034c78f8f127c1d03dea3636 diff --git a/deps/premake/gsc-tool.lua b/deps/premake/gsc-tool.lua index 0c5367f4..eedc274a 100644 --- a/deps/premake/gsc-tool.lua +++ b/deps/premake/gsc-tool.lua @@ -1,68 +1,62 @@ gsc_tool = { - source = path.join(dependencies.basePath, "gsc-tool-h2/src") + source = path.join(dependencies.basePath, "gsc-tool"), } function gsc_tool.import() - links {"xsk-gsc-h2", "xsk-gsc-utils"} - gsc_tool.includes() + links { "xsk-gsc-h2", "xsk-gsc-utils" } + gsc_tool.includes() end function gsc_tool.includes() - includedirs { - path.join(gsc_tool.source, "utils"), - path.join(gsc_tool.source, "h2"), - path.join(dependencies.basePath, "extra/gsc-tool") -- https://github.com/GEEKiDoS/open-teknomw3/blob/master/deps/extra/gsc-tool - } + includedirs { + path.join(gsc_tool.source, "include"), + } end --- https://github.com/xensik/gsc-tool/blob/dev/premake5.lua#L95 function gsc_tool.project() - project "xsk-gsc-utils" - kind "StaticLib" - language "C++" + project "xsk-gsc-utils" + kind "StaticLib" + language "C++" - pchheader "stdafx.hpp" - pchsource(path.join(gsc_tool.source, "utils/stdafx.cpp")) + files { + path.join(gsc_tool.source, "include/xsk/utils/*.hpp"), + path.join(gsc_tool.source, "src/utils/*.cpp"), + } - files { - path.join(gsc_tool.source, "utils/**.h"), - path.join(gsc_tool.source, "utils/**.hpp"), - path.join(gsc_tool.source, "utils/**.cpp") - } + includedirs { + path.join(gsc_tool.source, "include"), + } - includedirs { - path.join(gsc_tool.source, "utils"), - gsc_tool.source - } + zlib.includes() - zlib.includes() + project "xsk-gsc-h2" + kind "StaticLib" + language "C++" - project "xsk-gsc-h2" - kind "StaticLib" - language "C++" + filter "action:vs*" + buildoptions "/Zc:__cplusplus" + filter {} - pchheader "stdafx.hpp" - pchsource(path.join(gsc_tool.source, "h2/stdafx.cpp")) + files { + path.join(gsc_tool.source, "include/xsk/stdinc.hpp"), - files { - path.join(gsc_tool.source, "h2/**.h"), - path.join(gsc_tool.source, "h2/**.hpp"), - path.join(gsc_tool.source, "h2/**.cpp"), - path.join(dependencies.basePath, "extra/gsc-tool/interface.cpp") - } + path.join(gsc_tool.source, "include/xsk/gsc/engine/h2.hpp"), + path.join(gsc_tool.source, "src/gsc/engine/h2.cpp"), - includedirs { - path.join(gsc_tool.source, "h2"), - gsc_tool.source, - path.join(dependencies.basePath, "extra/gsc-tool") - } + path.join(gsc_tool.source, "src/gsc/engine/h2_code.cpp"), + path.join(gsc_tool.source, "src/gsc/engine/h2_func.cpp"), + path.join(gsc_tool.source, "src/gsc/engine/h2_meth.cpp"), + path.join(gsc_tool.source, "src/gsc/engine/h2_token.cpp"), - -- https://github.com/xensik/gsc-tool/blob/dev/premake5.lua#L25 - -- adding these build options fixes a bunch of parser stuff - filter "action:vs*" - buildoptions "/bigobj" - buildoptions "/Zc:__cplusplus" - filter {} + path.join(gsc_tool.source, "src/gsc/*.cpp"), + + path.join(gsc_tool.source, "src/gsc/common/*.cpp"), + path.join(gsc_tool.source, "include/xsk/gsc/common/*.hpp"), + } + + includedirs { + path.join(gsc_tool.source, "include"), + } end -table.insert(dependencies, gsc_tool) +table.insert(dependencies, gsc_tool) \ No newline at end of file diff --git a/deps/rapidjson b/deps/rapidjson index 012be852..3f73edae 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit 012be8528783cdbf4b7a9e64f78bd8f056b97e24 +Subproject commit 3f73edae00aba5b0112a80b4d41e6f1ff7d92a3d diff --git a/deps/sol2 b/deps/sol2 index eab1430c..e8e122e9 160000 --- a/deps/sol2 +++ b/deps/sol2 @@ -1 +1 @@ -Subproject commit eab1430ccdbf61a0d61d11bf86b4975838dcfb9a +Subproject commit e8e122e9ce46f4f1c0b04003d8b703fe1b89755a diff --git a/deps/zlib b/deps/zlib index 04f42cec..3c13497a 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit 04f42ceca40f73e2978b50e93806c2a18c1281fc +Subproject commit 3c13497a61c192dd255c280e73b806ed27ba8a0a diff --git a/premake5.lua b/premake5.lua index 3b69b2c5..8e68c6f2 100644 --- a/premake5.lua +++ b/premake5.lua @@ -228,7 +228,7 @@ targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}" configurations {"Debug", "Release"} language "C++" -cppdialect "C++20" +cppdialect "C++latest" architecture "x86_64" platforms "x64" diff --git a/src/client/component/achievements.cpp b/src/client/component/achievements.cpp new file mode 100644 index 00000000..18e02de3 --- /dev/null +++ b/src/client/component/achievements.cpp @@ -0,0 +1,437 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "achievements.hpp" +#include "console.hpp" +#include "scheduler.hpp" +#include "command.hpp" + +#include "gsc/script_extension.hpp" + +#include "game/ui_scripting/execution.hpp" + +#include +#include +#include + +#define ACHIEVEMENT_FILE_VERSION 1 +#define ACHIEVEMENT_FILE_SIGNATURE 'AM2H' + +namespace achievements +{ + namespace + { + std::mutex file_mutex; + + std::array achievements = + { + achievement_t(ACHIEVEMENT_ALL_ACHIEVEMENTS, "ACHIEVEMENTS_COMPLETED", ACHIEVEMENT_RARITY_3), + achievement_t(ACHIEVEMENT_1, "BACK_IN_THE_SADDLE", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_2, "DANGER_CLOSE", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_3, "COLD_SHOULDER", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_4, "TAGEM_AND_BAGEM", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_5, "ROYAL_WITH_CHEESE", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_6, "SOAP_ON_A_ROPE", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_7, "DESPERATE_TIMES", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_8, "HOUSTON_WE_HAVE_A_PROBLEM", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_9, "THE_PAWN", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_10, "OUT_OF_THE_FRYING_PAN", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_11, "FOR_THE_RECORD", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_12, "THE_PRICE_OF_WAR", ACHIEVEMENT_RARITY_2), + achievement_t(ACHIEVEMENT_13, "FIRST_DAY_OF_SCHOOL", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_14, "BLACK_DIAMOND", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_15, "TURISTAS", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_16, "RED_DAWN", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_17, "PRISONER_627", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_18, "ENDS_JUSTIFY_THE_MEANS", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_19, "HOME_COMING", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_20, "QUEEN_TAKES_ROOK", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_21, "OFF_THE_GRID", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_22, "PIT_BOSS", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_23, "GHOST", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_24, "COLONEL_SANDERSON", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_25, "TEN_PLUS_FOOT_MOBILES", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_26, "UNNECESSARY_ROUGHNESS", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_27, "KNOCK_KNOCK", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_28, "SOME_LIKE_IT_HOT", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_29, "TWO_BIRDS_WITH_ONE_STONE", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_30, "THE_ROAD_LESS_TRAVELED", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_31, "LEAVE_NO_STONE_UNTURNED", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_32, "DRIVE_BY", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_33, "THE_HARDER_THEY_FALL", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_34, "ONE_MAN_ARMY", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_35, "LOOK_MA_TWO_HANDS", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_36, "NO_REST_FOR_THE_WARY", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_37, "THREESOME", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_38, "TARGET_CONFIRMED", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_39, "ANGEL_SAVIOR", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_40, "NIGHT_MUSEUM", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_41, "STUDENT_MASTER", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_42, "REAL_GUN_GAME", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_43, "PRECOGNITIVE_PARANOIA", ACHIEVEMENT_RARITY_0, true), + achievement_t(ACHIEVEMENT_44, "IMMORTAL", ACHIEVEMENT_RARITY_2), + achievement_t(ACHIEVEMENT_45, "SILENT_SKIES", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_46, "CLAYMORE", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_47, "BIRD_HUNTER", ACHIEVEMENT_RARITY_1), + achievement_t(ACHIEVEMENT_48, "HOT_POTATO", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_49, "CLOWN_IN_TRAINING", ACHIEVEMENT_RARITY_0, true), + achievement_t(ACHIEVEMENT_50, "HEADBANGER", ACHIEVEMENT_RARITY_0), + achievement_t(ACHIEVEMENT_51, "BRAINS", ACHIEVEMENT_RARITY_2), + achievement_t(ACHIEVEMENT_52, "RAMIREZ", ACHIEVEMENT_RARITY_2), + }; + + std::filesystem::path get_achievements_path() + { + return utils::properties::get_appdata_path() / "player/achievements.bin"; + } + + void write_achievements(achievement_file_t* data) + { + std::lock_guard _0(file_mutex); + + data->version = ACHIEVEMENT_FILE_VERSION; + data->signature = ACHIEVEMENT_FILE_SIGNATURE; + + const auto path = get_achievements_path(); + const auto str = std::string(reinterpret_cast(data), sizeof(achievement_file_t)); + utils::io::write_file(path.generic_string(), str, false); + } + + bool has_achievement(achievement_file_t* file, int id) + { + if (id >= ACHIEVEMENT_TOTAL_COUNT) + { + return false; + } + + return file->achievements[id]; + } + + std::optional get_achievement_id(const std::string& name) + { + for (auto i = 0; i < ACHIEVEMENT_TOTAL_COUNT; i++) + { + const auto achievement = &achievements[i]; + if (name == achievement->code) + { + return {achievement->id}; + } + } + + return {}; + } + + void notifiy_achievement_id(int id) + { + scheduler::once([=] + { + ui_scripting::notify("earned_achievement", {{"id", id}}); + }, scheduler::lui); + } + + bool should_get_platinum(achievement_file_t* file) + { + if (has_achievement(file, ACHIEVEMENT_ALL_ACHIEVEMENTS)) + { + return false; + } + + for (auto i = static_cast(ACHIEVEMENT_START); i < ACHIEVEMENT_ORIGINAL_COUNT; i++) + { + if (!file->achievements[i]) + { + return false; + } + } + + return true; + } + + void give_achievement_id_internal(achievement_file_t* file, int id) + { + achievements::get_achievements(file); + if (has_achievement(file, id)) + { + return; + } + + file->achievements[id] = true; + write_achievements(file); + notifiy_achievement_id(id); + } + + void give_achievement_id(achievement_file_t* file, int id) + { + give_achievement_id_internal(file, id); + if (should_get_platinum(file)) + { + give_achievement_id_internal(file, ACHIEVEMENT_ALL_ACHIEVEMENTS); + } + } + + void give_achievement(const std::string& name) + { + achievement_file_t file{}; + + const auto id = get_achievement_id(name); + if (!id.has_value()) + { + return; + } + + give_achievement_id(&file, id.value()); + } + + void scr_give_achievement_stub() + { + give_achievement(game::Scr_GetString(0)); + } + + void give_mission_achievements() + { + game::GamerProfileData data{}; + game::GamerProfile_GetDataByName(&data, 0, "missionhighestdifficulty", 0xFFFFFFFF); + + if (data.type != game::TYPE_STRING) + { + return; + } + + achievement_file_t file{}; + achievements::get_achievements(&file); + + const auto completed_mission = [&](const game::level_number level, const std::string& achievement) + { + const auto id = get_achievement_id(achievement); + if (!id.has_value()) + { + return; + } + + const auto id_value = id.value(); + const auto highest_difficulty = data.u.stringVal[level] - '0'; + if (highest_difficulty) + { + file.achievements[id_value] = true; + } + }; + + std::unordered_map> veteran_achievements; + + const auto add_veteran_achievement = [&](const game::level_number level, const std::string& achievement) + { + const auto id = get_achievement_id(achievement); + if (!id.has_value()) + { + return; + } + + const auto id_value = static_cast(id.value()); + veteran_achievements[id_value].push_back(level); + }; + + const auto give_veteran_achievements = [&]() + { + for (const auto& achievement : veteran_achievements) + { + auto has_veteran = true; + for (const auto& mission : achievement.second) + { + if (data.u.stringVal[mission] != '3') + { + has_veteran = false; + break; + } + } + + if (has_veteran) + { + file.achievements[achievement.first] = true; + } + } + }; + + const auto give_completed_campaign_achievement = [&](const std::string& achievement) + { + const auto id = get_achievement_id(achievement); + if (!id.has_value()) + { + return; + } + + const auto id_value = static_cast(id.value()); + for (auto i = 0; i < game::LEVEL_COUNT; i++) + { + if (data.u.stringVal[i] - '0' < 2) + { + return; + } + } + + file.achievements[id_value] = true; + }; + + completed_mission(game::LEVEL_TRAINER, "BACK_IN_THE_SADDLE"); + completed_mission(game::LEVEL_ROADKILL, "DANGER_CLOSE"); + completed_mission(game::LEVEL_CLIFFHANGER, "COLD_SHOULDER"); + completed_mission(game::LEVEL_FAVELA, "TAGEM_AND_BAGEM"); + completed_mission(game::LEVEL_INVASION, "ROYAL_WITH_CHEESE"); + completed_mission(game::LEVEL_GULAG, "SOAP_ON_A_ROPE"); + completed_mission(game::LEVEL_CONTINGENCY, "DESPERATE_TIMES"); + completed_mission(game::LEVEL_DC_WHITEHOUSE, "HOUSTON_WE_HAVE_A_PROBLEM"); + completed_mission(game::LEVEL_ESTATE, "THE_PAWN"); + completed_mission(game::LEVEL_BONEYARD, "OUT_OF_THE_FRYING_PAN"); + completed_mission(game::LEVEL_ENDING, "FOR_THE_RECORD"); + + add_veteran_achievement(game::LEVEL_TRAINER, "FIRST_DAY_OF_SCHOOL"); + add_veteran_achievement(game::LEVEL_ROADKILL, "FIRST_DAY_OF_SCHOOL"); + add_veteran_achievement(game::LEVEL_CLIFFHANGER, "BLACK_DIAMOND"); + add_veteran_achievement(game::LEVEL_FAVELA, "TURISTAS"); + add_veteran_achievement(game::LEVEL_INVASION, "RED_DAWN"); + add_veteran_achievement(game::LEVEL_FAVELA_ESCAPE, "TURISTAS"); + add_veteran_achievement(game::LEVEL_ARCADIA, "RED_DAWN"); + add_veteran_achievement(game::LEVEL_OILRIG, "PRISONER_627"); + add_veteran_achievement(game::LEVEL_GULAG, "PRISONER_627"); + add_veteran_achievement(game::LEVEL_DCBURNING, "HOME_COMING"); + add_veteran_achievement(game::LEVEL_CONTINGENCY, "ENDS_JUSTIFY_THE_MEANS"); + add_veteran_achievement(game::LEVEL_DCEMP, "HOME_COMING"); + add_veteran_achievement(game::LEVEL_DC_WHITEHOUSE, "HOME_COMING"); + add_veteran_achievement(game::LEVEL_ESTATE, "QUEEN_TAKES_ROOK"); + add_veteran_achievement(game::LEVEL_BONEYARD, "QUEEN_TAKES_ROOK"); + add_veteran_achievement(game::LEVEL_AF_CAVES, "OFF_THE_GRID"); + add_veteran_achievement(game::LEVEL_AF_CHASE, "OFF_THE_GRID"); + add_veteran_achievement(game::LEVEL_ENDING, "OFF_THE_GRID"); + + give_veteran_achievements(); + give_completed_campaign_achievement("THE_PRICE_OF_WAR"); + + write_achievements(&file); + } + } + + void get_achievements(achievement_file_t* file) + { + std::lock_guard _0(file_mutex); + const auto path = get_achievements_path().generic_string(); + + if (!utils::io::file_exists(path)) + { + return; + } + + const auto data = utils::io::read_file(path); + if (data.size() < sizeof(achievement_file_t)) + { + return; + } + + std::memcpy(file, data.data(), std::min(data.size(), sizeof(achievement_file_t))); + if (file->signature != ACHIEVEMENT_FILE_SIGNATURE) + { + std::memset(file, 0, sizeof(achievement_file_t)); + } + } + + int get_count() + { + return ACHIEVEMENT_TOTAL_COUNT; + } + + bool has_achievement(int id) + { + achievement_file_t file{}; + get_achievements(&file); + return has_achievement(&file, id); + } + + std::string get_name(int id) + { + return utils::string::va("ACHIEVEMENT_NAME_%i", id); + } + + std::string get_details(int id) + { + return utils::string::va("ACHIEVEMENT_DETAIL_%i", id); + } + + std::optional get_background(int id) + { + const std::string name = utils::string::va("achievement_bg_%i", id); + if (game::DB_XAssetExists(game::ASSET_TYPE_MATERIAL, name.data()) && + !game::DB_IsXAssetDefault(game::ASSET_TYPE_MATERIAL, name.data())) + { + return {name}; + } + + return {}; + } + + int get_rarity(int id) + { + if (id >= ACHIEVEMENT_TOTAL_COUNT) + { + return 0; + } + + return achievements[id].rarity; + } + + bool is_secret(int id) + { + if (id >= ACHIEVEMENT_TOTAL_COUNT) + { + return false; + } + + return achievements[id].secret; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + utils::hook::jump(0x1404B6240, scr_give_achievement_stub); + + scheduler::once(give_mission_achievements, scheduler::main); + + command::add("reset_achievements", [] + { + achievement_file_t file{}; + write_achievements(&file); + }); + + command::add("give_achievement", [](const command::params& params) + { + if (params.size() < 2) + { + return; + } + + const auto id = std::atoi(params.get(1)); + achievement_file_t file{}; + get_achievements(&file); + give_achievement_id_internal(&file, id); + }); + + gsc::add_function("achievementunlocked", []() + { + const auto name = game::Scr_GetString(0); + const auto id = get_achievement_id(name); + if (!id.has_value()) + { + game::Scr_AddInt(0); + return; + } + + achievement_file_t file{}; + get_achievements(&file); + game::Scr_AddInt(has_achievement(&file, id.value())); + }); + } + }; +} + +REGISTER_COMPONENT(achievements::component) diff --git a/src/client/component/achievements.hpp b/src/client/component/achievements.hpp new file mode 100644 index 00000000..c098655f --- /dev/null +++ b/src/client/component/achievements.hpp @@ -0,0 +1,98 @@ +#pragma once + +namespace achievements +{ + enum achievement_rarity + { + ACHIEVEMENT_RARITY_0, + ACHIEVEMENT_RARITY_1, + ACHIEVEMENT_RARITY_2, + ACHIEVEMENT_RARITY_3, + }; + + enum achievement_id + { + ACHIEVEMENT_ALL_ACHIEVEMENTS = 0, + ACHIEVEMENT_START = 1, + ACHIEVEMENT_1 = 1, + ACHIEVEMENT_2, + ACHIEVEMENT_3, + ACHIEVEMENT_4, + ACHIEVEMENT_5, + ACHIEVEMENT_6, + ACHIEVEMENT_7, + ACHIEVEMENT_8, + ACHIEVEMENT_9, + ACHIEVEMENT_10, + ACHIEVEMENT_11, + ACHIEVEMENT_12, + ACHIEVEMENT_13, + ACHIEVEMENT_14, + ACHIEVEMENT_15, + ACHIEVEMENT_16, + ACHIEVEMENT_17, + ACHIEVEMENT_18, + ACHIEVEMENT_19, + ACHIEVEMENT_20, + ACHIEVEMENT_21, + ACHIEVEMENT_22, + ACHIEVEMENT_23, + ACHIEVEMENT_24, + ACHIEVEMENT_25, + ACHIEVEMENT_26, + ACHIEVEMENT_27, + ACHIEVEMENT_28, + ACHIEVEMENT_29, + ACHIEVEMENT_30, + ACHIEVEMENT_31, + ACHIEVEMENT_32, + ACHIEVEMENT_33, + ACHIEVEMENT_34, + ACHIEVEMENT_35, + ACHIEVEMENT_36, + ACHIEVEMENT_37, + ACHIEVEMENT_38, + ACHIEVEMENT_39, + ACHIEVEMENT_40, + ACHIEVEMENT_41, + ACHIEVEMENT_42, + ACHIEVEMENT_43, + ACHIEVEMENT_44, + ACHIEVEMENT_45, + ACHIEVEMENT_46, + ACHIEVEMENT_47, + ACHIEVEMENT_48, + ACHIEVEMENT_49, + ACHIEVEMENT_50, + ACHIEVEMENT_ORIGINAL_COUNT = 51, + ACHIEVEMENT_51 = 51, + ACHIEVEMENT_52, + ACHIEVEMENT_TOTAL_COUNT, + }; + + struct achievement_t + { + achievement_id id; + std::string_view code; + achievement_rarity rarity; + bool secret{}; + }; + + struct achievement_file_t + { + std::uint32_t signature; + std::uint8_t version; + bool achievements[ACHIEVEMENT_TOTAL_COUNT]; + }; + + void get_achievements(achievement_file_t* file); + + int get_count(); + bool has_achievement(int id); + + std::string get_name(int id); + std::string get_details(int id); + std::optional get_background(int id); + int get_rarity(int id); + bool is_secret(int id); +} diff --git a/src/client/component/battle_net.cpp b/src/client/component/battle_net.cpp new file mode 100644 index 00000000..eee4c054 --- /dev/null +++ b/src/client/component/battle_net.cpp @@ -0,0 +1,33 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "console.hpp" + +#include +#include +#include + +namespace battle_net +{ + namespace + { + + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Disable battle net game service + utils::hook::set(0x140272F70, 0xC301B0); + + // Disable battle net popup + utils::hook::nop(0x1405F4496, 5); + } + }; +} + +REGISTER_COMPONENT(battle_net::component) diff --git a/src/client/component/camera.cpp b/src/client/component/camera.cpp new file mode 100644 index 00000000..88ef97ba --- /dev/null +++ b/src/client/component/camera.cpp @@ -0,0 +1,288 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" +#include "game/ui_scripting/execution.hpp" + +#include "command.hpp" +#include "console.hpp" +#include "camera.hpp" +#include "gui/gui.hpp" + +#include +#include + +namespace camera +{ + namespace + { + utils::hook::detour sub_140781090_hook; + + game::dvar_t* cl_free_move_scale = nullptr; + game::dvar_t** cg_paused = nullptr; + + using cb_type = std::optional>; + utils::concurrency::container callback; + + float angle_normalize(const float angle) + { + const auto value = ((angle * 0.0027777778f) - std::floorf(angle * 0.0027777778f)) * 360.f; + auto result = value - 360.f; + + if ((value - 360.f) < 0.f) + { + result = value; + } + + return result; + } + + void vec_cross(float* a1, float* a2, float* a3) + { + a3[0] = (a2[2] * a1[1]) - (a2[1] * a1[2]); + a3[1] = (a1[2] * a2[0]) - (a2[2] * a1[0]); + a3[2] = (a2[1] * a1[0]) - (a1[1] * a2[0]); + } + + float camera_origin[3]{}; + + auto using_camera_override = false; + auto using_camera_angles_override = false; + + float camera_origin_override[3]{}; + float camera_angles_override[3]{}; + + void paused_free_move() + { + if ((*cg_paused)->current.integer != 2) + { + return; + } + + constexpr auto local_client_num = 0; + const auto ps = game::CG_GetPredictedPlayerState(local_client_num); + const auto cmd_number = game::CL_GetCurrentCmdNumber(local_client_num); + + game::usercmd_s cmd{}; + if (!game::CL_GetUserCmd(local_client_num, cmd_number, &cmd)) + { + return; + } + + callback.access([](cb_type& cb) + { + if (cb.has_value()) + { + auto& fn = cb.value(); + fn(); + } + }); + + if (using_camera_angles_override) + { + game::cgs->refdefViewAngles[0] = camera_angles_override[0]; + game::cgs->refdefViewAngles[1] = camera_angles_override[1]; + game::cgs->refdefViewAngles[2] = camera_angles_override[2]; + } + else + { + game::cgs->refdefViewAngles[0] = angle_normalize((cmd.angles[0] * 0.000021457672f) + ps->delta_angles[0]); + game::cgs->refdefViewAngles[1] = angle_normalize((cmd.angles[1] * 0.000021457672f) + ps->delta_angles[1]); + game::cgs->refdefViewAngles[2] = 0; + } + + const auto game_time = game::CG_GetGameTime(local_client_num); + + static auto saved_game_time = 0; + static auto saved_ms = 0; + + if (saved_game_time != game_time) + { + saved_game_time = game_time; + saved_ms = game::Sys_Milliseconds(); + } + + const auto now = game::Sys_Milliseconds(); + const auto diff = now - saved_ms; + saved_ms = game::Sys_Milliseconds(); + + auto scale = 1.f; + if ((cmd.buttons & 0x6) != 0) + { + scale = 10.f; + } + + scale *= cl_free_move_scale->current.value; + + game::AnglesToAxis(game::cgs->refdefViewAngles, game::refdef->axis); + + float v1[3] = {0.f, 0.f, 1.f}; + float v2[3] = {game::refdef->axis[0][0], game::refdef->axis[0][1], game::refdef->axis[0][2]}; + float v3[3]{}; + + vec_cross(v1, v2, v3); + vec_cross(v3, v1, v2); + + if (cmd.forwardmove) + { + ps->origin[0] += scale * (game::refdef->axis[0][0] * (static_cast(cmd.forwardmove) * 0.2f) * (static_cast(diff) * 0.05f)); + ps->origin[1] += scale * (game::refdef->axis[0][1] * (static_cast(cmd.forwardmove) * 0.2f) * (static_cast(diff) * 0.05f)); + ps->origin[2] += scale * (game::refdef->axis[0][2] * (static_cast(cmd.forwardmove) * 0.2f) * (static_cast(diff) * 0.05f)); + } + + if (cmd.rightmove) + { + ps->origin[0] += scale * (v3[0] * (static_cast(-1 * cmd.rightmove) * 0.2f) * (static_cast(diff) * 0.05f)); + ps->origin[1] += scale * (v3[1] * (static_cast(-1 * cmd.rightmove) * 0.2f) * (static_cast(diff) * 0.05f)); + ps->origin[2] += scale * (v3[2] * (static_cast(-1 * cmd.rightmove) * 0.2f) * (static_cast(diff) * 0.05f)); + } + + if ((cmd.buttons & 0x1) != 0) + { + ps->origin[2] += scale * 10.f; + } + + if ((cmd.buttons & 0x800) != 0) + { + ps->origin[2] -= scale * 10.f; + } + + if (using_camera_override) + { + game::refdef->org[0] = camera_origin_override[0]; + game::refdef->org[1] = camera_origin_override[1]; + game::refdef->org[2] = camera_origin_override[2]; + } + else + { + game::refdef->org[0] = ps->origin[0]; + game::refdef->org[1] = ps->origin[1]; + game::refdef->org[2] = ps->origin[2] + ps->viewHeightCurrent; + } + + camera_origin[0] = game::refdef->org[0]; + camera_origin[1] = game::refdef->org[1]; + camera_origin[2] = game::refdef->org[2]; + } + + void set_viewpos_now_stub(void* a1) + { + paused_free_move(); + utils::hook::invoke(0x1403B07C0, a1); + } + + void sub_140781090_stub(void* a1, void* a2, float a3) + { + sub_140781090_hook.invoke(a1, a2, a3); + + if ((*cg_paused)->current.integer == 2) + { + const auto lod_origin = reinterpret_cast(0x14EEE0890); + lod_origin[0] = camera_origin[0]; + lod_origin[1] = camera_origin[1]; + lod_origin[2] = camera_origin[2]; + } + } + } + + void enable_free_move() + { + (*cg_paused)->current.integer = 2; + } + + void disable_free_move() + { + (*cg_paused)->current.integer = 0; + } + + bool is_free_move_enabled() + { + return *cg_paused && (*cg_paused)->current.integer == 2; + } + + void set_camera_position(const float x, const float y, const float z) + { + camera_origin_override[0] = x; + camera_origin_override[1] = y; + camera_origin_override[2] = z; + } + + void set_camera_angles(const float x, const float y, const float z) + { + camera_angles_override[0] = x; + camera_angles_override[1] = y; + camera_angles_override[2] = z; + } + + void set_using_origin_override(bool value) + { + using_camera_override = value; + } + + void set_using_angles_override(bool value) + { + using_camera_angles_override = value; + } + + ui_scripting::table get_camera_position() + { + ui_scripting::table res; + res["x"] = camera_origin[0]; + res["y"] = camera_origin[1]; + res["z"] = camera_origin[2]; + return res; + } + + void set_callback(const ui_scripting::script_value& callback_) + { + callback.access([=](cb_type& cb) + { + cb = [=]() + { + try + { + const auto state = *game::hks::lua_state; + const ui_scripting::table globals = state->globals.v.table; + const auto pcall = globals["pcall"]; + const auto results = pcall(callback_); + + if (!results[0].as()) + { + const auto error = results[1].as(); + console::error("Error executing camera callback: %s\n", error.data()); + } + } + catch (const std::exception& e) + { + console::error("Error executing camera callback: %s\n", e.what()); + } + }; + }); + } + + void clear_lua() + { + callback.access([=](cb_type& cb) + { + cb.reset(); + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + cl_free_move_scale = dvars::register_float("cl_freemoveScale", 1.f, 0.0001f, 100.f, + game::DVAR_FLAG_SAVED, "Scale how fast you move in cl_freemove mode"); + + cg_paused = reinterpret_cast(0x141E39FC0); + + utils::hook::call(0x1403ACB2D, set_viewpos_now_stub); + sub_140781090_hook.create(0x140781090, sub_140781090_stub); + } + }; +} + +REGISTER_COMPONENT(camera::component) diff --git a/src/client/component/camera.hpp b/src/client/component/camera.hpp new file mode 100644 index 00000000..6fc5fbaa --- /dev/null +++ b/src/client/component/camera.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "game/ui_scripting/execution.hpp" + +namespace camera +{ + void enable_free_move(); + void disable_free_move(); + bool is_free_move_enabled(); + + void set_camera_position(const float x, const float y, const float z); + void set_camera_angles(const float x, const float y, const float z); + + void set_using_origin_override(bool value); + void set_using_angles_override(bool value); + + ui_scripting::table get_camera_position(); + + void set_callback(const ui_scripting::script_value& callback); + + void clear_lua(); +} diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index e833d724..567c01b4 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -24,6 +24,8 @@ namespace command std::unordered_map> handlers; + bool game_initialized{}; + void main_handler() { params params = {}; @@ -147,6 +149,11 @@ namespace command void execute(std::string command, const bool sync) { + if (!game_initialized) + { + return; + } + command += "\n"; if (sync) @@ -159,6 +166,11 @@ namespace command } } + bool is_game_initialized() + { + return game_initialized; + } + class component final : public component_interface { public: @@ -166,6 +178,11 @@ namespace command { utils::hook::jump(0x1405A74F0, dvar_command_stub, true); + scheduler::once([] + { + game_initialized = true; + }, scheduler::main); + add("quit", game::Quit); add("startmap", [](const params& params) diff --git a/src/client/component/command.hpp b/src/client/component/command.hpp index b7a4e5db..51046eb0 100644 --- a/src/client/component/command.hpp +++ b/src/client/component/command.hpp @@ -25,4 +25,6 @@ namespace command void add(const char* name, const std::function& callback); void execute(std::string command, bool sync = false); + + bool is_game_initialized(); } diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 422927f5..512d85ac 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -26,7 +26,7 @@ namespace console struct { - bool kill; + std::atomic_bool kill; std::thread thread; HANDLE kill_event; char buffer[512]{}; @@ -288,6 +288,13 @@ namespace console update(); break; } + case VK_ESCAPE: + { + con.cursor = 0; + clear_output(); + strncpy_s(con.buffer, "", sizeof(con.buffer)); + break; + } default: { const auto c = record.Event.KeyEvent.uChar.AsciiChar; @@ -321,6 +328,25 @@ namespace console return dispatch_message(con_type_info, result); } + + BOOL WINAPI console_ctrl_handler(DWORD ctrl_type) + { + if (ctrl_type == CTRL_CLOSE_EVENT) + { + if (command::is_game_initialized()) + { + command::execute("quit"); + while (!con.kill) + { + std::this_thread::sleep_for(10ms); + } + + return TRUE; + } + } + + return FALSE; + } } void print(const int type, const char* fmt, ...) @@ -351,12 +377,16 @@ namespace console ShowWindow(GetConsoleWindow(), SW_SHOW); SetConsoleTitle("H2-Mod"); +#ifndef DEBUG + SetConsoleCtrlHandler(console_ctrl_handler, TRUE); +#endif + con.kill_event = CreateEvent(NULL, TRUE, FALSE, NULL); con.thread = utils::thread::create_named_thread("Console", []() { const auto handle = GetStdHandle(STD_INPUT_HANDLE); - HANDLE handles[2] = { handle, con.kill_event }; + HANDLE handles[2] = {handle, con.kill_event}; MSG msg{}; INPUT_RECORD record{}; diff --git a/src/client/component/database.cpp b/src/client/component/database.cpp index 5bcadb97..c92f7fa7 100644 --- a/src/client/component/database.cpp +++ b/src/client/component/database.cpp @@ -39,10 +39,6 @@ namespace database utils::memory::allocator handle_allocator; - using sound_file_t = std::unordered_map; - std::unordered_map sound_files = {}; - std::unordered_map sound_sizes = {}; - game::dvar_t* db_filesysImpl = nullptr; utils::hook::detour db_fs_initialize_hook; @@ -466,6 +462,31 @@ namespace database } sys_set_folder_hook.create(0x140623830, sys_set_folder_stub); + + command::add("extractFile", [](const command::params& params) + { + const std::string file = params.get(1); + const auto fs_inst = game::DB_FSInitialize(); + const auto handle = fs_inst->vftbl->OpenFile(fs_inst, game::SF_ZONE, file.data()); + const auto _0 = gsl::finally([&] + { + if (handle != nullptr) + { + fs_inst->vftbl->Close(fs_inst, handle); + } + }); + + if (handle == nullptr) + { + return; + } + + const auto size = fs_inst->vftbl->Size(fs_inst, handle); + std::string buffer; + buffer.resize(size); + fs_inst->vftbl->Read(fs_inst, handle, 0, size, buffer.data()); + utils::io::write_file("bnet/" + file, buffer); + }); } }; } diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index ca9a96a7..e1cf9af8 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -18,94 +18,116 @@ namespace discord { DiscordRichPresence discord_presence; - std::optional state{}; - std::optional details{}; + struct + { + std::optional state{}; + std::optional details{}; + } custom_strings; + + void update_discord_frontend() + { + custom_strings.state.reset(); + custom_strings.details.reset(); + + discord_presence.details = game::UI_SafeTranslateString("MENU_MAIN_MENU"); + discord_presence.state = ""; + + discord_presence.startTimestamp = 0; + + const auto background_index = static_cast(game::Sys_Milliseconds() / 300000) % 10; + const auto background_image = std::format("bg_{}", background_index); + discord_presence.largeImageKey = background_image.data(); + + Discord_UpdatePresence(&discord_presence); + } + + void update_discord_ingame() + { + static const auto mapname_dvar = game::Dvar_FindVar("mapname"); + static const auto museum_mode_dvar = game::Dvar_FindVar("ui_char_museum_mode"); + + auto mapname = mapname_dvar->current.string; + auto map_image = mapname; + const auto museum_mode = museum_mode_dvar->current.string; + + const char* base_mapname = nullptr; + if (game::Com_IsAddonMap(mapname, &base_mapname)) + { + map_image = base_mapname; + } + + if (museum_mode == "free"s) + { + map_image = "museum"; + mapname = "MUSEUM"; + } + + const auto key = std::format("PRESENCE_SP_{}", mapname); + if (game::DB_XAssetExists(game::ASSET_TYPE_LOCALIZE_ENTRY, key.data()) && + !game::DB_IsXAssetDefault(game::ASSET_TYPE_LOCALIZE_ENTRY, key.data())) + { + mapname = game::UI_SafeTranslateString(key.data()); + } + + discord_presence.largeImageKey = map_image; + + if (custom_strings.details.has_value()) + { + const auto& details_value = custom_strings.details.value(); + if (details_value.starts_with("@") && details_value.size() > 1) + { + const auto loc_string = details_value.substr(1); + const auto value = game::UI_SafeTranslateString(loc_string.data()); + discord_presence.details = value; + } + else + { + discord_presence.details = details_value.data(); + } + } + else + { + discord_presence.details = mapname; + } + + const auto state_str = custom_strings.state.value_or(""); + discord_presence.state = state_str.data(); + + if (discord_presence.startTimestamp == 0) + { + discord_presence.startTimestamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + + Discord_UpdatePresence(&discord_presence); + } void update_discord() { - static char details_buf[128] = {0}; - static char state_buf[128] = {0}; - static char image_key_buf[32] = {0}; - Discord_RunCallbacks(); if (!game::CL_IsCgameInitialized()) { - state.reset(); - details.reset(); - - discord_presence.details = game::UI_SafeTranslateString("MENU_MAIN_MENU"); - discord_presence.state = ""; - - discord_presence.startTimestamp = 0; - - const auto background_index = static_cast(game::Sys_Milliseconds() / 300000) % 10; - strcpy_s(image_key_buf, sizeof(image_key_buf), utils::string::va("bg_%i", background_index)); - discord_presence.largeImageKey = image_key_buf; + update_discord_frontend(); } else { - const char* base_mapname = nullptr; - auto* mapname = game::Dvar_FindVar("mapname")->current.string; - auto* map_image = game::Dvar_FindVar("mapname")->current.string; - auto* museum_mode = game::Dvar_FindVar("ui_char_museum_mode")->current.string; - - if (game::Com_IsAddonMap(mapname, &base_mapname)) - { - map_image = base_mapname; - } - - if (museum_mode == "free"s) - { - map_image = "museum"; - } - - const auto key = utils::string::va("PRESENCE_SP_%s", mapname); - if (game::DB_XAssetExists(game::ASSET_TYPE_LOCALIZE, key) && !game::DB_IsXAssetDefault(game::ASSET_TYPE_LOCALIZE, key)) - { - mapname = game::UI_SafeTranslateString(key); - } - - discord_presence.largeImageKey = map_image; - - if (details.has_value()) - { - const auto& details_ = details.value(); - if (details_.starts_with("@") && details_.size() > 1) - { - const auto value = game::UI_SafeTranslateString(details_.substr(1).data()); - discord_presence.details = value; - } - else - { - strcpy_s(details_buf, sizeof(details_buf), utils::string::va("%s", details_.data())); - discord_presence.details = details_buf; - } - } - else - { - discord_presence.details = mapname; - } - - if (state.has_value()) - { - strcpy_s(state_buf, sizeof(state_buf), state.value().data()); - discord_presence.state = state_buf; - } - else - { - discord_presence.state = ""; - } - - - if (!discord_presence.startTimestamp) - { - discord_presence.startTimestamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count(); - } + update_discord_ingame(); } + } - Discord_UpdatePresence(&discord_presence); + void ready(const DiscordUser* /*request*/) + { + DiscordRichPresence presence{}; + presence.instance = 1; + presence.state = ""; + + Discord_UpdatePresence(&presence); + } + + void errored(const int error_code, const char* message) + { + console::error("Discord: (%i) %s", error_code, message); } } @@ -114,59 +136,36 @@ namespace discord public: void post_unpack() override { - DiscordEventHandlers handlers; - ZeroMemory(&handlers, sizeof(handlers)); + DiscordEventHandlers handlers{}; handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = nullptr; - handlers.spectateGame = nullptr; - handlers.joinRequest = nullptr; Discord_Initialize("835690302583996416", &handlers, 1, nullptr); scheduler::loop(update_discord, scheduler::pipeline::async, 5s); - initialized_ = true; - command::add("setdiscordstate", [](const command::params& params) { - const std::string _state = params.join(1); + const std::string state = params.join(1); scheduler::once([=]() { - state = _state; + custom_strings.state.emplace(state); update_discord(); }, scheduler::pipeline::async); }); command::add("setdiscorddetails", [](const command::params& params) { - const std::string details_ = params.join(1); + const std::string details = params.join(1); scheduler::once([=]() { - details = details_; + custom_strings.details.emplace(details); update_discord(); }, scheduler::pipeline::async); }); } - private: - bool initialized_ = false; - - static void ready(const DiscordUser* /*request*/) - { - ZeroMemory(&discord_presence, sizeof(discord_presence)); - - discord_presence.instance = 1; - discord_presence.state = ""; - - Discord_UpdatePresence(&discord_presence); - } - - static void errored(const int error_code, const char* message) - { - console::error("Discord: (%i) %s", error_code, message); - } }; } diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp new file mode 100644 index 00000000..4fcac730 --- /dev/null +++ b/src/client/component/dvars.cpp @@ -0,0 +1,466 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "dvars.hpp" +#include "console.hpp" + +#include + +namespace dvars +{ + struct dvar_base + { + unsigned int flags{}; + }; + + struct dvar_bool : dvar_base + { + bool value{}; + }; + + struct dvar_float : dvar_base + { + float value{}; + float min{}; + float max{}; + }; + + struct dvar_vector2 : dvar_base + { + float x{}; + float y{}; + float min{}; + float max{}; + }; + + struct dvar_vector3 : dvar_base + { + + float x{}; + float y{}; + float z{}; + float min{}; + float max{}; + }; + + struct dvar_int : dvar_base + { + int value{}; + int min{}; + int max{}; + }; + + struct dvar_string : dvar_base + { + std::string value{}; + }; + + namespace + { + template + T* find_dvar(std::unordered_map& map, const std::string& name) + { + auto i = map.find(name); + if (i != map.end()) + { + return &i->second; + } + + return nullptr; + } + + template + T* find_dvar(std::unordered_map& map, const std::uint32_t hash) + { + for (auto i = map.begin(); i != map.end(); ++i) + { + if (game::generateHashValue(i->first.data()) == hash) + { + return &i->second; + } + } + + return nullptr; + } + + bool find_dvar(std::unordered_set& set, const std::string& name) + { + return set.find(name) != set.end(); + } + + + bool find_dvar(std::unordered_set& set, const std::uint32_t hash) + { + for (auto i = set.begin(); i != set.end(); ++i) + { + if (game::generateHashValue(i->data()) == hash) + { + return true; + } + } + + return false; + } + } + + namespace disable + { + static std::unordered_set set_bool_disables; + static std::unordered_set set_float_disables; + static std::unordered_set set_int_disables; + static std::unordered_set set_string_disables; + + void set_bool(const std::string& name) + { + set_bool_disables.emplace(name); + } + + void set_float(const std::string& name) + { + set_float_disables.emplace(name); + } + + void set_int(const std::string& name) + { + set_int_disables.emplace(name); + } + + void set_string(const std::string& name) + { + set_string_disables.emplace(name); + } + } + + namespace override + { + static std::unordered_map register_bool_overrides; + static std::unordered_map register_float_overrides; + static std::unordered_map register_int_overrides; + static std::unordered_map register_string_overrides; + static std::unordered_map register_vector2_overrides; + static std::unordered_map register_vector3_overrides; + + static std::unordered_map set_bool_overrides; + static std::unordered_map set_float_overrides; + static std::unordered_map set_int_overrides; + static std::unordered_map set_string_overrides; + static std::unordered_map set_from_string_overrides; + + void register_bool(const std::string& name, const bool value, const unsigned int flags) + { + dvar_bool values; + values.value = value; + values.flags = flags; + register_bool_overrides[name] = std::move(values); + } + + void register_float(const std::string& name, const float value, const float min, const float max, + const unsigned int flags) + { + dvar_float values; + values.value = value; + values.min = min; + values.max = max; + values.flags = flags; + register_float_overrides[name] = std::move(values); + } + + void register_int(const std::string& name, const int value, const int min, const int max, + const unsigned int flags) + { + dvar_int values; + values.value = value; + values.min = min; + values.max = max; + values.flags = flags; + register_int_overrides[name] = std::move(values); + } + + void register_string(const std::string& name, const std::string& value, + const unsigned int flags) + { + dvar_string values; + values.value = value; + values.flags = flags; + register_string_overrides[name] = std::move(values); + } + + void register_vec2(const std::string& name, float x, float y, float min, float max, + const unsigned int flags) + { + dvar_vector2 values; + values.x = x; + values.y = y; + values.min = min; + values.max = max; + values.flags = flags; + register_vector2_overrides[name] = std::move(values); + } + + void register_vec3(const std::string& name, float x, float y, float z, float min, + float max, const unsigned int flags) + { + dvar_vector3 values; + values.x = x; + values.y = y; + values.z = z; + values.min = min; + values.max = max; + values.flags = flags; + register_vector3_overrides[name] = std::move(values); + } + + void set_bool(const std::string& name, const bool value) + { + set_bool_overrides[name] = value; + } + + void set_float(const std::string& name, const float value) + { + set_float_overrides[name] = value; + } + + void set_int(const std::string& name, const int value) + { + set_int_overrides[name] = value; + } + + void set_string(const std::string& name, const std::string& value) + { + set_string_overrides[name] = value; + } + + void set_from_string(const std::string& name, const std::string& value) + { + set_from_string_overrides[name] = value; + } + } + + utils::hook::detour dvar_register_bool_hook; + utils::hook::detour dvar_register_float_hook; + utils::hook::detour dvar_register_int_hook; + utils::hook::detour dvar_register_string_hook; + utils::hook::detour dvar_register_vector2_hook; + utils::hook::detour dvar_register_vector3_hook; + + utils::hook::detour dvar_set_bool_hook; + utils::hook::detour dvar_set_float_hook; + utils::hook::detour dvar_set_int_hook; + utils::hook::detour dvar_set_string_hook; + utils::hook::detour dvar_set_from_string_hook; + + game::dvar_t* dvar_register_bool(const int hash, const char* name, bool value, unsigned int flags) + { + auto* var = find_dvar(override::register_bool_overrides, hash); + if (var) + { + value = var->value; + flags = var->flags; + } + + return dvar_register_bool_hook.invoke(hash, name, value, flags); + } + + game::dvar_t* dvar_register_float(const int hash, const char* name, float value, float min, float max, unsigned int flags) + { + auto* var = find_dvar(override::register_float_overrides, hash); + if (var) + { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_float_hook.invoke(hash, name, value, min, max, flags); + } + + game::dvar_t* dvar_register_int(const int hash, const char* name, int value, int min, int max, unsigned int flags) + { + auto* var = find_dvar(override::register_int_overrides, hash); + if (var) + { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_int_hook.invoke(hash, name, value, min, max, flags); + } + + game::dvar_t* dvar_register_string(const int hash, const char* name, const char* value, unsigned int flags) + { + auto* var = find_dvar(override::register_string_overrides, hash); + + if (var) + { + value = var->value.data(); + flags = var->flags; + } + + return dvar_register_string_hook.invoke(hash, name, value, flags); + } + + game::dvar_t* dvar_register_vector2(const int hash, const char* name, float x, float y, float min, float max, + unsigned int flags) + { + auto* var = find_dvar(override::register_vector2_overrides, hash); + if (var) + { + x = var->x; + y = var->y; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_vector2_hook.invoke(hash, name, x, y, min, max, flags); + } + + game::dvar_t* dvar_register_vector3(const int hash, const char* name, float x, float y, float z, float min, + float max, unsigned int flags) + { + auto* var = find_dvar(override::register_vector3_overrides, hash); + if (var) + { + x = var->x; + y = var->y; + z = var->z; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_vector3_hook.invoke(hash, name, x, y, z, min, max, flags); + } + + void dvar_set_bool(game::dvar_t* dvar, bool boolean) + { + const auto disabled = find_dvar(disable::set_bool_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_bool_overrides, dvar->hash); + if (var) + { + boolean = *var; + } + + return dvar_set_bool_hook.invoke(dvar, boolean); + } + + void dvar_set_float(game::dvar_t* dvar, float fl) + { + const auto disabled = find_dvar(disable::set_float_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_float_overrides, dvar->hash); + if (var) + { + fl = *var; + } + + return dvar_set_float_hook.invoke(dvar, fl); + } + + void dvar_set_int(game::dvar_t* dvar, int integer) + { + const auto disabled = find_dvar(disable::set_int_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_int_overrides, dvar->hash); + if (var) + { + integer = *var; + } + + return dvar_set_int_hook.invoke(dvar, integer); + } + + void dvar_set_string(game::dvar_t* dvar, const char* string) + { + const auto disabled = find_dvar(disable::set_string_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_string_overrides, dvar->hash); + if (var) + { + string = var->data(); + } + + return dvar_set_string_hook.invoke(dvar, string); + } + + void dvar_set_from_string(game::dvar_t* dvar, const char* string, game::DvarSetSource source) + { + const auto disabled = find_dvar(disable::set_string_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_from_string_overrides, dvar->hash); + if (var) + { + string = var->data(); + } + + return dvar_set_from_string_hook.invoke(dvar, string, source); + } + + class component final : public component_interface + { + public: + void post_start() override + { + try + { + const auto list_json = utils::nt::load_resource(DVAR_LIST); + const auto list = nlohmann::json::parse(list_json); + for (const auto& [_0, dvar_info] : list.items()) + { + const auto name = dvar_info[0].get(); + const auto description = dvar_info[1].get(); + dvars::insert_dvar_info(name, description); + } + } + catch (const std::exception& e) + { + console::error("Failed to parse dvar list: %s\n", e.what()); + } + } + + void post_unpack() override + { + dvar_register_bool_hook.create(0x140617BB0, &dvar_register_bool); + dvar_register_float_hook.create(0x140617F80, &dvar_register_float); + dvar_register_int_hook.create(0x140618090, &dvar_register_int); + dvar_register_string_hook.create(0x140618170, &dvar_register_string); + dvar_register_vector2_hook.create(0x140618250, &dvar_register_vector2); + dvar_register_vector3_hook.create(0x140618390, &dvar_register_vector3); + + dvar_set_bool_hook.create(0x14061A310, &dvar_set_bool); + dvar_set_float_hook.create(0x14061A750, &dvar_set_float); + dvar_set_int_hook.create(0x14061A9D0, &dvar_set_int); + dvar_set_string_hook.create(0x14061ABE0, &dvar_set_string); + dvar_set_from_string_hook.create(0x14061A910, &dvar_set_from_string); + } + }; +} + +REGISTER_COMPONENT(dvars::component) diff --git a/src/client/component/dvars.hpp b/src/client/component/dvars.hpp new file mode 100644 index 00000000..66d6912d --- /dev/null +++ b/src/client/component/dvars.hpp @@ -0,0 +1,28 @@ +#pragma once + +namespace dvars +{ + namespace disable + { + void set_bool(const std::string& name); + void set_float(const std::string& name); + void set_int(const std::string& name); + void set_string(const std::string& name); + } + + namespace override + { + void register_bool(const std::string& name, bool value, const unsigned int flags); + void register_float(const std::string& name, float value, float min, float max, const unsigned int flags); + void register_int(const std::string& name, int value, int min, int max, const unsigned int flags); + void register_string(const std::string& name, const std::string& value, const unsigned int flags); + void register_vec2(const std::string& name, float x, float y, float min, float max, const unsigned int flags); + void register_vec3(const std::string& name, float x, float y, float z, float min, float max, const unsigned int flags); + + void set_bool(const std::string& name, bool boolean); + void set_float(const std::string& name, float fl); + void set_int(const std::string& name, int integer); + void set_string(const std::string& name, const std::string& string); + void set_from_string(const std::string& name, const std::string& value); + } +} diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index 0bb8c80c..1a3efde1 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -7,6 +7,7 @@ #include "console.hpp" #include "mods.hpp" #include "fonts.hpp" +#include "imagefiles.hpp" #include #include @@ -29,8 +30,9 @@ namespace fastfiles }; utils::hook::detour db_try_load_x_file_internal_hook; - utils::hook::detour db_find_xasset_header; + utils::hook::detour db_find_xasset_header_hook; utils::hook::detour load_xasset_header_hook; + utils::hook::detour db_unload_x_zones_hook; void db_try_load_x_file_internal(const char* zone_name, const int flags) { @@ -45,9 +47,20 @@ namespace fastfiles game::XAssetHeader db_find_xasset_header_stub(game::XAssetType type, const char* name, int allow_create_default) { const auto start = game::Sys_Milliseconds(); - const auto result = db_find_xasset_header.invoke(type, name, allow_create_default); + auto result = db_find_xasset_header_hook.invoke(type, name, allow_create_default); const auto diff = game::Sys_Milliseconds() - start; + if (type == game::ASSET_TYPE_RAWFILE && result.rawfile) + { + const std::string override_rawfile_name = "override/"s + name; + const auto override_rawfile = db_find_xasset_header_hook.invoke(type, override_rawfile_name.data(), 0); + if (override_rawfile.rawfile) + { + result.rawfile = override_rawfile.rawfile; + console::debug("using override asset for rawfile: \"%s\"\n", name); + } + } + if (db_print_default_assets->current.enabled && game::DB_IsXAssetDefault(type, name)) { console::warn("Waited %i msec for default asset \"%s\" of type \"%s\"\n", @@ -128,13 +141,21 @@ namespace fastfiles return true; } - void add_mod_zones(std::vector& zones, utils::memory::allocator& allocator) + void add_mod_zones(std::vector& zones, utils::memory::allocator& allocator, + const mods::zone_priority priority) { - try_add_zone(zones, allocator, "mod", true); + if (priority == mods::zone_priority::post_common) + { + if (mods::get_mod().has_value()) + { + try_add_zone(zones, allocator, "mod", true); + } + } + const auto mod_zones = mods::get_mod_zones(); for (const auto& zone : mod_zones) { - if (zone.alloc_flags & game::DB_ZONE_COMMON) + if ((zone.alloc_flags & game::DB_ZONE_COMMON) && zone.priority == priority) { try_add_zone(zones, allocator, zone.name, true); } @@ -153,12 +174,16 @@ namespace fastfiles void load_pre_gfx_zones(game::XZoneInfo* zone_info, unsigned int zone_count, game::DBSyncMode sync_mode) { + imagefiles::close_custom_handles(); + // code_pre_gfx utils::memory::allocator allocator; std::vector zones; + try_add_zone(zones, allocator, "h2_mod_pre_gfx", true); push_zones(zones, zone_info, zone_count); + add_mod_zones(zones, allocator, mods::zone_priority::pre_gfx); game::DB_LoadXAssets(zones.data(), static_cast(zones.size()), sync_mode); fonts::load_font_zones(); @@ -175,6 +200,8 @@ namespace fastfiles std::vector zones; try_add_zone(zones, allocator, "h2_mod_common", true); + add_mod_zones(zones, allocator, mods::zone_priority::post_gfx); + for (auto i = 0u; i < zone_count; i++) { zones.push_back(zone_info[i]); @@ -185,7 +212,7 @@ namespace fastfiles } } - add_mod_zones(zones, allocator); + add_mod_zones(zones, allocator, mods::zone_priority::post_common); game::DB_LoadXAssets(zones.data(), static_cast(zones.size()), sync_mode); } @@ -249,8 +276,6 @@ namespace fastfiles return reallocate_asset_pool(); } -#define RVA(ptr) static_cast(reinterpret_cast(ptr) - 0x140000000) - void reallocate_xmodel_pool() { // array used for DB_GetAllXAssetOfType, not big enough if many assets are added @@ -433,12 +458,12 @@ namespace fastfiles void reallocate_asset_pools() { reallocate_xmodel_pool(); - reallocate_asset_pool_multiplier(); - reallocate_asset_pool_multiplier(); + reallocate_asset_pool_multiplier(); reallocate_asset_pool_multiplier(); reallocate_asset_pool_multiplier(); reallocate_asset_pool_multiplier(); - reallocate_asset_pool_multiplier(); + reallocate_asset_pool_multiplier(); + reallocate_asset_pool_multiplier(); } void add_custom_level_load_zone(game::LevelLoad* load, const std::string& name, const size_t size_est) @@ -460,12 +485,12 @@ namespace fastfiles add_custom_level_load_zone(load, name, size_est); } - void add_mod_zones_to_load(game::LevelLoad* load) + void add_mod_zones_to_load(game::LevelLoad* load, const mods::zone_priority priority) { const auto mod_zones = mods::get_mod_zones(); for (const auto& zone : mod_zones) { - if (zone.alloc_flags & game::DB_ZONE_GAME) + if ((zone.alloc_flags & game::DB_ZONE_GAME) && zone.priority == priority) { add_custom_level_load_zone(load, zone.name.data(), 0x40000); } @@ -478,6 +503,7 @@ namespace fastfiles a.pushad64(); a.mov(rcx, rbx); + a.mov(rdx, mods::zone_priority::pre_map); a.call_aligned(add_mod_zones_to_load); a.popad64(); @@ -531,6 +557,8 @@ namespace fastfiles { add_custom_level_load_zone(load, name, size_est); } + + add_mod_zones_to_load(load, mods::zone_priority::post_map); } void db_load_xassets_stub(game::XZoneInfo* info, unsigned int zone_count, game::DBSyncMode sync_mode) @@ -561,6 +589,21 @@ namespace fastfiles load_xasset_header_hook.invoke(a1); } + + void db_unload_x_zones_stub(const unsigned short* unload_zones, + const unsigned int unload_count, const bool create_default) + { + for (auto i = 0u; i < unload_count; i++) + { + const auto zone_name = game::g_zones[unload_zones[i]].name; + if (zone_name[0] != '\0') + { + imagefiles::close_handle(zone_name); + } + } + + db_unload_x_zones_hook.invoke(unload_zones, unload_count, create_default); + } } bool exists(const std::string& zone) @@ -576,7 +619,6 @@ namespace fastfiles { db_fs->vftbl->Close(db_fs, handle); } - }); return handle != nullptr; @@ -591,6 +633,39 @@ namespace fastfiles }), &callback, includeOverride); } + void enum_asset_entries(const game::XAssetType type, const std::function& callback, bool include_override) + { + constexpr auto max_asset_count = 0x25D78; + auto hash = &game::db_hashTable[0]; + for (auto c = 0; c < max_asset_count; c++) + { + for (auto i = *hash; i; ) + { + const auto entry = &game::g_assetEntryPool[i]; + + if (entry->asset.type == type) + { + callback(entry); + + if (include_override && entry->nextOverride) + { + auto next_ovveride = entry->nextOverride; + while (next_ovveride) + { + const auto override = &game::g_assetEntryPool[next_ovveride]; + callback(override); + next_ovveride = override->nextOverride; + } + } + } + + i = entry->nextHash; + } + + ++hash; + } + } + std::string get_current_fastfile() { std::string fastfile_copy; @@ -633,7 +708,9 @@ namespace fastfiles false, game::DVAR_FLAG_NONE, "Print asset types being loaded"); db_try_load_x_file_internal_hook.create(0x1404173B0, db_try_load_x_file_internal); - db_find_xasset_header.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub); + db_find_xasset_header_hook.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub); + + db_unload_x_zones_hook.create(0x140417D80, db_unload_x_zones_stub); // Allow loading of mixed compressor types utils::hook::nop(0x1403E66A7, 2); diff --git a/src/client/component/fastfiles.hpp b/src/client/component/fastfiles.hpp index 227056d7..c9a4ac9d 100644 --- a/src/client/component/fastfiles.hpp +++ b/src/client/component/fastfiles.hpp @@ -6,6 +6,8 @@ namespace fastfiles { void enum_assets(const game::XAssetType type, const std::function& callback, const bool includeOverride); + void enum_asset_entries(const game::XAssetType type, const std::function& callback, bool include_override); + std::string get_current_fastfile(); bool exists(const std::string& zone); diff --git a/src/client/component/fonts.cpp b/src/client/component/fonts.cpp index c89fe3f7..218a1e51 100644 --- a/src/client/component/fonts.cpp +++ b/src/client/component/fonts.cpp @@ -23,7 +23,7 @@ namespace fonts { namespace { - const char* hudelem_fonts[] = + std::array hudelem_fonts { "", "bigfixed", @@ -45,26 +45,45 @@ namespace fonts game::Font_s* bank_font = nullptr; utils::hook::detour ui_get_font_handle_hook; + utils::hook::detour ui_get_font_handle2_hook; utils::hook::detour ui_asset_cache_hook; - game::Font_s* ui_get_font_handle_stub(void* a1, int font_index) + game::Font_s* get_font_handle_at_index(int font_index) { - if (font_index < 12 || bank_font == nullptr) - { - return ui_get_font_handle_hook.invoke(a1, font_index); - } - switch (font_index) { - case 12: - case 13: - case 14: + case game::HE_FONT_BANK: + case game::HE_FONT_BANKSHADOW: + case game::HE_FONT_BANKSHADOWMORE: return bank_font; } + return nullptr; + } + + game::Font_s* ui_get_font_handle_stub(void* a1, int font_index) + { + const auto res = get_font_handle_at_index(font_index); + if (res) + { + return res; + } + return ui_get_font_handle_hook.invoke(a1, font_index); } + game::Font_s* ui_get_font_handle2_stub(void* a1, size_t a2) + { + const auto font_index = *reinterpret_cast(a2 + 208); + const auto res = get_font_handle_at_index(font_index); + if (res) + { + return res; + } + + return ui_get_font_handle2_hook.invoke(a1, a2); + } + game::Font_s* get_bank_font() { if (language::is_asian()) @@ -87,9 +106,9 @@ namespace fonts { switch (hudelem_font_index) { - case 12: - case 13: - case 14: + case game::HE_FONT_BANK: + case game::HE_FONT_BANKSHADOW: + case game::HE_FONT_BANKSHADOWMORE: return hudelem_font_index; } @@ -117,11 +136,11 @@ namespace fonts { switch (font_index) { - case 12: + case game::HE_FONT_BANK: return 0; // none - case 13: + case game::HE_FONT_BANKSHADOW: return 2; // shadowed - case 14: + case game::HE_FONT_BANKSHADOWMORE: return 4; // shadowed more } @@ -172,7 +191,7 @@ namespace fonts } const auto lang = language::current(); - const std::string lang_name = game::languages[lang].name; + const std::string lang_name = language::languages[lang].name; for (auto row = 0; row < table->rowCount; row++) { if (table->columnCount < 3) @@ -212,10 +231,11 @@ namespace fonts // add custom fonts to hud elem fonts ui_asset_cache_hook.create(0x140606090, ui_asset_cache_stub); ui_get_font_handle_hook.create(0x1406058F0, ui_get_font_handle_stub); + ui_get_font_handle2_hook.create(0x1405F9820, ui_get_font_handle2_stub); // change hudelem font array - utils::hook::inject(0x1404C17A6, hudelem_fonts); - utils::hook::set(0x1404C17B7, static_cast(ARRAYSIZE(hudelem_fonts))); + utils::hook::inject(0x1404C17A6, hudelem_fonts.data()); + utils::hook::set(0x1404C17B7, static_cast(hudelem_fonts.size())); // handle custom fonts utils::hook::jump(0x14037B390, utils::hook::assemble(get_hud_elem_info_stub), true); @@ -230,7 +250,7 @@ namespace fonts } const auto name = params.get(1); - const auto ttf = game::DB_FindXAssetHeader(game::XAssetType::ASSET_TYPE_TTF, name, false).ttf; + const auto ttf = game::DB_FindXAssetHeader(game::XAssetType::ASSET_TYPE_TTF, name, false).ttfDef; if (ttf == nullptr) { console::error("Font does not exist\n"); @@ -238,7 +258,7 @@ namespace fonts } const auto path = utils::string::va("dumps/%s", ttf->name); - utils::io::write_file(path, std::string(ttf->buffer, ttf->len), false); + utils::io::write_file(path, std::string(ttf->file, ttf->fileLen), false); console::info("Dumped to %s", path); }); } diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index 0f08d293..91887f10 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -11,27 +11,29 @@ #include #define fps_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25) -#define speed_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 50) +#define speed_font game::R_RegisterFont("fonts/bank.ttf", 70) #define material_white game::Material_RegisterHandle("white") namespace fps { namespace { - game::dvar_t* cg_drawFps; - game::dvar_t* cg_drawSpeed; + game::dvar_t* cg_draw_fps = nullptr; + game::dvar_t* cg_draw_speed = nullptr; - game::dvar_t* cg_speedGraph; - game::dvar_t* cg_speedGraphColor; - game::dvar_t* cg_speedGraphFontColor; - game::dvar_t* cg_speedGraphBackgroundColor; - game::dvar_t* cg_speedGraphX; - game::dvar_t* cg_speedGraphY; - game::dvar_t* cg_speedGraphWidth; - game::dvar_t* cg_speedGraphHeight; - game::dvar_t* cg_speedGraphIncludeZAxis; + game::dvar_t* cg_speed_graph = nullptr; + game::dvar_t* cg_speed_graph_color = nullptr; + game::dvar_t* cg_speed_graph_font_color = nullptr; + game::dvar_t* cg_speed_graph_background_color = nullptr; + game::dvar_t* cg_speed_graph_x = nullptr; + game::dvar_t* cg_speed_graph_y = nullptr; + game::dvar_t* cg_speed_graph_width = nullptr; + game::dvar_t* cg_speed_graph_height = nullptr; + game::dvar_t* cg_speed_graph_include_zaxis = nullptr; - game::dvar_t* cg_drawGameTime; + game::dvar_t* cg_draw_game_time = nullptr; + + game::dvar_t* com_wait_end_frame_mode = nullptr; float fps_color_good[4] = {0.6f, 1.0f, 0.0f, 1.0f}; float fps_color_ok[4] = {1.0f, 0.7f, 0.3f, 1.0f}; @@ -46,7 +48,8 @@ namespace fps std::deque speed_history; - utils::hook::detour sub_7C55D0_hook; + utils::hook::detour sub_1407C55D0_hook; + utils::hook::detour com_frame_hook; struct cg_perf_data { @@ -114,7 +117,7 @@ namespace fps perf_calc_fps(&cg_perf, cg_perf.frame_ms); - sub_7C55D0_hook.invoke(); + sub_1407C55D0_hook.invoke(); } void check_resize() @@ -131,38 +134,42 @@ namespace fps void draw_line(float x, float y, float width, float height) { game::R_AddCmdDrawStretchPic(x, y, width, height, 0.0f, 0.0f, 0.0f, 0.0f, - cg_speedGraphColor->current.vector, material_white); + cg_speed_graph_color->current.vector, material_white); } std::chrono::high_resolution_clock::time_point last_speed_sample; void draw_speed() { - if (!cg_drawSpeed->current.enabled) + if (!cg_draw_speed->current.enabled) { return; } - const auto speed = static_cast(sqrt( - pow(game::g_clients[0].velocity[0], 2) + - pow(game::g_clients[0].velocity[1], 2) + - pow(game::g_clients[0].velocity[2], 2) + static auto prev_speed = 0.f; + + const auto ps = game::CG_GetPredictedPlayerState(0); + const auto speed = static_cast(std::sqrt( + std::pow(ps->velocity[0], 2) + + std::pow(ps->velocity[1], 2) )); const auto font = speed_font; - const auto speed_string = utils::string::va("%i\n", static_cast(speed)); + const auto speed_string = utils::string::va("%i", static_cast(speed)); const auto width = game::R_TextWidth(speed_string, 0x7FFFFFFF, font); const auto x = (screen_max[0] / 2) - (width / 2); - const auto y = screen_max[1] - 400.f; + const auto y = screen_max[1] - 300.f; - const auto color = speed >= 300.f + const auto color = speed >= prev_speed ? color_blue : fps_color_bad; + prev_speed = speed; + game::R_AddCmdDrawText(speed_string, 0x7FFFFFFF, font, x, - y, 1.0f, 1.0f, 0.0f, color, 0); + y, 1.0f, 1.0f, 0.0f, color, 4); } void draw_box(const float x, const float y, const float w, const float h, float* color) @@ -185,7 +192,7 @@ namespace fps void draw_speed_graph() { - if (!cg_speedGraph->current.enabled) + if (!cg_speed_graph->current.enabled) { return; } @@ -193,11 +200,11 @@ namespace fps const auto speed = static_cast(sqrt( pow(game::g_clients[0].velocity[0], 2) + pow(game::g_clients[0].velocity[1], 2) + - (cg_speedGraphIncludeZAxis->current.enabled ? pow(game::g_clients[0].velocity[2], 2) : 0) + (cg_speed_graph_include_zaxis->current.enabled ? pow(game::g_clients[0].velocity[2], 2) : 0) )); - const auto base_width = relative(cg_speedGraphWidth->current.integer); - const auto base_height = relative(cg_speedGraphHeight->current.integer); + const auto base_width = relative(cg_speed_graph_width->current.integer); + const auto base_height = relative(cg_speed_graph_height->current.integer); const auto max = static_cast(base_width); if (static_cast(speed_history.size()) > max) @@ -221,12 +228,12 @@ namespace fps } } - const auto base_x = relative(cg_speedGraphX->current.integer); - const auto base_y = screen_max[1] - relative(cg_speedGraphY->current.integer); + const auto base_x = relative(cg_speed_graph_x->current.integer); + const auto base_y = screen_max[1] - relative(cg_speed_graph_y->current.integer); const auto width = 1.f; draw_box(base_x, base_y - base_height - 4.f, base_width + 5.f, - base_height + 4.f, cg_speedGraphBackgroundColor->current.vector); + base_height + 4.f, cg_speed_graph_background_color->current.vector); const auto diff = max - static_cast(speed_history.size()); @@ -251,12 +258,12 @@ namespace fps const auto text_y = base_y - (base_height / 2.f) + (font_height / 2.f); game::R_AddCmdDrawText(speed_string, 0x7FFFFFFF, font, text_x, - text_y, 1.0f, 1.0f, 0.0f, cg_speedGraphFontColor->current.vector, 0); + text_y, 1.0f, 1.0f, 0.0f, cg_speed_graph_font_color->current.vector, 0); } void draw_fps() { - if (cg_drawFps->current.integer < 1) + if (cg_draw_fps->current.integer < 1) { return; } @@ -275,17 +282,16 @@ namespace fps void draw_pos() { - if (cg_drawFps->current.integer < 2) + if (cg_draw_fps->current.integer < 2) { return; } const auto font = fps_font; - const auto pos_string = utils::string::va("%f %f %f", - game::g_entities[0].origin[0], - game::g_entities[0].origin[1], - game::g_entities[0].origin[2]); + game::refdef->org[0], + game::refdef->org[1], + game::refdef->org[2]); const auto x = screen_max[0] - 15.f - game::R_TextWidth(pos_string, 0x7FFFFFFF, font); @@ -295,7 +301,7 @@ namespace fps void draw_game_time() { - if (!cg_drawGameTime->current.enabled) + if (!cg_draw_game_time->current.enabled) { return; } @@ -314,24 +320,24 @@ namespace fps const auto text = utils::string::va("%d:%02d.%02d", m, s, ms); const auto height = relative(24); - const auto base_width = relative(cg_speedGraphWidth->current.integer); - const auto base_height = cg_speedGraph->current.enabled ? relative(cg_speedGraphHeight->current.integer) : 0; + const auto base_width = relative(cg_speed_graph_width->current.integer); + const auto base_height = cg_speed_graph->current.enabled ? relative(cg_speed_graph_height->current.integer) : 0; - const auto base_x = relative(cg_speedGraphX->current.integer); - const auto base_y = screen_max[1] - relative(cg_speedGraphY->current.integer) - base_height - height - - (cg_speedGraph->current.enabled ? 2.f : 0.f); + const auto base_x = relative(cg_speed_graph_x->current.integer); + const auto base_y = screen_max[1] - relative(cg_speed_graph_y->current.integer) - base_height - height + - (cg_speed_graph->current.enabled ? 2.f : 0.f); const auto font_height = relative(20); const auto font = game::R_RegisterFont("fonts/default.otf", static_cast(font_height)); const auto text_width = game::R_TextWidth(text, 0x7FFFFFFF, font); draw_box(base_x, base_y, base_width + 5.f, - height, cg_speedGraphBackgroundColor->current.vector); + height, cg_speed_graph_background_color->current.vector); const auto text_y = base_y + (height / 2.f) + ((font_height + relative(5)) / 2.f); game::R_AddCmdDrawText(text, 0x7FFFFFFF, font, base_x + base_width - text_width, - text_y, 1.0f, 1.0f, 0.0f, cg_speedGraphFontColor->current.vector, 0); + text_y, 1.0f, 1.0f, 0.0f, cg_speed_graph_font_color->current.vector, 0); } void draw() @@ -354,6 +360,56 @@ namespace fps draw_speed_graph(); draw_game_time(); } + + void r_process_workers_with_timeout_stub(void* a1, void* a2) + { + if (com_wait_end_frame_mode->current.enabled) + { + return; + } + + utils::hook::invoke(0x140793DE0, a1, a2); + } + + void com_frame_stub() + { + const auto value = com_wait_end_frame_mode->current.integer; + if (value == 0) + { + return com_frame_hook.invoke(); + } + + const auto start = std::chrono::high_resolution_clock::now(); + com_frame_hook.invoke(); + + auto max_fps = (*dvars::com_max_fps)->current.integer; + if (max_fps == 0) + { + max_fps = 1000; + } + + constexpr auto nano_secs = std::chrono::duration_cast(1s); + const auto frame_time = nano_secs / max_fps; + + if (value == 1) + { + const auto diff = (std::chrono::high_resolution_clock::now() - start); + if (diff > frame_time) + { + return; + } + + const auto ms = std::chrono::duration_cast(frame_time - diff); + std::this_thread::sleep_for(ms); + } + else if (value == 2) + { + while (std::chrono::high_resolution_clock::now() - start < frame_time) + { + std::this_thread::sleep_for(0ms); + } + } + } } class component final : public component_interface @@ -363,30 +419,35 @@ namespace fps { scheduler::loop(draw, scheduler::pipeline::renderer); - sub_7C55D0_hook.create(0x1407C55D0, perf_update); + sub_1407C55D0_hook.create(0x1407C55D0, perf_update); - cg_drawSpeed = dvars::register_bool("cg_drawSpeed", 0, game::DVAR_FLAG_SAVED, "Draw speed"); - cg_drawFps = dvars::register_int("cg_drawFPS", 0, 0, 4, game::DVAR_FLAG_SAVED, "Draw fps"); + cg_draw_speed = dvars::register_bool("cg_drawSpeed", 0, game::DVAR_FLAG_SAVED, "Draw speed"); + cg_draw_fps = dvars::register_int("cg_drawFPS", 0, 0, 4, game::DVAR_FLAG_SAVED, "Draw fps"); - cg_speedGraph = dvars::register_bool("cg_speedGraph", 0, game::DVAR_FLAG_SAVED, "Enable speed graph"); + cg_speed_graph = dvars::register_bool("cg_speedGraph", 0, game::DVAR_FLAG_SAVED, "Enable speed graph"); - cg_speedGraphColor = dvars::register_vec4("cg_speedGraphColor", + cg_speed_graph_color = dvars::register_vec4("cg_speedGraphColor", 1.f, 0.f, 0.f, 1.0f, 0.f, 1.f, game::DVAR_FLAG_SAVED, "Speed graph color"); - cg_speedGraphFontColor = dvars::register_vec4("cg_speedGraphFontColor", + cg_speed_graph_font_color = dvars::register_vec4("cg_speedGraphFontColor", 1.f, 1.f, 1.f, 1.f, 0.f, 1.f, game::DVAR_FLAG_SAVED, "Speed graph font color"); - cg_speedGraphBackgroundColor = dvars::register_vec4("cg_speedGraphBackgroundColor", + cg_speed_graph_background_color = dvars::register_vec4("cg_speedGraphBackgroundColor", 0.f, 0.f, 0.f, 0.8f, 0.f, 1.f, game::DVAR_FLAG_SAVED, "Speed graph background color"); - cg_speedGraphX = dvars::register_int("cg_speedGraphX", 15, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph x position"); - cg_speedGraphY = dvars::register_int("cg_speedGraphY", 15, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph y position"); + cg_speed_graph_x = dvars::register_int("cg_speedGraphX", 15, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph x position"); + cg_speed_graph_y = dvars::register_int("cg_speedGraphY", 15, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph y position"); - cg_speedGraphWidth = dvars::register_int("cg_speedGraphWidth", 200, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph width"); - cg_speedGraphHeight = dvars::register_int("cg_speedGraphHeight", 80, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph height"); + cg_speed_graph_width = dvars::register_int("cg_speedGraphWidth", 200, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph width"); + cg_speed_graph_height = dvars::register_int("cg_speedGraphHeight", 80, 0, 1000, game::DVAR_FLAG_SAVED, "Speed graph height"); - cg_speedGraphIncludeZAxis = dvars::register_bool("cg_speedGraphIncludeZAxis", false, game::DVAR_FLAG_SAVED, + cg_speed_graph_include_zaxis = dvars::register_bool("cg_speedGraphIncludeZAxis", false, game::DVAR_FLAG_SAVED, "Include velocity on the z axis when calculating the speed"); - cg_drawGameTime = dvars::register_bool("cg_drawGameTime", false, game::DVAR_FLAG_SAVED, "Draw game time"); + cg_draw_game_time = dvars::register_bool("cg_drawGameTime", false, game::DVAR_FLAG_SAVED, "Draw game time"); + + // Make fps capping accurate + com_wait_end_frame_mode = dvars::register_int("com_waitEndFrameMode", 0, 0, 2, game::DVAR_FLAG_SAVED, "Wait end frame mode (0 = default, 1 = sleep(n), 2 = loop sleep(0)"); + utils::hook::call(0x1405A38B9, r_process_workers_with_timeout_stub); + com_frame_hook.create(0x1405A3740, com_frame_stub); } }; } diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index a3bf435d..22608fd3 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -82,7 +82,7 @@ namespace game_console con.display_line_offset++; } - output.push_back(data); + output.emplace_back(data); if (output.size() > 512) { output.pop_front(); @@ -239,7 +239,15 @@ namespace game_console else if (matches.size() == 1) { auto* const dvar = game::Dvar_FindVar(matches[0].name.data()); - const auto line_count = dvar ? 3 : 1; + auto line_count = dvar ? 3 : 1; + + for (const auto& c : matches[0].description) + { + if (c == '\n') + { + ++line_count; + } + } const auto height = draw_hint_box(line_count, dvars::con_inputHintBoxColor->current.vector); draw_hint_text(0, matches[0].name.data(), dvar @@ -290,11 +298,12 @@ namespace game_console { const auto value = game::Dvar_ValueToString(dvar, nullptr, &dvar->current); const auto truncated = utils::string::truncate(value, 34, "..."); + const auto truncated_desc = utils::string::truncate(matches[i].description, 160, "..."); draw_hint_text(static_cast(i), truncated.data(), dvars::con_inputDvarValueColor->current.vector, offset); - draw_hint_text(static_cast(i), matches[i].description.data(), + draw_hint_text(static_cast(i), truncated_desc.data(), dvars::con_inputDvarValueColor->current.vector, offset * 1.5f); } } @@ -697,12 +706,12 @@ namespace game_console { input = utils::string::to_lower(input); - for (const auto& dvar : dvars::dvar_list) + for (const auto& [hash, dvar] : dvars::dvar_map) { auto name = utils::string::to_lower(dvar.name); if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) { - suggestions.push_back(dvar); + suggestions.emplace_back(dvar); } if (exact && suggestions.size() > 1) @@ -713,7 +722,7 @@ namespace game_console if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) { - suggestions.push_back({ input, "" }); + suggestions.emplace_back(input, ""); } game::cmd_function_s* cmd = (*game::cmd_functions); @@ -725,7 +734,7 @@ namespace game_console if (match_compare(input, name, exact)) { - suggestions.push_back({cmd->name, ""}); + suggestions.emplace_back(cmd->name, ""); } if (exact && suggestions.size() > 1) diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp new file mode 100644 index 00000000..6f696071 --- /dev/null +++ b/src/client/component/game_module.cpp @@ -0,0 +1,125 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "game_module.hpp" + +#include + +namespace game_module +{ + namespace + { + utils::hook::detour handle_a_hook; + utils::hook::detour handle_w_hook; + utils::hook::detour handle_ex_a_hook; + utils::hook::detour handle_ex_w_hook; + utils::hook::detour file_name_a_hook; + utils::hook::detour file_name_w_hook; + + HMODULE __stdcall get_module_handle_a(const LPCSTR module_name) + { + if (!module_name) + { + return get_game_module(); + } + + return handle_a_hook.invoke(module_name); + } + + HMODULE __stdcall get_module_handle_w(const LPWSTR module_name) + { + if (!module_name) + { + return get_game_module(); + } + + return handle_w_hook.invoke(module_name); + } + + BOOL __stdcall get_module_handle_ex_a(const DWORD flags, const LPCSTR module_name, HMODULE* hmodule) + { + if (!module_name) + { + *hmodule = get_game_module(); + return TRUE; + } + + return handle_ex_a_hook.invoke(flags, module_name, hmodule); + } + + BOOL __stdcall get_module_handle_ex_w(const DWORD flags, const LPCWSTR module_name, HMODULE* hmodule) + { + if (!module_name) + { + *hmodule = get_game_module(); + return TRUE; + } + + return handle_ex_w_hook.invoke(flags, module_name, hmodule); + } + + DWORD __stdcall get_module_file_name_a(HMODULE hmodule, const LPSTR filename, const DWORD size) + { + if (!hmodule || utils::nt::library(hmodule) == get_game_module()) + { + hmodule = get_host_module(); + } + + return file_name_a_hook.invoke(hmodule, filename, size); + } + + DWORD __stdcall get_module_file_name_w(HMODULE hmodule, const LPWSTR filename, const DWORD size) + { + if (!hmodule || utils::nt::library(hmodule) == get_game_module()) + { + hmodule = get_host_module(); + } + + return file_name_w_hook.invoke(hmodule, filename, size); + } + + void hook_module_resolving() + { + handle_a_hook.create(&GetModuleHandleA, &get_module_handle_a); + handle_w_hook.create(&GetModuleHandleW, &get_module_handle_w); + handle_ex_w_hook.create(&GetModuleHandleExA, &get_module_handle_ex_a); + handle_ex_w_hook.create(&GetModuleHandleExW, &get_module_handle_ex_w); + file_name_a_hook.create(&GetModuleFileNameA, &get_module_file_name_a); + file_name_w_hook.create(&GetModuleFileNameW, &get_module_file_name_w); + } + } + + utils::nt::library get_game_module() + { + static utils::nt::library game{HMODULE(BASE_ADDRESS)}; + return game; + } + + utils::nt::library get_host_module() + { + static utils::nt::library host{}; + return host; + } + + class component final : public component_interface + { + public: + void post_start() override + { + get_host_module(); + } + + void post_load() override + { +#ifdef INJECT_HOST_AS_LIB + hook_module_resolving(); +#else + assert(get_host_module() == get_game_module()); +#endif + } + }; +} + +REGISTER_COMPONENT(game_module::component) diff --git a/src/client/component/game_module.hpp b/src/client/component/game_module.hpp new file mode 100644 index 00000000..35a39f74 --- /dev/null +++ b/src/client/component/game_module.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace game_module +{ + utils::nt::library get_game_module(); + utils::nt::library get_host_module(); +} diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index 18728c4f..d2974045 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -13,6 +13,8 @@ namespace gameplay utils::hook::detour pm_player_trace_hook; utils::hook::detour pm_crashland_hook; + game::dvar_t* pm_snap_vector = nullptr; + void pm_player_trace_stub(game::pmove_t* pm, game::trace_t* results, const float* start, const float* end, const game::Bounds* bounds, int passEntityNum, int contentMask) { @@ -111,6 +113,51 @@ namespace gameplay a.bind(loc_140691518); a.jmp(0x140691518); } + + void sys_snap_vector(float* velocity) + { + if (!pm_snap_vector->current.enabled) + { + return; + } + + velocity[0] = std::floorf(velocity[0] + 0.5f); + velocity[1] = std::floorf(velocity[1] + 0.5f); + velocity[2] = std::floorf(velocity[2] + 0.5f); + } + + void add_snap_vector_call(utils::hook::assembler& a) + { + a.pushad64(); + a.mov(rcx, rsi); + a.call_aligned(sys_snap_vector); + a.popad64(); + } + + void pmove_single_stub1(utils::hook::assembler& a) + { + const auto loc_14068FEBD = a.newLabel(); + + a.comiss(xmm5, xmm4); + a.jbe(loc_14068FEBD); + a.mov(rax, 0x3F800000); + a.movq(xmm1, rax); + a.jmp(0x14068FE99); + + a.bind(loc_14068FEBD); + add_snap_vector_call(a); + a.jmp(0x14068FEBD); + } + + void pmove_single_stub2(utils::hook::assembler& a) + { + a.movss(dword_ptr(rsi, 8), xmm1); + a.movss(dword_ptr(rsi, 4), xmm0); + a.movss(dword_ptr(rsi), xmm6); + + add_snap_vector_call(a); + a.jmp(0x14068FEBD); + } } class component final : public component_interface @@ -154,6 +201,11 @@ namespace gameplay game::DVAR_FLAG_REPLICATED, "Game gravity in inches per second squared"); dvars::register_int("g_speed", 190, 0, 1000, game::DVAR_FLAG_REPLICATED, "Player speed"); + + pm_snap_vector = dvars::register_bool("pm_snapVector", false, game::DVAR_FLAG_REPLICATED, "Snap velocity vector (mp movement)"); + + utils::hook::jump(0x14068FE8C, utils::hook::assemble(pmove_single_stub1), true); + utils::hook::jump(0x14068FEAF, utils::hook::assemble(pmove_single_stub2), true); } }; } diff --git a/src/client/component/gsc.cpp b/src/client/component/gsc.cpp deleted file mode 100644 index 3f1234f3..00000000 --- a/src/client/component/gsc.cpp +++ /dev/null @@ -1,789 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "console.hpp" -#include "filesystem.hpp" -#include "scripting.hpp" -#include "gsc.hpp" -#include "scheduler.hpp" -#include "fastfiles.hpp" -#include "command.hpp" - -#include "game/scripting/execution.hpp" -#include "game/scripting/functions.hpp" -#include "game/scripting/lua/error.hpp" - -#include "notifies.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace gsc -{ - void* func_table[0x1000]{}; - - namespace - { - game::dvar_t* developer_script = nullptr; - - auto compiler = ::gsc::compiler(); - auto decompiler = ::gsc::decompiler(); - auto assembler = ::gsc::assembler(); - auto disassembler = ::gsc::disassembler(); - - std::unordered_map main_handles; - std::unordered_map init_handles; - - std::unordered_map functions; - std::optional gsc_error; - - utils::memory::allocator scriptfile_allocator; - std::unordered_map loaded_scripts; - - struct - { - char* buf = nullptr; - char* pos = nullptr; - unsigned int size = 0x1000000; - } script_memory; - - char* allocate_buffer(size_t size) - { - if (script_memory.buf == nullptr) - { - script_memory.buf = game::PMem_AllocFromSource_NoDebug(script_memory.size, 4, 1, game::PMEM_SOURCE_SCRIPT); - script_memory.pos = script_memory.buf; - } - - if (script_memory.pos + size > script_memory.buf + script_memory.size) - { - game::Com_Error(game::ERR_FATAL, "Out of custom script memory"); - } - - const auto pos = script_memory.pos; - script_memory.pos += size; - return pos; - } - - void free_script_memory() - { - game::PMem_PopFromSource_NoDebug(script_memory.buf, script_memory.size, 4, 1, game::PMEM_SOURCE_SCRIPT); - script_memory.buf = nullptr; - script_memory.pos = nullptr; - } - - void clear() - { - main_handles.clear(); - init_handles.clear(); - loaded_scripts.clear(); - scriptfile_allocator.clear(); - free_script_memory(); - } - - bool read_scriptfile(const std::string& name, std::string* data) - { - if (filesystem::read_file(name, data)) - { - return true; - } - - const auto name_str = name.data(); - if (game::DB_XAssetExists(game::ASSET_TYPE_RAWFILE, name_str) && - !game::DB_IsXAssetDefault(game::ASSET_TYPE_RAWFILE, name_str)) - { - const auto asset = game::DB_FindXAssetHeader(game::ASSET_TYPE_RAWFILE, name.data(), false); - const auto len = game::DB_GetRawFileLen(asset.rawfile); - data->resize(len); - game::DB_GetRawBuffer(asset.rawfile, data->data(), len); - if (len > 0) - { - data->pop_back(); - } - - return true; - } - - return false; - } - - game::ScriptFile* load_custom_script(const char* file_name, const std::string& real_name) - { - if (loaded_scripts.find(real_name) != loaded_scripts.end()) - { - return loaded_scripts[real_name]; - } - - std::string source_buffer{}; - if (!read_scriptfile(real_name + ".gsc", &source_buffer)) - { - return nullptr; - } - - auto data = std::vector{source_buffer.begin(), source_buffer.end()}; - - try - { - compiler->compile(real_name, data); - } - catch (const std::exception& e) - { - - console::error("*********** script compile error *************\n"); - console::error("failed to compile '%s':\n%s", real_name.data(), e.what()); - console::error("**********************************************\n"); - return nullptr; - } - - auto assembly = compiler->output(); - - try - { - assembler->assemble(real_name, assembly); - } - catch (const std::exception& e) - { - console::error("*********** script compile error *************\n"); - console::error("failed to assemble '%s':\n%s", real_name.data(), e.what()); - console::error("**********************************************\n"); - return nullptr; - } - - const auto script_file_ptr = scriptfile_allocator.allocate(); - script_file_ptr->name = file_name; - - const auto stack = assembler->output_stack(); - script_file_ptr->len = static_cast(stack.size()); - - const auto script = assembler->output_script(); - script_file_ptr->bytecodeLen = static_cast(script.size()); - - script_file_ptr->buffer = scriptfile_allocator.allocate_array(stack.size() + 1); - std::memcpy(script_file_ptr->buffer, stack.data(), stack.size()); - - script_file_ptr->bytecode = allocate_buffer(script.size() + 1); - std::memcpy(script_file_ptr->bytecode, script.data(), script.size()); - - script_file_ptr->compressedLen = 0; - - loaded_scripts[real_name] = script_file_ptr; - - return script_file_ptr; - } - - void load_script(const std::string& name) - { - if (!game::Scr_LoadScript(name.data())) - { - return; - } - - const auto main_handle = game::Scr_GetFunctionHandle(name.data(), - xsk::gsc::h2::resolver::token_id("main")); - const auto init_handle = game::Scr_GetFunctionHandle(name.data(), - xsk::gsc::h2::resolver::token_id("init")); - - if (main_handle) - { - console::info("Loaded '%s::main'\n", name.data()); - main_handles[name] = main_handle; - } - - if (init_handle) - { - console::info("Loaded '%s::init'\n", name.data()); - init_handles[name] = init_handle; - } - } - - void load_scripts(const std::filesystem::path& root_dir, const std::string& subfolder) - { - std::filesystem::path script_dir = root_dir / subfolder; - if (!utils::io::directory_exists(script_dir.generic_string())) - { - return; - } - - const auto scripts = utils::io::list_files(script_dir.generic_string()); - for (const auto& script : scripts) - { - if (!script.ends_with(".gsc")) - { - continue; - } - - std::filesystem::path path(script); - const auto relative = path.lexically_relative(root_dir).generic_string(); - const auto base_name = relative.substr(0, relative.size() - 4); - - load_script(base_name); - } - } - - void load_gametype_script_stub(void* a1, void* a2) - { - utils::hook::invoke(0x1404E1400, a1, a2); - - fastfiles::enum_assets(game::ASSET_TYPE_RAWFILE, [](game::XAssetHeader header) - { - std::string name = header.rawfile->name; - - if (name.ends_with(".gsc") && name.starts_with("scripts/")) - { - const auto base_name = name.substr(0, name.size() - 4); - load_script(base_name); - } - }, true); - - const auto mapname = game::Dvar_FindVar("mapname"); - for (const auto& path : filesystem::get_search_paths()) - { - load_scripts(path, "scripts"); - load_scripts(path, "scripts/"s + mapname->current.string); - } - } - - void g_load_structs_stub() - { - for (auto& function_handle : main_handles) - { - console::info("Executing '%s::main'\n", function_handle.first.data()); - const auto thread = game::Scr_ExecThread(function_handle.second, 0); - game::RemoveRefToObject(thread); - } - - utils::hook::invoke(0x140510B40); - } - - void scr_load_level_stub() - { - utils::hook::invoke(0x1404FD130); - - for (auto& function_handle : init_handles) - { - console::info("Executing '%s::init'\n", function_handle.first.data()); - const auto thread = game::Scr_ExecThread(function_handle.second, 0); - game::RemoveRefToObject(thread); - } - } - - int db_is_xasset_default(int type, const char* name) - { - if (loaded_scripts.find(name) != loaded_scripts.end()) - { - return 0; - } - - return utils::hook::invoke(0x1404143C0, type, name); - } - - void db_get_raw_buffer_stub(const game::RawFile* rawfile, char* buf, const int size) - { - if (rawfile->len > 0 && rawfile->compressedLen == 0) - { - std::memset(buf, 0, size); - std::memcpy(buf, rawfile->buffer, std::min(rawfile->len, size)); - return; - } - - utils::hook::invoke(0x140413C40, rawfile, buf, size); - } - - std::optional> find_function(const char* pos) - { - for (const auto& file : scripting::script_function_table_sort) - { - for (auto i = file.second.begin(); i != file.second.end() && std::next(i) != file.second.end(); ++i) - { - const auto next = std::next(i); - if (pos >= i->second && pos < next->second) - { - return {std::make_pair(i->first, file.first)}; - } - } - } - - return {}; - } - - void print_callstack() - { - for (auto frame = game::scr_VmPub->function_frame; frame != game::scr_VmPub->function_frame_start; --frame) - { - const auto pos = frame == game::scr_VmPub->function_frame - ? game::scr_function_stack->pos - : frame->fs.pos; - const auto function = find_function(frame->fs.pos); - - if (function.has_value()) - { - console::warn("\tat function \"%s\" in file \"%s.gsc\"", - function.value().first.data(), function.value().second.data()); - } - else - { - console::warn("\tat unknown location %p", pos); - } - } - } - - std::optional get_opcode_name(const std::uint8_t opcode) - { - try - { - return {xsk::gsc::h2::resolver::opcode_name(opcode)}; - } - catch (...) - { - return {}; - } - } - - void builtin_call_error(const std::string& error) - { - const auto pos = game::scr_function_stack->pos; - const auto function_id = *reinterpret_cast( - reinterpret_cast(pos - 2)); - - if (function_id > 0x1000) - { - console::warn("in call to builtin method \"%s\"%s", - xsk::gsc::h2::resolver::method_name(function_id).data(), error.data()); - } - else - { - console::warn("in call to builtin function \"%s\"%s", - xsk::gsc::h2::resolver::function_name(function_id).data(), error.data()); - } - } - - bool force_error_print = false; - void* vm_error_stub(void* a1) - { - if (!developer_script->current.enabled && !force_error_print) - { - return utils::hook::invoke(0x140614670, a1); - } - - console::warn("*********** script runtime error *************\n"); - - const auto opcode_id = *reinterpret_cast(0x14BAA93E8); - const std::string error = gsc_error.has_value() - ? utils::string::va(": %s", gsc_error.value().data()) - : ""; - - if ((opcode_id >= 0x1A && opcode_id <= 0x20) || (opcode_id >= 0xA9 && opcode_id <= 0xAF)) - { - builtin_call_error(error); - } - else - { - const auto opcode = get_opcode_name(opcode_id); - if (opcode.has_value()) - { - console::warn("while processing instruction %s%s\n", - opcode.value().data(), error.data()); - } - else - { - console::warn("while processing instruction 0x%X%s\n", - opcode_id, error.data()); - } - } - - force_error_print = false; - gsc_error = {}; - - print_callstack(); - console::warn("**********************************************\n"); - return utils::hook::invoke(0x140614670, a1); - } - - std::string unknown_function_error{}; - void get_unknown_function_error(const char* code_pos) - { - const auto function = find_function(code_pos); - if (function.has_value()) - { - const auto& pos = function.value(); - unknown_function_error = utils::string::va( - "while processing function '%s' in script '%s':\nunknown script '%s'", - pos.first.data(), pos.second.data(), scripting::current_file.data() - ); - } - else - { - unknown_function_error = utils::string::va( - "unknown script '%s'", - scripting::current_file.data() - ); - } - } - - unsigned int current_filename{}; - std::string get_filename_name() - { - const auto filename_str = game::SL_ConvertToString( - static_cast(current_filename)); - const auto id = std::atoi(filename_str); - if (id == 0) - { - return filename_str; - } - - return scripting::get_token_single(id); - } - - - void get_unknown_function_error(unsigned int thread_name) - { - const auto filename = get_filename_name(); - const auto name = scripting::get_token_single(thread_name); - - unknown_function_error = utils::string::va( - "while processing script '%s':\nunknown function '%s::%s'", - scripting::current_file.data(), filename.data(), name.data() - ); - } - - void unknown_function_stub(const char* code_pos) - { - get_unknown_function_error(code_pos); - game::Com_Error(game::ERR_DROP, "script link error\n%s", - unknown_function_error.data()); - } - - unsigned int find_variable_stub(unsigned int parent_id, unsigned int thread_name) - { - const auto res = game::FindVariable(parent_id, thread_name); - if (!res) - { - get_unknown_function_error(thread_name); - game::Com_Error(game::ERR_DROP, "script link error\n%s", - unknown_function_error.data()); - } - return res; - } - - void register_gsc_functions_stub(void* a1, void* a2) - { - utils::hook::invoke(0x140509F20, a1, a2); - for (const auto& func : functions) - { - game::Scr_RegisterFunction(func.first, 0, func.second); - } - } - - scripting::script_value get_argument(int index) - { - if (index >= static_cast(game::scr_VmPub->outparamcount)) - { - return {}; - } - - return game::scr_VmPub->top[-index]; - } - - auto function_id_start = 0x320; - void add_function(const std::string& name, scripting::script_function function) - { - if (xsk::gsc::h2::resolver::find_function(name)) - { - const auto id = xsk::gsc::h2::resolver::function_id(name); - functions[function] = id; - } - else - { - const auto id = ++function_id_start; - xsk::gsc::h2::resolver::add_function(name, static_cast(id)); - functions[function] = id; - } - } - - void execute_custom_function(scripting::script_function function) - { - auto error = false; - - try - { - function({}); - } - catch (const std::exception& e) - { - error = true; - force_error_print = true; - gsc_error = e.what(); - } - - if (error) - { - game::Scr_ErrorInternal(); - } - } - - void vm_call_builtin_stub(scripting::script_function function) - { - auto custom = false; - { - custom = functions.find(function) != functions.end(); - } - - if (!custom) - { - function({}); - } - else - { - execute_custom_function(function); - } - } - - utils::hook::detour scr_emit_function_hook; - void scr_emit_function_stub(unsigned int filename, unsigned int thread_name, char* code_pos) - { - current_filename = filename; - scr_emit_function_hook.invoke(filename, thread_name, code_pos); - } - - std::string get_script_file_name(const std::string& name) - { - const auto id = xsk::gsc::h2::resolver::token_id(name); - if (id == 0) - { - return name; - } - - return std::to_string(id); - } - - std::vector decompile_scriptfile(const std::string& name, const std::string& real_name) - { - const auto* scriptfile = game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, name.data(), false).scriptfile; - if (scriptfile == nullptr) - { - throw std::runtime_error(std::format("couldn't load scriptfile '{}'", real_name)); - } - - console::info("Decompiling scriptfile '%s'\n", real_name.data()); - - std::vector stack{scriptfile->buffer, scriptfile->buffer + scriptfile->len}; - std::vector bytecode{scriptfile->bytecode, scriptfile->bytecode + scriptfile->bytecodeLen}; - - auto decompressed_stack = xsk::utils::zlib::decompress(stack, static_cast(stack.size())); - - disassembler->disassemble(name, bytecode, decompressed_stack); - auto output = disassembler->output(); - - decompiler->decompile(name, output); - - return decompiler->output(); - } - - void pmem_init_stub() - { - utils::hook::invoke(0x14061EC80); - - const auto type_0 = &game::g_scriptmem[0]; - const auto type_1 = &game::g_scriptmem[1]; - - const auto size_0 = 0x200000; // default size - const auto size_1 = 0x200000 + script_memory.size; - - const auto block = reinterpret_cast(VirtualAlloc(NULL, size_0 + size_1, MEM_RESERVE, PAGE_READWRITE)); - - type_0->buf = block; - type_0->size = size_0; - - type_1->buf = block + size_0; - type_1->size = size_1; - - utils::hook::set(0x14061EC72, size_0 + size_1); - } - } - - game::ScriptFile* find_script(game::XAssetType /*type*/, const char* name, int /*allow_create_default*/) - { - std::string real_name = name; - const auto id = static_cast(std::atoi(name)); - if (id) - { - real_name = xsk::gsc::h2::resolver::token_name(id); - } - - const auto script = load_custom_script(name, real_name); - if (script) - { - return script; - } - - return game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, name, 1).scriptfile; - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - developer_script = dvars::register_bool("developer_script", false, 0, "Print GSC errors"); - - // Allow custom scripts to include other custom scripts - xsk::gsc::h2::resolver::init([](const auto& include_name) - { - const auto real_name = include_name + ".gsc"; - - std::string file_buffer; - if (!read_scriptfile(real_name, &file_buffer) || file_buffer.empty()) - { - const auto name = get_script_file_name(include_name); - if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, name.data())) - { - return decompile_scriptfile(name, real_name); - } - else - { - throw std::runtime_error(std::format("couldn't load gsc file '{}'", real_name)); - } - } - - std::vector result; - result.assign(file_buffer.begin(), file_buffer.end()); - - return result; - }); - - utils::hook::call(0x1405C6177, find_script); - utils::hook::call(0x1405C6187, db_is_xasset_default); - - // Loads scripts with an uncompressed stack - utils::hook::call(0x1405C61E0, db_get_raw_buffer_stub); - - // load handles - utils::hook::call(0x1404E17B2, load_gametype_script_stub); - - // execute handles - utils::hook::call(0x1404C8F71, g_load_structs_stub); - utils::hook::call(0x1404C8F80, scr_load_level_stub); - - utils::hook::call(0x1405CB94F, vm_error_stub); - - utils::hook::call(0x1405BC583, unknown_function_stub); - utils::hook::call(0x1405BC5CF, unknown_function_stub); - utils::hook::call(0x1405BC6BA, find_variable_stub); - scr_emit_function_hook.create(0x1405BC5E0, scr_emit_function_stub); - - utils::hook::call(0x1405BCBAB, register_gsc_functions_stub); - utils::hook::set(0x1405BC7BC, 0x1000); // change builtin func count - -#define RVA(ptr) static_cast(reinterpret_cast(ptr) - 0x140000000) - utils::hook::set(0x1405BC7C2 + 4, RVA(&func_table)); - utils::hook::inject(0x1405BCB78 + 3, &func_table); - utils::hook::set(0x1405CA678 + 4, RVA(&func_table)); - - utils::hook::nop(0x1405CA683, 8); - utils::hook::call(0x1405CA683, vm_call_builtin_stub); - - // Increase script memory - utils::hook::call(0x1405A4798, pmem_init_stub); - - add_function("print", [](const game::scr_entref_t ref) - { - const auto num = game::Scr_GetNumParam(); - std::string buffer{}; - - for (auto i = 0; i < num; i++) - { - const auto str = game::Scr_GetString(i); - buffer.append(str); - buffer.append("\t"); - } - - printf("%s\n", buffer.data()); - }); - - add_function("assert", [](const game::scr_entref_t ref) - { - const auto expr = get_argument(0).as(); - if (!expr) - { - throw std::runtime_error("assert fail"); - } - }); - - add_function("assertex", [](const game::scr_entref_t ref) - { - const auto expr = get_argument(0).as(); - if (!expr) - { - const auto error = get_argument(1).as(); - throw std::runtime_error(error); - } - }); - - add_function("replacefunc", [](const game::scr_entref_t ref) - { - const auto what = get_argument(0).get_raw(); - const auto with = get_argument(1).get_raw(); - - if (what.type != game::SCRIPT_FUNCTION) - { - throw std::runtime_error("parameter 1 must be a function"); - } - - if (with.type != game::SCRIPT_FUNCTION) - { - throw std::runtime_error("parameter 2 must be a function"); - } - - notifies::set_gsc_hook(what.u.codePosValue, with.u.codePosValue); - }); - - add_function("getsoundlength", [](const game::scr_entref_t ref) - { - const auto name = get_argument(0); - if (!name.is()) - { - throw std::runtime_error("parameter 1 must be a string"); - } - - const auto name_str = name.as(); - const auto sound = game::DB_FindXAssetHeader(game::ASSET_TYPE_SOUND, name_str.data(), false).sound; - if (!sound || !sound->count || !sound->head->soundFile || sound->head->soundFile->type != game::SAT_STREAMED) - { - return game::Scr_AddInt(-1); - } - - return game::Scr_AddInt(sound->head->soundFile->u.streamSnd.totalMsec); - }); - - add_function("executecommand", [](const game::scr_entref_t ref) - { - const auto cmd = get_argument(0).as(); - command::execute(cmd); - }); - - scripting::on_shutdown([](bool free_scripts, bool post_shutdown) - { - if (free_scripts && post_shutdown) - { - xsk::gsc::h2::resolver::cleanup(); - clear(); - } - }); - } - }; -} - -REGISTER_COMPONENT(gsc::component) diff --git a/src/client/component/gsc.hpp b/src/client/component/gsc.hpp deleted file mode 100644 index 12277297..00000000 --- a/src/client/component/gsc.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace gsc -{ - extern void* func_table[0x1000]; - - game::ScriptFile* find_script(game::XAssetType /*type*/, const char* name, int /*allow_create_default*/); -} diff --git a/src/client/component/gsc/script_error.cpp b/src/client/component/gsc/script_error.cpp new file mode 100644 index 00000000..c31fe2cf --- /dev/null +++ b/src/client/component/gsc/script_error.cpp @@ -0,0 +1,349 @@ +#include +#include "loader/component_loader.hpp" +#include "game/game.hpp" + +#include "script_extension.hpp" +#include "script_error.hpp" + +#include "component/scripting.hpp" + +#include +#include + +namespace gsc +{ + std::array var_typename = + { + "undefined", + "object", + "string", + "localized string", + "vector", + "float", + "int", + "codepos", + "precodepos", + "function", + "builtin function", + "builtin method", + "stack", + "animation", + "pre animation", + "thread", + "thread", + "thread", + "thread", + "struct", + "removed entity", + "entity", + "array", + "removed thread", + "", + "thread list", + "endon list", + }; + + namespace + { + utils::hook::detour scr_emit_function_hook; + + unsigned int current_filename = 0; + + std::string unknown_function_error; + + void scr_emit_function_stub(unsigned int filename, unsigned int thread_name, char* code_pos) + { + current_filename = filename; + scr_emit_function_hook.invoke(filename, thread_name, code_pos); + } + + std::string get_filename_name() + { + const auto filename_str = game::SL_ConvertToString(static_cast(current_filename)); + const auto id = std::atoi(filename_str); + if (!id) + { + return filename_str; + } + + return scripting::get_token(id); + } + + void get_unknown_function_error(const char* code_pos) + { + const auto function = find_function(code_pos); + if (function.has_value()) + { + const auto& pos = function.value(); + unknown_function_error = std::format( + "while processing function '{}' in script '{}':\nunknown script '{}'", pos.function, pos.file, scripting::current_file + ); + } + else + { + unknown_function_error = std::format("unknown script '{}'", scripting::current_file); + } + } + + void get_unknown_function_error(unsigned int thread_name) + { + const auto filename = get_filename_name(); + const auto name = scripting::get_token(thread_name); + + unknown_function_error = std::format( + "while processing script '{}':\nunknown function '{}::{}'", scripting::current_file, filename, name + ); + } + + void compile_error_stub(const char* code_pos, [[maybe_unused]] const char* msg) + { + get_unknown_function_error(code_pos); + game::Com_Error(game::ERR_DROP, "script link error\n%s", unknown_function_error.data()); + } + + unsigned int find_variable_stub(unsigned int parent_id, unsigned int thread_name) + { + const auto res = game::FindVariable(parent_id, thread_name); + if (!res) + { + get_unknown_function_error(thread_name); + game::Com_Error(game::ERR_DROP, "script link error\n%s", unknown_function_error.data()); + } + + return res; + } + + unsigned int scr_get_object(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + auto* value = game::scr_VmPub->top - index; + if (value->type == game::VAR_POINTER) + { + return value->u.pointerValue; + } + + scr_error(false, "Type %s is not an object", var_typename[value->type]); + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0; + } + + unsigned int scr_get_const_string(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + auto* value = game::scr_VmPub->top - index; + if (game::Scr_CastString(value)) + { + assert(value->type == game::VAR_STRING); + return value->u.stringValue; + } + + game::Scr_ErrorInternal(); + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0; + } + + unsigned int scr_get_const_istring(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + auto* value = game::scr_VmPub->top - index; + if (value->type == game::VAR_ISTRING) + { + return value->u.stringValue; + } + + scr_error(false, "type %s is not a localized string", var_typename[value->type]); + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0; + } + + void scr_validate_localized_string_ref(int parm_index, const char* token, int token_len) + { + assert(token); + assert(token_len >= 0); + + if (token_len < 2) + { + return; + } + + for (auto char_iter = 0; char_iter < token_len; ++char_iter) + { + if (!std::isalnum(static_cast(token[char_iter])) && token[char_iter] != '_') + { + scr_error(false, "illegal localized string reference: %s must contain only alpha-numeric characters and underscores", token); + } + } + } + + void scr_get_vector(unsigned int index, float* vector_value) + { + if (index < game::scr_VmPub->outparamcount) + { + auto* value = game::scr_VmPub->top - index; + if (value->type == game::VAR_VECTOR) + { + std::memcpy(vector_value, value->u.vectorValue, sizeof(std::float_t[3])); + return; + } + + scr_error(false, "type %s is not a vector", var_typename[value->type]); + } + + scr_error(false, "parameter %u does not exist", index + 1); + } + + int scr_get_int(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + auto* value = game::scr_VmPub->top - index; + if (value->type == game::VAR_INTEGER) + { + return value->u.intValue; + } + + scr_error(false, "type %s is not an int", var_typename[value->type]); + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0; + } + + float scr_get_float(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + auto* value = game::scr_VmPub->top - index; + if (value->type == game::VAR_FLOAT) + { + return value->u.floatValue; + } + + if (value->type == game::VAR_INTEGER) + { + return static_cast(value->u.intValue); + } + + scr_error(false, "type %s is not a float", var_typename[value->type]); + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0.0f; + } + + int scr_get_pointer_type(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + if ((game::scr_VmPub->top - index)->type == game::VAR_POINTER) + { + return static_cast(game::GetObjectType((game::scr_VmPub->top - index)->u.uintValue)); + } + + scr_error(false, "type %s is not an object", var_typename[(game::scr_VmPub->top - index)->type]); + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0; + } + + int scr_get_type(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + return (game::scr_VmPub->top - index)->type; + } + + scr_error(false, "parameter %u does not exist", index + 1); + return 0; + } + + const char* scr_get_type_name(unsigned int index) + { + if (index < game::scr_VmPub->outparamcount) + { + return var_typename[(game::scr_VmPub->top - index)->type]; + } + + scr_error(false, "parameter %u does not exist", index + 1); + return nullptr; + } + + void g_model_index_no_cache_stub(utils::hook::assembler& a) + { + a.lea(ecx, qword_ptr(rbx, 0xA81)); + a.call(0x1406B3580); + a.cmp(eax, 1); + a.mov(rcx, rdi); // restore rcx + a.jmp(0x140290351); + } + + void g_model_index_no_cache_error_stub(const char* model) + { + scr_error(false, "model \"%s\" must be precached", model); + } + } + + std::optional find_function(const char* pos) + { + for (const auto& file : scripting::script_function_table_sort) + { + const auto first_function = file.second.begin(); + for (auto i = file.second.begin(); i != file.second.end() && std::next(i) != file.second.end(); ++i) + { + const auto next = std::next(i); + if (pos >= i->second && pos < next->second) + { + script_info_t info{}; + info.function = i->first; + info.file = file.first; + info.script_start = first_function->second; + return {info}; + } + } + } + + return {}; + } + + class error final : public component_interface + { + public: + void post_unpack() override + { + scr_emit_function_hook.create(0x1405BC5E0, scr_emit_function_stub); + + utils::hook::call(0x1405BC583, compile_error_stub); // LinkFile + utils::hook::call(0x1405BC5CF, compile_error_stub); // LinkFile + utils::hook::call(0x1405BC6BA, find_variable_stub); // Scr_EmitFunction + + // Restore basic error messages for commonly used scr functions + utils::hook::jump(0x1405C7950, scr_get_object); + utils::hook::jump(0x1405C7420, scr_get_const_string); + utils::hook::jump(0x1405C71E0, scr_get_const_istring); + utils::hook::jump(0x1404FEED0, scr_validate_localized_string_ref); + utils::hook::jump(0x1405C7E90, scr_get_vector); + utils::hook::jump(0x1405C7890, scr_get_int); + utils::hook::jump(0x1405C7730, scr_get_float); + + utils::hook::jump(0x1405C7B70, scr_get_pointer_type); + utils::hook::jump(0x1405C7D40, scr_get_type); + utils::hook::jump(0x1405C7DB0, scr_get_type_name); + + // add error print to G_PrecacheModel + utils::hook::jump(0x140290340, utils::hook::assemble(g_model_index_no_cache_stub), true); + utils::hook::call(0x140290365, g_model_index_no_cache_error_stub); + } + }; +} + +REGISTER_COMPONENT(gsc::error) diff --git a/src/client/component/gsc/script_error.hpp b/src/client/component/gsc/script_error.hpp new file mode 100644 index 00000000..de095a63 --- /dev/null +++ b/src/client/component/gsc/script_error.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace gsc +{ + extern std::array var_typename; + + struct script_info_t + { + const char* script_start; + std::string file; + std::string function; + }; + + std::optional find_function(const char* pos); +} diff --git a/src/client/component/gsc/script_extension.cpp b/src/client/component/gsc/script_extension.cpp new file mode 100644 index 00000000..ec6858a2 --- /dev/null +++ b/src/client/component/gsc/script_extension.cpp @@ -0,0 +1,539 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "script_error.hpp" +#include "script_extension.hpp" +#include "script_loading.hpp" + +#include "component/console.hpp" +#include "component/command.hpp" +#include "component/notifies.hpp" +#include "component/scheduler.hpp" +#include "component/mods.hpp" +#include "component/mod_stats.hpp" +#include "component/scripting.hpp" + +#include "game/scripting/script_value.hpp" +#include "game/scripting/execution.hpp" + +#include "game/ui_scripting/execution.hpp" + +#include +#include + +namespace gsc +{ + std::uint16_t function_id_start = 0x320; + void* func_table[FUNC_TABLE_SIZE]; + + namespace + { + struct gsc_error : public std::runtime_error + { + using std::runtime_error::runtime_error; + }; + + std::unordered_map functions; + + bool force_error_print = false; + std::optional gsc_error_msg; + + utils::hook::detour scr_register_function_hook; + + unsigned int scr_get_function_stub(const char** p_name, int* type) + { + const auto result = utils::hook::invoke(0x140509F20, p_name, type); + + for (const auto& [id, func] : functions) + { + game::Scr_RegisterFunction(func, 0, id); + } + + return result; + } + + void execute_custom_function(game::BuiltinFunction function) + { + auto error = false; + + try + { + function(); + } + catch (const std::exception& e) + { + error = true; + force_error_print = true; + gsc_error_msg = e.what(); + } + + if (error) + { + game::Scr_ErrorInternal(); + } + } + + bool is_in_game_memory_range(uintptr_t ptr) + { + return ptr <= BASE_ADDRESS + BINARY_PAYLOAD_SIZE; + } + + bool is_in_game_memory_range(void* ptr) + { + return is_in_game_memory_range(reinterpret_cast(ptr)); + } + + void vm_call_builtin_function(const game::BuiltinFunction function) + { + const auto custom = !is_in_game_memory_range(function); + if (!custom) + { + function(); + } + else + { + execute_custom_function(function); + } + } + + void builtin_call_error(const std::string& error) + { + const auto pos = game::scr_function_stack->pos; + const auto function_id = *reinterpret_cast(reinterpret_cast(pos - 2)); + + if (function_id > FUNC_TABLE_SIZE) + { + console::warn("in call to builtin method \"%s\"%s", gsc_ctx->meth_name(function_id).data(), error.data()); + } + else + { + console::warn("in call to builtin function \"%s\"%s", gsc_ctx->func_name(function_id).data(), error.data()); + } + } + + std::optional get_opcode_name(const std::uint8_t opcode) + { + try + { + const auto index = gsc_ctx->opcode_enum(opcode); + return {gsc_ctx->opcode_name(index)}; + } + catch (...) + { + return {}; + } + } + + void print_callstack() + { + for (auto frame = game::scr_VmPub->function_frame; frame != game::scr_VmPub->function_frame_start; --frame) + { + const auto pos = frame == game::scr_VmPub->function_frame ? game::scr_function_stack->pos - 1 : frame->fs.pos; + const auto info = find_function(pos); + + if (!info.has_value()) + { + console::warn("\tat unknown location %p\n", pos); + continue; + } + + const auto& function = info->function; + const auto& file = info->file; + const auto devmap_opt = get_script_devmap(file); + + if (devmap_opt.has_value()) + { + const auto& devmap = devmap_opt.value(); + const auto rel_pos = static_cast(pos - info->script_start); + const auto& iter = devmap->find(rel_pos); + + if (iter != devmap->end()) + { + console::warn("\tat function \"%s\" in file \"%s.gsc\" (line %d, column %d)\n", + function.data(), file.data(), + iter->second.line, iter->second.column); + } + else + { + console::warn("\tat function \"%s\" in file \"%s.gsc\"\n", function.data(), file.data()); + } + } + else + { + console::warn("\tat function \"%s\" in file \"%s.gsc\"\n", function.data(), file.data()); + } + } + } + + bool is_call_opcode(const std::uint8_t opcode_id) + { + return (opcode_id >= 0x1A && opcode_id <= 0x20) || (opcode_id >= 0xA9 && opcode_id <= 0xAF); + } + + void vm_error_stub(int mark_pos) + { + if (!developer_script->current.enabled && !force_error_print) + { + utils::hook::invoke(0x140614670, mark_pos); + return; + } + + console::warn("******* script runtime error ********\n"); + const auto opcode_id = *reinterpret_cast(0x14BAA93E8); + + const std::string error = gsc_error_msg.has_value() ? std::format(": {}", gsc_error_msg.value()) : std::string(); + + if (is_call_opcode(opcode_id)) + { + builtin_call_error(error); + } + else + { + const auto opcode = get_opcode_name(opcode_id); + if (opcode.has_value()) + { + console::warn("while processing instruction %s%s\n", opcode.value().data(), error.data()); + } + else + { + console::warn("while processing instruction 0x%X%s\n", opcode_id, error.data()); + } + } + + force_error_print = false; + gsc_error_msg = {}; + + print_callstack(); + console::warn("************************************\n"); + utils::hook::invoke(0x140614670, mark_pos); + } + + void scr_print() + { + const auto num = game::Scr_GetNumParam(); + std::string buffer{}; + + for (auto i = 0u; i < num; i++) + { + const auto str = game::Scr_GetString(i); + buffer.append(str); + buffer.append("\t"); + } + + console::info("%s\n", buffer.data()); + } + + void assert_cmd() + { + if (!game::Scr_GetInt(0)) + { + scr_error(true, "assert fail"); + } + } + + void assert_ex_cmd() + { + if (!game::Scr_GetInt(0)) + { + scr_error(true, "assert fail: %s", game::Scr_GetString(1)); + } + } + + void assert_msg_cmd() + { + scr_error(true, "assert fail: %s", game::Scr_GetString(0)); + } + + scripting::script_value get_argument(int index) + { + if (index >= static_cast(game::scr_VmPub->outparamcount)) + { + return {}; + } + + return game::scr_VmPub->top[-index]; + } + + nlohmann::json gsc_to_json(const scripting::script_value& value) + { +#define CHECK_TYPE(__type__) \ + if (value.is<__type__>()) \ + { \ + return value.as<__type__>(); \ + } \ + + CHECK_TYPE(std::string); + CHECK_TYPE(int); + CHECK_TYPE(float); + CHECK_TYPE(bool); + + return {}; + +#undef CHECK_TYPE + } + + scripting::script_value json_to_gsc(const nlohmann::json& value) + { +#define CHECK_TYPE(__func__, __type__) \ + if (value.__func__()) \ + { \ + return value.get<__type__>(); \ + } \ + + CHECK_TYPE(is_string, std::string); + CHECK_TYPE(is_number_integer, int); + CHECK_TYPE(is_number_float, float); + CHECK_TYPE(is_boolean, bool); + + return {}; + +#undef CHECK_TYPE + } + + void return_value(const scripting::script_value& value) + { + if (game::scr_VmPub->outparamcount) + { + game::Scr_ClearOutParams(); + } + + scripting::push_value(value); + } + } + + void scr_error(bool force_print, const char* fmt, ...) + { + { + char buffer[2048]{}; + + va_list ap; + va_start(ap, fmt); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, fmt, ap); + + va_end(ap); + + force_error_print = force_print; + gsc_error_msg = buffer; + } + + game::Scr_ErrorInternal(); + } + + void add_function(const std::string& name, game::BuiltinFunction function) + { + if (gsc_ctx->func_exists(name)) + { + const auto id = gsc_ctx->func_id(name); + functions[id] = function; + } + else + { + const auto id = ++function_id_start; + functions[id] = function; + gsc_ctx->func_add(name, id); + } + } + + class extension final : public component_interface + { + public: + void post_unpack() override + { + utils::hook::set(0x1405BC7BC, FUNC_TABLE_SIZE); // change builtin func count + + utils::hook::set(0x1405BCB6C + 2, sizeof(func_table)); + utils::hook::set(0x1405BC7C2 + 4, RVA(&func_table)); + utils::hook::inject(0x1405BCB78 + 3, &func_table); + utils::hook::set(0x1405CA678 + 4, RVA(&func_table)); + + utils::hook::nop(0x1405CA683, 8); + utils::hook::call(0x1405CA683, vm_call_builtin_function); + + utils::hook::call(0x1405CB94F, vm_error_stub); // LargeLocalResetToMark + + utils::hook::call(0x1405BCBAB, scr_get_function_stub); + + add_function("print", scr_print); + add_function("println", scr_print); + + add_function("assert", assert_cmd); + add_function("assertex", assert_ex_cmd); + add_function("assertmsg", assert_msg_cmd); + + add_function("replacefunc", []() + { + const auto what = get_argument(0).get_raw(); + const auto with = get_argument(1).get_raw(); + + if (what.type != game::SCRIPT_FUNCTION) + { + throw std::runtime_error("parameter 1 must be a function"); + } + + if (with.type != game::SCRIPT_FUNCTION) + { + throw std::runtime_error("parameter 2 must be a function"); + } + + notifies::set_gsc_hook(what.u.codePosValue, with.u.codePosValue); + }); + + add_function("getsoundlength", []() + { + const auto name = game::Scr_GetString(0); + const auto sound = game::DB_FindXAssetHeader(game::ASSET_TYPE_SOUND, name, false).sound; + if (!sound || !sound->count || !sound->head->soundFile || sound->head->soundFile->type != game::SAT_STREAMED) + { + return game::Scr_AddInt(-1); + } + + return game::Scr_AddInt(sound->head->soundFile->u.streamSnd.totalMsec); + }); + + add_function("executecommand", []() + { + const auto cmd = game::Scr_GetString(0); + command::execute(cmd); + }); + + add_function("luinotify", []() + { + const std::string name = game::Scr_GetString(0); + const std::string data = game::Scr_GetString(1); + + scheduler::once([=]() + { + ui_scripting::notify(name, {{"data", data}}); + }, scheduler::pipeline::lui); + }); + + add_function("statsset", []() + { + const auto key = game::Scr_GetString(0); + const auto value = get_argument(1); + const auto json_value = gsc_to_json(value); + mod_stats::set(key, json_value); + }); + + add_function("statssetstruct", []() + { + const auto struct_ = game::Scr_GetString(0); + const auto field = game::Scr_GetString(1); + const auto value = get_argument(2); + const auto json_value = gsc_to_json(value); + mod_stats::set_struct(struct_, field, json_value); + }); + + add_function("statsget", []() + { + const auto key = game::Scr_GetString(0); + const auto& value = mod_stats::get(key); + return_value(json_to_gsc(value)); + }); + + add_function("statsgetor", []() + { + const auto key = game::Scr_GetString(0); + const auto default_value = get_argument(1); + const auto json_default_value = gsc_to_json(default_value); + const auto value = mod_stats::get(key, json_default_value); + return_value(json_to_gsc(value)); + }); + + add_function("statsgetstruct", []() + { + const auto struct_ = game::Scr_GetString(0); + const auto field = game::Scr_GetString(1); + const auto value = mod_stats::get_struct(struct_, field); + return_value(json_to_gsc(value)); + }); + + add_function("statsgetstructor", []() + { + const auto struct_ = game::Scr_GetString(0); + const auto field = game::Scr_GetString(1); + const auto default_value = get_argument(2); + const auto json_default_value = gsc_to_json(default_value); + const auto value = mod_stats::get_struct(struct_, field, json_default_value); + return_value(json_to_gsc(value)); + }); + + add_function("typeof", []() + { + const auto arg = get_argument(0); + const auto type = arg.get_raw().type; + + if (type < var_typename.size()) + { + game::Scr_AddString(var_typename[type]); + } + else + { + game::Scr_AddString("unknown"); + } + }); + + add_function("sharedset", []() + { + const std::string key = game::Scr_GetString(0); + const std::string value = game::Scr_GetString(1); + + scripting::shared_table.access([&](scripting::shared_table_t& table) + { + table[key] = value; + }); + }); + + add_function("sharedget", []() + { + const std::string key = game::Scr_GetString(0); + const auto value = scripting::shared_table.access( + [&](scripting::shared_table_t& table) + { + return table[key]; + } + ); + + game::Scr_AddString(value.data()); + }); + + add_function("sharedclear", []() + { + scripting::shared_table.access([&](scripting::shared_table_t& table) + { + table.clear(); + }); + }); + + add_function("assetexists", []() + { + const std::string type = game::Scr_GetString(0); + const auto name = game::Scr_GetString(1); + + game::XAssetType type_index = game::ASSET_TYPE_COUNT; + + for (auto i = 0; i < ::game::XAssetType::ASSET_TYPE_COUNT; i++) + { + if (type == ::game::g_assetNames[i]) + { + type_index = static_cast(i); + } + } + + if (type_index == game::ASSET_TYPE_COUNT) + { + return scr_error(true, "invalid asset type %s", type.data()); + } + + const auto result = game::DB_XAssetExists(type_index, name) && + !game::DB_IsXAssetDefault(type_index, name); + game::Scr_AddInt(result); + }); + } + }; +} + +REGISTER_COMPONENT(gsc::extension) diff --git a/src/client/component/gsc/script_extension.hpp b/src/client/component/gsc/script_extension.hpp new file mode 100644 index 00000000..1c9f7dd5 --- /dev/null +++ b/src/client/component/gsc/script_extension.hpp @@ -0,0 +1,11 @@ +#pragma once + +#define FUNC_TABLE_SIZE 0x1000 + +namespace gsc +{ + extern void* func_table[FUNC_TABLE_SIZE]; + + void scr_error(bool force_print, const char* fmt, ...); + void add_function(const std::string& name, game::BuiltinFunction function); +} diff --git a/src/client/component/gsc/script_loading.cpp b/src/client/component/gsc/script_loading.cpp new file mode 100644 index 00000000..127d9e1c --- /dev/null +++ b/src/client/component/gsc/script_loading.cpp @@ -0,0 +1,495 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "component/filesystem.hpp" +#include "component/console.hpp" +#include "component/scripting.hpp" +#include "component/fastfiles.hpp" +#include "component/memory.hpp" + +#include "script_loading.hpp" + +#include +#include +#include +#include + +namespace gsc +{ + std::unique_ptr gsc_ctx; + game::dvar_t* developer_script = nullptr; + + namespace + { + std::unordered_map main_handles; + std::unordered_map init_handles; + + struct loaded_script_t + { + game::ScriptFile* ptr; + std::map devmap; + }; + + std::unordered_map loaded_scripts; + utils::memory::allocator script_allocator; + + struct + { + char* buf = nullptr; + char* pos = nullptr; + unsigned int size = memory::custom_script_mem_size; + } script_memory; + + char* allocate_buffer(size_t size) + { + if (script_memory.buf == nullptr) + { + script_memory.buf = game::PMem_AllocFromSource_NoDebug(script_memory.size, 4, 1, game::PMEM_SOURCE_SCRIPT); + script_memory.pos = script_memory.buf; + } + + if (script_memory.pos + size > script_memory.buf + script_memory.size) + { + game::Com_Error(game::ERR_FATAL, "Out of custom script memory"); + } + + const auto pos = script_memory.pos; + script_memory.pos += size; + return pos; + } + + void free_script_memory() + { + game::PMem_PopFromSource_NoDebug(script_memory.buf, script_memory.size, 4, 1, game::PMEM_SOURCE_SCRIPT); + script_memory.buf = nullptr; + script_memory.pos = nullptr; + } + + void clear() + { + main_handles.clear(); + init_handles.clear(); + loaded_scripts.clear(); + script_allocator.clear(); + free_script_memory(); + } + + bool read_raw_script_file(const std::string& name, std::string* data) + { + if (filesystem::read_file(name, data)) + { + return true; + } + + const auto name_str = name.data(); + if (game::DB_XAssetExists(game::ASSET_TYPE_RAWFILE, name_str) && + !game::DB_IsXAssetDefault(game::ASSET_TYPE_RAWFILE, name_str)) + { + const auto asset = game::DB_FindXAssetHeader(game::ASSET_TYPE_RAWFILE, name.data(), false); + const auto len = game::DB_GetRawFileLen(asset.rawfile); + data->resize(len); + game::DB_GetRawBuffer(asset.rawfile, data->data(), len); + if (len > 0) + { + data->pop_back(); + } + + return true; + } + + return false; + } + + std::map parse_devmap(const xsk::gsc::buffer& devmap) + { + auto devmap_ptr = devmap.data; + + const auto read_32 = [&]() + { + const auto val = *reinterpret_cast(devmap_ptr); + devmap_ptr += sizeof(std::uint32_t); + return val; + }; + + const auto read_16 = [&]() + { + const auto val = *reinterpret_cast(devmap_ptr); + devmap_ptr += sizeof(std::uint16_t); + return val; + }; + + std::map pos_map; + + const auto devmap_count = read_32(); + for (auto i = 0u; i < devmap_count; i++) + { + const auto script_pos = read_32() - 1; + const auto line = read_16(); + const auto col = read_16(); + + pos_map[script_pos] = {line, col}; + } + + return pos_map; + } + + game::ScriptFile* load_custom_script(const char* file_name, const std::string& real_name) + { + if (const auto itr = loaded_scripts.find(file_name); itr != loaded_scripts.end()) + { + return itr->second.ptr; + } + + try + { + auto& compiler = gsc_ctx->compiler(); + auto& assembler = gsc_ctx->assembler(); + + std::string source_buffer{}; + if (!read_raw_script_file(real_name + ".gsc", &source_buffer)) + { + return nullptr; + } + + std::vector data; + data.assign(source_buffer.begin(), source_buffer.end()); + + const auto assembly_ptr = compiler.compile(real_name, data); + [[maybe_unused]] const auto& [script, stack, devmap] = assembler.assemble(*assembly_ptr); + + const auto script_file_ptr = static_cast(script_allocator.allocate(sizeof(game::ScriptFile))); + script_file_ptr->name = file_name; + + script_file_ptr->len = static_cast(stack.size); + script_file_ptr->bytecodeLen = static_cast(script.size); + + const auto stack_size = static_cast(stack.size + 1); + const auto byte_code_size = static_cast(script.size + 1); + + script_file_ptr->buffer = static_cast(script_allocator.allocate(stack_size)); + std::memcpy(const_cast(script_file_ptr->buffer), stack.data, stack.size); + + script_file_ptr->bytecode = allocate_buffer(byte_code_size); + std::memcpy(script_file_ptr->bytecode, script.data, script.size); + + script_file_ptr->compressedLen = 0; + + loaded_script_t loaded_script{}; + loaded_script.ptr = script_file_ptr; + loaded_script.devmap = parse_devmap(devmap); + loaded_scripts.insert(std::make_pair(file_name, loaded_script)); + + return script_file_ptr; + } + catch (const std::exception& ex) + { + console::error("*********** script compile error *************\n"); + console::error("failed to compile '%s':\n%s", real_name.data(), ex.what()); + console::error("**********************************************\n"); + return nullptr; + } + } + + std::string get_raw_script_file_name(const std::string& name) + { + if (name.ends_with(".gsh") || name.ends_with(".gsc")) + { + return name; + } + + return name + ".gsc"; + } + + std::string get_script_file_name(const std::string& name) + { + std::string script_name = name; + if (script_name.ends_with(".gsc")) + { + const auto dot_idx = script_name.find_last_of('.'); + script_name = script_name.substr(0, dot_idx); + } + + const auto id = gsc_ctx->token_id(script_name); + if (!id) + { + return script_name; + } + + return std::to_string(id); + } + + auto read_compiled_script_file(const std::string& name, const std::string& real_name) + { + const auto* script_file = game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, name.data(), false).scriptfile; + if (!script_file) + { + throw std::runtime_error(std::format("Could not load scriptfile '{}'", real_name)); + } + + const auto len = script_file->compressedLen; + const std::string stack{script_file->buffer, static_cast(len)}; + + const auto decompressed_stack = utils::compression::zlib::decompress(stack); + + std::vector stack_data; + stack_data.assign(decompressed_stack.begin(), decompressed_stack.end()); + + const xsk::gsc::buffer buffer + { + reinterpret_cast(script_file->bytecode), + static_cast(script_file->bytecodeLen) + }; + + return std::make_pair(buffer, stack_data); + } + + void load_script(const std::string& name) + { + if (!game::Scr_LoadScript(name.data())) + { + return; + } + + const auto main_handle = game::Scr_GetFunctionHandle(name.data(), gsc_ctx->token_id("main")); + const auto init_handle = game::Scr_GetFunctionHandle(name.data(), gsc_ctx->token_id("init")); + + if (main_handle) + { + console::info("Loaded '%s::main'\n", name.data()); + main_handles[name] = main_handle; + } + + if (init_handle) + { + console::info("Loaded '%s::init'\n", name.data()); + init_handles[name] = init_handle; + } + } + + void load_scripts(const std::filesystem::path& root_dir, const std::string& subfolder) + { + std::filesystem::path script_dir = root_dir / subfolder; + if (!utils::io::directory_exists(script_dir.generic_string())) + { + return; + } + + const auto scripts = utils::io::list_files(script_dir.generic_string()); + for (const auto& script : scripts) + { + if (!script.ends_with(".gsc")) + { + continue; + } + + std::filesystem::path path(script); + const auto relative = path.lexically_relative(root_dir).generic_string(); + const auto base_name = relative.substr(0, relative.size() - 4); + + load_script(base_name); + } + } + + int db_is_x_asset_default(game::XAssetType type, const char* name) + { + if (loaded_scripts.contains(name)) + { + return 0; + } + + return game::DB_IsXAssetDefault(type, name); + } + + void load_gametype_script_stub(void* a1, void* a2) + { + utils::hook::invoke(0x1404E1400, a1, a2); + + fastfiles::enum_assets(game::ASSET_TYPE_RAWFILE, [](game::XAssetHeader header) + { + std::string name = header.rawfile->name; + + if (name.ends_with(".gsc") && name.starts_with("scripts/")) + { + const auto base_name = name.substr(0, name.size() - 4); + load_script(base_name); + } + }, true); + + const auto mapname = game::Dvar_FindVar("mapname"); + for (const auto& path : filesystem::get_search_paths()) + { + load_scripts(path, "scripts"); + load_scripts(path, "scripts/"s + mapname->current.string); + } + } + + void db_get_raw_buffer_stub(const game::RawFile* rawfile, char* buf, const int size) + { + if (rawfile->len > 0 && rawfile->compressedLen == 0) + { + std::memset(buf, 0, size); + std::memcpy(buf, rawfile->buffer, std::min(rawfile->len, size)); + return; + } + + game::DB_GetRawBuffer(rawfile, buf, size); + } + + void g_load_structs_stub() + { + for (auto& function_handle : main_handles) + { + console::info("Executing '%s::main'\n", function_handle.first.data()); + const auto thread = game::Scr_ExecThread(function_handle.second, 0); + game::RemoveRefToObject(thread); + } + + utils::hook::invoke(0x140510B40); + } + + void scr_load_level_stub() + { + utils::hook::invoke(0x1404FD130); + + for (auto& function_handle : init_handles) + { + console::info("Executing '%s::init'\n", function_handle.first.data()); + const auto thread = game::Scr_ExecThread(function_handle.second, 0); + game::RemoveRefToObject(thread); + } + } + + void scr_begin_load_scripts_stub() + { + const auto comp_mode = developer_script->current.enabled + ? xsk::gsc::build::dev + : xsk::gsc::build::prod; + + gsc_ctx->init(comp_mode, [](const xsk::gsc::context* context, const std::string& include_name) + -> std::pair> + { + const auto real_name = get_raw_script_file_name(include_name); + + std::string file_buffer; + if (!read_raw_script_file(real_name, &file_buffer) || file_buffer.empty()) + { + const auto name = get_script_file_name(include_name); + if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, name.data())) + { + return read_compiled_script_file(name, real_name); + } + + throw std::runtime_error(std::format("Could not load gsc file '{}'", real_name)); + } + + std::vector script_data; + script_data.assign(file_buffer.begin(), file_buffer.end()); + + return {{}, script_data}; + }); + + utils::hook::invoke(0x1405BCAE0); + } + + void sl_end_load_scripts_stub() + { + gsc_ctx->cleanup(); + utils::hook::invoke(0x1405BFBF0); + } + + void add_function_name(const std::string& name, const std::uint16_t id) + { + const std::string_view name_ = utils::memory::get_allocator()->duplicate_string(name); + auto& func_map = gsc_ctx->func_map(); + auto func_map_ = reinterpret_cast*>( + reinterpret_cast(&func_map)); + func_map_->insert(std::make_pair(name_, id)); + } + + void add_method_name(const std::string& name, const std::uint16_t id) + { + const std::string_view name_ = utils::memory::get_allocator()->duplicate_string(name); + auto& func_map = gsc_ctx->meth_map(); + auto func_map_ = reinterpret_cast*>( + reinterpret_cast(&func_map)); + func_map_->insert(std::make_pair(name_, id)); + } + } + + game::ScriptFile* find_script(game::XAssetType type, const char* name, int allow_create_default) + { + std::string real_name = name; + const auto id = static_cast(std::strtol(name, nullptr, 10)); + if (id) + { + real_name = gsc_ctx->token_name(id); + } + + auto* script = load_custom_script(name, real_name); + if (script) + { + return script; + } + + return game::DB_FindXAssetHeader(type, name, allow_create_default).scriptfile; + } + + std::optional*> get_script_devmap(const std::string& name) + { + const auto iter = loaded_scripts.find(name); + if (iter == loaded_scripts.end()) + { + return {}; + } + + return {&iter->second.devmap}; + } + + class loading final : public component_interface + { + public: + void post_load() override + { + gsc_ctx = std::make_unique(); + } + + void post_unpack() override + { + utils::hook::call(0x1404E1627, scr_begin_load_scripts_stub); + utils::hook::call(0x1405BCC14, sl_end_load_scripts_stub); + + developer_script = dvars::register_bool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments"); + + utils::hook::call(0x1405C6177, find_script); + utils::hook::call(0x1405C6187, db_is_x_asset_default); + + // Loads scripts with an uncompressed stack + utils::hook::call(0x1405C61E0, db_get_raw_buffer_stub); + + // load handles + utils::hook::call(0x1404E17B2, load_gametype_script_stub); + + // execute handles + utils::hook::call(0x1404C8F71, g_load_structs_stub); + utils::hook::call(0x1404C8F80, scr_load_level_stub); + + add_function_name("isusinghdr", 0x242); + add_function_name("tablegetrowcount", 0x2A6); + add_function_name("setshaderconstant", 0x2F1); + add_method_name("setclutforplayer", 0x849F); + + scripting::on_shutdown([](bool free_scripts, bool post_shutdown) + { + if (free_scripts && post_shutdown) + { + clear(); + } + }); + } + }; +} + +REGISTER_COMPONENT(gsc::loading) diff --git a/src/client/component/gsc/script_loading.hpp b/src/client/component/gsc/script_loading.hpp new file mode 100644 index 00000000..1065b639 --- /dev/null +++ b/src/client/component/gsc/script_loading.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "game/scripting/functions.hpp" +#include + +namespace gsc +{ + struct col_line_t + { + std::uint16_t line; + std::uint16_t column; + }; + + extern std::unique_ptr gsc_ctx; + extern game::dvar_t* developer_script; + + game::ScriptFile* find_script(game::XAssetType type, const char* name, int allow_create_default); + + std::optional*> get_script_devmap(const std::string& name); +} diff --git a/src/client/component/gui/asset_list.cpp b/src/client/component/gui/asset_list.cpp new file mode 100644 index 00000000..ae53b45d --- /dev/null +++ b/src/client/component/gui/asset_list.cpp @@ -0,0 +1,278 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "component/scheduler.hpp" +#include "component/command.hpp" +#include "component/fastfiles.hpp" +#include "gui.hpp" +#include "asset_list.hpp" + +#include +#include + +namespace gui::asset_list +{ + namespace + { + bool shown_assets[game::XAssetType::ASSET_TYPE_COUNT]{}; + std::string asset_type_filter; + std::string assets_name_filter[game::XAssetType::ASSET_TYPE_COUNT]; + std::string assets_value_filter[game::XAssetType::ASSET_TYPE_COUNT]; + std::string zone_name_filter[game::XAssetType::ASSET_TYPE_COUNT]; + + std::unordered_map> asset_view_callbacks; + + bool default_only[game::ASSET_TYPE_COUNT] = {}; + int asset_count[game::ASSET_TYPE_COUNT] = {}; + bool disabled_zones[game::ASSET_TYPE_COUNT][0x100] = {}; + bool show_asset_zone = true; + + void draw_table_row(game::XAssetType type, const game::XAssetEntry* entry, bool should_add_view_btn) + { + const auto asset = entry->asset; + auto asset_name = game::DB_GetXAssetName(&asset); + const auto is_default = entry->zoneIndex == 0; + + if (asset_name[0] == '\0' || disabled_zones[type][entry->zoneIndex] || default_only[type] && !is_default) + { + return; + } + + if (is_default) + { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.43f, 0.15f, 0.15f, 1.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.98f, 0.26f, 0.26f, 1.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.98f, 0.06f, 0.06f, 1.f)); + } + + const auto _0 = gsl::finally([&] + { + if (is_default) + { + ImGui::PopStyleColor(3); + } + }); + + auto col_index = 0; + if (!utils::string::strstr_lower(asset_name, assets_name_filter[type].data())) + { + return; + } + + if (type == game::ASSET_TYPE_LOCALIZE_ENTRY) + { + if (!utils::string::strstr_lower(entry->asset.header.localize->value, assets_value_filter[type].data())) + { + return; + } + } + + ImGui::TableNextRow(); + + if (should_add_view_btn) + { + ImGui::TableSetColumnIndex(col_index++); + ImGui::PushID(asset_count[type]); + if (ImGui::Button("view")) + { + asset_view_callbacks.at(type)(asset_name); + } + ImGui::PopID(); + } + + if (show_asset_zone) + { + ImGui::TableSetColumnIndex(col_index++); + if (entry->zoneIndex > 0) + { + ImGui::Text(game::g_zones[entry->zoneIndex].name); + } + else + { + ImGui::Text("default"); + } + } + + ImGui::TableSetColumnIndex(col_index++); + + if (ImGui::Button(asset_name)) + { + gui::copy_to_clipboard(asset_name); + } + + if (type == game::ASSET_TYPE_LOCALIZE_ENTRY) + { + ImGui::TableSetColumnIndex(col_index++); + + if (ImGui::Button(entry->asset.header.localize->value)) + { + gui::copy_to_clipboard(entry->asset.header.localize->value); + } + } + } + + void draw_asset_type_list() + { + if (ImGui::TreeNode("loaded zones")) + { + for (auto i = 1u; i <= *game::g_zoneCount; i++) + { + if (ImGui::Button(game::g_zones[i].name)) + { + gui::copy_to_clipboard(game::g_zones[i].name); + } + } + + ImGui::TreePop(); + } + + ImGui::Checkbox("show asset zone", &show_asset_zone); + ImGui::InputText("asset type", &asset_type_filter); + ImGui::BeginChild("asset type list"); + + for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) + { + const auto name = game::g_assetNames[i]; + const auto type = static_cast(i); + + if (asset_type_filter.size() == 0 || utils::string::strstr_lower(name, asset_type_filter.data())) + { + ImGui::Checkbox(name, &shown_assets[type]); + } + } + + ImGui::EndChild(); + } + + void draw_asset_list_filter(const game::XAssetType type) + { + ImGui::Text("count: %i / %i", asset_count[type], game::g_poolSize[type]); + ImGui::InputText("name", &assets_name_filter[type]); + + if (type == game::ASSET_TYPE_LOCALIZE_ENTRY) + { + ImGui::InputText("value", &assets_value_filter[type]); + } + + if (ImGui::InputText("zone name", &zone_name_filter[type])) + { + for (auto zone = 0u; zone <= *game::g_zoneCount; zone++) + { + const auto zone_name = game::g_zones[zone].name; + disabled_zones[type][zone] = !utils::string::strstr_lower(zone_name, zone_name_filter[type].data()); + } + } + + ImGui::Checkbox("default assets only", &default_only[type]); + } + + constexpr auto get_table_flags() + { + constexpr auto flags = + ImGuiTableFlags_BordersInnerH | + ImGuiTableFlags_BordersOuterH | + ImGuiTableFlags_BordersInnerV | + ImGuiTableFlags_BordersOuterV | + ImGuiTableFlags_RowBg | + ImGuiTableFlags_ScrollX | + ImGuiTableFlags_ScrollY; + + return flags; + } + + void draw_asset_list_entries(const game::XAssetType type) + { + const auto should_add_view_btn = asset_view_callbacks.contains(type); + constexpr auto flags = get_table_flags(); + + asset_count[type] = 0; + + ImGui::BeginChild("assets list"); + + auto column_count = 1; + column_count += should_add_view_btn; + column_count += show_asset_zone; + column_count += type == game::ASSET_TYPE_LOCALIZE_ENTRY; + + if (ImGui::BeginTable("assets", column_count, flags)) + { + fastfiles::enum_asset_entries(type, [&](const game::XAssetEntry* entry) + { + asset_count[type]++; + draw_table_row(type, entry, should_add_view_btn); + }, true); + + ImGui::EndTable(); + } + + ImGui::EndChild(); + } + + void draw_asset_list(const game::XAssetType type) + { + if (!shown_assets[type]) + { + return; + } + + const auto name = game::g_assetNames[type]; + + auto& io = ImGui::GetIO(); + ImGui::SetNextWindowSizeConstraints(ImVec2(500, 500), io.DisplaySize); + ImGui::Begin(name, &shown_assets[type]); + + draw_asset_list_filter(type); + draw_asset_list_entries(type); + + ImGui::End(); + } + + void render_window() + { + static auto* enabled = &gui::enabled_menus["asset_list"]; + ImGui::Begin("Asset list", enabled); + + draw_asset_type_list(); + + for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) + { + draw_asset_list(static_cast(i)); + } + + ImGui::End(); + } + } + + void add_view_button(int id, game::XAssetType type, const char* name) + { + if (asset_view_callbacks.contains(type)) + { + ImGui::SameLine(); + ImGui::PushID(id); + if (ImGui::Button("view")) + { + asset_view_callbacks.at(type)(name); + } + ImGui::PopID(); + } + } + + void add_asset_view_callback(game::XAssetType type, const std::function& callback) + { + asset_view_callbacks.insert(std::make_pair(type, callback)); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + gui::register_menu("asset_list", "Asset List", render_window); + } + }; +} + +REGISTER_COMPONENT(gui::asset_list::component) diff --git a/src/client/component/gui/asset_list.hpp b/src/client/component/gui/asset_list.hpp new file mode 100644 index 00000000..24b021fa --- /dev/null +++ b/src/client/component/gui/asset_list.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include "game/structs.hpp" +#include "gui.hpp" + +namespace gui::asset_list +{ + void add_asset_view_callback(game::XAssetType, const std::function& callback); + void add_view_button(int id, game::XAssetType type, const char* name); + + template + void add_asset_view(game::XAssetType type, const std::function& draw_callback, ImVec2 min_size = ImVec2(0, 0)) + { + static std::unordered_set opened_assets; + add_asset_view_callback(type, [](const std::string& name) + { + opened_assets.insert(name); + }); + + gui::register_callback([=]() + { + for (auto i = opened_assets.begin(); i != opened_assets.end(); ) + { + const auto& name = *i; + const auto header = reinterpret_cast(game::DB_FindXAssetHeader(type, name.data(), 0).data); + if (header == nullptr) + { + i = opened_assets.erase(i); + continue; + } + + if (min_size.x != 0 && min_size.y != 0) + { + auto& io = ImGui::GetIO(); + ImGui::SetNextWindowSizeConstraints(min_size, ImVec2(io.DisplaySize.x, io.DisplaySize.y)); + } + + auto is_open = true; + if (ImGui::Begin(name.data(), &is_open)) + { + if (!draw_callback(header)) + { + is_open = false; + } + } + ImGui::End(); + + if (is_open) + { + ++i; + } + else + { + i = opened_assets.erase(i); + } + } + }, false); + } +} diff --git a/src/client/component/gui/assets/mapents.cpp b/src/client/component/gui/assets/mapents.cpp new file mode 100644 index 00000000..35f0a1f1 --- /dev/null +++ b/src/client/component/gui/assets/mapents.cpp @@ -0,0 +1,140 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "component/scheduler.hpp" +#include "component/command.hpp" +#include "component/fastfiles.hpp" +#include "component/gsc/script_loading.hpp" +#include "../gui.hpp" +#include "../asset_list.hpp" + +#include "utils/mapents.hpp" + +#include +#include +#include +#include + +namespace gui::asset_list::mapents +{ + namespace + { + using entity_t = std::vector>; + + struct mapents_t + { + game::MapEnts* asset; + std::string converted_mapents; + std::thread parse_thread; + std::atomic_bool is_parsing = false; + std::atomic_bool done_parsing = false; + }; + + utils::concurrency::container mapents; + + void parse_mapents(game::MapEnts* asset, mapents_t& data) + { + data.is_parsing = true; + data.asset = asset; + const auto str_data = std::string{asset->entityString, static_cast(asset->numEntityChars)}; + data.parse_thread = std::thread([=] + { + const auto new_data = ::mapents::parse(str_data, [](const std::uint16_t id) + { + return gsc::gsc_ctx->token_name(id); + }); + + std::string converted_mapents; + for (const auto& entity : new_data.entities) + { + converted_mapents.append("{\n"); + const auto var_list = entity.get_var_list(); + for (const auto& var : var_list) + { + if (var.sl_string) + { + converted_mapents.append( + utils::string::va("0 \"%s\" \"%s\"\n", var.key.data(), var.value.data())); + } + else + { + converted_mapents.append( + utils::string::va("\"%s\" \"%s\"\n", var.key.data(), var.value.data())); + } + } + converted_mapents.append("}\n"); + } + + mapents.access([=](mapents_t& data) + { + data.is_parsing = false; + data.done_parsing = true; + data.converted_mapents = converted_mapents; + }); + }); + } + + void draw_entity_string(game::MapEnts* asset) + { + ImGui::InputTextMultiline("entity_string", asset->entityString, asset->numEntityChars, + ImGui::GetWindowSize(), ImGuiInputTextFlags_ReadOnly); + } + + bool create_and_open_mapents_file(mapents_t& data) + { + const auto current_path = std::filesystem::current_path().generic_string(); + const std::string path = utils::string::va("%s\\h2-mod\\tmp\\%s", current_path.data(), data.asset->name); + + utils::io::write_file(path, data.converted_mapents, false); + ShellExecuteA(nullptr, nullptr, path.data(), nullptr, nullptr, SW_SHOWNORMAL); + + return false; + } + + bool draw_asset(game::MapEnts* asset) + { + return mapents.access([&](mapents_t& data) + { + if (!data.is_parsing && data.done_parsing) + { + if (data.parse_thread.joinable()) + { + data.parse_thread.join(); + } + else + { + create_and_open_mapents_file(data); + return false; + } + } + + if (!data.is_parsing && !data.done_parsing) + { + parse_mapents(asset, data); + } + + ImGui::Text("Parsing mapents..."); + return true; + }); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + gui::asset_list::add_asset_view(game::ASSET_TYPE_MAP_ENTS, draw_asset); + } + + void pre_destroy() override + { + utils::io::remove_directory("h2-mod/tmp"); + } + }; +} + +REGISTER_COMPONENT(gui::asset_list::mapents::component) diff --git a/src/client/component/gui/assets/material.cpp b/src/client/component/gui/assets/material.cpp new file mode 100644 index 00000000..43ddd3b0 --- /dev/null +++ b/src/client/component/gui/assets/material.cpp @@ -0,0 +1,117 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "component/scheduler.hpp" +#include "component/command.hpp" +#include "component/fastfiles.hpp" +#include "../gui.hpp" +#include "../asset_list.hpp" + +#include +#include + +namespace gui::asset_list::material +{ + namespace + { + std::unordered_map image_type_names = + { + {0x0, "2D"}, + {0x1, "FUNCTION"}, + {0x2, "COLOR_MAP"}, + {0x3, "DETAIL_MAP"}, + {0x4, "UNUSED_2"}, + {0x5, "NORMAL_MAP"}, + {0x6, "UNUSED_3"}, + {0x7, "UNUSED_4"}, + {0x8, "SPECULAR_MAP"}, + {0x9, "UNUSED_5"}, + {0xA, "OCEANFLOW_DISPLACEMENT_MAP"}, + {0xB, "WATER_MAP"}, + {0xC, "OCEAN_DISPLACEMENT_MAP"}, + {0xD, "DISPLACEMENT_MAP"}, + {0xE, "PARALLAX_MAP"}, + }; + + std::string get_image_type_name(unsigned char type) + { + if (!image_type_names.contains(type)) + { + return "UNKNOWN"; + } + + return image_type_names[type]; + } + + bool draw_material_window(game::Material* asset) + { + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("textures")) + { + for (auto i = 0; i < asset->textureCount; i++) + { + if (asset->textureTable && asset->textureTable->u.image && asset->textureTable->u.image->texture.shaderView) + { + const auto type_name = get_image_type_name(asset->textureTable[i].semantic); + + ImGui::Text("%s", type_name.data()); + ImGui::SameLine(); + if (ImGui::Button(asset->textureTable[i].u.image->name)) + { + gui::copy_to_clipboard(asset->textureTable->u.image->name); + } + + const auto width = asset->textureTable[i].u.image->width; + const auto height = asset->textureTable[i].u.image->height; + const auto ratio = static_cast(width) / static_cast(height); + constexpr auto size = 200.f; + + ImGui::Image(asset->textureTable[i].u.image->texture.shaderView, + ImVec2(size * ratio, size) + ); + } + } + + ImGui::TreePop(); + } + +#define DRAW_ASSET_PROPERTY(__name__, __fmt__) \ + ImGui::Text(#__name__ ": " __fmt__, asset->__name__); \ + +#define DRAW_ASSET_PROPERTY_COPY(__name__) \ + ImGui::Text(#__name__ ": "); \ + ImGui::SameLine(); \ + if (ImGui::Button(asset->__name__)) \ + { \ + gui::copy_to_clipboard(asset->__name__); \ + } \ + + DRAW_ASSET_PROPERTY_COPY(name); + DRAW_ASSET_PROPERTY_COPY(techniqueSet->name); + DRAW_ASSET_PROPERTY(textureCount, "%i"); + DRAW_ASSET_PROPERTY(constantCount, "%i"); + DRAW_ASSET_PROPERTY(stateBitsCount, "%i"); + DRAW_ASSET_PROPERTY(stateFlags, "%i"); + DRAW_ASSET_PROPERTY(cameraRegion, "%i"); + DRAW_ASSET_PROPERTY(materialType, "%i"); + DRAW_ASSET_PROPERTY(layerCount, "%i"); + DRAW_ASSET_PROPERTY(assetFlags, "%X"); + + return true; + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + gui::asset_list::add_asset_view(game::ASSET_TYPE_MATERIAL, draw_material_window); + } + }; +} + +REGISTER_COMPONENT(gui::asset_list::material::component) diff --git a/src/client/component/gui/assets/stringtable.cpp b/src/client/component/gui/assets/stringtable.cpp new file mode 100644 index 00000000..bac7ccee --- /dev/null +++ b/src/client/component/gui/assets/stringtable.cpp @@ -0,0 +1,138 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "component/scheduler.hpp" +#include "component/command.hpp" +#include "component/fastfiles.hpp" +#include "component/gsc/script_loading.hpp" +#include "../gui.hpp" +#include "../asset_list.hpp" + +#include "utils/mapents.hpp" + +#include +#include +#include +#include + +namespace gui::asset_list::stringtable +{ + namespace + { + void copy_table(game::StringTable* asset) + { + std::string buffer; + for (auto row = 0; row < asset->rowCount; row++) + { + for (auto column = 0; column < asset->columnCount; column++) + { + const auto index = (row * asset->columnCount) + column; + const auto string_value = asset->values[index].string; + const auto last_char = (column == asset->columnCount - 1) ? "\n" : ","; + + if (string_value == nullptr) + { + buffer.append(last_char); + } + else + { + std::string str = string_value; + auto added_quotes = false; + if (str.contains(',')) + { + added_quotes = true; + str.insert(str.begin(), '"'); + str.insert(str.end(), '"'); + } + + if (str.contains('\"') && !added_quotes) + { + str = std::regex_replace(str, std::regex("\""), "\\\""); + + str.insert(str.begin(), '"'); + str.insert(str.end(), '"'); + } + + str = std::regex_replace(str, std::regex("\n"), "\\n"); + buffer.append(utils::string::va("%s%s", str.data(), last_char)); + } + } + } + + gui::copy_to_clipboard(buffer); + } + + bool draw_asset(game::StringTable* asset) + { + if (asset->columnCount * asset->rowCount == 0) + { + ImGui::Text("empty table"); + return true; + } + + constexpr auto flags = + ImGuiTableFlags_BordersInnerH | + ImGuiTableFlags_BordersOuterH | + ImGuiTableFlags_BordersInnerV | + ImGuiTableFlags_BordersOuterV | + ImGuiTableFlags_RowBg | + ImGuiTableFlags_ScrollX | + ImGuiTableFlags_ScrollY; + + const auto size = ImGui::GetContentRegionAvail(); + + if (ImGui::Button("copy all")) + { + copy_table(asset); + } + + if (ImGui::BeginTable(asset->name, asset->columnCount, flags, size)) + { + for (auto row = 0; row < asset->rowCount; row++) + { + ImGui::TableNextRow(); + + for (auto column = 0; column < asset->columnCount; column++) + { + ImGui::TableSetColumnIndex(column); + const auto index = (row * asset->columnCount) + column; + const auto string_value = asset->values[index].string; + if (string_value == nullptr) + { + ImGui::Text(""); + } + else + { + ImGui::PushStyleColor(ImGuiCol_::ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + ImGui::PushID(index); + if (ImGui::Button(string_value)) + { + gui::copy_to_clipboard(string_value); + } + ImGui::PopID(); + ImGui::PopStyleColor(); + } + } + } + + ImGui::EndTable(); + } + + return true; + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + gui::asset_list::add_asset_view(game::ASSET_TYPE_STRINGTABLE, draw_asset, ImVec2(200, 200)); + } + }; +} + +REGISTER_COMPONENT(gui::asset_list::stringtable::component) diff --git a/src/client/component/gui/assets/xmodel.cpp b/src/client/component/gui/assets/xmodel.cpp new file mode 100644 index 00000000..bfbf7921 --- /dev/null +++ b/src/client/component/gui/assets/xmodel.cpp @@ -0,0 +1,309 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "component/scheduler.hpp" +#include "component/command.hpp" +#include "component/fastfiles.hpp" +#include "../gui.hpp" +#include "../asset_list.hpp" + +#include +#include + +namespace gui::asset_list::xmodel +{ + namespace + { + ImVec2 project_vertex(game::vec3_t v, bool flip_axis, float scale = 1.f, + bool rotate = false, float rotation_speed = 0.f) + { + constexpr auto left = -1.0f; + constexpr auto right = 1.0f; + constexpr auto bottom = -1.0f; + constexpr auto top = 1.0f; + + auto rotation_angle = 0.f; + if (rotate) + { + rotation_angle = game::Sys_Milliseconds() * rotation_speed; + } + + const auto cos_angle = std::cos(rotation_angle); + const auto sin_angle = std::sin(rotation_angle); + + float o_x = 0.f; + float o_y = 0.f; + float o_z = 0.f; + + if (flip_axis) + { + o_x = v[0] * scale; + o_y = v[1] * scale; + o_z = v[2] * scale; + } + else + { + o_x = v[1] * scale; + o_y = v[0] * scale; + o_z = v[2] * scale; + } + + const auto x = o_x * cos_angle - o_z * sin_angle; + const auto y = o_y; + + const auto proj_x = (2.0f * x) / (right - left) - (right + left) / (right - left); + const auto proj_y = (2.0f * y) / (top - bottom) - (top + bottom) / (top - bottom); + + const auto screen_x = (proj_x + 1.0f) * 0.5f * 50.f; + const auto screen_y = (1.0f - proj_y) * 0.5f * 50.f; + + return ImVec2(screen_x, screen_y); + } + + int sum_verts(game::XSurface* surf, game::vec3_t mins, game::vec3_t maxs, game::vec3_t origin) + { + for (auto i = 0u; i < surf->triCount; i++) + { + game::GfxPackedVertex* vertices[3]{}; + + vertices[0] = &surf->verts0.packedVerts0[surf->triIndices[i].v1]; + vertices[1] = &surf->verts0.packedVerts0[surf->triIndices[i].v2]; + vertices[2] = &surf->verts0.packedVerts0[surf->triIndices[i].v3]; + + for (auto o = 0; o < 3; o++) + { + for (auto j = 0; j < 3; j++) + { + origin[j] += vertices[o]->xyz[j]; + + if (vertices[o]->xyz[j] > maxs[j]) + { + maxs[j] = vertices[o]->xyz[j]; + } + + if (vertices[o]->xyz[j] < mins[j]) + { + mins[j] = vertices[o]->xyz[j]; + } + } + } + } + + return surf->triCount * 2; + } + + void draw_surf(game::XSurface* surf, game::vec3_t mins, game::vec3_t maxs, game::vec3_t origin, + game::vec2_t maxs_2d, ImVec2 window_pos, bool flip_axis) + { + const auto draw_list = ImGui::GetWindowDrawList(); + constexpr auto max_size = 10.f; + const auto extent = std::sqrt(maxs[0] * maxs[0] + maxs[1] * maxs[1] + maxs[2] * maxs[2]); + const auto scale = max_size / extent; + + for (auto i = 0u; i < surf->triCount; i++) + { + game::GfxPackedVertex* vertices[3]{}; + + vertices[0] = &surf->verts0.packedVerts0[surf->triIndices[i].v1]; + vertices[1] = &surf->verts0.packedVerts0[surf->triIndices[i].v2]; + vertices[2] = &surf->verts0.packedVerts0[surf->triIndices[i].v3]; + + ImVec2 points[3]{}; + + for (auto o = 0; o < 3; o++) + { + game::vec3_t trans_vertex{}; + trans_vertex[0] = vertices[o]->xyz[0] - origin[0]; + trans_vertex[1] = vertices[o]->xyz[1] - origin[1]; + trans_vertex[2] = vertices[o]->xyz[2] - origin[2]; + points[o] = project_vertex(trans_vertex, flip_axis, scale, true, 0.001f); + + if (maxs_2d[0] < points[o].x) + { + maxs_2d[0] = points[o].x; + } + + if (maxs_2d[1] < points[o].y) + { + maxs_2d[1] = points[o].y; + } + + points[o][0] += window_pos.x; + points[o][1] += window_pos.y; + } + + draw_list->AddLine(points[0], points[1], IM_COL32_WHITE, 1.f); + draw_list->AddLine(points[1], points[2], IM_COL32_WHITE, 1.f); + draw_list->AddLine(points[2], points[0], IM_COL32_WHITE, 1.f); + } + } + + int sum_verts_in_xmodels(game::XModel* asset, game::vec3_t mins, game::vec3_t maxs, game::vec3_t origin) + { + int vert_count = 0; + + for (auto o = 0; o < asset->lodInfo[0].numsurfs; o++) + { + const auto surf = &asset->lodInfo[0].surfs[o]; + if (surf) + { + vert_count += sum_verts(surf, mins, maxs, origin); + } + } + + return vert_count; + } + + void draw_xmodel(game::XModel* asset, bool flip_axis, game::vec3_t mins, game::vec3_t maxs, game::vec3_t origin, game::vec3_t maxs_2d) + { + if (asset->numLods > 0) + { + auto window_pos = ImGui::GetCursorScreenPos(); + constexpr auto offset = ImVec2(400, 150); + window_pos.x += offset.x; + window_pos.y += offset.y; + + for (auto o = 0; o < asset->lodInfo[0].numsurfs; o++) + { + const auto surf = &asset->lodInfo[0].surfs[o]; + if (surf) + { + draw_surf(surf, mins, maxs, origin, maxs_2d, window_pos, flip_axis); + } + } + } + } + + bool draw_xmodel_window(game::XModel* asset) + { + static bool flip_axis = false; + ImGui::Checkbox("flip axis", &flip_axis); + + ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver); + if (ImGui::TreeNode("3d mesh")) + { + int vert_count = 0; + + game::vec3_t mins{}; + game::vec3_t maxs{}; + game::vec3_t origin{}; + game::vec2_t maxs_2d{}; + + vert_count += sum_verts_in_xmodels(asset, mins, maxs, origin); + for (auto i = 0; i < asset->numCompositeModels; i++) + { + vert_count += sum_verts_in_xmodels(asset->compositeModels[i], mins, maxs, origin); + } + + for (auto o = 0; o < 3; o++) + { + origin[o] /= static_cast(vert_count); + } + + draw_xmodel(asset, flip_axis, mins, maxs, origin, maxs_2d); + for (auto i = 0; i < asset->numCompositeModels; i++) + { + draw_xmodel(asset->compositeModels[i], flip_axis, mins, maxs, origin, maxs_2d); + } + + ImGui::Dummy(ImVec2(maxs_2d[0] + 800, maxs_2d[1] + 250)); + ImGui::TreePop(); + } + +#define DRAW_ASSET_PROPERTY(__name__, __fmt__) \ + ImGui::Text(#__name__ ": " __fmt__, asset->__name__); \ + +#define DRAW_ASSET_PROPERTY_COPY(__name__) \ + ImGui::Text(#__name__ ": "); \ + ImGui::SameLine(); \ + if (ImGui::Button(asset->__name__)) \ + { \ + gui::copy_to_clipboard(asset->__name__); \ + } \ + + DRAW_ASSET_PROPERTY_COPY(name); + DRAW_ASSET_PROPERTY(numRootBones, "%i"); + DRAW_ASSET_PROPERTY(numsurfs, "%i"); + DRAW_ASSET_PROPERTY(lodRampType, "%i"); + DRAW_ASSET_PROPERTY(numBonePhysics, "%i"); + DRAW_ASSET_PROPERTY(numCompositeModels, "%i"); + DRAW_ASSET_PROPERTY(unk_float, "%f"); + DRAW_ASSET_PROPERTY(scale, "%f"); + + if (ImGui::TreeNode("bones")) + { + for (auto i = 0; i < asset->numBones; i++) + { + const auto bone_name = game::SL_ConvertToString(asset->boneNames[i]); + if (bone_name) + { + if (ImGui::Button(bone_name)) + { + gui::copy_to_clipboard(bone_name); + } + } + } + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("surface materials")) + { + game::Material* prev_material = nullptr; + + for (auto i = 0; i < asset->numsurfs; i++) + { + if (prev_material == asset->materialHandles[i]) + { + continue; + } + + prev_material = asset->materialHandles[i]; + + if (ImGui::Button(asset->materialHandles[i]->name)) + { + gui::copy_to_clipboard(asset->materialHandles[i]->name); + } + + add_view_button(i, game::ASSET_TYPE_MATERIAL, asset->materialHandles[i]->name); + } + + ImGui::TreePop(); + } + + if (asset->numCompositeModels > 0) + { + if (ImGui::TreeNode("composite models")) + { + for (auto i = 0; i < asset->numCompositeModels; i++) + { + if (ImGui::Button(asset->compositeModels[i]->name)) + { + gui::copy_to_clipboard(asset->compositeModels[i]->name); + } + + gui::asset_list::add_view_button(i, game::ASSET_TYPE_XMODEL, asset->compositeModels[i]->name); + } + + ImGui::TreePop(); + } + } + + return true; + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + gui::asset_list::add_asset_view(game::ASSET_TYPE_XMODEL, draw_xmodel_window); + } + }; +} + +REGISTER_COMPONENT(gui::asset_list::xmodel::component) diff --git a/src/client/component/gui_debug.cpp b/src/client/component/gui/debug.cpp similarity index 87% rename from src/client/component/gui_debug.cpp rename to src/client/component/gui/debug.cpp index d41cabdb..44a68462 100644 --- a/src/client/component/gui_debug.cpp +++ b/src/client/component/gui/debug.cpp @@ -4,8 +4,8 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include "scheduler.hpp" -#include "command.hpp" +#include "component/scheduler.hpp" +#include "component/command.hpp" #include "gui.hpp" #include "game/scripting/lua/context.hpp" @@ -20,6 +20,25 @@ namespace gui::debug { namespace { + struct debug_line + { + float start[3]; + float end[3]; + float color[4]; + bool deleted; + }; + + struct debug_square + { + float origin[3]; + float color[4]; + bool deleted; + }; + + std::vector debug_lines; + std::vector debug_squares; + std::mutex debug_items_mutex; + game::dvar_t* cl_paused = nullptr; enum object_type @@ -570,6 +589,12 @@ namespace gui::debug continue; } + float screen_center[2]{}; + ImGuiWindow* window = ImGui::GetCurrentWindow(); + world_pos_to_screen_pos(origin, screen_center); + window->DrawList->AddText(ImGui::GetDefaultFont(), ImGui::GetFontSize(), ImVec2(screen_center[0], + screen_center[1]), ImColor(255, 255, 0, 255), utils::string::va("%i", node->constant.type), 0, 0.f, 0); + switch (path_node_settings.type) { case object_type::square: @@ -654,6 +679,31 @@ namespace gui::debug } } + void draw_debug_items() + { + std::lock_guard _0(debug_items_mutex); + + for (auto& line : debug_lines) + { + if (line.deleted) + { + continue; + } + + draw_line(line.start, line.end, line.color, 1.f); + } + + for (auto& square : debug_squares) + { + if (square.deleted) + { + continue; + } + + draw_square(square.origin, 50.f, square.color); + } + } + void update_camera() { camera[0] = game::refdef->org[0]; @@ -688,12 +738,91 @@ namespace gui::debug } } + size_t add_debug_line(const float* start, const float* end, const float* color) + { + debug_line line{}; + std::memcpy(line.start, start, sizeof(float[3])); + std::memcpy(line.end, end, sizeof(float[3])); + std::memcpy(line.color, color, sizeof(float[4])); + + std::lock_guard _0(debug_items_mutex); + const auto index = debug_lines.size(); + debug_lines.emplace_back(line); + return index; + } + + void remove_debug_line(const size_t line) + { + std::lock_guard _0(debug_items_mutex); + if (line >= debug_lines.size()) + { + return; + } + + debug_lines[line].deleted = true; + } + + void set_debug_line_color(size_t line, const float* color) + { + std::lock_guard _0(debug_items_mutex); + if (line >= debug_lines.size()) + { + return; + } + + auto& line_ = debug_lines.at(line); + std::memcpy(line_.color, color, sizeof(float[4])); + } + + size_t add_debug_square(const float* origin, const float* color) + { + debug_square line{}; + std::memcpy(line.origin, origin, sizeof(float[3])); + std::memcpy(line.color, color, sizeof(float[4])); + + std::lock_guard _0(debug_items_mutex); + const auto index = debug_squares.size(); + debug_squares.emplace_back(line); + return index; + } + + void remove_debug_square(const size_t square) + { + std::lock_guard _0(debug_items_mutex); + if (square >= debug_squares.size()) + { + return; + } + + debug_squares[square].deleted = true; + } + + void set_debug_square_color(size_t square, const float* color) + { + std::lock_guard _0(debug_items_mutex); + if (square >= debug_squares.size()) + { + return; + } + + auto& square_ = debug_squares.at(square); + std::memcpy(square_.color, color, sizeof(float[4])); + } + + void reset_debug_items() + { + std::lock_guard _0(debug_items_mutex); + debug_lines.clear(); + debug_squares.clear(); + } + class component final : public component_interface { public: void post_unpack() override { - gui::on_frame(draw_window); + gui::register_menu("debug", "Debug", draw_window); + gui::on_frame([]() { if (!game::SV_Loaded() || cl_paused->current.integer) @@ -704,6 +833,7 @@ namespace gui::debug begin_render_window(); draw_nodes(); draw_triggers(); + draw_debug_items(); end_render_window(); }, true); diff --git a/src/client/component/gui/debug.hpp b/src/client/component/gui/debug.hpp new file mode 100644 index 00000000..2bac408c --- /dev/null +++ b/src/client/component/gui/debug.hpp @@ -0,0 +1,12 @@ +namespace gui::debug +{ + size_t add_debug_line(const float* start, const float* end, const float* color); + void remove_debug_line(const size_t line); + void set_debug_line_color(size_t line, const float* color); + + size_t add_debug_square(const float* origin, const float* color); + void remove_debug_square(const size_t line); + void set_debug_square_color(size_t square, const float* color); + + void reset_debug_items(); +} diff --git a/src/client/component/gui_entity_list.cpp b/src/client/component/gui/entity_list.cpp similarity index 98% rename from src/client/component/gui_entity_list.cpp rename to src/client/component/gui/entity_list.cpp index cd991e8c..7458ce77 100644 --- a/src/client/component/gui_entity_list.cpp +++ b/src/client/component/gui/entity_list.cpp @@ -4,10 +4,10 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include "scheduler.hpp" -#include "command.hpp" +#include "component/scheduler.hpp" +#include "component/command.hpp" +#include "component/scripting.hpp" #include "gui.hpp" -#include "scripting.hpp" #include "game/scripting/execution.hpp" @@ -807,14 +807,8 @@ namespace gui::entity_list ImGui::End(); } - void on_frame() + void render_window() { - static auto* enabled = &gui::enabled_menus["entity_list"]; - if (!*enabled) - { - return; - } - data_.access([](data_t& data) { if (!game::CL_IsCgameInitialized()) @@ -845,7 +839,8 @@ namespace gui::entity_list public: void post_unpack() override { - gui::on_frame(on_frame); + gui::register_menu("entity_list", "Entity List", render_window); + scheduler::loop([]() { try diff --git a/src/client/component/gui.cpp b/src/client/component/gui/gui.cpp similarity index 75% rename from src/client/component/gui.cpp rename to src/client/component/gui/gui.cpp index c421ecf7..73b1e0a0 100644 --- a/src/client/component/gui.cpp +++ b/src/client/component/gui/gui.cpp @@ -4,9 +4,9 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include "scheduler.hpp" +#include "component/scheduler.hpp" +#include "component/console.hpp" #include "gui.hpp" -#include "console.hpp" #include #include @@ -34,9 +34,17 @@ namespace gui LPARAM lParam; }; + struct menu_t + { + std::string name; + std::string title; + std::function render; + }; + utils::concurrency::container> on_frame_callbacks; utils::concurrency::container> notifications; utils::concurrency::container> event_queue; + std::vector menus; ID3D11Device* device; ID3D11DeviceContext* device_context; @@ -67,6 +75,63 @@ namespace gui }); } + std::vector imgui_colors = + { + ImGuiCol_FrameBg, + ImGuiCol_FrameBgHovered, + ImGuiCol_FrameBgActive, + ImGuiCol_TitleBgActive, + ImGuiCol_ScrollbarGrabActive, + ImGuiCol_CheckMark, + ImGuiCol_SliderGrab, + ImGuiCol_SliderGrabActive, + ImGuiCol_Button, + ImGuiCol_ButtonHovered, + ImGuiCol_ButtonActive, + ImGuiCol_Header, + ImGuiCol_HeaderHovered, + ImGuiCol_HeaderActive, + ImGuiCol_SeparatorHovered, + ImGuiCol_SeparatorActive, + ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGripHovered, + ImGuiCol_ResizeGripActive, + ImGuiCol_TextSelectedBg, + ImGuiCol_NavHighlight, + }; + + void update_colors() + { + auto& style = ImGui::GetStyle(); + const auto colors = style.Colors; + + const auto now = std::chrono::system_clock::now(); + const auto days = std::chrono::floor(now); + std::chrono::year_month_day y_m_d{days}; + + if (y_m_d.month() != std::chrono::month(6)) + { + return; + } + + for (const auto& id : imgui_colors) + { + const auto color = colors[id]; + + ImVec4 hsv_color = + { + static_cast((game::Sys_Milliseconds() / 100) % 256) / 255.f, + 1.f, 1.f, 1.f, + }; + + ImVec4 rgba_color{}; + ImGui::ColorConvertHSVtoRGB(hsv_color.x, hsv_color.y, hsv_color.z, rgba_color.x, rgba_color.y, rgba_color.z); + + rgba_color.w = color.w; + colors[id] = rgba_color; + } + } + void new_gui_frame() { ImGui::GetIO().MouseDrawCursor = toggled; @@ -79,6 +144,8 @@ namespace gui *game::keyCatchers &= ~0x10; } + update_colors(); + ImGui_ImplDX11_NewFrame(); ImGui_ImplWin32_NewFrame(); run_event_queue(); @@ -161,11 +228,10 @@ namespace gui { if (ImGui::BeginMenu("Windows")) { - menu_checkbox("Asset list", "asset_list"); - menu_checkbox("Entity list", "entity_list"); - menu_checkbox("Console", "console"); - menu_checkbox("Script console", "script_console"); - menu_checkbox("Debug", "debug"); + for (const auto& menu : menus) + { + menu_checkbox(menu.title, menu.name); + } ImGui::EndMenu(); } @@ -194,10 +260,23 @@ namespace gui } } + void shutdown_gui() + { + if (initialized) + { + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + } + + initialized = false; + } + HRESULT d3d11_create_device_stub(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, const D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext) { + shutdown_gui(); + const auto result = D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext); @@ -210,21 +289,6 @@ namespace gui return result; } - void dxgi_swap_chain_present_stub(utils::hook::assembler& a) - { - a.pushad64(); - a.call_aligned(gui_on_frame); - a.popad64(); - - a.mov(r8d, esi); - a.mov(edx, r15d); - a.mov(rcx, rdi); - a.call(rbx); - a.mov(ecx, eax); - - a.jmp(0x1407A14D1); - } - utils::hook::detour wnd_proc_hook; LRESULT wnd_proc_stub(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -232,7 +296,7 @@ namespace gui { event_queue.access([hWnd, msg, wParam, lParam](std::vector& queue) { - queue.push_back({hWnd, msg, wParam, lParam}); + queue.emplace_back(hWnd, msg, wParam, lParam); }); } @@ -271,7 +335,7 @@ namespace gui { on_frame_callbacks.access([always, callback](std::vector& callbacks) { - callbacks.push_back({callback, always}); + callbacks.emplace_back(callback, always); }); } @@ -300,6 +364,29 @@ namespace gui gui::notification("Text copied to clipboard", utils::string::va("\"%s\"", text.data())); } + void register_menu(const std::string& name, const std::string& title, + const std::function& callback, bool always) + { + menus.emplace_back(name, title, callback); + enabled_menus[name] = false; + + on_frame([=] + { + if (enabled_menus.at(name)) + { + callback(); + } + }, always); + } + + void register_callback(const std::function& callback, bool always) + { + on_frame([=] + { + callback(); + }, always); + } + class component final : public component_interface { public: @@ -328,11 +415,7 @@ namespace gui void pre_destroy() override { - if (initialized) - { - ImGui_ImplWin32_Shutdown(); - ImGui::DestroyContext(); - } + shutdown_gui(); } }; } diff --git a/src/client/component/gui.hpp b/src/client/component/gui/gui.hpp similarity index 77% rename from src/client/component/gui.hpp rename to src/client/component/gui/gui.hpp index ad8b3aee..e55c90dc 100644 --- a/src/client/component/gui.hpp +++ b/src/client/component/gui/gui.hpp @@ -20,4 +20,9 @@ namespace gui bool is_menu_open(const std::string& name); void notification(const std::string& title, const std::string& text, const std::chrono::milliseconds duration = 3s); void copy_to_clipboard(const std::string& text); + + void register_menu(const std::string& name, const std::string& title, + const std::function& callback, bool always = false); + + void register_callback(const std::function& callback, bool always = false); } \ No newline at end of file diff --git a/src/client/component/gui_script_console.cpp b/src/client/component/gui/script_console.cpp similarity index 94% rename from src/client/component/gui_script_console.cpp rename to src/client/component/gui/script_console.cpp index 2c036934..c5a785b5 100644 --- a/src/client/component/gui_script_console.cpp +++ b/src/client/component/gui/script_console.cpp @@ -4,8 +4,8 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include "scheduler.hpp" -#include "command.hpp" +#include "component/scheduler.hpp" +#include "component/command.hpp" #include "gui.hpp" #include "game/scripting/lua/context.hpp" @@ -114,13 +114,8 @@ namespace gui::script_console return 0; } - void on_frame() + void render_window() { - if (!gui::enabled_menus["script_console"]) - { - return; - } - menu_data.access([](menu_data_t& menu_data_) { if (!game::CL_IsCgameInitialized()) @@ -132,7 +127,8 @@ namespace gui::script_console static const auto input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; - ImGui::Begin("Script console", &gui::enabled_menus["script_console"]); + static auto* enabled = &gui::enabled_menus["script_console"]; + ImGui::Begin("Script console", enabled); if (ImGui::BeginPopup("Options")) { @@ -222,7 +218,7 @@ namespace gui::script_console public: void post_unpack() override { - gui::on_frame(on_frame); + gui::register_menu("script_console", "Script Console", render_window); scheduler::loop(run_commands, scheduler::pipeline::server); } }; diff --git a/src/client/component/gui_asset_list.cpp b/src/client/component/gui_asset_list.cpp deleted file mode 100644 index d94241cb..00000000 --- a/src/client/component/gui_asset_list.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "scheduler.hpp" -#include "command.hpp" -#include "gui.hpp" -#include "fastfiles.hpp" - -#include -#include - -namespace asset_list -{ - namespace - { - bool shown_assets[game::XAssetType::ASSET_TYPE_COUNT]; - std::string asset_type_filter; - std::string assets_name_filter[game::XAssetType::ASSET_TYPE_COUNT]; - - void on_frame() - { - static auto* enabled = &gui::enabled_menus["asset_list"]; - if (!*enabled) - { - return; - } - - ImGui::Begin("Asset list", enabled); - - ImGui::InputText("asset type", &asset_type_filter); - ImGui::BeginChild("asset type list"); - - for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) - { - const auto name = game::g_assetNames[i]; - const auto type = static_cast(i); - - if (utils::string::strstr_lower(name, asset_type_filter.data())) - { - ImGui::Checkbox(name, &shown_assets[type]); - } - } - - ImGui::EndChild(); - ImGui::End(); - - for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) - { - const auto name = game::g_assetNames[i]; - const auto type = static_cast(i); - - if (!shown_assets[type]) - { - continue; - } - - ImGui::SetNextWindowSizeConstraints(ImVec2(500, 500), ImVec2(1000, 1000)); - ImGui::Begin(name, &shown_assets[type]); - - ImGui::InputText("asset name", &assets_name_filter[type]); - ImGui::BeginChild("assets list"); - - size_t asset_num{}; - fastfiles::enum_assets(type, [type, &asset_num](const game::XAssetHeader header) - { - const auto asset = game::XAsset{type, header}; - auto asset_name = game::DB_GetXAssetName(&asset); - if (asset_name[0] == '\0') - { - asset_name = utils::string::va("__%i", asset_num); - } - - if (utils::string::strstr_lower(asset_name, assets_name_filter[type].data()) && ImGui::Button(asset_name)) - { - gui::copy_to_clipboard(asset_name); - } - - asset_num++; - }, true); - - ImGui::EndChild(); - ImGui::End(); - } - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - gui::on_frame(on_frame); - } - }; -} - -REGISTER_COMPONENT(asset_list::component) diff --git a/src/client/component/imagefiles.cpp b/src/client/component/imagefiles.cpp index ea2e0782..2d10cb2b 100644 --- a/src/client/component/imagefiles.cpp +++ b/src/client/component/imagefiles.cpp @@ -26,6 +26,7 @@ namespace imagefiles char __pad0[88]; }; + utils::memory::allocator image_file_allocator; std::unordered_map image_file_unk_map; std::unordered_map image_file_handles; @@ -44,7 +45,7 @@ namespace imagefiles const auto name = get_image_file_name(); if (image_file_unk_map.find(name) == image_file_unk_map.end()) { - const auto unk = utils::memory::get_allocator()->allocate(); + const auto unk = image_file_allocator.allocate(); image_file_unk_map[name] = unk; return unk; } @@ -65,7 +66,6 @@ namespace imagefiles void db_create_gfx_image_stream_stub(utils::hook::assembler& a) { - const auto check_image_file_handle = a.newLabel(); const auto handle_is_open = a.newLabel(); a.movzx(eax, cx); @@ -129,6 +129,41 @@ namespace imagefiles } } + void close_custom_handles() + { + const auto db_fs = game::DB_FSInitialize(); + for (const auto& handle : image_file_handles) + { + if (handle.second != nullptr) + { + db_fs->vftbl->Close(db_fs, handle.second); + } + } + + image_file_handles.clear(); + image_file_unk_map.clear(); + image_file_allocator.clear(); + } + + void close_handle(const std::string& fastfile) + { + if (!image_file_handles.contains(fastfile)) + { + return; + } + + const auto db_fs = game::DB_FSInitialize(); + const auto handle = image_file_handles[fastfile]; + if (handle != nullptr) + { + db_fs->vftbl->Close(db_fs, handle); + } + + image_file_handles.erase(fastfile); + image_file_allocator.free(image_file_unk_map[fastfile]); + image_file_unk_map.erase(fastfile); + } + class component final : public component_interface { public: diff --git a/src/client/component/imagefiles.hpp b/src/client/component/imagefiles.hpp new file mode 100644 index 00000000..ff309625 --- /dev/null +++ b/src/client/component/imagefiles.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace imagefiles +{ + void close_custom_handles(); + void close_handle(const std::string& fastfile); +} diff --git a/src/client/component/images.cpp b/src/client/component/images.cpp index 4f9bbd44..6217134b 100644 --- a/src/client/component/images.cpp +++ b/src/client/component/images.cpp @@ -60,8 +60,10 @@ namespace images return false; } - image->imageFormat = 0x1000003; - image->resourceSize = -1; + image->mapType = game::MAPTYPE_2D; + image->semantic = 2; + image->category = 3; + image->flags = 0; D3D11_SUBRESOURCE_DATA data{}; data.SysMemPitch = raw_image->get_width() * 4; @@ -69,7 +71,7 @@ namespace images data.pSysMem = raw_image->get_buffer(); game::Image_Setup(image, raw_image->get_width(), raw_image->get_height(), image->depth, image->numElements, - image->imageFormat, DXGI_FORMAT_R8G8B8A8_UNORM, 0, image->name, &data); + image->mapType, DXGI_FORMAT_R8G8B8A8_UNORM, 0, image->name, &data); return true; } diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 6ce036bd..a2d9bb30 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -4,7 +4,7 @@ #include "game/game.hpp" #include "game_console.hpp" -#include "gui.hpp" +#include "gui/gui.hpp" #include "game/ui_scripting/execution.hpp" #include diff --git a/src/client/component/language.cpp b/src/client/component/language.cpp index c534853c..de105f8f 100644 --- a/src/client/component/language.cpp +++ b/src/client/component/language.cpp @@ -12,6 +12,8 @@ namespace language { + game::language_values languages[game::LANGUAGE_COUNT + 1]{}; + namespace { std::unordered_set non_latin_languages = @@ -48,6 +50,7 @@ namespace language std::unordered_set custom_languages = { {game::LANGUAGE_CZECH}, + {game::LANGUAGE_TURKISH}, }; const char* get_loc_language_string() @@ -75,7 +78,7 @@ namespace language const auto lower = utils::string::to_lower(name); for (auto i = 0; i < game::LANGUAGE_COUNT; i++) { - if (game::languages[i].name == lower) + if (languages[i].name == lower) { return true; } @@ -88,7 +91,7 @@ namespace language { for (const auto& language : custom_languages) { - if (game::languages[language].name == name || game::languages[language].shortname == name) + if (languages[language].name == name || languages[language].shortname == name) { return true; } @@ -140,7 +143,7 @@ namespace language return; } - const auto language = game::languages[index]; + const auto language = languages[index]; set(language.name); } @@ -158,9 +161,57 @@ namespace language utils::io::remove_file(OLD_LANGUAGE_FILE); } + std::memcpy(languages, game::languages.get(), sizeof(game::language_values) * game::LANGUAGE_COUNT_ORIGINAL); + languages[game::LANGUAGE_TURKISH].name = "turkish"; + languages[game::LANGUAGE_TURKISH].shortname = "tur"; + languages[game::LANGUAGE_TURKISH].prefix1 = "tr"; + languages[game::LANGUAGE_TURKISH].prefix2 = "tr"; + languages[game::LANGUAGE_TURKISH].prefix3 = "tr"; + languages[game::LANGUAGE_TURKISH].is_supported = 1; + + utils::hook::inject(0x1405E3B67 + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E5217 + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E5223 + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E524D + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E5398 + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E53AB + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E53E8 + 3, &languages[game::LANGUAGE_ENGLISH].name); + utils::hook::inject(0x1405E6273 + 3, &languages[game::LANGUAGE_ENGLISH].name); + + utils::hook::inject(0x1405E5197 + 3, &languages[game::LANGUAGE_ENGLISH].shortname); + utils::hook::inject(0x1405E51A3 + 3, &languages[game::LANGUAGE_ENGLISH].shortname); + utils::hook::inject(0x1405E58B2 + 3, &languages[game::LANGUAGE_ENGLISH].shortname); + utils::hook::inject(0x1405E58BF + 3, &languages[game::LANGUAGE_ENGLISH].shortname); + utils::hook::inject(0x1405E6144 + 3, &languages[game::LANGUAGE_ENGLISH].shortname); + utils::hook::inject(0x1405E6189 + 3, &languages[game::LANGUAGE_ENGLISH].shortname); + + utils::hook::inject(0x1405E51E7 + 3, &languages[game::LANGUAGE_ENGLISH].prefix2); + utils::hook::inject(0x1405E51F3 + 3, &languages[game::LANGUAGE_ENGLISH].prefix2); + + utils::hook::inject(0x1405E5157 + 3, &languages[game::LANGUAGE_ENGLISH].prefix3); + utils::hook::inject(0x1405E5163 + 3, &languages[game::LANGUAGE_ENGLISH].prefix3); + + utils::hook::inject(0x1405E5470 + 3, &languages[game::LANGUAGE_ENGLISH].is_supported); + utils::hook::inject(0x1405E57FA + 3, &languages[game::LANGUAGE_ENGLISH].is_supported); + utils::hook::inject(0x1405E612F + 3, &languages[game::LANGUAGE_ENGLISH].is_supported); + + utils::hook::inject(0x1405E5D79 + 3, &languages[game::LANGUAGE_GERMAN].is_supported); + + utils::hook::inject(0x1405E5E3B + 3, &languages[game::LANGUAGE_ENGLISH_SAFE].is_supported); + + utils::hook::inject(0x1405E5257 + 3, &languages[game::LANGUAGE_COUNT].name); + + utils::hook::set(0x140342B59 + 2, game::LANGUAGE_COUNT); + utils::hook::set(0x1405E5390 + 2, game::LANGUAGE_COUNT - 1); + utils::hook::set(0x1405E518B + 2, game::LANGUAGE_COUNT - 1); + utils::hook::set(0x1405E520B + 2, game::LANGUAGE_COUNT - 1); + + utils::hook::set(0x1405E556C + 4, game::LANGUAGE_COUNT - 1); + utils::hook::set(0x1403D7480 + 4, game::LANGUAGE_COUNT - 1); + for (const auto& language : custom_languages) { - game::languages[language].is_supported = 1; + languages[language].is_supported = 1; } } }; diff --git a/src/client/component/language.hpp b/src/client/component/language.hpp index 5cc74dac..ae053c67 100644 --- a/src/client/component/language.hpp +++ b/src/client/component/language.hpp @@ -4,6 +4,8 @@ namespace language { + extern game::language_values languages[game::LANGUAGE_COUNT + 1]; + std::string get_default_language(); bool is_valid_language(const std::string& name); bool is_custom_language(const std::string& name); diff --git a/src/client/component/logger.cpp b/src/client/component/logger.cpp index 5f5fe60b..c5d14ccf 100644 --- a/src/client/component/logger.cpp +++ b/src/client/component/logger.cpp @@ -14,8 +14,8 @@ namespace logger namespace { utils::hook::detour com_error_hook; - utils::hook::detour nullsub_48_hook; utils::hook::detour sub_32AEF0; + utils::hook::detour bnet_print_hook; game::dvar_t* logger_dev = nullptr; @@ -146,6 +146,17 @@ namespace logger vsnprintf(buffer, buffer_length, msg, va); console::warn(buffer); } + + struct bnet_unk_t + { + const char* string; + }; + + void bnet_print_stub(bnet_unk_t* a1) + { + console::debug("[BNET] %s\n", a1->string); + bnet_print_hook.invoke(a1); + } } class component final : public component_interface @@ -163,6 +174,8 @@ namespace logger utils::hook::call(0x140791A01, r_warn_once_per_frame_vsnprintf_stub); + bnet_print_hook.create(0x1402736D0, bnet_print_stub); + logger_dev = dvars::register_bool("logger_dev", false, game::DVAR_FLAG_SAVED, "Print dev stuff"); } }; diff --git a/src/client/component/map_patches.cpp b/src/client/component/map_patches.cpp new file mode 100644 index 00000000..f2b6df57 --- /dev/null +++ b/src/client/component/map_patches.cpp @@ -0,0 +1,64 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include + +namespace map_patches +{ + struct GfxLightGridTree + { + unsigned char index; + unsigned char maxDepth; + char unused[2]; + int nodeCount; + int leafCount; + int coordMinGridSpace[3]; + int coordMaxGridSpace[3]; + int coordHalfSizeGridSpace[3]; + int defaultColorIndexBitCount; + int defaultLightIndexBitCount; + unsigned int* p_nodeTable; + int leafTableSize; + unsigned char* p_leafTable; + }; + + enum leaf_table_version : std::int8_t + { + h2 = 0, + h1 = 0, + s1 = 0, + iw6 = 1, + }; + + utils::hook::detour r_decode_light_grid_block_hook; + void r_decode_light_grid_block_stub(GfxLightGridTree* p_tree, int child_mask, + char child_index, int encoded_node_address, char* p_node_raw, char* p_leaf_raw) + { + constexpr auto p_address = 0x140766F7F; + if (p_tree->unused[0] == leaf_table_version::iw6) + { + utils::hook::set(p_address, 6); // iw6 + } + else + { + utils::hook::set(p_address, 7); // s1,h1,h2 + } + + r_decode_light_grid_block_hook.invoke(p_tree, child_mask, + child_index, encoded_node_address, p_node_raw, p_leaf_raw); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // patch iw6 leafTable decoding + r_decode_light_grid_block_hook.create(0x140765420, r_decode_light_grid_block_stub); + } + }; +} + +REGISTER_COMPONENT(map_patches::component) diff --git a/src/client/component/mapents.cpp b/src/client/component/mapents.cpp index bf9988ef..1108f10b 100644 --- a/src/client/component/mapents.cpp +++ b/src/client/component/mapents.cpp @@ -8,9 +8,6 @@ #include "command.hpp" #include "game/scripting/functions.hpp" -#include -#include - #include #include #include @@ -50,7 +47,7 @@ namespace mapents continue; } - const auto token = xsk::gsc::h2::resolver::token_name(static_cast(id)); + const auto token = scripting::find_token_single(static_cast(id)); const auto key = "\"" + token + "\""; const auto new_line = key + line.substr(first_space); @@ -76,14 +73,14 @@ namespace mapents fastfiles::enum_assets(game::ASSET_TYPE_MAP_ENTS, [](game::XAssetHeader header) { - if (header.mapents == nullptr) + if (header.mapEnts == nullptr) { console::info("Failed to dump mapents\n"); return; } - const auto dest = utils::string::va("dumps/%s.ents", header.mapents->name); - const auto str = std::string(header.mapents->entityString, header.mapents->numEntityChars); + const auto dest = utils::string::va("dumps/%s.ents", header.mapEnts->name); + const auto str = std::string(header.mapEnts->entityString, header.mapEnts->numEntityChars); const auto data = replace_mapents_keys(str); utils::io::write_file(dest, data, false); console::info("Mapents dumped to %s\n", dest); diff --git a/src/client/component/memory.cpp b/src/client/component/memory.cpp new file mode 100644 index 00000000..eaacd465 --- /dev/null +++ b/src/client/component/memory.cpp @@ -0,0 +1,104 @@ +#include +#include "loader/component_loader.hpp" + +#include "memory.hpp" + +#include "game/game.hpp" + +#include +#include + +namespace memory +{ + namespace + { + constexpr auto mem_low_size = 0x80000000ull * 2; // default: 0x80000000 + constexpr auto mem_high_size = 0x80000000ull * 2; // default: 0x80000000 + + constexpr auto script_mem_low_size = 0x200000ull; // default: 0x200000 + constexpr auto script_mem_high_size = 0x200000ull + custom_script_mem_size; // default: 0x200000 + + constexpr auto phys_mem_low_size = 0x400000000ull * 2; // default: 0x400000000 + constexpr auto phys_mem_high_size = 0x400000000ull * 2; // default: 0x400000000 + + constexpr auto pmem_alloc_size = + mem_low_size + + mem_high_size + + script_mem_low_size + + script_mem_high_size + + phys_mem_low_size + + phys_mem_high_size; + + constexpr auto mem_low_buf = 0; + constexpr auto mem_high_buf = mem_low_buf + mem_low_size; + + constexpr auto script_mem_low_buf = mem_high_buf + mem_high_size; + constexpr auto script_mem_high_buf = script_mem_low_buf + script_mem_low_size; + + constexpr auto phys_mem_low_buf = script_mem_high_buf + script_mem_high_size; + constexpr auto phys_mem_high_buf = phys_mem_low_buf + phys_mem_low_size; + + constexpr auto stream_mem_size = 0x2000000ull; + + void pmem_init() + { + const auto size = pmem_alloc_size; + const auto allocated_buffer = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_READWRITE); + auto buffer = reinterpret_cast(allocated_buffer); + *game::pmem_size = size; + *game::pmem_buffer = buffer; + + std::memset(game::g_mem, 0, sizeof(*game::g_mem)); + + game::g_mem->prim[game::PHYS_ALLOC_LOW].buf = buffer + mem_low_buf; + game::g_mem->prim[game::PHYS_ALLOC_LOW].pos = mem_low_size; + game::g_mem->prim[game::PHYS_ALLOC_HIGH].buf = buffer + mem_high_buf; + game::g_mem->prim[game::PHYS_ALLOC_HIGH].pos = mem_high_size; + + game::g_mem->prim[game::PHYS_ALLOC_LOW].unk1 = 0; + game::g_mem->prim[game::PHYS_ALLOC_HIGH].unk1 = 0; + + std::memset(game::g_scriptmem, 0, sizeof(*game::g_scriptmem)); + + game::g_scriptmem->prim[game::PHYS_ALLOC_LOW].buf = buffer + script_mem_low_buf; + game::g_scriptmem->prim[game::PHYS_ALLOC_LOW].pos = script_mem_low_size; + game::g_scriptmem->prim[game::PHYS_ALLOC_HIGH].buf = buffer + script_mem_high_buf; + game::g_scriptmem->prim[game::PHYS_ALLOC_HIGH].pos = script_mem_high_size; + + game::g_scriptmem->prim[game::PHYS_ALLOC_LOW].unk1 = 0; + game::g_scriptmem->prim[game::PHYS_ALLOC_HIGH].unk1 = 0; + + std::memset(game::g_physmem, 0, sizeof(*game::g_physmem)); + + game::g_physmem->prim[game::PHYS_ALLOC_LOW].buf = buffer + phys_mem_low_buf; + game::g_physmem->prim[game::PHYS_ALLOC_LOW].pos = phys_mem_low_size; + game::g_physmem->prim[game::PHYS_ALLOC_HIGH].buf = buffer + phys_mem_high_buf; + game::g_physmem->prim[game::PHYS_ALLOC_HIGH].pos = phys_mem_high_size; + + game::g_physmem->prim[game::PHYS_ALLOC_LOW].unk1 = 2; + game::g_physmem->prim[game::PHYS_ALLOC_HIGH].unk1 = 2; + + *game::stream_size = stream_mem_size; + *game::stream_buffer = reinterpret_cast(VirtualAlloc(NULL, *game::stream_size, MEM_COMMIT, PAGE_READWRITE)); + } + + void pmem_init_stub() + { + pmem_init(); + const auto script_mem_size = script_mem_low_size + script_mem_high_size; + utils::hook::set(0x14061EC72, static_cast(script_mem_size)); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // patch PMem_Init, so we can use whatever memory size we want + utils::hook::call(0x1405A4798, pmem_init_stub); + } + }; +} + +REGISTER_COMPONENT(memory::component) diff --git a/src/client/component/memory.hpp b/src/client/component/memory.hpp new file mode 100644 index 00000000..c0f0ea63 --- /dev/null +++ b/src/client/component/memory.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace memory +{ + constexpr auto custom_script_mem_size = 0x1000000ull; +} diff --git a/src/client/component/menus.cpp b/src/client/component/menus.cpp new file mode 100644 index 00000000..368b3f90 --- /dev/null +++ b/src/client/component/menus.cpp @@ -0,0 +1,61 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "console.hpp" + +#include + +namespace menus +{ + namespace + { + constexpr auto patch_menu_list_name = "ui/patch_code.txt"; + + void ui_add_menu_list_stub(void* context, void* menu_list, int a3) + { + game::UI_AddMenuList(context, menu_list, a3); + + if (game::DB_XAssetExists(game::ASSET_TYPE_MENULIST, patch_menu_list_name) && + !game::DB_IsXAssetDefault(game::ASSET_TYPE_MENULIST, patch_menu_list_name)) + { + const auto patch_code_list = game::UI_LoadMenus(patch_menu_list_name); + game::UI_AddMenuList(context, patch_code_list, a3); + } + } + + int menus_open_by_name_stub(void* context, const char* name) + { + const std::string override_name = "override/"s + name; + const auto override_menu = game::Menus_FindByName(context, override_name.data()); + + if (override_menu) + { + game::Menus_Open(context, override_menu, 0); + return 1; + } + + const auto menu = game::Menus_FindByName(context, name); + if (menu) + { + game::Menus_Open(context, menu, 0); + return 1; + } + + return 0; + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + utils::hook::call(0x1405F0A45, ui_add_menu_list_stub); + utils::hook::jump(game::Menus_OpenByName, menus_open_by_name_stub); + } + }; +} + +REGISTER_COMPONENT(menus::component) diff --git a/src/client/component/mod_stats.cpp b/src/client/component/mod_stats.cpp new file mode 100644 index 00000000..814750df --- /dev/null +++ b/src/client/component/mod_stats.cpp @@ -0,0 +1,245 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "console.hpp" +#include "filesystem.hpp" +#include "mods.hpp" +#include "mod_stats.hpp" + +#include +#include +#include +#include +#include +#include + +namespace mod_stats +{ + namespace + { + struct + { + utils::concurrency::container current_stats; + std::atomic_bool modified_stats; + std::atomic_bool kill_thread; + std::thread stats_write_thread; + } globals{}; + + std::optional get_mod_basename() + { + const auto mod = mods::get_mod(); + if (!mod.has_value()) + { + return {}; + } + + const auto& value = mod.value(); + const auto last_index = value.find_last_of('/'); + const auto basename = value.substr(last_index + 1); + return {basename}; + } + + std::optional get_stats_path() + { + const auto current_mod = get_mod_basename(); + if (!current_mod.has_value()) + { + return {}; + } + + const auto path = utils::properties::get_appdata_path() / + "player/modstats" / (current_mod.value() + ".json"); + return {path.generic_string()}; + } + + nlohmann::json default_mod_stats() + { + nlohmann::json json; + json["maps"] = {}; + return json; + } + + nlohmann::json verify_mod_stats(nlohmann::json& json) + { + if (!json.is_object()) + { + json = {}; + } + + if (!json.contains("maps") || !json["maps"].is_object()) + { + json["maps"] = {}; + } + + return json; + } + + nlohmann::json parse_mod_stats() + { + const auto stats_file = get_stats_path(); + if (!stats_file.has_value()) + { + return default_mod_stats(); + } + + const auto& stats_file_value = stats_file.value(); + if (!utils::io::file_exists(stats_file_value)) + { + return default_mod_stats(); + } + + const auto data = utils::io::read_file(stats_file_value); + try + { + auto json = nlohmann::json::parse(data); + return verify_mod_stats(json); + } + catch (const std::exception& e) + { + console::error("Failed to parse json mod stats file \"%s\": %s", + stats_file_value.data(), e.what()); + } + + return default_mod_stats(); + } + } + + void initialize() + { + globals.modified_stats = false; + globals.current_stats.access([](mod_stats_t& stats) + { + stats = parse_mod_stats(); + }); + } + + utils::concurrency::container& get_stats() + { + return globals.current_stats; + } + + void set_modified() + { + globals.modified_stats = true; + } + + void write() + { + const auto path = get_stats_path(); + if (!path.has_value()) + { + return; + } + + console::debug("[Mod stats] writing stats\n"); + globals.current_stats.access([&](mod_stats_t& stats) + { + const auto dump = stats.dump(4); + const auto& path_value = path.value(); + utils::io::write_file(path_value, dump, false); + globals.modified_stats = false; + }); + } + + nlohmann::json get(const std::string& key, const nlohmann::json& default_value) + { + return get_stats().access([&](mod_stats_t& stats) + -> nlohmann::json + { + if (!stats.is_object() || stats[key].is_null()) + { + return default_value; + } + + return stats[key]; + }); + } + + nlohmann::json get_all() + { + return get_stats().access([&](mod_stats_t& stats) + -> nlohmann::json + { + return stats; + }); + } + + nlohmann::json get_struct(const std::string& name, const std::string& field, const nlohmann::json& default_value) + { + return get_stats().access([&](mod_stats_t& stats) + -> nlohmann::json + { + if (!stats.is_object() || !stats[name].is_object() || stats[name][field].is_null()) + { + return default_value; + } + + return stats[name][field]; + }); + } + + void set(const std::string& key, const nlohmann::json& value) + { + get_stats().access([&](mod_stats_t& stats) + { + stats[key] = value; + set_modified(); + }); + } + + void set_struct(const std::string& name, const std::string& field, const nlohmann::json& value) + { + get_stats().access([&](mod_stats_t& stats) + { + stats[name][field] = value; + set_modified(); + }); + } + + void set_all(const nlohmann::json& value) + { + get_stats().access([&](mod_stats_t& stats) + { + stats = value; + set_modified(); + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + globals.stats_write_thread = utils::thread::create_named_thread("Stats Write (H2-Mod)", []() + { + while (!globals.kill_thread) + { + const auto _0 = gsl::finally([] + { + std::this_thread::sleep_for(50ms); + }); + + if (!globals.modified_stats) + { + continue; + } + + write(); + } + }); + } + + void pre_destroy() override + { + globals.kill_thread = true; + if (globals.stats_write_thread.joinable()) + { + globals.stats_write_thread.join(); + } + } + }; +} + +REGISTER_COMPONENT(mod_stats::component) diff --git a/src/client/component/mod_stats.hpp b/src/client/component/mod_stats.hpp new file mode 100644 index 00000000..957b9d11 --- /dev/null +++ b/src/client/component/mod_stats.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +namespace mod_stats +{ + using mod_stats_t = nlohmann::ordered_json; + utils::concurrency::container& get_stats(); + + void initialize(); + void set_modified(); + void write(); + + nlohmann::json get(const std::string& key, const nlohmann::json& default_value = {}); + nlohmann::json get_struct(const std::string& name, const std::string& field, const nlohmann::json& default_value = {}); + nlohmann::json get_all(); + + void set(const std::string& key, const nlohmann::json& value); + void set_struct(const std::string& name, const std::string& field, const nlohmann::json& value); + void set_all(const nlohmann::json& value); +} diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index 40a0b897..02e336cc 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -9,11 +9,13 @@ #include "filesystem.hpp" #include "fonts.hpp" #include "mods.hpp" +#include "mod_stats.hpp" #include "loadscreen.hpp" #include #include #include +#include #define MOD_FOLDER "mods" #define MOD_STATS_FOLDER "players2/modstats" @@ -40,16 +42,53 @@ namespace mods {"game", game::DB_ZONE_GAME}, }; + std::unordered_map priority_map = + { + {"none", zone_priority::none}, + + {"pre_gfx", zone_priority::post_gfx}, + {"post_gfx", zone_priority::post_gfx}, + {"post_common", zone_priority::post_common}, + + {"pre_map", zone_priority::pre_map}, + {"post_map", zone_priority::post_map}, + }; + unsigned int get_alloc_flag(const std::string& name) { const auto lower = utils::string::to_lower(name); - if (alloc_flags_map.find(lower) != alloc_flags_map.end()) + if (const auto iter = alloc_flags_map.find(lower); iter != alloc_flags_map.end()) { - return alloc_flags_map[lower]; + return iter->second; } return game::DB_ZONE_COMMON; } + + zone_priority get_default_zone_priority(unsigned int alloc_flags) + { + if (alloc_flags & game::DB_ZONE_COMMON) + { + return zone_priority::post_common; + } + else if (alloc_flags & game::DB_ZONE_GAME) + { + return zone_priority::pre_map; + } + + return zone_priority::none; + } + + zone_priority get_zone_priority(const std::string& name, unsigned int alloc_flags) + { + const auto lower = utils::string::to_lower(name); + if (const auto iter = priority_map.find(lower); iter != priority_map.end()) + { + return iter->second; + } + + return get_default_zone_priority(alloc_flags); + } utils::hook::detour db_release_xassets_hook; bool release_assets = false; @@ -113,106 +152,30 @@ namespace mods continue; } + mod_zone zone{}; + const auto alloc_flags = get_alloc_flag(values[0]) | game::DB_ZONE_CUSTOM; if (alloc_flags & game::DB_ZONE_COMMON) { mod_info.zone_info.has_common_zones = true; } - mod_info.zone_info.zones.emplace_back(values[1], alloc_flags); + zone.alloc_flags = alloc_flags; + + if (values.size() <= 2) + { + zone.name = values[1]; + zone.priority = get_default_zone_priority(zone.alloc_flags); + mod_info.zone_info.zones.emplace_back(zone); + } + else + { + zone.name = values[2]; + zone.priority = get_zone_priority(values[1], zone.alloc_flags); + mod_info.zone_info.zones.emplace_back(zone); + } } } - - std::optional get_mod_basename() - { - const auto mod = get_mod(); - if (!mod.has_value()) - { - return {}; - } - - const auto& value = mod.value(); - const auto last_index = value.find_last_of('/'); - const auto basename = value.substr(last_index + 1); - return {basename}; - } - - nlohmann::json default_mod_stats() - { - nlohmann::json json; - json["maps"] = {}; - return json; - } - - nlohmann::json verify_mod_stats(nlohmann::json& json) - { - if (!json.is_object()) - { - json = {}; - } - - if (!json.contains("maps") || !json["maps"].is_object()) - { - json["maps"] = {}; - } - - return json; - } - - nlohmann::json parse_mod_stats() - { - const auto name = get_mod_basename(); - if (!name.has_value()) - { - return default_mod_stats(); - } - - const auto& name_value = name.value(); - const auto stat_file = MOD_STATS_FOLDER "/" + name_value + ".json"; - if (!utils::io::file_exists(stat_file)) - { - return default_mod_stats(); - } - - const auto data = utils::io::read_file(stat_file); - try - { - auto json = nlohmann::json::parse(data); - return verify_mod_stats(json); - } - catch (const std::exception& e) - { - console::error("Failed to parse json mod stat file \"%s.json\": %s", - name_value.data(), e.what()); - } - - return default_mod_stats(); - } - - void initialize_stats() - { - get_current_stats() = parse_mod_stats(); - } - } - - nlohmann::json& get_current_stats() - { - static nlohmann::json stats; - stats = verify_mod_stats(stats); - return stats; - } - - void write_mod_stats() - { - const auto name = get_mod_basename(); - if (!name.has_value()) - { - return; - } - - const auto& name_value = name.value(); - const auto stat_file = MOD_STATS_FOLDER "/" + name_value + ".json"; - utils::io::write_file(stat_file, get_current_stats().dump(), false); } bool mod_requires_restart(const std::string& path) @@ -229,9 +192,9 @@ namespace mods filesystem::unregister_path(mod_info.path.value()); } - write_mod_stats(); - initialize_stats(); + mod_stats::write(); mod_info.path = path; + mod_stats::initialize(); filesystem::register_path(path); parse_mod_zones(); } @@ -280,6 +243,11 @@ namespace mods return mod_list; } + bool mod_exists(const std::string& folder) + { + return utils::io::directory_exists(utils::string::va("%s\\%s", MOD_FOLDER, folder.data())); + } + std::optional get_mod_info(const std::string& name) { const auto info_file = name + "/info.json"; @@ -301,6 +269,46 @@ namespace mods return {}; } + void load(const std::string& path) + { + if (!utils::io::directory_exists(path)) + { + console::error("Mod %s not found!\n", path.data()); + return; + } + + console::info("Loading mod %s\n", path.data()); + set_mod(path); + + if ((mod_info.path.has_value() && mod_requires_restart(mod_info.path.value())) || + mod_requires_restart(path)) + { + // vid_restart is still broken :( + console::info("Restarting...\n"); + full_restart("-mod "s + path); + } + else + { + restart(); + } + } + + void unload() + { + console::info("Unloading mod %s\n", mod_info.path.value().data()); + + if (mod_requires_restart(mod_info.path.value())) + { + console::info("Restarting...\n"); + full_restart(""); + } + else + { + clear_mod(); + restart(); + } + } + class component final : public component_interface { public: @@ -311,11 +319,6 @@ namespace mods utils::io::create_directory(MOD_FOLDER); } - if (!utils::io::directory_exists(MOD_STATS_FOLDER)) - { - utils::io::create_directory(MOD_STATS_FOLDER); - } - db_release_xassets_hook.create(0x140416A80, db_release_xassets_stub); command::add("loadmod", [](const command::params& params) @@ -334,26 +337,7 @@ namespace mods } const auto path = params.get(1); - if (!utils::io::directory_exists(path)) - { - console::error("Mod %s not found!\n", path); - return; - } - - console::info("Loading mod %s\n", path); - set_mod(path); - - if ((mod_info.path.has_value() && mod_requires_restart(mod_info.path.value())) || - mod_requires_restart(path)) - { - // vid_restart is still broken :( - console::info("Restarting...\n"); - full_restart("-mod "s + path); - } - else - { - restart(); - } + load(path); }); command::add("unloadmod", [](const command::params& params) @@ -371,18 +355,7 @@ namespace mods return; } - console::info("Unloading mod %s\n", mod_info.path.value().data()); - - if (mod_requires_restart(mod_info.path.value())) - { - console::info("Restarting...\n"); - full_restart(""); - } - else - { - clear_mod(); - restart(); - } + unload(); }); command::add("com_restart", []() diff --git a/src/client/component/mods.hpp b/src/client/component/mods.hpp index bc2a523d..e0be23a8 100644 --- a/src/client/component/mods.hpp +++ b/src/client/component/mods.hpp @@ -2,10 +2,25 @@ namespace mods { + enum zone_priority + { + none, + + // common + pre_gfx, + post_gfx, + post_common, + + // game + pre_map, + post_map, + }; + struct mod_zone { std::string name; unsigned int alloc_flags; + zone_priority priority; }; bool mod_requires_restart(const std::string& path); @@ -13,9 +28,10 @@ namespace mods std::optional get_mod(); std::vector get_mod_zones(); + void load(const std::string& path); + void unload(); + std::vector get_mod_list(); std::optional get_mod_info(const std::string& mod); - - nlohmann::json& get_current_stats(); - void write_mod_stats(); + bool mod_exists(const std::string& folder); } \ No newline at end of file diff --git a/src/client/component/motd.cpp b/src/client/component/motd.cpp index 577ac674..42bd0bd7 100644 --- a/src/client/component/motd.cpp +++ b/src/client/component/motd.cpp @@ -5,34 +5,167 @@ #include "console.hpp" #include "images.hpp" #include "command.hpp" +#include "updater.hpp" #include #include #include - -#define MAX_FEATURED_TABS 8 +#include +#include +#include namespace motd { namespace { - utils::concurrency::container links; + constexpr auto max_featured_tabs = 8; + constexpr auto cache_max_age = 24h * 5; // 5 days + constexpr auto cache_file_signature = 'CM2H'; // H2MC (H2-MOD Cache); + utils::concurrency::container links; utils::concurrency::container marketing; - std::unordered_map image_cache; + struct cached_file_header + { + std::uint32_t signature; + time_t date_created; + }; + + struct parsed_cache_file + { + cached_file_header header{}; + std::string data; + }; + + std::atomic_bool killed; + + std::filesystem::path get_cache_folder() + { + return utils::properties::get_appdata_path() / "cache"; + } + + std::string get_cached_file_name(const std::string& name) + { + const auto hash = utils::cryptography::sha1::compute(name, true); + return (get_cache_folder() / hash).generic_string(); + } + + void cache_file(const std::string& name, const std::string& data) + { + std::string buffer; + const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + cached_file_header header{}; + header.signature = cache_file_signature; + header.date_created = now; + + buffer.append(reinterpret_cast(&header), sizeof(header)); + buffer.append(data); + + const auto path = get_cached_file_name(name); + utils::io::write_file(path, buffer, false); + } + + std::optional parse_cached_file_header(std::string& data) + { + if (data.size() < sizeof(cached_file_header)) + { + return {}; + } + + auto buffer = data.data(); + const auto header = reinterpret_cast(buffer); + return {*header}; + } + + std::optional parse_cached_file(const std::string& path) + { + parsed_cache_file parsed{}; + + auto data = utils::io::read_file(path); + const auto header = parse_cached_file_header(data); + + if (!header.has_value()) + { + return {}; + } + + if (header->signature != cache_file_signature) + { + return {}; + } + + const auto file_data = data.data() + sizeof(cached_file_header); + parsed.header = *header; + parsed.data = std::string{file_data, data.size() - sizeof(cached_file_header)}; + + return {parsed}; + } + + std::optional read_cached_file(const std::string& name) + { + const auto path = get_cached_file_name(name); + if (!utils::io::file_exists(path)) + { + return {}; + } + + const auto parsed = parse_cached_file(path); + if (!parsed.has_value()) + { + return {}; + } + + return {parsed->data}; + } + + void delete_old_files() + { + const auto path = get_cache_folder().generic_string(); + if (!utils::io::directory_exists(path)) + { + return; + } + + const auto now = std::chrono::system_clock::now(); + const auto files = utils::io::list_files(path); + + for (const auto& file : files) + { + std::string data{}; + if (!utils::io::read_file(file, &data)) + { + continue; + } + + const auto header = parse_cached_file_header(data); + const auto date = std::chrono::system_clock::from_time_t(header->date_created); + if (now - date >= cache_max_age) + { + utils::io::remove_file(file); + } + } + } std::optional download_image(const std::string& url) { - if (image_cache.contains(url)) + if (killed) { - return {image_cache.at(url)}; + return {}; } + const auto cached = read_cached_file(url); + if (cached.has_value()) + { + return {cached.value()}; + } + + console::debug("[HTTP] GET File \"%s\"\n", url.data()); + const auto res = utils::http::get_data(url); if (res.has_value()) { - image_cache[url] = res.value(); + cache_file(url, res.value()); } return res; @@ -50,7 +183,6 @@ namespace motd if (image_data.has_value()) { const auto& image = image_data.value(); - console::debug("Downloaded motd image\n"); images::override_texture("motd_image", image); } } @@ -66,7 +198,7 @@ namespace motd for (const auto& [key, tab] : data["featured"].items()) { index++; - if (index >= MAX_FEATURED_TABS + 1) + if (index >= max_featured_tabs + 1) { return; } @@ -83,8 +215,7 @@ namespace motd if (image_data.has_value()) { const auto& image = image_data.value(); - console::debug("Downloaded featured tab image %i\n", index); - images::override_texture(image_name + std::format("_{}", index), image); + images::override_texture(std::format("{}_{}", image_name, index), image); } }; @@ -110,6 +241,7 @@ namespace motd { {"github", "https://github.com/fedddddd/h2-mod"}, {"donate", "https://www.paypal.com/donate/?hosted_button_id=LM5BA9UABEV4Q"}, + {"specops", "https://github.com/fedddddd/h2-specops-mod"}, {"credits_1", "https://github.com/momo5502"}, {"credits_2", "https://github.com/VladWinner"}, {"credits_3", "https://github.com/diamante0018"}, @@ -145,6 +277,8 @@ namespace motd void init(bool load_images = true) { + delete_old_files(); + links.access([](links_map_t& map) { init_links(map); @@ -152,10 +286,9 @@ namespace motd marketing.access([&](nlohmann::json& data) { - image_cache.clear(); data.clear(); - const auto marketing_data = utils::http::get_data("https://master.fed0001.xyz/h2-mod/marketing.json"); + const auto marketing_data = updater::get_server_file("h2-mod/marketing.json"); if (marketing_data.has_value()) { try @@ -196,7 +329,7 @@ namespace motd return 0; } - return std::min(MAX_FEATURED_TABS, static_cast(data["featured"].size())); + return std::min(max_featured_tabs, static_cast(data["featured"].size())); }); } @@ -233,12 +366,34 @@ namespace motd }); } + bool has_motd() + { + return marketing.access([](nlohmann::json& data) + -> nlohmann::json + { + return data.is_object() && data["motd"].is_object(); + }); + } + + std::thread init_thread; + class component final : public component_interface { public: + void post_start() override + { + init_thread = std::thread([] + { + init(); + }); + } + void post_unpack() override { - init(); + if (init_thread.joinable()) + { + init_thread.join(); + } command::add("reloadmotd", []() { @@ -250,6 +405,15 @@ namespace motd init(false); }); } + + void pre_destroy() override + { + killed = true; + if (init_thread.joinable()) + { + init_thread.join(); + } + } }; } diff --git a/src/client/component/motd.hpp b/src/client/component/motd.hpp index 4a94b751..547204d0 100644 --- a/src/client/component/motd.hpp +++ b/src/client/component/motd.hpp @@ -8,4 +8,5 @@ namespace motd int get_num_featured_tabs(); nlohmann::json get_motd(); nlohmann::json get_featured_tab(const int index); + bool has_motd(); } diff --git a/src/client/component/notifies.cpp b/src/client/component/notifies.cpp index 376915d9..8827ce57 100644 --- a/src/client/component/notifies.cpp +++ b/src/client/component/notifies.cpp @@ -20,7 +20,9 @@ namespace notifies struct gsc_hook_t { bool is_lua_hook{}; + bool is_variable{}; const char* target_pos{}; + size_t rel_source_pos{}; sol::protected_function lua_function; }; @@ -30,39 +32,54 @@ namespace notifies char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END const char* target_function = nullptr; + bool gsc_hooks_buffer[0x1400000]{}; - unsigned int local_id_to_entity(unsigned int local_id) + scripting::entity local_id_to_entity(unsigned int local_id) { - const auto variable = game::scr_VarGlob->objectVariableValue[local_id]; - return variable.u.f.next; + return game::scr_VarGlob->objectVariableValue[local_id].u.f.next; + } + + char* get_program_buffer() + { + return *reinterpret_cast(0x14B5E0B78); + } + + size_t get_program_buffer_offset(const char* pos) + { + const auto rel_offset = pos - get_program_buffer(); + return rel_offset; } bool execute_vm_hook(const char* pos) { - if (vm_execute_hooks.find(pos) == vm_execute_hooks.end()) + const auto program_buffer = get_program_buffer(); + if (pos >= program_buffer && (pos - program_buffer < 0x1400000)) + { + const auto rel_offset = pos - program_buffer; + if (!gsc_hooks_buffer[rel_offset]) + { + hook_enabled = true; + return false; + } + } + + const auto iter = vm_execute_hooks.find(pos); + if (iter == vm_execute_hooks.end() || (!hook_enabled && !iter->second.is_variable)) { hook_enabled = true; return false; } - if (!hook_enabled && pos > reinterpret_cast(vm_execute_hooks.size())) - { - hook_enabled = true; - return false; - } - - const auto& hook = vm_execute_hooks[pos]; + const auto& hook = iter->second; if (hook.is_lua_hook) { const auto& function = hook.lua_function; const auto state = function.lua_state(); - const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); - + const auto self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); std::vector args; const auto top = game::scr_function_stack->top; - for (auto* value = top; value->type != game::SCRIPT_END; --value) { args.push_back(scripting::lua::convert(state, *value)); @@ -119,16 +136,14 @@ namespace notifies return {}; } - const auto player = scripting::call("getentbynum", {ent->s.entityNum}); - - return scripting::lua::convert(state, player); + const scripting::entity entity{game::scr_entref_t(ent->s.entityNum, 0)}; + return scripting::lua::convert(state, entity); } std::string get_weapon_name(unsigned int weapon, bool isAlternate) { char output[1024] = {0}; game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024); - return output; } @@ -139,37 +154,34 @@ namespace notifies return {}; } - const auto _vec = scripting::vector(vec); - - return scripting::lua::convert(state, _vec); + return scripting::lua::convert(state, scripting::vector(vec)); } std::string convert_mod(const int meansOfDeath) { const auto value = reinterpret_cast(0x140BF49B0)[meansOfDeath]; - const auto string = game::SL_ConvertToString(*value); - - return string; + return game::SL_ConvertToString(*value); } - void scr_entity_damage_stub(game::gentity_s* self, game::gentity_s* inflictor, game::gentity_s* attacker, const float* vDir, const float* vPoint, - int damage, int dflags, const unsigned int meansOfDeath, const unsigned int weapon, bool isAlternate, unsigned int a11, const int hitLoc, unsigned int a13, unsigned int a14) + void scr_entity_damage_stub(game::gentity_s* self, game::gentity_s* inflictor, game::gentity_s* attacker, const float* v_dir, const float* v_point, + int damage, int dflags, const unsigned int means_of_death, const unsigned int weapon, bool is_alternate, + unsigned int a11, const int hit_loc, unsigned int a13, unsigned int a14) { { - const std::string _hitLoc = reinterpret_cast(0x140BF4AA0)[hitLoc]; - const auto _mod = convert_mod(meansOfDeath); - const auto _weapon = get_weapon_name(weapon, isAlternate); + const std::string hit_loc_str = reinterpret_cast(0x140BF4AA0)[hit_loc]; + const auto mod_str = convert_mod(means_of_death); + const auto weapon_str = get_weapon_name(weapon, is_alternate); for (const auto& callback : entity_damage_callbacks) { const auto state = callback.lua_state(); - const auto _self = convert_entity(state, self); - const auto _inflictor = convert_entity(state, inflictor); - const auto _attacker = convert_entity(state, attacker); - const auto _vDir = convert_vector(state, vDir); + const auto self_ent = convert_entity(state, self); + const auto inflictor_ent = convert_entity(state, inflictor); + const auto attacker_ent = convert_entity(state, attacker); + const auto v_dir_vec = convert_vector(state, v_dir); - const auto result = callback(_self, _inflictor, _attacker, damage, _mod, _weapon, _vDir, _hitLoc); + const auto result = callback(self_ent, inflictor_ent, attacker_ent, damage, mod_str, weapon_str, v_dir_vec, hit_loc_str); scripting::lua::handle_error(result); if (result.valid()) @@ -188,8 +200,20 @@ namespace notifies } } - scr_entity_damage_hook.invoke(self,inflictor, attacker, vDir, vPoint, damage, dflags, - meansOfDeath, weapon, isAlternate, a11, hitLoc, a13, a14); + scr_entity_damage_hook.invoke(self, inflictor, attacker, v_dir, v_point, damage, dflags, + means_of_death, weapon, is_alternate, a11, hit_loc, a13, a14); + } + + void set_hook(const char* pos, gsc_hook_t& hook) + { + if (!hook.is_variable) + { + const auto rel_pos = get_program_buffer_offset(pos); + gsc_hooks_buffer[rel_pos] = true; + hook.rel_source_pos = rel_pos; + } + + vm_execute_hooks[pos] = hook; } } @@ -204,6 +228,11 @@ namespace notifies { if (i->second.is_lua_hook) { + if (!i->second.is_variable) + { + gsc_hooks_buffer[i->second.rel_source_pos] = false; + } + i = vm_execute_hooks.erase(i); } else @@ -215,24 +244,27 @@ namespace notifies entity_damage_callbacks.clear(); } - void set_lua_hook(const char* pos, const sol::protected_function& callback) + void set_lua_hook(const char* pos, const sol::protected_function& callback, bool is_variable) { - gsc_hook_t hook; + gsc_hook_t hook{}; hook.is_lua_hook = true; + hook.is_variable = is_variable; hook.lua_function = callback; - vm_execute_hooks[pos] = hook; + set_hook(pos, hook); } void set_gsc_hook(const char* source, const char* target) { - gsc_hook_t hook; + gsc_hook_t hook{}; hook.is_lua_hook = false; hook.target_pos = target; - vm_execute_hooks[source] = hook; + set_hook(source, hook); } void clear_hook(const char* pos) { + const auto rel_offset = get_program_buffer_offset(pos); + gsc_hooks_buffer[rel_offset] = false; vm_execute_hooks.erase(pos); } @@ -254,6 +286,7 @@ namespace notifies { if (free_scripts && !post_shutdown) { + std::memset(gsc_hooks_buffer, 0, sizeof(gsc_hooks_buffer)); vm_execute_hooks.clear(); } }); @@ -261,4 +294,4 @@ namespace notifies }; } -REGISTER_COMPONENT(notifies::component) \ No newline at end of file +REGISTER_COMPONENT(notifies::component) diff --git a/src/client/component/notifies.hpp b/src/client/component/notifies.hpp index 9ea66a9c..8a9dd844 100644 --- a/src/client/component/notifies.hpp +++ b/src/client/component/notifies.hpp @@ -1,10 +1,12 @@ #pragma once +#include "game/scripting/lua/error.hpp" + namespace notifies { extern bool hook_enabled; - void set_lua_hook(const char* pos, const sol::protected_function&); + void set_lua_hook(const char* pos, const sol::protected_function&, bool is_variable = false); void set_gsc_hook(const char* source, const char* target); void clear_hook(const char* pos); size_t get_hook_count(); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index be5f8526..2d89ede2 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -3,6 +3,7 @@ #include "game/game.hpp" #include "game/dvars.hpp" +#include "dvars.hpp" #include #include @@ -14,21 +15,20 @@ namespace patches utils::hook::detour gscr_set_save_dvar_hook; utils::hook::detour dvar_register_float_hook; - void* sub_46148() - { - static uint64_t off_11C52460 = 0x140AD0C58; - return &off_11C52460; - } - DECLSPEC_NORETURN void quit_stub() { - component_loader::pre_destroy(); - exit(0); + utils::hook::invoke(0x1408B1BA0); } void gscr_set_save_dvar_stub() { - const auto string = utils::string::to_lower(utils::hook::invoke(0x1405C7C20, 0)); + const auto dvar = game::Scr_GetString(0); + if (dvar == nullptr) + { + return; + } + + const auto string = utils::string::to_lower(dvar); if (string == "cg_fov" || string == "cg_fovscale") { return; @@ -37,47 +37,34 @@ namespace patches gscr_set_save_dvar_hook.invoke(); } - game::dvar_t* cg_fov = nullptr; - game::dvar_t* cg_fovScale = nullptr; - - game::dvar_t* dvar_register_float_stub(int hash, const char* dvarName, float value, float min, float max, unsigned int flags) - { - static const auto cg_fov_hash = game::generateHashValue("cg_fov"); - static const auto cg_fov_scale_hash = game::generateHashValue("cg_fovscale"); - - if (hash == cg_fov_hash) - { - return cg_fov; - } - - if (hash == cg_fov_scale_hash) - { - return cg_fovScale; - } - - return dvar_register_float_hook.invoke(hash, dvarName, value, min, max, flags); - } - - void free_lui_memory() + void vid_restart_stub() { + // free stuff + *reinterpret_cast(0x141E584D8) = nullptr; // free material + utils::hook::invoke(0x1406926B0); // free scripted viewmodel xanim stuff utils::hook::invoke(0x14032A540); // properly free lui memory - } - void vid_restart_stub_1() - { - free_lui_memory(); utils::hook::invoke(0x1405A6480); } - void vid_restart_stub_2() + void exec_config_stub(void* a1) { - free_lui_memory(); - utils::hook::invoke(0x1406B5290); + dvars::register_string("name", "Unknown Soldier", game::DVAR_FLAG_SAVED, "Player name"); + utils::hook::invoke(0x1405A35E0, a1); } - game::dvar_t* register_snd_music_stub(int hash, const char* name, bool value, unsigned int /*flags*/) + const char* dvar_get_hash_stub(game::dvar_t* dvar) { - return game::Dvar_RegisterBool(hash, name, value, game::DVAR_FLAG_SAVED); + const auto info = dvars::get_dvar_info_from_hash(dvar->hash); + if (info.has_value()) + { + const auto& value = info.value(); + return utils::string::va("%s", value.name.data()); + } + else + { + return utils::hook::invoke(0x140619240, dvar); + } } } @@ -86,19 +73,15 @@ namespace patches public: void post_unpack() override { - // Fix startup crashes - utils::hook::set(0x140633080, 0xC301B0); - utils::hook::set(0x140272F70, 0xC301B0); - utils::hook::jump(0x140046148, sub_46148); + // Fix shutdown crash + utils::hook::jump(0x1408B1CD0, 0x1408B1BA0); - utils::hook::jump(0x1408B1CD0, quit_stub); + // Disable splash screen + utils::hook::nop(0x14064F546, 5); // Unlock fps in main menu utils::hook::set(0x1403D8E1B, 0xEB); - // Disable battle net popup - utils::hook::nop(0x1405F4496, 5); - // Allow kbam input when gamepad is enabled utils::hook::nop(0x1403D2F8E, 2); utils::hook::nop(0x1403D0C9C, 6); @@ -106,23 +89,29 @@ namespace patches // Prevent game from overriding cg_fov and cg_fovscale values gscr_set_save_dvar_hook.create(0x140504C60, &gscr_set_save_dvar_stub); - // Make cg_fov and cg_fovscale saved dvars - cg_fov = dvars::register_float("cg_fov", 65.f, 40.f, 200.f, - game::DVAR_FLAG_SAVED, "The field of view angle in degrees for client 0"); - cg_fovScale = dvars::register_float("cg_fovScale", 1.f, 0.1f, 2.f, - game::DVAR_FLAG_SAVED, "Scale applied to the field of view"); - - dvar_register_float_hook.create(game::Dvar_RegisterFloat.get(), dvar_register_float_stub); - // fix vid_restart crashing - utils::hook::call(0x1403D7413, vid_restart_stub_1); - utils::hook::jump(0x1403D7402, vid_restart_stub_2); - - // make snd_musicDisabledForCustomSoundtrack saved - utils::hook::call(0x1405D05FB, register_snd_music_stub); + utils::hook::call(0x1403D7413, vid_restart_stub); // cinematicingameloopresident -> cinematicingameloop (fix ingame cinematics) utils::hook::jump(0x140502140, 0x1405020C0); + + // override dvar flags + dvars::override::register_float("cg_fovScale", 1.f, 0.1f, 2.f, game::DVAR_FLAG_SAVED); + dvars::override::register_float("cg_fov", 65.f, 40.f, 200.f, game::DVAR_FLAG_SAVED); + dvars::override::register_bool("snd_musicDisabledForCustomSoundtrack", false, game::DVAR_FLAG_SAVED); + + // make "name" saved + utils::hook::call(0x1405A4960, exec_config_stub); + dvars::override::register_string("name", "Unknown Soldier", game::DVAR_FLAG_SAVED); + + utils::hook::call(0x1405A7CB7, dvar_get_hash_stub); + + // fix vehicle hud compass color + utils::hook::set(0x140948F40, 1.f); + utils::hook::set(0x140948F44, 1.f); + utils::hook::set(0x140948F48, 1.f); + + utils::hook::nop(0x14037B8AE, 7); } }; } diff --git a/src/client/component/pathnodes.cpp b/src/client/component/pathnodes.cpp index 74bad445..24f29baa 100644 --- a/src/client/component/pathnodes.cpp +++ b/src/client/component/pathnodes.cpp @@ -508,17 +508,10 @@ namespace pathnodes void restore_code(const size_t ptr, char* data, const size_t size) { - const auto ptr_ = reinterpret_cast(ptr); - DWORD old_protect; - VirtualProtect(ptr_, size, PAGE_EXECUTE_READWRITE, &old_protect); - for (auto i = 0; i < size; i++) { - ptr_[i] = data[i]; + utils::hook::set(ptr + i, data[i]); } - - VirtualProtect(ptr_, size, old_protect, &old_protect); - FlushInstructionCache(GetCurrentProcess(), ptr_, size); } void restore_functions() diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index 5332f293..db7228c1 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -56,6 +56,21 @@ namespace renderer return r_update_front_end_dvar_options_hook.invoke(); } + + utils::hook::detour r_filter_things_into_cells_r_hook; + void r_filter_things_into_cells_r_stub(void* node, unsigned int dyn_ent_index, game::Bounds* bounds, unsigned int* cell_bits, unsigned int word_count) + { + const auto gfx_world = *reinterpret_cast(0x14EE49000); + const auto bsp_version = *reinterpret_cast(gfx_world + 16); + if (bsp_version == 115) // h2 bsp version + { + return r_filter_things_into_cells_r_hook.invoke(node, dyn_ent_index, bounds, cell_bits, word_count); + } + + constexpr auto cell_index = 0; + const auto index = (dyn_ent_index >> 5) + word_count * cell_index; + cell_bits[index] |= 0x80000000 >> (dyn_ent_index & 0x1F); + } } class component final : public component_interface @@ -67,6 +82,9 @@ namespace renderer r_init_draw_method_hook.create(0x14072F950, &r_init_draw_method_stub); r_update_front_end_dvar_options_hook.create(0x14076EE70, &r_update_front_end_dvar_options_stub); + + // workaround for zonetool issue + r_filter_things_into_cells_r_hook.create(0x140724720, r_filter_things_into_cells_r_stub); } }; } diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index 03a1a214..f9d02a91 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -6,8 +6,10 @@ #include "scheduler.hpp" #include "scripting.hpp" -#include "gsc.hpp" #include "console.hpp" +#include "command.hpp" + +#include "gsc/script_loading.hpp" #include "game/scripting/event.hpp" #include "game/scripting/functions.hpp" @@ -162,9 +164,9 @@ namespace scripting { auto result = scripting::find_token(id); - if (canonical_string_table.find(id) != canonical_string_table.end()) + if (const auto itr = canonical_string_table.find(id); itr != canonical_string_table.end()) { - result.push_back(canonical_string_table[id]); + result.push_back(itr->second); } return result; @@ -323,12 +325,22 @@ namespace scripting std::optional get_canonical_string(const unsigned int id) { - if (canonical_string_table.find(id) == canonical_string_table.end()) + if (const auto itr = canonical_string_table.find(id); itr != canonical_string_table.end()) { - return {}; + return itr->second; } - return {canonical_string_table[id]}; + return {}; + } + + std::string get_token(unsigned int id) + { + if (const auto itr = canonical_string_table.find(id); itr != canonical_string_table.end()) + { + return itr->second; + } + + return find_token_single(id); } class component final : public component_interface @@ -358,6 +370,12 @@ namespace scripting utils::hook::call(0x1404B07D2, get_spawn_point_stub); + command::add("getfunctionptr", [](const command::params& params) + { + const auto func = find_function(params.get(1), false); + console::info("%p\n", func); + }); + scheduler::loop([]() { lua::engine::run_frame(); diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp index 3f0d5b64..2f4dca3f 100644 --- a/src/client/component/scripting.hpp +++ b/src/client/component/scripting.hpp @@ -17,4 +17,5 @@ namespace scripting void on_shutdown(const std::function& callback); std::optional get_canonical_string(const unsigned int id); std::string get_token_single(unsigned int id); + std::string get_token(unsigned int id); } \ No newline at end of file diff --git a/src/client/component/sound.cpp b/src/client/component/sound.cpp index 03b7d752..8ee83e71 100644 --- a/src/client/component/sound.cpp +++ b/src/client/component/sound.cpp @@ -13,6 +13,10 @@ namespace sound { namespace { + game::dvar_t* snd_music_volume = nullptr; + game::dvar_t** snd_music_disabled_for_custom_sndtrack = nullptr; + int music_volmod_index = -1; + void com_sprintf_raw_sound_localized_stub(char* buffer, int size, const char* fmt, const char* lang, const char* name, const char* extension) { @@ -35,6 +39,50 @@ namespace sound return snd_is_music_playing_hook.invoke(a1); } + + bool is_sound_music(game::snd_alias_t* sound) + { + return sound->dspBusIndex == *game::music_dsp_bus_index || + sound->volModIndex == music_volmod_index; + } + + float get_snd_volume(game::snd_alias_t* sound, float original_volume) + { + if (is_sound_music(sound) && + snd_music_disabled_for_custom_sndtrack && + (*snd_music_disabled_for_custom_sndtrack)->current.enabled) + { + return 0.f; + } + + if (is_sound_music(sound)) + { + return original_volume * snd_music_volume->current.value; + } + + return original_volume; + } + + void snd_update_channel_stub(utils::hook::assembler& a) + { + a.pushad64(); + a.mov(rcx, qword_ptr(rdi, 0xD0)); + a.call_aligned(get_snd_volume); + a.movaps(xmm1, xmm0); + a.popad64(); + + a.jmp(0x1407CD8C7); + } + + double atof_stub(const char* str) + { + if (!std::strncmp(game::sound_data->volmods[*game::volmod_index].name, "music", sizeof(game::volmod_t::name))) + { + music_volmod_index = *game::volmod_index; + } + + return std::atof(str); + } } class component final : public component_interface @@ -42,12 +90,18 @@ namespace sound public: void post_unpack() override { + snd_music_volume = dvars::register_float("snd_musicVolume", 1.f, 0.0f, 1.f, game::DVAR_FLAG_SAVED, "Music volume scale"); + snd_music_disabled_for_custom_sndtrack = reinterpret_cast(0x151B818C8); + // remove raw/sound or raw/language/sound prefix when loading raw sounds utils::hook::call(0x140622FEF, com_sprintf_raw_sound_localized_stub); utils::hook::call(0x14062306C, com_sprintf_raw_sound_stub); // fix playing non-existing music crashing snd_is_music_playing_hook.create(0x1407C58A0, snd_is_music_playing_stub); + + utils::hook::jump(0x1407CD8A5, utils::hook::assemble(snd_update_channel_stub), true); + utils::hook::call(0x1407C5F2F, atof_stub); } }; } diff --git a/src/client/component/thread_names.cpp b/src/client/component/thread_names.cpp index 84b5fa70..19e469ac 100644 --- a/src/client/component/thread_names.cpp +++ b/src/client/component/thread_names.cpp @@ -27,10 +27,13 @@ namespace thread_names {game::THREAD_CONTEXT_WORKER7, "Worker7"}, {game::THREAD_CONTEXT_SERVER, "Server"}, {game::THREAD_CONTEXT_CINEMATIC, "Cinematic"}, + {game::THREAD_CONTEXT_WINDOW, "Window"}, + {game::THREAD_CONTEXT_INPUT, "Input"}, {game::THREAD_CONTEXT_DATABASE, "Database"}, - {game::THREAD_CONTEXT_STREAM, "Stream"}, - {game::THREAD_CONTEXT_SNDSTREAMPACKETCALLBACK, "Snd stream packet callback"}, - {game::THREAD_CONTEXT_STATS_WRITE, "Stats write"}, + {game::THREAD_CONTEXT_STREAM, "Sound"}, + {game::THREAD_CONTEXT_UNK_16, "Thread 16"}, // not used? + {game::THREAD_CONTEXT_UNK_17, "Thread 17"}, // sound stream related + {game::THREAD_CONTEXT_UNK_18, "Thread 18"}, // ^ }; for (const auto& thread_name : thread_names) diff --git a/src/client/component/tls.cpp b/src/client/component/tls.cpp new file mode 100644 index 00000000..bd411223 --- /dev/null +++ b/src/client/component/tls.cpp @@ -0,0 +1,122 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "console.hpp" +#include "game_module.hpp" + +#include +#include + +namespace tls +{ + namespace + { + DWORD get_tls_index() + { + const auto game = game_module::get_game_module(); + const auto game_tls = reinterpret_cast(game.get_ptr() + game.get_optional_header() + ->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); + return *reinterpret_cast(game_tls->AddressOfIndex); + } + + void get_tls_stub(utils::hook::assembler& a) + { + a.mov(rax, seg_ptr(gs, 0x58)); + a.add(rax, get_tls_index() * 8); + a.ret(); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Add tls_index * 8 offset to tls access where it's missing (it was optimized away in the bnet code) + + std::vector address_list = + { + 0x14004614C, + 0x140047A85, + 0x140048B4C, + 0x140049A04, + 0x140049DDE, + 0x140049FA9, + 0x14004A491, + 0x14004A879, + 0x14004AB34, + 0x14004AFE0, + 0x14004B305, + 0x14004B846, + 0x14004BC34, + 0x14004C024, + 0x14004C2CC, + 0x14004C94A, + 0x14004CBA1, + 0x1400619E9, + 0x1400A29CB, + 0x1400A2AF7, + 0x1400A2C23, + 0x1400A2D4F, + 0x1400A4A9F, + 0x1400A4EC5, + 0x1400A50CB, + 0x1400A53A8, + 0x1400A5618, + 0x1400A58A2, + 0x1400A5B08, + 0x1400A5D52, + 0x1400A5F44, + 0x1400A9B94, + 0x1400AA126, + 0x1400AA8D0, + 0x1400AACC6, + 0x1400AAF87, + 0x1400AB230, + 0x1400AB565, + 0x1400AB822, + 0x1400ABA43, + 0x1400ABCC9, + 0x1400ABED1, + 0x1400AC141, + 0x1400AC65B, + 0x1400AC833, + 0x1400ACA66, + 0x1400ACE27, + 0x1400AD048, + 0x1400AD51B, + 0x1400AD719, + 0x1400ADA2C, + 0x1400ADCD7, + 0x1400AE1B9, + 0x1400AE722, + 0x1400C795C, + 0x1400E3C93, + 0x1400E4165, + 0x1400E43F7, + 0x1400E46A7, + 0x1400F4951, + 0x1400F4BA6, + 0x1400F4DFF, + 0x140100938, + 0x140193761, + 0x1401DA392, + 0x1401FEA2A, + 0x1402039BB, + 0x14020C5A3, + }; + + const auto tls_stub_ptr = utils::hook::assemble(get_tls_stub); + + for (const auto& address : address_list) + { + utils::hook::nop(address, 0x9); + utils::hook::far_call(address, tls_stub_ptr); + } + } + }; +} + +REGISTER_COMPONENT(tls::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 9c9d6f42..f6fa713f 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -11,11 +11,14 @@ #include "scripting.hpp" #include "fastfiles.hpp" #include "mods.hpp" +#include "mod_stats.hpp" #include "updater.hpp" #include "console.hpp" #include "language.hpp" #include "config.hpp" #include "motd.hpp" +#include "achievements.hpp" +#include "camera.hpp" #include "game/ui_scripting/execution.hpp" #include "game/scripting/execution.hpp" @@ -34,7 +37,8 @@ namespace ui_scripting const auto lui_updater = utils::nt::load_resource(LUI_UPDATER); const auto lua_json = utils::nt::load_resource(LUA_JSON); - std::unordered_map> converted_functions; + using lua_function_t = std::function; + std::vector> lua_functions; utils::hook::detour hks_start_hook; utils::hook::detour hks_shutdown_hook; @@ -361,12 +365,7 @@ namespace ui_scripting { const auto links = motd::get_links(); const auto link = links.find(name); - if (link == links.end()) - { - return false; - } - - return true; + return link != links.end(); }; lua["string"]["escapelocalization"] = [](const std::string& str) @@ -442,6 +441,7 @@ namespace ui_scripting updater_table["getupdatedownloadstatus"] = updater::get_update_download_status; updater_table["cancelupdate"] = updater::cancel_update; updater_table["isrestartrequired"] = updater::is_restart_required; + updater_table["shouldforceupdate"] = updater::should_force_update; updater_table["getlasterror"] = updater::get_last_error; updater_table["getcurrentfile"] = updater::get_current_file; @@ -481,6 +481,22 @@ namespace ui_scripting return info_table; }; + + mods_table["load"] = [](const std::string& mod) + { + scheduler::once([=]() + { + mods::load(mod); + }, scheduler::main); + }; + + mods_table["unload"] = [] + { + scheduler::once([]() + { + mods::unload(); + }, scheduler::main); + }; auto mods_stats_table = table(); mods_table["stats"] = mods_stats_table; @@ -488,41 +504,50 @@ namespace ui_scripting mods_stats_table["set"] = [](const std::string& key, const script_value& value) { const auto json_value = lua_to_json(value); - mods::get_current_stats()[key] = json_value; - mods::write_mod_stats(); + mod_stats::set(key, json_value); }; mods_stats_table["get"] = [](const std::string& key) { - return json_to_lua(mods::get_current_stats()); + return json_to_lua(mod_stats::get(key)); }; - mods_stats_table["mapset"] = [](const std::string& mapname, + mods_stats_table["getor"] = [](const std::string& key, const script_value& default_value) + { + const auto json_default_value = lua_to_json(default_value); + return json_to_lua(mod_stats::get(key, json_default_value)); + }; + + mods_stats_table["setstruct"] = [](const std::string& mapname, const std::string& key, const script_value& value) { const auto json_value = lua_to_json(value); - auto& stats = mods::get_current_stats(); - stats["maps"][mapname][key] = json_value; - mods::write_mod_stats(); + mod_stats::set_struct(mapname, key, json_value); }; - mods_stats_table["mapget"] = [](const std::string& mapname, + mods_stats_table["getstruct"] = [](const std::string& mapname, const std::string& key) { - auto& stats = mods::get_current_stats(); - return json_to_lua(stats["maps"][mapname][key]); + return json_to_lua(mod_stats::get_struct(mapname, key)); }; - mods_stats_table["save"] = mods::write_mod_stats; + mods_stats_table["getstructor"] = [](const std::string& mapname, + const std::string& key, const script_value& default_value) + { + const auto json_default_value = lua_to_json(default_value); + return json_to_lua(mod_stats::get_struct(mapname, key, json_default_value)); + }; + + mods_stats_table["save"] = mod_stats::write; mods_stats_table["getall"] = []() { - return json_to_lua(mods::get_current_stats()); + return json_to_lua(mod_stats::get_all()); }; mods_stats_table["setfromjson"] = [](const std::string& data) { const auto json = nlohmann::json::parse(data); - mods::get_current_stats() = json; + mod_stats::set_all(json); }; auto config_table = table(); @@ -654,6 +679,48 @@ namespace ui_scripting const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); config::set("motd_last_seen", static_cast(now)); }; + + motd_table["hasmotd"] = motd::has_motd; + + auto achievements_table = table(); + lua["achievements"] = achievements_table; + + achievements_table["hasachievement"] = achievements::has_achievement; + achievements_table["getrarity"] = achievements::get_rarity; + achievements_table["getname"] = achievements::get_name; + achievements_table["getdetails"] = achievements::get_details; + achievements_table["getbackground"] = achievements::get_background; + achievements_table["issecret"] = achievements::is_secret; + achievements_table["count"] = achievements::get_count; + + achievements_table["table"] = []() + { + table table{}; + + achievements::achievement_file_t file{}; + achievements::get_achievements(&file); + + for (auto i = 0; i < achievements::ACHIEVEMENT_TOTAL_COUNT; i++) + { + table[i] = file.achievements[i]; + } + + return table; + }; + + table camera_table; + lua["camera"] = camera_table; + + camera::clear_lua(); + camera_table["enablefreemove"] = camera::enable_free_move; + camera_table["disablefreemove"] = camera::disable_free_move; + camera_table["isfreemoveenabled"] = camera::is_free_move_enabled; + camera_table["setposition"] = camera::set_camera_position; + camera_table["setangles"] = camera::set_camera_angles; + camera_table["getposition"] = camera::get_camera_position; + camera_table["setusingoriginoverride"] = camera::set_using_origin_override; + camera_table["setusinganglesoverride"] = camera::set_using_angles_override; + camera_table["setcallback"] = camera::set_callback; } void start() @@ -699,6 +766,11 @@ namespace ui_scripting lua["table"]["unpack"] = lua["unpack"]; lua["luiglobals"] = lua; + lua["printmemoryusage"] = []() + { + utils::hook::invoke(0x14031F470); + }; + load_script("lui_common", lui_common); load_script("lui_updater", lui_updater); load_script("lua_json", lua_json); @@ -729,7 +801,8 @@ namespace ui_scripting void hks_shutdown_stub() { - converted_functions.clear(); + camera::clear_lua(); + lua_functions.clear(); globals = {}; hks_shutdown_hook.invoke(); } @@ -780,10 +853,10 @@ namespace ui_scripting return utils::hook::invoke(0x1402D9410, state, compiler_options, reader, reader_data, chunk_name); } - std::string current_error; int main_handler(game::hks::lua_State* state) { - bool error = false; + static std::string error_str; + auto error = false; try { @@ -794,15 +867,14 @@ namespace ui_scripting } const auto closure = value.v.cClosure; - if (!converted_functions.contains(closure)) + if (closure->m_numUpvalues < 1) { return 0; } - const auto& function = converted_functions[closure]; - + const auto function = reinterpret_cast(closure->m_upvalues->v.i64); const auto args = get_return_values(); - const auto results = function(args); + const auto results = function->operator()(args); for (const auto& result : results) { @@ -813,13 +885,13 @@ namespace ui_scripting } catch (const std::exception& e) { - current_error = e.what(); + error_str = e.what(); error = true; } if (error) { - game::hks::hksi_luaL_error(state, current_error.data()); + game::hks::hksi_luaL_error(state, error_str.data()); } return 0; @@ -835,8 +907,23 @@ namespace ui_scripting game::hks::cclosure* convert_function(F f) { const auto state = *game::hks::lua_state; - const auto closure = game::hks::cclosure_Create(state, main_handler, 0, 0, 0); - converted_functions[closure] = wrap_function(f); + const auto top = state->m_apistack.top; + + game::hks::HksObject func_ptr{}; + func_ptr.t = game::hks::TUI64; + func_ptr.v.i64 = 0; + + push_value(func_ptr); + const auto closure = game::hks::cclosure_Create(state, main_handler, 1, 0, 0); + state->m_apistack.top = top; + + const auto function = wrap_function(f); + const auto& iterator = lua_functions.insert(lua_functions.end(), std::make_unique(function)); + const auto ptr = iterator->get(); + + closure->m_upvalues[0].t = game::hks::TUI64; + closure->m_upvalues[0].v.i64 = reinterpret_cast(ptr); + return closure; } @@ -859,13 +946,18 @@ namespace ui_scripting utils::hook::jump(0x14031E700, 0x1402D86E0); utils::hook::jump(0x1402BFCC0, removed_function_stub); // io - utils::hook::jump(0x14017EE60, removed_function_stub); // profile utils::hook::jump(0x1402C0150, removed_function_stub); // os - utils::hook::jump(0x14017F730, removed_function_stub); // serialize + utils::hook::jump(0x1402C1020, removed_function_stub); // serialize utils::hook::jump(0x1402C0FF0, removed_function_stub); // hks - utils::hook::jump(0x14017EC60, removed_function_stub); // debug + utils::hook::jump(0x1402C0470, removed_function_stub); // debug utils::hook::nop(0x1402BFC48, 5); // coroutine + // profile + utils::hook::jump(0x1402B6250, removed_function_stub); + utils::hook::jump(0x1402B6260, removed_function_stub); + utils::hook::jump(0x1402B6270, removed_function_stub); + utils::hook::jump(0x1402B6330, removed_function_stub); + utils::hook::jump(0x1402B7FD0, removed_function_stub); utils::hook::jump(0x1402B7C40, removed_function_stub); utils::hook::jump(0x1402BAC30, removed_function_stub); diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index e3cbcfbf..b2853b51 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -52,6 +52,12 @@ namespace updater std::string data; }; + struct file_info + { + std::string name; + std::string hash; + }; + struct update_data_t { bool restart_required{}; @@ -60,16 +66,10 @@ namespace updater status download{}; std::string error{}; std::string current_file{}; - std::vector required_files{}; + std::vector required_files{}; std::vector garbage_files{}; }; - // remove this at some point - std::vector old_data_files = - { - {"./cdata"}, - }; - utils::concurrency::container update_data; std::string select(const std::string& main, const std::string& develop) @@ -159,31 +159,16 @@ namespace updater return utils::string::va("%i", uint32_t(time(nullptr))); } - std::optional download_file(const std::string& name) + std::optional download_data_file(const std::string& name) { - return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); + const auto file = std::format("{}{}?{}", select(DATA_PATH, DATA_PATH_DEV), name, get_time_str()); + return updater::get_server_file(file); } - bool has_old_data_files() + std::optional download_file_list() { - bool has = false; - for (const auto& file : old_data_files) - { - if (utils::io::directory_exists(file)) - { - has = true; - } - } - - return has; - } - - void delete_old_data_files() - { - for (const auto& file : old_data_files) - { - std::filesystem::remove_all(file); - } + const auto file = std::format("{}?{}", select(FILES_PATH, FILES_PATH_DEV), get_time_str()); + return updater::get_server_file(file); } bool is_update_cancelled() @@ -279,6 +264,34 @@ namespace updater } } + std::optional get_server_file(const std::string& endpoint) + { + static std::vector server_urls = + { + {"https://h2-mod.fed.cat/"}, + {"https://master.fed0001.xyz/"}, // remove this at some point + }; + + const auto try_url = [&](const std::string& base_url) + { + const auto url = base_url + endpoint; + console::debug("[HTTP] GET file \"%s\"\n", url.data()); + const auto result = utils::http::get_data(url); + return result; + }; + + for (const auto& url : server_urls) + { + const auto result = try_url(url); + if (result.has_value()) + { + return result; + } + } + + return {}; + } + void relaunch() { utils::nt::relaunch_self("-singleplayer"); @@ -336,7 +349,7 @@ namespace updater { return update_data.access([](update_data_t& data_) { - return data_.required_files.size() > 0 || data_.garbage_files.size() > 0 || has_old_data_files(); + return data_.required_files.size() > 0 || data_.garbage_files.size() > 0; }); } @@ -387,7 +400,7 @@ namespace updater scheduler::once([]() { - const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); + const auto files_data = download_file_list(); if (is_update_cancelled()) { @@ -410,7 +423,7 @@ namespace updater return; } - std::vector required_files; + std::vector required_files; std::vector update_files; const auto files = j.GetArray(); @@ -449,7 +462,7 @@ namespace updater console::info("[Updater] need file %s\n", name); #endif - required_files.push_back(name); + required_files.emplace_back(name, sha); } } @@ -478,8 +491,6 @@ namespace updater return; } - delete_old_data_files(); - const auto garbage_files = update_data.access>([](update_data_t& data_) { return data_.garbage_files; @@ -507,7 +518,7 @@ namespace updater scheduler::once([]() { - const auto required_files = update_data.access>([](update_data_t& data_) + const auto required_files = update_data.access>([](update_data_t& data_) { return data_.required_files; }); @@ -516,16 +527,16 @@ namespace updater for (const auto& file : required_files) { - update_data.access([file](update_data_t& data_) + update_data.access([&](update_data_t& data_) { - data_.current_file = file; + data_.current_file = file.name; }); #ifdef DEBUG - console::info("[Updater] downloading file %s\n", file.data()); + console::info("[Updater] downloading file %s\n", file.name.data()); #endif - const auto data = download_file(file); + const auto data = download_data_file(file.name); if (is_update_cancelled()) { @@ -535,11 +546,18 @@ namespace updater if (!data.has_value()) { - set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); + set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file.name); return; } - downloads.push_back({file, data.value()}); + const auto& value = data.value(); + if (file.hash != utils::cryptography::sha1::compute(value, true)) + { + set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file.name); + return; + } + + downloads.emplace_back(file.name, data.value()); } for (const auto& download : downloads) @@ -555,6 +573,12 @@ namespace updater }, scheduler::pipeline::async); } + bool should_force_update() + { + const auto folder = (utils::properties::get_appdata_path() / CLIENT_DATA_FOLDER).generic_string(); + return !utils::io::directory_exists(folder) || utils::io::directory_is_empty(folder); + } + class component final : public component_interface { public: diff --git a/src/client/component/updater.hpp b/src/client/component/updater.hpp index 0301a6c3..a72e34b4 100644 --- a/src/client/component/updater.hpp +++ b/src/client/component/updater.hpp @@ -4,6 +4,8 @@ namespace updater { + std::optional get_server_file(const std::string& endpoint); + void relaunch(); void set_has_tried_update(bool tried); @@ -25,4 +27,6 @@ namespace updater void start_update_check(); void start_update_download(); void cancel_update(); + + bool should_force_update(); } \ No newline at end of file diff --git a/src/client/game/assets.hpp b/src/client/game/assets.hpp new file mode 100644 index 00000000..53f50c59 --- /dev/null +++ b/src/client/game/assets.hpp @@ -0,0 +1,6346 @@ +#pragma once +#include + +#define assert_sizeof(__ASSET__, __SIZE__) static_assert(sizeof(__ASSET__) == __SIZE__) +#define assert_offsetof(__ASSET__, __VARIABLE__, __OFFSET__) static_assert(offsetof(__ASSET__, __VARIABLE__) == __OFFSET__) + +#pragma warning(disable: 4201) + +namespace game +{ + typedef float vec_t; + typedef vec_t vec2_t[2]; + typedef vec_t vec3_t[3]; + typedef vec_t vec4_t[4]; + + template + struct VecInternal + { + float data[N]; + }; + + struct dummy + { + }; + + enum scr_string_t : std::int32_t + { + }; + + enum XAssetType + { + ASSET_TYPE_PHYSPRESET, + ASSET_TYPE_PHYSCOLLMAP, + ASSET_TYPE_PHYSWATERPRESET, + ASSET_TYPE_PHYSWORLDMAP, + ASSET_TYPE_PHYSCONSTRAINT, + ASSET_TYPE_XANIM, + ASSET_TYPE_XMODEL_SURFS, + ASSET_TYPE_XMODEL, + ASSET_TYPE_MATERIAL, + ASSET_TYPE_COMPUTESHADER, + ASSET_TYPE_VERTEXSHADER, + ASSET_TYPE_HULLSHADER, + ASSET_TYPE_DOMAINSHADER, + ASSET_TYPE_PIXELSHADER, + ASSET_TYPE_VERTEXDECL, + ASSET_TYPE_TECHNIQUE_SET, + ASSET_TYPE_IMAGE, + ASSET_TYPE_SOUND, + ASSET_TYPE_SOUNDSUBMIX, + ASSET_TYPE_SOUND_CURVE, + ASSET_TYPE_LPF_CURVE, + ASSET_TYPE_REVERB_CURVE, + ASSET_TYPE_SOUND_CONTEXT, + ASSET_TYPE_LOADED_SOUND, + ASSET_TYPE_COL_MAP_SP, + ASSET_TYPE_COM_MAP, + ASSET_TYPE_GLASS_MAP, + ASSET_TYPE_AIPATHS, + ASSET_TYPE_VEHICLE_TRACK, + ASSET_TYPE_MAP_ENTS, + ASSET_TYPE_FX_MAP, + ASSET_TYPE_GFX_MAP, + ASSET_TYPE_LIGHT_DEF, + ASSET_TYPE_UI_MAP, + ASSET_TYPE_MENULIST, + ASSET_TYPE_MENU, + ASSET_TYPE_ANIMCLASS, + ASSET_TYPE_LOCALIZE_ENTRY, + ASSET_TYPE_ATTACHMENT, + ASSET_TYPE_WEAPON, + ASSET_TYPE_SNDDRIVERGLOBALS, + ASSET_TYPE_FX, + ASSET_TYPE_IMPACT_FX, + ASSET_TYPE_SURFACE_FX, + ASSET_TYPE_AITYPE, + ASSET_TYPE_MPTYPE, + ASSET_TYPE_CHARACTER, + ASSET_TYPE_XMODELALIAS, + ASSET_TYPE_RAWFILE, + ASSET_TYPE_SCRIPTFILE, + ASSET_TYPE_STRINGTABLE, + ASSET_TYPE_LEADERBOARDDEF, + ASSET_TYPE_VIRTUAL_LEADERBOARD, + ASSET_TYPE_STRUCTUREDDATADEF, + ASSET_TYPE_DDL, + ASSET_TYPE_PROTO, + ASSET_TYPE_TRACER, + ASSET_TYPE_VEHICLE, + ASSET_TYPE_ADDON_MAP_ENTS, + ASSET_TYPE_NET_CONST_STRINGS, + ASSET_TYPE_REVERB_PRESET, + ASSET_TYPE_LUA_FILE, + ASSET_TYPE_SCRIPTABLE, + ASSET_TYPE_EQUIPMENT_SND_TABLE, + ASSET_TYPE_VECTORFIELD, + ASSET_TYPE_DOPPLER_PRESET, + ASSET_TYPE_PARTICLE_SIM_ANIMATION, + ASSET_TYPE_LASER, + ASSET_TYPE_SKELETONSCRIPT, + ASSET_TYPE_CLUT, + ASSET_TYPE_TTF, + ASSET_TYPE_COUNT + }; + + struct FxEffectDef; + + struct Bounds + { + vec3_t midPoint; + vec3_t halfSize; + }; + + struct PhysPreset + { + const char* name; + char __pad0[32]; + const char* sndAliasPrefix; + char __pad1[48]; + }; static_assert(sizeof(PhysPreset) == 0x60); + + typedef std::int8_t dm_int8; + typedef std::uint8_t dm_uint8; + typedef std::int16_t dm_int16; + typedef std::uint16_t dm_uint16; + typedef std::int32_t dm_int32; + typedef std::uint32_t dm_uint32; + typedef std::int64_t dm_int64; + typedef std::uint64_t dm_uint64; + typedef float dm_float32; + + struct dmFloat3 + { + dm_float32 x; + dm_float32 y; + dm_float32 z; + }; + + struct dmFloat4 + { + dm_float32 x; + dm_float32 y; + dm_float32 z; + dm_float32 w; + }; + + struct dmMeshNode_anon_fields + { + unsigned int axis : 2; + unsigned int triangleCount : 4; + unsigned int index : 26; + }; + + union dmMeshNode_anon + { + dmMeshNode_anon_fields fields; + unsigned int packed; + }; + + struct dmMeshNode + { + dm_int16 lowerX; + dm_int16 lowerY; + dm_int16 lowerZ; + dm_int16 upperX; + dm_int16 upperY; + dm_int16 upperZ; + dmMeshNode_anon anon; + }; assert_sizeof(dmMeshNode, 16); + + struct dmMeshTriangle + { + dm_int32 i1; + dm_int32 i2; + dm_int32 i3; + dm_int32 w1; + dm_int32 w2; + dm_int32 w3; + dm_int32 materialIndex; + dm_int32 collisionFlags; + }; assert_sizeof(dmMeshTriangle, 32); + + struct dmMeshData + { + dmMeshNode* m_pRoot; + dmFloat4* m_aVertices; + dmMeshTriangle* m_aTriangles; + dmFloat3 m_center; + dmFloat3 m_extents; + dmFloat3 m_unquantize; + dm_int32 m_nodeCount; + dm_int32 m_vertexCount; + dm_int32 m_triangleCount; + dm_int32 m_height; + dm_int32 contents; + }; assert_sizeof(dmMeshData, 0x50); + + struct dmSubEdge + { + dm_int8 twinOffset; + dm_uint8 tail; + dm_uint8 left; + dm_uint8 next; + }; assert_sizeof(dmSubEdge, 4); + + struct dmPolytopeData + { + dmFloat4* vec4_array0; // count: m_vertexCount, m_aVertices? + dmFloat4* vec4_array1; // count: m_faceCount, m_aPlanes? + dm_uint16* uint16_array0; // count: m_faceCount, m_vertexMaterials? surfaceType? // ALWAYS 0 + dm_uint16* uint16_array1; // count: m_vertexCount, m_vertexMaterials? // ALWAYS 0 + dmSubEdge* m_aSubEdges; // count: m_subEdgeCount + dm_uint8* m_aFaceSubEdges; // count: m_faceCount + dmFloat3 m_centroid; + dm_int32 m_vertexCount; + dm_int32 m_faceCount; + dm_int32 m_subEdgeCount; + float pad1[8]; + int contents; + int pad2; + }; assert_sizeof(dmPolytopeData, 0x70); + + struct PhysGeomInfo + { + dmPolytopeData* data; + }; + + struct PhysMass + { + float centerOfMass[3]; + float momentsOfInertia[3]; + float productsOfInertia[3]; + }; + + struct PhysCollmap + { + const char* name; + unsigned int count; + PhysGeomInfo* geoms; + PhysMass mass; + Bounds bounds; + }; assert_sizeof(PhysCollmap, 0x58); + + struct PhysWaterPreset + { + const char* name; + char __pad0[64]; + FxEffectDef* fx0; + FxEffectDef* fx1; + FxEffectDef* fx2; + FxEffectDef* fx3; + FxEffectDef* fx4; + FxEffectDef* fx5; + FxEffectDef* fx6; + }; assert_sizeof(PhysWaterPreset, 0x80); + + struct PhysWaterVolumeDef + { + PhysWaterPreset* physWaterPreset; + char __pad0[12]; + scr_string_t string; + short brushModelIndex; + char __pad1[6]; + }; assert_sizeof(PhysWaterVolumeDef, 0x20); + assert_offsetof(PhysWaterVolumeDef, string, 20); + + struct PhysBrushModelPacked + { + std::uint64_t p; + }; + + struct PhysBrushModelFields + { + short polytopeIndex; + short unk; + short worldIndex; + short meshIndex; + }; + + union PhysBrushModel + { + PhysBrushModelPacked packed; + PhysBrushModelFields fields; + }; assert_sizeof(PhysBrushModel, 8); + + struct PhysWorld // PhysicsWorld + { + const char* name; + PhysBrushModel* brushModels; + dmPolytopeData* polytopeDatas; + dmMeshData* meshDatas; + PhysWaterVolumeDef* waterVolumeDefs; + unsigned int brushModelCount; + unsigned int polytopeCount; + unsigned int meshDataCount; + unsigned int waterVolumeDefCount; + }; assert_sizeof(PhysWorld, 0x38); + + + struct PhysConstraint + { + const char* name; + char __pad0[32]; + }; static_assert(sizeof(PhysConstraint) == 0x28); + + struct Packed128 + { + std::uint64_t p0; + std::uint64_t p1; + }; + + union GfxDrawSurf + { + //GfxDrawSurfFields fields; + Packed128 packed; + }; + + enum MaterialTechniqueType : std::int32_t + { + TECHNIQUE_UNLIT = 8, + TECHNIQUE_EMISSIVE = 9, + TECHNIQUE_LIT = 13, + TECHNIQUE_WIREFRAME = 53, + }; + + struct GfxComputeShaderLoadDef + { + unsigned char* program; + unsigned int programSize; + char __pad[4]; + }; + + struct ComputeShaderProgram + { + ID3D11ComputeShader* cs; + GfxComputeShaderLoadDef loadDef; + }; + + struct ComputeShader + { + const char* name; + ComputeShaderProgram prog; + }; static_assert(sizeof(ComputeShader) == 0x20); + + struct GfxVertexShaderLoadDef + { + unsigned char* program; + unsigned int programSize; + unsigned int microCodeCrc; + }; + + struct MaterialVertexShaderProgram + { + ID3D11VertexShader* vs; + GfxVertexShaderLoadDef loadDef; + }; + + struct MaterialVertexShader + { + const char* name; + MaterialVertexShaderProgram prog; + }; static_assert(sizeof(MaterialVertexShader) == 0x20); + + struct GfxPixelShaderLoadDef + { + unsigned char* program; + unsigned int programSize; + unsigned int microCodeCrc; + }; + + struct MaterialPixelShaderProgram + { + ID3D11PixelShader* ps; + GfxPixelShaderLoadDef loadDef; + }; + + struct MaterialPixelShader + { + const char* name; + MaterialPixelShaderProgram prog; + }; static_assert(sizeof(MaterialPixelShader) == 0x20); + + struct GfxHullShaderLoadDef + { + unsigned char* program; + unsigned int programSize; + char __pad[4]; + }; + + struct MaterialHullShaderProgram + { + ID3D11HullShader* hs; + GfxHullShaderLoadDef loadDef; + }; + + struct MaterialHullShader + { + const char* name; + MaterialHullShaderProgram prog; + }; static_assert(sizeof(MaterialHullShader) == 0x20); + + struct GfxDomainShaderLoadDef + { + unsigned char* program; + unsigned int programSize; + char __pad[4]; + }; + + struct MaterialDomainShaderProgram + { + ID3D11DomainShader* ds; + GfxDomainShaderLoadDef loadDef; + }; + + struct MaterialDomainShader + { + const char* name; + MaterialDomainShaderProgram prog; + }; static_assert(sizeof(MaterialDomainShader) == 0x20); + + enum MaterialConstSource : std::int32_t + { + CONST_SRC_CODE_LIGHT_POSITION, + CONST_SRC_CODE_LIGHT_DIFFUSE, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE, + CONST_SRC_CODE_LIGHT_FADEOFFSET, + CONST_SRC_CODE_LIGHT_SPECULAR, + CONST_SRC_CODE_LIGHT_SPOTDIR, + CONST_SRC_CODE_LIGHT_SPOTFACTORS, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM, + CONST_SRC_CODE_LIGHT_POSITION1, + CONST_SRC_CODE_LIGHT_DIFFUSE1, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE1, + CONST_SRC_CODE_LIGHT_FADEOFFSET1, + CONST_SRC_CODE_LIGHT_SPECULAR1, + CONST_SRC_CODE_LIGHT_SPOTDIR1, + CONST_SRC_CODE_LIGHT_SPOTFACTORS1, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT1, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM1, + CONST_SRC_CODE_LIGHT_POSITION2, + CONST_SRC_CODE_LIGHT_DIFFUSE2, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE2, + CONST_SRC_CODE_LIGHT_FADEOFFSET2, + CONST_SRC_CODE_LIGHT_SPECULAR2, + CONST_SRC_CODE_LIGHT_SPOTDIR2, + CONST_SRC_CODE_LIGHT_SPOTFACTORS2, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT2, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM2, + CONST_SRC_CODE_LIGHT_POSITION3, + CONST_SRC_CODE_LIGHT_DIFFUSE3, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE3, + CONST_SRC_CODE_LIGHT_FADEOFFSET3, + CONST_SRC_CODE_LIGHT_SPECULAR3, + CONST_SRC_CODE_LIGHT_SPOTDIR3, + CONST_SRC_CODE_LIGHT_SPOTFACTORS3, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT3, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM3, + CONST_SRC_CODE_LIGHT_POSITION_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_POSITION_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_POSITION_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_POSITION_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_DIFFUSE_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_DIFFUSE_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_DIFFUSE_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_DIFFUSE_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_PHYSICALSIZE_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_FADEOFFSET_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_FADEOFFSET_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_FADEOFFSET_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_FADEOFFSET_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_SPECULAR_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_SPECULAR_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_SPECULAR_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_SPECULAR_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_SPOTDIR_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_SPOTDIR_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_SPOTDIR_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_SPOTDIR_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_SPOTFACTORS_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_SPOTFACTORS_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_SPOTFACTORS_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_SPOTFACTORS_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_CUCOLORIS_ANIM_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT_DB_ARRAY_0, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT_DB_ARRAY_1, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT_DB_ARRAY_2, + CONST_SRC_CODE_LIGHT_FALLOFF_PLACEMENT_DB_ARRAY_3, + CONST_SRC_CODE_LIGHT_DYN_COUNT, + CONST_SRC_CODE_LIGHT_DYN_TYPES, + CONST_SRC_CODE_LIGHT_DYN_SHADOW_TYPES, + CONST_SRC_CODE_PARTICLE_CLOUD_COLOR, + CONST_SRC_CODE_GAMETIME, + CONST_SRC_CODE_SYSTEMTIME, + CONST_SRC_CODE_GENERIC_MATERIAL_DATA, + CONST_SRC_CODE_EYEOFFSET, + CONST_SRC_CODE_RATIO_MASK, + CONST_SRC_CODE_WORLD_MATRIX_EYE_OFFSET, + CONST_SRC_CODE_HUD_OUTLINE_PARMS, + CONST_SRC_CODE_MODEL_VELOCITY_PARMS, + CONST_SRC_CODE_MODEL_VELOCITY_SKINNED_PARMS, + CONST_SRC_CODE_POSTFX_CONTROL0, + CONST_SRC_CODE_POSTFX_CONTROL1, + CONST_SRC_CODE_POSTFX_CONTROL2, + CONST_SRC_CODE_POSTFX_CONTROL3, + CONST_SRC_CODE_POSTFX_CONTROL4, + CONST_SRC_CODE_POSTFX_CONTROL5, + CONST_SRC_CODE_POSTFX_CONTROL6, + CONST_SRC_CODE_POSTFX_CONTROL7, + CONST_SRC_CODE_POSTFX_CONTROL8, + CONST_SRC_CODE_POSTFX_CONTROL9, + CONST_SRC_CODE_POSTFX_CONTROLA, + CONST_SRC_CODE_POSTFX_CONTROLB, + CONST_SRC_CODE_POSTFX_CONTROLC, + CONST_SRC_CODE_POSTFX_CONTROLD, + CONST_SRC_CODE_POSTFX_CONTROLE, + CONST_SRC_CODE_POSTFX_CONTROLF, + CONST_SRC_CODE_SCRIPT_PARMS, + CONST_SRC_CODE_EFFECT_MODEL_COLOR, + CONST_SRC_CODE_EFFECT_MODEL_COLOR_EMISSIVE, + CONST_SRC_CODE_FILTER_TAP_0, + CONST_SRC_CODE_FILTER_TAP_1, + CONST_SRC_CODE_FILTER_TAP_2, + CONST_SRC_CODE_FILTER_TAP_3, + CONST_SRC_CODE_FILTER_TAP_4, + CONST_SRC_CODE_FILTER_TAP_5, + CONST_SRC_CODE_FILTER_TAP_6, + CONST_SRC_CODE_FILTER_TAP_7, + CONST_SRC_CODE_FILTER_TAP_8, + CONST_SRC_CODE_FILTER_TAP_9, + CONST_SRC_CODE_FILTER_TAP_10, + CONST_SRC_CODE_FILTER_TAP_11, + CONST_SRC_CODE_COLOR_MATRIX_R, + CONST_SRC_CODE_COLOR_MATRIX_G, + CONST_SRC_CODE_COLOR_MATRIX_B, + CONST_SRC_CODE_RENDER_TARGET_SIZE, + CONST_SRC_CODE_RENDER_SOURCE_SIZE, + CONST_SRC_CODE_VEIL_PARAMS, + CONST_SRC_CODE_FXAA_RCPFRAMEOPT, + CONST_SRC_CODE_VOLUME_LIGHT_SCATTER_1, + CONST_SRC_CODE_VOLUME_LIGHT_SCATTER_2, + CONST_SRC_CODE_VOLUME_LIGHT_SCATTER_3, + CONST_SRC_CODE_MODEL_LIGHTMAP_PARAMS, + CONST_SRC_CODE_NEARPLANE_ORG, + CONST_SRC_CODE_NEARPLANE_DX, + CONST_SRC_CODE_NEARPLANE_DY, + CONST_SRC_CODE_SSAO_POWER_BB_SHARPNESS_STEP, + CONST_SRC_CODE_SSAO_COLOR_COEFF, + CONST_SRC_CODE_SSAO_FALLOFF_DEPTH_SCALE, + CONST_SRC_CODE_SSAO_UV_TO_ROT_SCALE_AND_FADE, + CONST_SRC_CODE_SSAO_SAMPLE_MAT_SCALE, + CONST_SRC_CODE_SSAO_DEPTH_OFFSET_REJECT, + CONST_SRC_CODE_LIT2D_LIGHTDIRX2, + CONST_SRC_CODE_LIT2D_SPECHALFANGLEDIRX2, + CONST_SRC_CODE_LIT2D_AMBIENTCOLOR, + CONST_SRC_CODE_LIT2D_DIFFUSECOLOR, + CONST_SRC_CODE_LIT2D_SPECCOLOR_SPECEXPONENT, + CONST_SRC_CODE_LIT2D_ADDITIVECOLOR, + CONST_SRC_CODE_LIT2D_BLOODSPATTER_AMBIENTCOLOR, + CONST_SRC_CODE_LIT2D_BLOODSPATTER_DIFFUSECOLOR, + CONST_SRC_CODE_LIT2D_BLOODSPATTER_SPECCOLOR_SPECEXPONENT, + CONST_SRC_CODE_LIT2D_BLOODSPATTER_ADDITIVECOLOR, + CONST_SRC_CODE_LIT2D_HUDBLOOD_COLOR, + CONST_SRC_CODE_LIT2D_HUDBLOOD_COLOR_THIN, + CONST_SRC_CODE_DOF_EQUATION_VIEWMODEL_AND_FAR_BLUR, + CONST_SRC_CODE_DOF_EQUATION_SCENE, + CONST_SRC_CODE_DOF_UNK, + CONST_SRC_CODE_DOF_LERP_SCALE, + CONST_SRC_CODE_DOF_LERP_BIAS, + CONST_SRC_CODE_DOF_ROW_DELTA, + CONST_SRC_CODE_DOF_EQUATION, + CONST_SRC_CODE_DOF_PARAMS, + CONST_SRC_CODE_DOF_TILE_PARAMS, + CONST_SRC_CODE_FRAME_COUNT_PARAMS, + CONST_SRC_CODE_MOTION_MATRIX_X, + CONST_SRC_CODE_MOTION_MATRIX_Y, + CONST_SRC_CODE_MOTION_MATRIX_W, + CONST_SRC_CODE_SSR_PREV_FRAME_VIEWPROJECTION_MATRIX_R0, + CONST_SRC_CODE_SSR_PREV_FRAME_VIEWPROJECTION_MATRIX_R1, + CONST_SRC_CODE_SSR_PREV_FRAME_VIEWPROJECTION_MATRIX_R2, + CONST_SRC_CODE_SSR_PREV_FRAME_VIEWPROJECTION_MATRIX_R3, + CONST_SRC_CODE_PREV_EYEPOSITION_TRANSFORM, + CONST_SRC_CODE_SCREEN_SPACE_REFLECTION_PARAMETERS, + CONST_SRC_CODE_CLIP_SPACE_LOOKUP_SCALE_AND_OFFSET, + CONST_SRC_CODE_SSR_CLIP_TO_FADE_SCALE_OFFSET_PS, + CONST_SRC_CODE_SSS_MRT_OFF_SHADER_OFF, + CONST_SRC_CODE_MDAO_VIEWTOOCCLUDER_MATRIX_R0, + CONST_SRC_CODE_MDAO_VIEWTOOCCLUDER_MATRIX_R1, + CONST_SRC_CODE_MDAO_VIEWTOOCCLUDER_MATRIX_R2, + CONST_SRC_CODE_MDAO_VIEWTOOCCLUDER_MATRIX_R3, + CONST_SRC_CODE_MDAO_WORLDTOOCCLUDERFRAME_MATRIX_R0, + CONST_SRC_CODE_MDAO_WORLDTOOCCLUDERFRAME_MATRIX_R1, + CONST_SRC_CODE_MDAO_WORLDTOOCCLUDERFRAME_MATRIX_R2, + CONST_SRC_CODE_MDAO_WORLDTOOCCLUDERFRAME_MATRIX_R3, + CONST_SRC_CODE_MDAO_SCREEN_PARAMS, + CONST_SRC_CODE_MDAO_CAMERA_PARAMS, + CONST_SRC_CODE_MDAO_LOOKUP_PARAMS, + CONST_SRC_CODE_MDAO_VOLUME_PARAMS, + CONST_SRC_CODE_DISTORTION_SAMPLE_LIMITS_PS, + CONST_SRC_CODE_SCOPE_SAMPLE_LIMITS_PS, + CONST_SRC_CODE_UV_TO_PREV_SCALED_CLIP_MAT_C0_PS, + CONST_SRC_CODE_UV_TO_PREV_SCALED_CLIP_MAT_C1_PS, + CONST_SRC_CODE_UV_TO_PREV_SCALED_CLIP_MAT_C3_PS, + CONST_SRC_CODE_PREV_FRAME_VIEWPROJECTION_MATRIX_R0, + CONST_SRC_CODE_PREV_FRAME_VIEWPROJECTION_MATRIX_R1, + CONST_SRC_CODE_PREV_FRAME_VIEWPROJECTION_MATRIX_R2, + CONST_SRC_CODE_PREV_FRAME_VIEWPROJECTION_MATRIX_R3, + CONST_SRC_CODE_PREV_FRAME_WORLD_MATRIX_EYE_OFFSET, + CONST_SRC_CODE_STATIC_VELOCITY_PARMS, + CONST_SRC_CODE_MOTION_BLUR_HQ_PARAMS, + CONST_SRC_CODE_MOTION_BLUR_HQ_TILE_MAX_PARAMS, + CONST_SRC_CODE_MB_UV_TO_PREV_SCALED_CLIP_MAT_C0_PS, + CONST_SRC_CODE_MB_UV_TO_PREV_SCALED_CLIP_MAT_C1_PS, + CONST_SRC_CODE_MB_UV_TO_PREV_SCALED_CLIP_MAT_C3_PS, + CONST_SRC_CODE_SHADOWMAP_SWITCH_PARTITION_ARRAY_0, + CONST_SRC_CODE_SHADOWMAP_SWITCH_PARTITION_ARRAY_1, + CONST_SRC_CODE_SHADOWMAP_DISTANCE_BIAS, + CONST_SRC_CODE_SHADOWMAP_SCALE, + CONST_SRC_CODE_SHADOWMAP_PARTITION_UV_OFFSET, + CONST_SRC_CODE_SHADOWMAP_CASCADE_MASK, + CONST_SRC_CODE_SHADOWMAP_DISTANCE_BLEND, + CONST_SRC_CODE_ZNEAR, + CONST_SRC_CODE_LIGHTING_LOOKUP_SCALE, + CONST_SRC_CODE_INV_SCENE_PROJECTION, + CONST_SRC_CODE_RIM_LIGHT_0_DIR, + CONST_SRC_CODE_RIM_LIGHT_0_COLOR, + CONST_SRC_CODE_RIM_LIGHT_1_DIR, + CONST_SRC_CODE_RIM_LIGHT_1_COLOR, + CONST_SRC_CODE_RIM_LIGHT_TECHNIQUE, + CONST_SRC_CODE_DEBUG_BUMPMAP, + CONST_SRC_CODE_DEBUG_TEXDENSITY, + CONST_SRC_CODE_MATERIAL_COLOR, + CONST_SRC_CODE_FOG, + CONST_SRC_CODE_FOG_COLOR_LINEAR, + CONST_SRC_CODE_FOG_COLOR_GAMMA, + CONST_SRC_CODE_FOG_SUN_CONSTS, + CONST_SRC_CODE_FOG_SUN_COLOR_LINEAR, + CONST_SRC_CODE_FOG_SUN_COLOR_GAMMA, + CONST_SRC_CODE_FOG_SUN_DIR, + CONST_SRC_CODE_FOG_SKY_FOG, + CONST_SRC_CODE_FOG_HEIGHT_FOG, + CONST_SRC_CODE_ATMOS_FOG_PARMS_0, + CONST_SRC_CODE_ATMOS_FOG_PARMS_1, + CONST_SRC_CODE_ATMOS_FOG_PARMS_2, + CONST_SRC_CODE_ATMOS_FOG_PARMS_3, + CONST_SRC_CODE_ATMOS_FOG_PARMS_4, + CONST_SRC_CODE_ATMOS_FOG_PARMS_5, + CONST_SRC_CODE_ATMOS_FOG_PARMS_6, + CONST_SRC_CODE_ATMOS_FOG_PARMS_7, + CONST_SRC_CODE_FOG_SKY_DIR, + CONST_SRC_CODE_FOG_DEPTHHACK, + CONST_SRC_CODE_GLOW_SETUP, + CONST_SRC_CODE_GLOW_APPLY, + CONST_SRC_CODE_GLOW_SETUP_ALT_COLOR_SCALE, + CONST_SRC_CODE_COLOR_BIAS, + CONST_SRC_CODE_COLOR_TINT_BASE, + CONST_SRC_CODE_COLOR_TINT_DELTA, + CONST_SRC_CODE_COLOR_TINT_QUADRATIC_DELTA, + CONST_SRC_CODE_COLOR_TINT_HDR_CROSSOVER, + CONST_SRC_CODE_COLOR_TINT_HDR_DARK, + CONST_SRC_CODE_COLOR_TINT_HDR_DARK_TANGENT, + CONST_SRC_CODE_COLOR_TINT_HDR_MEDIUM, + CONST_SRC_CODE_COLOR_TINT_HDR_MEDIUM_TANGENT, + CONST_SRC_CODE_COLOR_TINT_HDR_LIGHT, + CONST_SRC_CODE_COLOR_TINT_HDR_LIGHT_TANGENT, + CONST_SRC_CODE_COLOR_TINT_HDR_SPECULAR, + CONST_SRC_CODE_COLOR_TINT_HDR_SPECULAR_TANGENT, + CONST_SRC_CODE_PERCEPTUAL_PARMS, + CONST_SRC_CODE_FILMIC_PARMS, + CONST_SRC_CODE_FILMIC_SHOULDER_PARMS, + CONST_SRC_CODE_FILMIC_TOE_PARMS, + CONST_SRC_CODE_TONEMAP_PARMS, + CONST_SRC_CODE_HDR_STAGE_PARMS, + CONST_SRC_CODE_UI3D_UV_SETUP_0, + CONST_SRC_CODE_UI3D_UV_SETUP_1, + CONST_SRC_CODE_UI3D_UV_SETUP_2, + CONST_SRC_CODE_UI3D_UV_SETUP_3, + CONST_SRC_CODE_UI3D_UV_SETUP_4, + CONST_SRC_CODE_UI3D_UV_SETUP_5, + CONST_SRC_CODE_HUDFX_PARMS, + CONST_SRC_CODE_HUDFX_PARMS2, + CONST_SRC_CODE_SSSS_PARAMS, + CONST_SRC_CODE_SSSS_SCALE, + CONST_SRC_CODE_SSSS_KERNEL_0, + CONST_SRC_CODE_SSSS_KERNEL_1, + CONST_SRC_CODE_SSSS_KERNEL_2, + CONST_SRC_CODE_SSSS_KERNEL_3, + CONST_SRC_CODE_SSSS_KERNEL_4, + CONST_SRC_CODE_SSSS_KERNEL_5, + CONST_SRC_CODE_SSSS_KERNEL_6, + CONST_SRC_CODE_SSSS_KERNEL_7, + CONST_SRC_CODE_SSSS_KERNEL_8, + CONST_SRC_CODE_SSSS_KERNEL_9, + CONST_SRC_CODE_SSSS_KERNEL_10, + CONST_SRC_CODE_SSSS_KERNEL_11, + CONST_SRC_CODE_SSSS_KERNEL_12, + CONST_SRC_CODE_OUTDOOR_FEATHER_PARMS, + CONST_SRC_CODE_ENVMAP_PARMS, + CONST_SRC_CODE_SUN_SHADOWMAP_PIXEL_ADJUST_ARRAY_0, + CONST_SRC_CODE_SUN_SHADOWMAP_PIXEL_ADJUST_ARRAY_1, + CONST_SRC_CODE_SUN_SHADOWMAP_PIXEL_ADJUST_ARRAY_2, + CONST_SRC_CODE_SUN_SHADOWMAP_CASCADE_V_CLAMP, + CONST_SRC_CODE_SUN_SHADOWMAP_NEAR_FAR_PLANE, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_1, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_2, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_3, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_ARRAY_0, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_ARRAY_1, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_ARRAY_2, + CONST_SRC_CODE_SPOT_SHADOWMAP_PIXEL_ADJUST_ARRAY_3, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_1, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_2, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_3, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_ARRAY_0, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_ARRAY_1, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_ARRAY_2, + CONST_SRC_CODE_SPOT_SHADOWMAP_ZTRANSFORM_ARRAY_3, + CONST_SRC_CODE_COMPOSITE_FX_DISTORTION, + CONST_SRC_CODE_POSTFX_FADE_EFFECT, + CONST_SRC_CODE_SCENE_UV_MULT, + CONST_SRC_CODE_SCENE_VIEW_MULT, + CONST_SRC_CODE_TEXCOORD_CLAMP_0, + CONST_SRC_CODE_TEXCOORD_CLAMP_1, + CONST_SRC_CODE_VIEWPORT_DIMENSIONS, + CONST_SRC_CODE_FRAMEBUFFER_READ, + CONST_SRC_CODE_THERMAL_COLOR_OFFSET, + CONST_SRC_CODE_THERMAL_FADE_CONTROL, + CONST_SRC_CODE_THERMAL_FADE_COLOR, + CONST_SRC_CODE_PLAYLIST_POPULATION_PARAMS, + CONST_SRC_CODE_TESSELLATION_PARMS, + CONST_SRC_CODE_TESSELLATION_PARMS2, + CONST_SRC_CODE_EYE_PARAMETER_DVAR, + CONST_SRC_CODE_MP_RIM_PARAMETER_DVAR1, + CONST_SRC_CODE_MP_RIM_PARAMETER_DVAR2, + CONST_SRC_CODE_HEAD_ROT_MAT_R0, + CONST_SRC_CODE_HEAD_ROT_MAT_R1, + CONST_SRC_CODE_HEAD_ROT_MAT_R2, + CONST_SRC_CODE_GUN_SIGHT_COLOR, + CONST_SRC_CODE_GUN_RETICLE_COLOR, + CONST_SRC_CODE_ADS_OVERLAY_RECT, + CONST_SRC_CODE_BASE_LIGHTING_COORDS, + CONST_SRC_CODE_LIGHT_PROBE_AMBIENT, + CONST_SRC_CODE_CLIP_SPACE_LOOKUP_SCALE, + CONST_SRC_CODE_CLIP_SPACE_LOOKUP_OFFSET, + CONST_SRC_CODE_PARTICLE_CLOUD_TEXTURE_ATLAS_SETTINGS, + CONST_SRC_CODE_PARTICLE_CLOUD_VEL_WORLD, + CONST_SRC_CODE_PARTICLE_CLOUD_MATRIX0, + CONST_SRC_CODE_PARTICLE_CLOUD_MATRIX1, + CONST_SRC_CODE_PARTICLE_CLOUD_MATRIX2, + CONST_SRC_CODE_PARTICLE_CLOUD_SPARK_COLOR0, + CONST_SRC_CODE_PARTICLE_CLOUD_SPARK_COLOR1, + CONST_SRC_CODE_PARTICLE_CLOUD_SPARK_COLOR2, + CONST_SRC_CODE_PARTICLE_FOUNTAIN_PARM0, + CONST_SRC_CODE_PARTICLE_FOUNTAIN_PARM1, + CONST_SRC_CODE_LIT2D_BLOODSPATTER_FADESHARPNESS, + CONST_SRC_CODE_BLUR_SCENE_PIXEL_POS_TO_UV, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_0, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_1, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_2, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_3, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_4, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_5, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_6, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_7, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_8, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_9, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_10, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_11, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_12, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_13, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_14, + CONST_SRC_CODE_REACTIVEMOTION_CENTERS_15, + CONST_SRC_CODE_DEPTH_FROM_CLIP, + CONST_SRC_CODE_CODE_MESH_ARG_0, + CONST_SRC_CODE_CODE_MESH_ARG_1, + CONST_SRC_CODE_CODE_MESH_ARG_3, + CONST_SRC_CODE_CODE_MESH_ARG_4, + CONST_SRC_CODE_SCRIPT_CONST0, + CONST_SRC_CODE_VIEW_MATRIX, + CONST_SRC_CODE_INVERSE_VIEW_MATRIX, + CONST_SRC_CODE_TRANSPOSE_VIEW_MATRIX, + CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_MATRIX, + CONST_SRC_CODE_PROJECTION_MATRIX, + CONST_SRC_CODE_INVERSE_PROJECTION_MATRIX, + CONST_SRC_CODE_TRANSPOSE_PROJECTION_MATRIX, + CONST_SRC_CODE_INVERSE_TRANSPOSE_PROJECTION_MATRIX, + CONST_SRC_CODE_VIEW_PROJECTION_MATRIX, + CONST_SRC_CODE_INVERSE_VIEW_PROJECTION_MATRIX, + CONST_SRC_CODE_TRANSPOSE_VIEW_PROJECTION_MATRIX, + CONST_SRC_CODE_INVERSE_TRANSPOSE_VIEW_PROJECTION_MATRIX, + CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX, + CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX, + CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX, + CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX, + CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX1, + CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX1, + CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX1, + CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX1, + CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX2, + CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX2, + CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX2, + CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX2, + CONST_SRC_CODE_SHADOW_LOOKUP_MATRIX3, + CONST_SRC_CODE_INVERSE_SHADOW_LOOKUP_MATRIX3, + CONST_SRC_CODE_TRANSPOSE_SHADOW_LOOKUP_MATRIX3, + CONST_SRC_CODE_INVERSE_TRANSPOSE_SHADOW_LOOKUP_MATRIX3, + CONST_SRC_CODE_WORLD_OUTDOOR_LOOKUP_MATRIX, + CONST_SRC_CODE_INVERSE_WORLD_OUTDOOR_LOOKUP_MATRIX, + CONST_SRC_CODE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_OUTDOOR_LOOKUP_MATRIX, + CONST_SRC_CODE_PREV_FRAME_WORLD_MATRIX, + CONST_SRC_CODE_PREV_FRAME_INVERSE_WORLD_MATRIX, + CONST_SRC_CODE_PREV_FRAME_TRANSPOSE_WORLD_MATRIX, + CONST_SRC_CODE_PREV_FRAME_INVERSE_TRANSPOSE_WORLD_MATRIX, + CONST_SRC_CODE_WORLD_MATRIX0, + CONST_SRC_CODE_INVERSE_WORLD_MATRIX0, + CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX0, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX0, + CONST_SRC_CODE_WORLD_VIEW_MATRIX0, + CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX0, + CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX0, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX0, + CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX0, + CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX0, + CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX0, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX0, + CONST_SRC_CODE_WORLD_MATRIX1, + CONST_SRC_CODE_INVERSE_WORLD_MATRIX1, + CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX1, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX1, + CONST_SRC_CODE_WORLD_VIEW_MATRIX1, + CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX1, + CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX1, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX1, + CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX1, + CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX1, + CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX1, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX1, + CONST_SRC_CODE_WORLD_MATRIX2, + CONST_SRC_CODE_INVERSE_WORLD_MATRIX2, + CONST_SRC_CODE_TRANSPOSE_WORLD_MATRIX2, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_MATRIX2, + CONST_SRC_CODE_WORLD_VIEW_MATRIX2, + CONST_SRC_CODE_INVERSE_WORLD_VIEW_MATRIX2, + CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_MATRIX2, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX2, + CONST_SRC_CODE_WORLD_VIEW_PROJECTION_MATRIX2, + CONST_SRC_CODE_INVERSE_WORLD_VIEW_PROJECTION_MATRIX2, + CONST_SRC_CODE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX2, + CONST_SRC_CODE_INVERSE_TRANSPOSE_WORLD_VIEW_PROJECTION_MATRIX2, + CONST_SRC_TOTAL_COUNT, + CONST_SRC_NONE, + }; + + struct MaterialArgumentCodeConst + { + unsigned short index; + unsigned char firstRow; + unsigned char rowCount; + }; + + union MaterialArgumentDef + { + const float* literalConst; + MaterialArgumentCodeConst codeConst; + unsigned int codeSampler; + unsigned int nameHash; + }; + + struct MaterialShaderArgument + { + unsigned char type; + unsigned char shader; + unsigned short dest; + MaterialArgumentDef u; + }; static_assert(sizeof(MaterialShaderArgument) == 0x10); + + struct MaterialStreamRouting + { + unsigned char source; + unsigned char dest; + unsigned char mask; + }; + + struct MaterialVertexStreamRouting + { + MaterialStreamRouting data[32]; + ID3D11InputLayout* decl[250]; + }; + + struct MaterialVertexDeclaration + { + const char* name; + unsigned char streamCount; + bool hasOptionalSource; + MaterialVertexStreamRouting routing; + }; static_assert(sizeof(MaterialVertexDeclaration) == 0x840); + + struct MaterialPass + { + MaterialVertexShader* vertexShader; + MaterialVertexDeclaration* vertexDecl; + MaterialHullShader* hullShader; + MaterialDomainShader* domainShader; + MaterialPixelShader* pixelShader; + unsigned char pixelOutputMask; + unsigned char perPrimArgCount; + unsigned char perObjArgCount; + unsigned char stableArgCount; + unsigned short perPrimArgSize; + unsigned short perObjArgSize; + unsigned short stableArgSize; + unsigned short zone; + unsigned char perPrimConstantBuffer; + unsigned char perObjConstantBuffer; + unsigned char stableConstantBuffer; + unsigned int customBufferFlags; + unsigned char customSamplerFlags; + unsigned char precompiledIndex; + unsigned char stageConfig; + MaterialShaderArgument* args; + }; + + static_assert(offsetof(MaterialPass, zone) == 50); + + struct MaterialTechniqueHeader + { + const char* name; + unsigned short flags; + unsigned short passCount; + }; + + struct MaterialTechnique + { + //const char* name; + //unsigned short flags; + //unsigned short passCount; + MaterialTechniqueHeader hdr; + MaterialPass passArray[1]; + }; + + struct MaterialTechniqueSet + { + const char* name; + unsigned short flags; + unsigned char worldVertFormat; + unsigned char preDisplacementOnlyCount; + MaterialTechnique* techniques[252]; + }; static_assert(sizeof(MaterialTechniqueSet) == 0x7F0); + + static_assert(offsetof(MaterialTechniqueSet, techniques) == 16); + + struct GfxImage; + + struct WaterWritable + { + float floatTime; + }; + + struct water_t + { + WaterWritable writable; + float* H0X; + float* H0Y; + float* wTerm; + int M; + int N; + float Lx; + float Lz; + float gravity; + float windvel; + float winddir[2]; + float amplitude; + GfxImage* image; + GfxImage* stagingImage; + }; + + union MaterialTextureDefInfo + { + GfxImage* image; + water_t* water; + }; + + struct MaterialTextureDef + { + unsigned int nameHash; + char nameStart; + char nameEnd; + unsigned char samplerState; + unsigned char semantic; + MaterialTextureDefInfo u; + }; static_assert(sizeof(MaterialTextureDef) == 0x10); + + struct MaterialConstantDef + { + unsigned int nameHash; + char name[12]; + float literal[4]; + }; static_assert(sizeof(MaterialConstantDef) == 0x20); + + struct GfxStateBits + { + unsigned int loadBits[6]; // loadbits[3], blendstatebits[3] + unsigned short zone; + unsigned char depthStencilState[10]; + unsigned char blendState; + unsigned char rasterizerState; + }; static_assert(sizeof(GfxStateBits) == 0x28); + + struct MaterialConstantBufferDef + { + unsigned int vsDataSize; + unsigned int hsDataSize; + unsigned int dsDataSize; + unsigned int psDataSize; + unsigned int vsOffsetDataSize; + unsigned int hsOffsetDataSize; + unsigned int dsOffsetDataSize; + unsigned int psOffsetDataSize; + unsigned char* vsData; + unsigned char* hsData; + unsigned char* dsData; + unsigned char* psData; + unsigned short* vsOffsetData; + unsigned short* hsOffsetData; + unsigned short* dsOffsetData; + unsigned short* psOffsetData; + ID3D11Buffer* vsConstantBuffer; + ID3D11Buffer* hsConstantBuffer; + ID3D11Buffer* dsConstantBuffer; + ID3D11Buffer* psConstantBuffer; + }; + + enum SurfaceTypeBits : std::uint64_t + { + SURFTYPE_BITS_NONE = 0x0, + SURFTYPE_BITS_DEFAULT = 0x1, + SURFTYPE_BITS_BARK = 0x2, + SURFTYPE_BITS_CARPET = 0x4, + SURFTYPE_BITS_CLOTH = 0x8, + SURFTYPE_BITS_CONCRETE = 0x10, + SURFTYPE_BITS_DIRT = 0x20, + SURFTYPE_BITS_FLESH = 0x40, + SURFTYPE_BITS_FOLIAGE_DEBRIS = 0x80, + SURFTYPE_BITS_GLASS = 0x100, + SURFTYPE_BITS_GRASS = 0x200, + SURFTYPE_BITS_GRAVEL = 0x400, + SURFTYPE_BITS_ICE = 0x800, + SURFTYPE_BITS_METAL_SOLID = 0x1000, + SURFTYPE_BITS_METAL_GRATE = 0x2000, + SURFTYPE_BITS_MUD = 0x4000, + SURFTYPE_BITS_PAPER = 0x8000, + SURFTYPE_BITS_PLASTER = 0x10000, + SURFTYPE_BITS_ROCK = 0x20000, + SURFTYPE_BITS_SAND = 0x40000, + SURFTYPE_BITS_SNOW = 0x80000, + SURFTYPE_BITS_WATER_WAIST = 0x100000, + SURFTYPE_BITS_WOOD_SOLID = 0x200000, + SURFTYPE_BITS_ASPHALT = 0x400000, + SURFTYPE_BITS_CERAMIC = 0x800000, + SURFTYPE_BITS_PLASTIC_SOLID = 0x1000000, + SURFTYPE_BITS_RUBBER = 0x2000000, + SURFTYPE_BITS_FRUIT = 0x4000000, + SURFTYPE_BITS_PAINTEDMETAL = 0x8000000, + SURFTYPE_BITS_RIOTSHIELD = 0x10000000, + SURFTYPE_BITS_SLUSH = 0x20000000, + SURFTYPE_BITS_ASPHALT_WET = 0x40000000, + SURFTYPE_BITS_ASPHALT_DEBRIS = 0x80000000, + SURFTYPE_BITS_CONCRETE_WET = 0x100000000, + SURFTYPE_BITS_CONCRETE_DEBRIS = 0x200000000, + SURFTYPE_BITS_FOLIAGE_VEGETATION = 0x400000000, + SURFTYPE_BITS_FOLIAGE_LEAVES = 0x800000000, + SURFTYPE_BITS_GRASS_TALL = 0x1000000000, + SURFTYPE_BITS_METAL_HOLLOW = 0x2000000000, + SURFTYPE_BITS_METAL_VEHICLE = 0x4000000000, + SURFTYPE_BITS_METAL_THIN = 0x8000000000, + SURFTYPE_BITS_METAL_WET = 0x10000000000, + SURFTYPE_BITS_METAL_DEBRIS = 0x20000000000, + SURFTYPE_BITS_PLASTIC_HOLLOW = 0x40000000000, + SURFTYPE_BITS_PLASTIC_TARP = 0x80000000000, + SURFTYPE_BITS_ROCK_WET = 0x100000000000, + SURFTYPE_BITS_ROCK_DEBRIS = 0x200000000000, + SURFTYPE_BITS_WATER_ANKLE = 0x400000000000, + SURFTYPE_BITS_WATER_KNEE = 0x800000000000, + SURFTYPE_BITS_WOOD_HOLLOW = 0x1000000000000, + SURFTYPE_BITS_WOOD_WET = 0x2000000000000, + SURFTYPE_BITS_WOOD_DEBRIS = 0x4000000000000, + SURFTYPE_BITS_CUSHION = 0x8000000000000, + }; + + struct MaterialInfo + { + const char* name; + unsigned char gameFlags; + unsigned char sortKey; + unsigned char textureAtlasRowCount; + unsigned char textureAtlasColumnCount; + unsigned char textureAtlasFrameBlend; + unsigned char textureAtlasAsArray; + unsigned char renderFlags; + GfxDrawSurf drawSurf; + SurfaceTypeBits surfaceTypeBits; + unsigned int hashIndex; + }; static_assert(sizeof(MaterialInfo) == 48); + + struct Material + { + union + { + const char* name; + MaterialInfo info; + }; + unsigned char stateBitsEntry[252]; + unsigned char textureCount; + unsigned char constantCount; + unsigned char stateBitsCount; + unsigned char stateFlags; + unsigned char cameraRegion; + unsigned char materialType; + unsigned char layerCount; + unsigned char assetFlags; + MaterialTechniqueSet* techniqueSet; + MaterialTextureDef* textureTable; + MaterialConstantDef* constantTable; + GfxStateBits* stateBitsTable; + unsigned char constantBufferIndex[252]; + char __pad0[4]; + MaterialConstantBufferDef* constantBufferTable; + unsigned char constantBufferCount; + const char** subMaterials; + }; static_assert(sizeof(Material) == 0x270); + + static_assert(offsetof(Material, textureCount) == 0x12C); + static_assert(offsetof(Material, techniqueSet) == 0x138); + static_assert(offsetof(Material, textureTable) == 0x140); + static_assert(offsetof(Material, constantTable) == 0x148); + static_assert(offsetof(Material, stateBitsTable) == 0x150); + static_assert(offsetof(Material, constantBufferTable) == 0x258); + static_assert(offsetof(Material, constantBufferCount) == 0x260); + static_assert(offsetof(Material, subMaterials) == 0x268); + + struct GfxImageLoadDef + { + char levelCount; + char numElements; + char pad[2]; + int flags; + int format; + int resourceSize; + char data[1]; + }; + + struct GfxTexture + { + union + { + ID3D11Texture1D* linemap; + ID3D11Texture2D* map; + ID3D11Texture3D* volmap; + ID3D11Texture2D* cubemap; + GfxImageLoadDef* loadDef; + }; + ID3D11ShaderResourceView* shaderView; + ID3D11ShaderResourceView* shaderViewAlternate; + }; + + struct Picmip + { + unsigned char platform[2]; + }; + + struct GfxImageStreamData + { + unsigned short width; + unsigned short height; + union + { + unsigned char bytes[4]; + unsigned int pixelSize; + }; + }; + + enum MapType : std::uint8_t + { + MAPTYPE_NONE = 0x0, + MAPTYPE_INVALID1 = 0x1, + MAPTYPE_1D = 0x2, + MAPTYPE_2D = 0x3, + MAPTYPE_3D = 0x4, + MAPTYPE_CUBE = 0x5, + MAPTYPE_ARRAY = 0x6, + MAPTYPE_COUNT = 0x7, + }; + + struct GfxImage + { + GfxTexture texture; + DXGI_FORMAT imageFormat; + MapType mapType; + unsigned char semantic; + unsigned char category; + unsigned char flags; + union + { + struct + { + Picmip picmip; + char __pad0[2]; + }; + unsigned int resourceSize; + }; + unsigned int dataLen1; + unsigned int dataLen2; + unsigned short width; + unsigned short height; + unsigned short depth; + unsigned short numElements; + unsigned char levelCount; + unsigned char streamed; + char __pad1[2]; + unsigned char* pixelData; + GfxImageStreamData streams[4]; + const char* name; + }; static_assert(sizeof(GfxImage) == 0x68); + + struct GfxLightImage + { + GfxImage* image; + unsigned char samplerState; + }; + + struct GfxLightDef + { + const char* name; + GfxLightImage attenuation; + GfxLightImage cucoloris; + int lmapLookupStart; + }; static_assert(sizeof(GfxLightDef) == 0x30); + + struct GfxColorFloat + { + float array[4]; + }; + + enum snd_alias_type_t : std::int8_t + { + SAT_UNKNOWN = 0x0, + SAT_LOADED = 0x1, + SAT_STREAMED = 0x2, + SAT_PRIMED = 0x3, + SAT_COUNT = 0x4, + }; + + struct StreamFileNameRaw + { + const char* dir; + const char* name; + }; + + struct StreamFileNamePacked + { + unsigned __int64 offset; + unsigned __int64 length; + }; + + union StreamFileInfo + { + StreamFileNameRaw raw; + StreamFileNamePacked packed; + }; + + struct StreamFileName + { + bool isLocalized; + bool isStreamed; + unsigned short fileIndex; + StreamFileInfo info; + }; + + struct StreamedSound + { + StreamFileName filename; + unsigned int totalMsec; + }; + + struct LoadedSoundInfo + { + char* data; + unsigned int sampleRate; + unsigned int dataByteCount; + unsigned int numSamples; + char channels; + char numBits; + char blockAlign; + short format; + int loadedSize; + }; static_assert(sizeof(LoadedSoundInfo) == 0x20); + + struct LoadedSound + { + const char* name; + StreamFileName filename; + LoadedSoundInfo info; + }; static_assert(sizeof(LoadedSound) == 0x40); + + struct PrimedSound + { + LoadedSound* loadedPart; + StreamFileName streamedPart; + int dataOffset; // not sure + int totalSize; // not sure + }; static_assert(sizeof(PrimedSound) == 0x28); + + union SoundFileRef + { + LoadedSound* loadSnd; + StreamedSound streamSnd; + PrimedSound primedSnd; + }; + + struct SoundFile + { + snd_alias_type_t type; + bool exists; + SoundFileRef u; + }; + + struct SndContext + { + const char* name; + char __pad0[8]; + }; + + struct SndCurve + { + bool isDefault; + union + { + const char* filename; + const char* name; + }; + unsigned short knotCount; + float knots[16][2]; + }; static_assert(sizeof(SndCurve) == 0x98); + + struct SpeakerLevels + { + char speaker; + char numLevels; + float levels[2]; + }; + + struct ChannelMap + { + int speakerCount; + SpeakerLevels speakers[6]; + }; + + struct SpeakerMap + { + bool isDefault; + const char* name; + int unknown; + ChannelMap channelMaps[2][2]; + }; static_assert(sizeof(SpeakerMap) == 0x148); + + struct DopplerPreset + { + const char* name; + float speedOfSound; + float playerVelocityScale; + float minPitch; + float maxPitch; + float smoothing; + }; static_assert(sizeof(DopplerPreset) == 0x20); + + union SoundAliasFlags + { + struct _ + { + unsigned int looping : 1; + unsigned int isMaster : 1; + unsigned int isSlave : 1; + unsigned int fullDryLevel : 1; + unsigned int noWetLevel : 1; + unsigned int is3d : 1; + unsigned int type : 2; + }; + unsigned int intValue; + }; + + struct snd_alias_t + { + const char* aliasName; + const char* subtitle; + const char* secondaryAliasName; + const char* chainAliasName; + SoundFile* soundFile; + const char* mixerGroup; + short poly; + short polyGlobal; + char polyEntityType; + char polyGlobalType; + char dspBusIndex; + char priority; + char __pad0[12]; // unknown + float volMin; + float volMax; + short volModIndex; + float pitchMin; + float pitchMax; + float distMin; + float distMax; + float velocityMin; + int flags; + char masterPriority; + float masterPercentage; + float slavePercentage; + char playbackPercentage; + float probability; + char u1; // value: 0-4 + SndContext* sndContext; + int sequence; + float lfePercentage; + float centerPercentage; + int startDelay; + SndCurve* sndCurve; + float envelopMin; + float envelopMax; + SndCurve* lpfCurve; + SndCurve* hpfCurve; + SndCurve* reverbSendCurve; + SpeakerMap* speakerMap; + float reverbWetMixOverride; + float reverbMultiplier; + float smartPanDistance2d; + float smartPanDistance3d; + float smartPanAttenuation3d; + float envelopPercentage; + short stereo3dAngle; + //char __padding4[2]; // padding + float stereo3dStart; + float stereo3dEnd; + unsigned char allowDoppler; + //char __padding5[3]; // padding + DopplerPreset* dopplerPreset; + float u2; + //char __padding6[4]; // padding + }; + + static_assert(sizeof(snd_alias_t) == 256); + + struct snd_alias_context_list + { + short unk; + }; + + struct snd_alias_list_t + { + union + { + const char* aliasName; + const char* name; + }; + snd_alias_t* head; + snd_alias_context_list* contextList; + unsigned char count; + unsigned char contextListCount; + char __pad0[6]; + }; + + struct LocalizeEntry + { + const char* value; + const char* name; + }; static_assert(sizeof(LocalizeEntry) == 0x10); + + struct TriggerModel + { + int contents; + unsigned short hullCount; + unsigned short firstHull; + }; + + struct TriggerHull + { + Bounds bounds; + int contents; + unsigned short slabCount; + unsigned short firstSlab; + }; + + struct TriggerSlab + { + float dir[3]; + float midPoint; + float halfSize; + }; + + struct MapTriggers + { + unsigned int count; + TriggerModel* models; + unsigned int hullCount; + TriggerHull* hulls; + unsigned int slabCount; + TriggerSlab* slabs; + }; + + struct ClientTriggerAabbNode + { + Bounds bounds; + unsigned short firstChild; + unsigned short childCount; + }; + + struct ClientTriggers + { + MapTriggers trigger; + unsigned short numClientTriggerNodes; + ClientTriggerAabbNode* clientTriggerAabbTree; + unsigned int triggerStringLength; + char* triggerString; + short* visionSetTriggers; + short* blendLookup; + short* unk1; + short* triggerType; + vec3_t* origins; + float* scriptDelay; + short* audioTriggers; + short* unk2; + short* unk3; + short* unk4; + short* unk5; + short* unk6; + }; static_assert(sizeof(ClientTriggers) == 0xB0); + + struct ClientTriggerBlendNode + { + float pointA[3]; + float pointB[3]; + unsigned short triggerA; + unsigned short triggerB; + }; + + struct ClientTriggerBlend + { + unsigned short numClientTriggerBlendNodes; + ClientTriggerBlendNode* blendNodes; + }; + + struct SpawnPointEntityRecord + { + unsigned short index; + scr_string_t name; + scr_string_t target; + scr_string_t script_noteworthy; + scr_string_t unknown; + float origin[3]; + float angles[3]; + }; + + struct SpawnPointRecordList + { + unsigned short spawnsCount; + SpawnPointEntityRecord* spawns; + }; + + struct SplinePointEntityRecord + { + int splineId; + int splineNodeId; + char* splineNodeLabel; + float splineNodeTension; + float origin[3]; + float corridorDims[2]; + float tangent[3]; + float distToNextNode; + vec3_t* positionCubic; + vec3_t* tangentQuadratic; + }; + + struct SplinePointRecordList + { + unsigned short splinePointCount; + float splineLength; + SplinePointEntityRecord* splinePoints; + }; + + struct SplineRecordList + { + unsigned short splineCount; + SplinePointRecordList* splines; + }; + + struct MapEnts + { + const char* name; + char* entityString; + int numEntityChars; + MapTriggers trigger; + ClientTriggers clientTrigger; + ClientTriggerBlend clientTriggerBlend; + SpawnPointRecordList spawnList; + SplineRecordList splineList; + }; static_assert(sizeof(MapEnts) == 0x128); + + struct AddonMapEntsUnk1 + { + char __pad0[8]; + }; + + struct AddonMapEntsUnk2_unk1 + { + char __pad0[16]; + }; + + struct AddonMapEntsUnk2_unk2 + { + char __pad0[16]; + }; + + struct AddonMapEntsUnk2 + { + AddonMapEntsUnk2_unk1* unk1; // 0 [unkCount1] + AddonMapEntsUnk2_unk2* unk2; // 8 [unkCount2] + unsigned short* unk3; // 16 [unkCount2] + unsigned short* unk4; // 24 [unkCount1] + unsigned int* unk5; // 32 [unkCount3] + unsigned char* unk6; // 40 [unkCount2] + char __pad0[12]; + unsigned int unkCount1; + unsigned int unkCount2; + unsigned int unkCount3; + char __pad1[40]; + }; + + assert_sizeof(AddonMapEntsUnk2, 112); + assert_offsetof(AddonMapEntsUnk2, unk1, 0); + assert_offsetof(AddonMapEntsUnk2, unk2, 8); + assert_offsetof(AddonMapEntsUnk2, unk3, 16); + assert_offsetof(AddonMapEntsUnk2, unk4, 24); + assert_offsetof(AddonMapEntsUnk2, unk5, 32); + assert_offsetof(AddonMapEntsUnk2, unk6, 40); + assert_offsetof(AddonMapEntsUnk2, unkCount1, 60); + assert_offsetof(AddonMapEntsUnk2, unkCount2, 64); + assert_offsetof(AddonMapEntsUnk2, unkCount3, 68); + + struct AddonMapEntsUnk3 + { + char __pad0[80]; + }; + + struct cmodel_t; + struct ClipInfo; + struct GfxBrushModel; + + struct AddonMapEnts + { + const char* name; + char* entityString; + int numEntityChars; + MapTriggers trigger; + ClipInfo* info; + unsigned int numSubModels; + cmodel_t* cmodels; + GfxBrushModel* models; + AddonMapEntsUnk1* unk1; // [numSubmodels] + AddonMapEntsUnk2* unk2; // [unkCount1] + AddonMapEntsUnk3* unk3; // [unkCount2] + unsigned int unkCount1; + unsigned int unkCount2; + }; + + static_assert(offsetof(AddonMapEnts, info) == 72); + static_assert(offsetof(AddonMapEnts, cmodels) == 88); + static_assert(offsetof(AddonMapEnts, numSubModels) == 80); + assert_offsetof(AddonMapEnts, models, 96); + assert_offsetof(AddonMapEnts, unk1, 104); + assert_offsetof(AddonMapEnts, unk2, 112); + assert_offsetof(AddonMapEnts, unk3, 120); + assert_offsetof(AddonMapEnts, unkCount1, 128); + assert_offsetof(AddonMapEnts, unkCount2, 132); + + static_assert(sizeof(AddonMapEnts) == 136); + + struct Clut + { + int count0; + int count1; + int count2; + int pad; + char* unk; + const char* name; + }; assert_sizeof(Clut, 0x20); + + struct pathnode_yaworient_t + { + float fLocalAngle; + float localForward[2]; + }; + + union $3936EE84564F75EDA6DCBAC77A545FC8 + { + pathnode_yaworient_t yaw_orient; + float angles[3]; + }; + + union PathNodeParentUnion + { + scr_string_t name; + unsigned short index; + }; + + enum nodeType + { + NODE_ERROR = 0x0, + NODE_PATHNODE = 0x1, + NODE_NEGOTIATION_BEGIN = 0x13, + NODE_NEGOTIATION_END = 0x14 + }; + + enum PathNodeErrorCode : std::int32_t + { + PNERR_NONE = 0x0, + PNERR_INSOLID = 0x1, + PNERR_FLOATING = 0x2, + PNERR_NOLINK = 0x3, + PNERR_DUPLICATE = 0x4, + PNERR_NOSTANCE = 0x5, + PNERR_INVALIDDOOR = 0x6, + PNERR_NOANGLES = 0x7, + PNERR_BADPLACEMENT = 0x8, + NUM_PATH_NODE_ERRORS = 0x9, + }; + + union $5F11B9753862CE791E23553F99FA1738 + { + float minUseDistSq; + PathNodeErrorCode error; + }; + + struct pathnode_t; + + struct pathlink_s + { + float fDist; + unsigned short nodeNum; + unsigned char disconnectCount; + unsigned char negotiationLink; + unsigned char flags; + unsigned char ubBadPlaceCount[3]; + }; + + struct pathnode_constant_t + { + unsigned short type; + unsigned int spawnflags; + scr_string_t targetname; + scr_string_t script_linkName; + scr_string_t script_noteworthy; + scr_string_t target; + scr_string_t animscript; + int animscriptfunc; + float vLocalOrigin[3]; + $3936EE84564F75EDA6DCBAC77A545FC8 ___u9; + PathNodeParentUnion parent; + $5F11B9753862CE791E23553F99FA1738 ___u11; + short wOverlapNode[2]; + char __pad0[4]; + unsigned short totalLinkCount; + pathlink_s* Links; + scr_string_t unk; + char __pad1[4]; + }; + + assert_sizeof(pathnode_constant_t, 0x60); + assert_offsetof(pathnode_constant_t, parent.index, 56); + + struct SentientHandle + { + unsigned short number; + unsigned short infoIndex; + }; + + struct pathnode_dynamic_t + { + SentientHandle pOwner; + int iFreeTime; + int iValidTime[3]; + short wLinkCount; + short wOverlapCount; + short turretEntNumber; + unsigned char userCount; + unsigned char hasBadPlaceLink; + int spreadUsedTime[2]; + short flags; + short dangerousCount; + int recentUseProxTime; + }; + + union $73F238679C0419BE2C31C6559E8604FC + { + float nodeCost; + int linkIndex; + }; + + struct pathnode_transient_t + { + int iSearchFrame; + pathnode_t* pNextOpen; + pathnode_t* pPrevOpen; + pathnode_t* pParent; + float fCost; + float fHeuristic; + $73F238679C0419BE2C31C6559E8604FC ___u6; + }; + + struct pathnode_t + { + pathnode_constant_t constant; + pathnode_dynamic_t dynamic; + pathnode_transient_t transient; + }; + + struct pathnode_tree_nodes_t + { + int nodeCount; + unsigned short* nodes; + }; + + struct pathnode_tree_t; + union pathnode_tree_info_t + { + pathnode_tree_t* child[2]; + pathnode_tree_nodes_t s; + }; + + struct pathnode_tree_t + { + int axis; + float dist; + pathnode_tree_info_t u; + }; + + struct PathDynamicNodeGroup + { + unsigned short parentIndex; + int nodeTreeCount; + pathnode_tree_t* nodeTree; + }; + + struct PathData + { + const char* name; + unsigned int nodeCount; + pathnode_t* nodes; + bool parentIndexResolved; + unsigned short version; + int visBytes; + unsigned char* pathVis; + int nodeTreeCount; + pathnode_tree_t* nodeTree; + int dynamicNodeGroupCount; + PathDynamicNodeGroup* dynamicNodeGroups; + int exposureBytes; + unsigned char* pathExposure; + int noPeekVisBytes; + unsigned char* pathNoPeekVis; + int zoneCount; + int zonesBytes; + unsigned char* pathZones; + int dynStatesBytes; + unsigned char* pathDynStates; + }; assert_sizeof(PathData, 0x88); + + assert_offsetof(PathData, parentIndexResolved, 24); + + struct RawFile + { + const char* name; + int compressedLen; + int len; + const char* buffer; + }; static_assert(sizeof(RawFile) == 0x18); + + struct ScriptFile + { + const char* name; + int compressedLen; + int len; + int bytecodeLen; + const char* buffer; + char* bytecode; + }; static_assert(sizeof(ScriptFile) == 0x28); + + struct StringTableCell + { + const char* string; + int hash; + }; + + struct StringTable + { + const char* name; + int columnCount; + int rowCount; + StringTableCell* values; + }; static_assert(sizeof(StringTable) == 0x18); + + struct StructuredDataEnumEntry + { + scr_string_t string; + unsigned short index; + }; + + struct StructuredDataEnum + { + int entryCount; + int reservedEntryCount; + StructuredDataEnumEntry* entries; + }; + + enum StructuredDataTypeCategory + { + DATA_INT = 0x0, + DATA_BYTE = 0x1, + DATA_BOOL = 0x2, + DATA_STRING = 0x3, + DATA_ENUM = 0x4, + DATA_STRUCT = 0x5, + DATA_INDEXED_ARRAY = 0x6, + DATA_ENUM_ARRAY = 0x7, + DATA_FLOAT = 0x8, + DATA_SHORT = 0x9, + DATA_COUNT = 0xA, + }; + + union StructuredDataTypeUnion + { + unsigned int stringDataLength; + int enumIndex; + int structIndex; + int indexedArrayIndex; + int enumedArrayIndex; + int index; + }; + + struct StructuredDataType + { + StructuredDataTypeCategory type; + StructuredDataTypeUnion u; + }; + + enum StructuredDataValidationType + { + VALIDATION_NONE = 0x0, + }; + + struct StructuredDataStructProperty + { + scr_string_t name; + StructuredDataType type; + unsigned int offset; + StructuredDataValidationType validation; + }; + + struct StructuredDataStruct + { + int propertyCount; + StructuredDataStructProperty* properties; + int size; + unsigned int bitOffset; + }; + + struct StructuredDataIndexedArray + { + int arraySize; + StructuredDataType elementType; + unsigned int elementSize; + }; + + struct StructuredDataEnumedArray + { + int enumIndex; + StructuredDataType elementType; + unsigned int elementSize; + }; + + struct StructuredDataDef + { + int version; + unsigned int formatChecksum; + int enumCount; + StructuredDataEnum* enums; + int structCount; + StructuredDataStruct* structs; + int indexedArrayCount; + StructuredDataIndexedArray* indexedArrays; + int enumedArrayCount; + StructuredDataEnumedArray* enumedArrays; + StructuredDataType rootType; + unsigned int size; + }; static_assert(sizeof(StructuredDataDef) == 0x58); + + struct StructuredDataDefSet + { + const char* name; + unsigned int defCount; + StructuredDataDef* defs; + }; static_assert(sizeof(StructuredDataDefSet) == 0x18); + + enum NetConstStringType + { + }; + + enum NetConstStringSource + { + }; + + struct NetConstStrings + { + const char* name; + NetConstStringType stringType; + NetConstStringSource sourceType; + unsigned int entryCount; + const char** stringList; + }; static_assert(sizeof(NetConstStrings) == 0x20); + + struct LuaFile + { + const char* name; + int len; + char strippingType; + const char* buffer; + }; static_assert(sizeof(LuaFile) == 0x18); + + struct TTFDef + { + const char* name; + int fileLen; + const char* file; + void* ftFace; + }; static_assert(sizeof(TTFDef) == 0x20); + + struct FxParticleSimAnimationHeader + { + float playbackRate; + float duration; + unsigned int frameCount; + float minX; + float minY; + float minZ; + float boundsXDelta; + float boundsYDelta; + float boundsZDelta; + float maxWidth; + float maxHeight; + unsigned int colorTableSize; + unsigned int particleDataCount; + bool evalVisStatePerParticle; + bool sortParticlesAtRuntime; + }; + + struct FxParticleSimAnimationParticleData + { + unsigned short xNormalizedPos; + unsigned short yNormalizedPos; + unsigned short zNormalizedPos; + unsigned short xNormalizedWidth; + unsigned short yNormalizedHeight; + unsigned short orientation; + unsigned short lifetime; + unsigned short particleID; + unsigned short xNormalizedPosNextFrame; + unsigned short yNormalizedPosNextFrame; + unsigned short zNormalizedPosNextFrame; + unsigned short xNormalizedWidthNextFrame; + unsigned short yNormalizedHeightNextFrame; + short orientationDelta; + unsigned short colorTableIndex; + unsigned short nextColorTableIndex; + }; + + struct FxParticleSimAnimationFrame + { + unsigned int particleDataOffset; + unsigned int numActiveParticles; + }; + + struct FxParticleSimAnimation + { + const char* name; + Material* material; + FxParticleSimAnimationHeader header; + FxParticleSimAnimationParticleData* particleData; + FxParticleSimAnimationFrame* frames; + GfxColorFloat* colorTable; + }; + + enum FxElemType : std::uint8_t + { + FX_ELEM_TYPE_SPRITE_BILLBOARD = 0, + FX_ELEM_TYPE_SPRITE_ORIENTED = 1, + FX_ELEM_TYPE_SPRITE_ROTATED = 2, + FX_ELEM_TYPE_TAIL = 3, + FX_ELEM_TYPE_LINE = 4, + FX_ELEM_TYPE_TRAIL = 5, + FX_ELEM_TYPE_FLARE = 6, + FX_ELEM_TYPE_PARTICLE_SIM_ANIMATION = 7, + FX_ELEM_TYPE_CLOUD = 8, + FX_ELEM_TYPE_SPARK_CLOUD = 9, + FX_ELEM_TYPE_SPARK_FOUNTAIN = 10, + FX_ELEM_TYPE_MODEL = 11, + FX_ELEM_TYPE_OMNI_LIGHT = 12, + FX_ELEM_TYPE_SPOT_LIGHT = 13, + FX_ELEM_TYPE_SOUND = 14, + FX_ELEM_TYPE_DECAL = 15, + FX_ELEM_TYPE_RUNNER = 16, + FX_ELEM_TYPE_VECTORFIELD = 17, + }; + + struct FxFloatRange + { + float base; + float amplitude; + }; + + struct FxSpawnDefLooping + { + int intervalMsec; + int count; + }; + + struct FxIntRange + { + int base; + int amplitude; + }; + + struct FxSpawnDefOneShot + { + FxIntRange count; + }; + + union FxSpawnDef + { + FxSpawnDefLooping looping; + FxSpawnDefOneShot oneShot; + }; + + struct FxElemAtlas + { + unsigned char behavior; + unsigned char index; + unsigned char fps; + unsigned char loopCount; + unsigned char colIndexBits; + unsigned char rowIndexBits; + short entryCount; + }; + + struct FxEffectDef; + union FxEffectDefRef + { + FxEffectDef* handle; + const char* name; + }; + + struct FxElemVec3Range + { + float base[3]; + float amplitude[3]; + }; + + struct FxElemVelStateInFrame + { + FxElemVec3Range velocity; + FxElemVec3Range totalDelta; + FxElemVec3Range unk_range; + }; + + struct FxElemVelStateSample + { + FxElemVelStateInFrame local; + FxElemVelStateInFrame world; + }; static_assert(sizeof(FxElemVelStateSample) == 144); + + struct FxElemVisualState + { + float color[4]; + float pad1[3]; + float rotationDelta; + float rotationTotal; + float size[2]; + float scale; + float pad2[2]; + }; + + static_assert(sizeof(FxElemVisualState) == 56); + + struct FxElemVisStateSample + { + FxElemVisualState base; + FxElemVisualState amplitude; + }; static_assert(sizeof(FxElemVisStateSample) == 112); + + struct FxElemMarkVisuals + { + Material* materials[3]; + }; + + struct XModel; + union FxElemVisuals + { + const void* anonymous; + Material* material; + XModel* model; + FxEffectDefRef effectDef; + const char* soundName; + const char* vectorFieldName; + GfxLightDef* lightDef; + FxParticleSimAnimation* particleSimAnimation; + }; + + union FxElemDefVisuals + { + FxElemMarkVisuals* markArray; + FxElemVisuals* array; + FxElemVisuals instance; + }; + + struct FxTrailVertex + { + float pos[2]; + float normal[2]; + float texCoord[2]; + char __pad0[8]; + }; static_assert(sizeof(FxTrailVertex) == 32); + + struct FxTrailDef + { + int scrollTimeMsec; + int repeatDist; + float invSplitDist; + float invSplitArcDist; + float invSplitTime; + char __pad0[12]; + int vertCount; + FxTrailVertex* verts; + int indCount; + unsigned short* inds; + }; static_assert(sizeof(FxTrailDef) == 0x40); + static_assert(offsetof(FxTrailDef, verts) == 40); + static_assert(offsetof(FxTrailDef, inds) == 56); + static_assert(offsetof(FxTrailDef, vertCount) == 32); + static_assert(offsetof(FxTrailDef, indCount) == 48); + + struct FxSparkFountainDef + { + float gravity; + float bounceFrac; + float bounceRand; + float sparkSpacing; + float sparkLength; + int sparkCount; + float loopTime; + float velMin; + float velMax; + float velConeFrac; + float restSpeed; + float boostTime; + float boostFactor; + }; static_assert(sizeof(FxSparkFountainDef) == 0x34); + + struct FxSpotLightDef + { + float fovInnerFraction; + float startRadius; + float endRadius; + float brightness; + float maxLength; + int exponent; + char __pad0[24]; + }; static_assert(sizeof(FxSpotLightDef) == 0x30); + + struct FxOmniLightDef + { + char __pad0[16]; + }; static_assert(sizeof(FxOmniLightDef) == 0x10); + + struct FxFlareDef + { + float position; + int angularRotCount; + int flags; + FxFloatRange depthScaleRange; + FxFloatRange depthScaleValue; + FxFloatRange radialRot; + FxFloatRange radialScaleX; + FxFloatRange radialScaleY; + float dir[3]; + int intensityXIntervalCount; + int intensityYIntervalCount; + int srcCosIntensityIntervalCount; + int srcCosScaleIntervalCount; + float* intensityX; + float* intensityY; + float* srcCosIntensity; + float* srcCosScale; + }; static_assert(sizeof(FxFlareDef) == 0x70); + + struct FxDecalDef + { + char __pad0[3]; + }; + + union FxElemExtendedDefPtr + { + char* unknownDef; + FxTrailDef* trailDef; + FxSparkFountainDef* sparkFountainDef; + FxSpotLightDef* spotLightDef; + FxOmniLightDef* omniLightDef; + FxFlareDef* flareDef; + FxDecalDef* decalDef; + }; + + struct FxElemDef + { + int flags; + int flags2; + FxSpawnDef spawn; + FxFloatRange spawnRange; + FxFloatRange fadeInRange; + FxFloatRange fadeOutRange; + float spawnFrustumCullRadius; + FxIntRange spawnDelayMsec; + FxIntRange lifeSpanMsec; + FxFloatRange spawnOrigin[3]; + char __pad0[4]; + FxFloatRange spawnOffsetRadius; + FxFloatRange spawnOffsetHeight; + char __pad1[8]; + FxFloatRange spawnAngles[3]; + FxFloatRange angularVelocity[3]; + FxFloatRange initialRotation; + FxFloatRange gravity; + FxFloatRange reflectionFactor; + FxElemAtlas atlas; + FxElemType elemType; + unsigned char elemLitType; + unsigned char visualCount; + unsigned char velIntervalCount; + unsigned char visStateIntervalCount; + FxElemVelStateSample* velSamples; + FxElemVisStateSample* visSamples; + FxElemDefVisuals visuals; + Bounds collBounds; + FxEffectDefRef effectOnImpact; + FxEffectDefRef effectOnDeath; + FxEffectDefRef effectEmitted; + FxFloatRange emitDist; + FxFloatRange emitDistVariance; + FxElemExtendedDefPtr extended; + unsigned char sortOrder; + unsigned char lightingFrac; + unsigned char useItemClip; + unsigned char fadeInfo; + int randomSeed; + float unk_floats[4]; + }; static_assert(sizeof(FxElemDef) == 0x140); + + static_assert(offsetof(FxElemDef, spawnOrigin) == 60); + static_assert(offsetof(FxElemDef, spawnOffsetRadius) == 88); + static_assert(offsetof(FxElemDef, spawnOffsetHeight) == 96); + static_assert(offsetof(FxElemDef, spawnAngles) == 112); + static_assert(offsetof(FxElemDef, spawnDelayMsec) == 44); + static_assert(offsetof(FxElemDef, lifeSpanMsec) == 52); + static_assert(offsetof(FxElemDef, spawn) == 8); + static_assert(offsetof(FxElemDef, visualCount) == 194); + static_assert(offsetof(FxElemDef, effectOnDeath) == 256); + static_assert(offsetof(FxElemDef, spawnAngles) == 112); + static_assert(offsetof(FxElemDef, elemType) == 192); + static_assert(offsetof(FxElemDef, visSamples) == 0xD0); + static_assert(offsetof(FxElemDef, visuals) == 0xD8); + static_assert(offsetof(FxElemDef, effectOnImpact) == 0xF8); + static_assert(offsetof(FxElemDef, effectOnDeath) == 0x100); + static_assert(offsetof(FxElemDef, effectEmitted) == 0x108); + static_assert(offsetof(FxElemDef, extended) == 0x120); + static_assert(offsetof(FxElemDef, effectEmitted) == 0x108); + static_assert(offsetof(FxElemDef, visStateIntervalCount) == 0xC4); + static_assert(offsetof(FxElemDef, visualCount) == 194); + static_assert(offsetof(FxElemDef, velIntervalCount) == 0xC3); + + struct FxEffectDef + { + const char* name; + int flags; + int totalSize; + int msecLoopingLife; + int elemDefCountLooping; + int elemDefCountEmission; + int elemDefCountOneShot; + float elemMaxRadius; + float occlusionQueryDepthBias; + int occlusionQueryFadeIn; + int occlusionQueryFadeOut; + FxFloatRange occlusionQueryScaleRange; + float xU_01; + FxElemDef* elemDefs; + }; static_assert(sizeof(FxEffectDef) == 0x48); + + static_assert(offsetof(FxEffectDef, elemDefs) == 0x40); + static_assert(offsetof(FxEffectDef, elemDefCountLooping) == 0x14); + //static_assert(offsetof(FxEffectDef, elemDefCountOneShot) == 0x18); + //static_assert(offsetof(FxEffectDef, elemDefCountEmission) == 0x1C); + + struct XModelIKData + { + unsigned char charDataLen; + unsigned char floatDataLen; + unsigned char int32DataLen; + unsigned char stringsCount; + char* charData; + float* floatData; + int* int32Data; + scr_string_t* strings; + }; static_assert(sizeof(XModelIKData) == 0x28); + + struct SkeletonScriptCode + { + char __pad0[4]; + }; + + struct SkeletonScript + { + const char* name; + XModelIKData ikData; + unsigned short codeLen; + SkeletonScriptCode* code; + }; static_assert(sizeof(SkeletonScript) == 0x40); + + static_assert(offsetof(SkeletonScript, ikData) == 8); + static_assert(offsetof(XModelIKData, strings) == 32); + static_assert(offsetof(XModelIKData, stringsCount) == 3); + static_assert(offsetof(XModelIKData, int32Data) == 24); + static_assert(offsetof(XModelIKData, int32DataLen) == 2); + static_assert(offsetof(XModelIKData, floatData) == 16); + static_assert(offsetof(XModelIKData, floatDataLen) == 1); + + union XAnimDynamicFrames + { + unsigned char(*_1)[3]; + unsigned short(*_2)[3]; + }; + + union XAnimDynamicIndices + { + unsigned char _1[1]; + unsigned short _2[1]; + }; + + struct XAnimPartTransFrames + { + float mins[3]; + float size[3]; + XAnimDynamicFrames frames; + XAnimDynamicIndices indices; + }; + + union XAnimPartTransData + { + XAnimPartTransFrames frames; + float frame0[3]; + }; + + struct XAnimPartTrans + { + unsigned short size; + unsigned char smallTrans; + XAnimPartTransData u; + }; + + struct XAnimDeltaPartQuatDataFrames2 + { + short(*frames)[2]; + XAnimDynamicIndices indices; + }; + + union XAnimDeltaPartQuatData2 + { + XAnimDeltaPartQuatDataFrames2 frames; + short frame0[2]; + }; + + struct XAnimDeltaPartQuat2 + { + unsigned short size; + XAnimDeltaPartQuatData2 u; + }; + + struct XAnimDeltaPartQuatDataFrames + { + short(*frames)[4]; + XAnimDynamicIndices indices; + }; + + union XAnimDeltaPartQuatData + { + XAnimDeltaPartQuatDataFrames frames; + short frame0[4]; + }; + + struct XAnimDeltaPartQuat + { + unsigned short size; + XAnimDeltaPartQuatData u; + }; + + struct XAnimDeltaPart + { + XAnimPartTrans* trans; + XAnimDeltaPartQuat2* quat2; + XAnimDeltaPartQuat* quat; + }; + + union XAnimIndices + { + unsigned char* _1; + unsigned short* _2; + void* data; + }; + + struct XAnimNotifyInfo + { + scr_string_t name; + float time; + }; + + enum XAnimPartsFlags : std::uint8_t + { + ANIM_NONE = 0x0, + ANIM_LOOP = 0x1, + ANIM_DELTA = 0x2, + ANIM_DELTA_3D = 0x4, + ANIM_DEFAULT = 0x8, + }; + + typedef float BlendShapeWeight; + typedef char XAnimScriptedViewmodelAnimData; + + struct XAnimParts + { + const char* name; // 0 + unsigned short dataByteCount; // 8 + unsigned short dataShortCount; // 10 + unsigned short dataIntCount; // 12 + unsigned short numframes; // 14 + unsigned char flags; // 15 + unsigned char boneCount[10]; // 16 + char u1; // unused? + char u2; // unused? + unsigned char notifyCount; // 29 + unsigned char assetType; // 30 + unsigned char ikType; // 31 + unsigned int randomDataByteCount; // 32 + unsigned int randomDataShortCount; // 36 + unsigned int randomDataIntCount; // 40 + unsigned int indexCount; // 44 + float framerate; // 48 + float frequency; // 56 + scr_string_t* names; // 56 + char* dataByte; // 64 + short* dataShort; // 72 + int* dataInt; // 80 + short* randomDataShort; // 88 + unsigned char* randomDataByte; // 96 + int* randomDataInt; // 104 + XAnimIndices indices; // 112 + XAnimNotifyInfo* notify; // 120 + XAnimDeltaPart* deltaPart; // 128 + const char* secondaryName; // 136 + short u3; // unknown + unsigned short blendShapeWeightCount; // 146 + short u4; // unused? padding? + scr_string_t* blendShapeWeightNames; // 152 + char(*blendShapeWeightUnknown1)[3]; // 160 + unsigned short* blendShapeWeightUnknown2; // 168 + unsigned short* blendShapeWeightUnknown3; // 176 + unsigned short* blendShapeWeightUnknown4; // 184 + BlendShapeWeight* blendShapeWeights; // 192 + std::uint64_t u5; // unused? + XAnimScriptedViewmodelAnimData* scriptedViewmodelAnimData; // 208 // count = 8 + }; static_assert(sizeof(XAnimParts) == 0xD8); + + union PackedUnitVec + { + unsigned int packed; + }; + + union PackedTexCoords + { + unsigned int packed; + }; + + union GfxColor + { + unsigned char array[4]; + unsigned int packed; + }; + + struct GfxPackedVertex + { + float xyz[3]; + float binormalSign; + GfxColor color; + PackedTexCoords texCoord; + PackedUnitVec normal; + PackedUnitVec tangent; + }; + + struct GfxPackedMotionVertex + { + float xyz[3]; + float binormalSignAndHeight; + GfxColor pieceIndex; + PackedTexCoords texCoord; + PackedUnitVec normal; + PackedUnitVec tangent; + }; + + union GfxVertexUnion0 + { + GfxPackedVertex* packedVerts0; + GfxPackedMotionVertex* packedMotionVerts0; + void* verts0; + }; + + struct Face + { + unsigned short v1; + unsigned short v2; + unsigned short v3; + }; + + struct XSurfaceCollisionAabb + { + unsigned short mins[3]; + unsigned short maxs[3]; + }; + + struct XSurfaceCollisionNode + { + XSurfaceCollisionAabb aabb; + unsigned short childBeginIndex; + unsigned short childCount; + }; + + struct XSurfaceCollisionLeaf + { + unsigned short triangleBeginIndex; + }; + + struct XSurfaceCollisionTree + { + float trans[3]; + float scale[3]; + unsigned int nodeCount; + XSurfaceCollisionNode* nodes; + unsigned int leafCount; + XSurfaceCollisionLeaf* leafs; + }; + + struct XRigidVertList + { + unsigned short boneOffset; + unsigned short vertCount; + unsigned short triOffset; + unsigned short triCount; + XSurfaceCollisionTree* collisionTree; + }; + + struct UnknownXSurface0 + { + float xyz[3]; + PackedUnitVec normal; + }; + + struct BlendVertsUnknown + { + unsigned short b[15]; + unsigned short blendVertCountIndex; // 30 + }; static_assert(sizeof(BlendVertsUnknown) == 32); + + struct XSubdivRigidVertList + { + unsigned int firstFace; + unsigned int faceCount; + unsigned int firstRegularPatch; + unsigned int regularPatchCount; + }; + + struct XSurfaceSubdivLevel + { + XSubdivRigidVertList* rigidVertLists; + unsigned int faceCount; + unsigned int regularPatchCount; + unsigned int regularPatchOffset; + unsigned int facePointCount; + unsigned int facePointValence4Count; + unsigned int facePointBufferSize; + unsigned int edgePointCount; + unsigned int edgePointSmoothEnd; + unsigned int edgePointUVBorderEnd; + unsigned int vertexPointCount; + unsigned int vertexPointValence4Count; + unsigned int vertexPointBufferSize; + unsigned int normalCount; + unsigned int normalBufferSize; + unsigned int transitionPointCount; + unsigned int vertCount; + unsigned int vertOffset; + unsigned short* faceIndices; + unsigned short* regularPatchIndices; + unsigned int* regularPatchFlags; + unsigned int* facePoints; + unsigned int* edgePoints; + unsigned int* vertexPoints; + unsigned int* normals; + unsigned int* transitionPoints; + float* regularPatchCones; + ID3D11Buffer* regularPatchIndexBuffer; + ID3D11Buffer* faceIndexBuffer; + ID3D11ShaderResourceView* regularPatchIndexBufferView; + ID3D11ShaderResourceView* regularPatchFlagsView; + ID3D11ShaderResourceView* facePointsView; + ID3D11ShaderResourceView* edgePointsView; + ID3D11ShaderResourceView* vertexPointsView; + ID3D11ShaderResourceView* normalsView; + ID3D11ShaderResourceView* transitionPointsView; + ID3D11ShaderResourceView* regularPatchConesView; + }; static_assert(sizeof(XSurfaceSubdivLevel) == 0xE8); + + struct GfxSubdivCache + { + unsigned int size; + ID3D11Buffer* subdivCacheBuffer; + ID3D11ShaderResourceView* subdivCacheView; + }; static_assert(sizeof(GfxSubdivCache) == 0x18); + + struct XSurfaceSubdivInfo + { + XSurfaceSubdivLevel* levels; + char __pad0[24]; + GfxSubdivCache cache; + }; static_assert(sizeof(XSurfaceSubdivInfo) == 0x38); + + struct BlendShapeVert + { + char __pad0[32]; + }; + + struct BlendShape + { + unsigned int vertCount; + BlendShapeVert* verts; + ID3D11Buffer* blendShapeVertsBuffer; + ID3D11ShaderResourceView* blendShapeVertsView; + }; + + typedef char alignCompBufByte_t; + typedef unsigned short alignVertBufFloat16Vec2_t[2]; + typedef unsigned short alignCompBufUShort_t; + typedef float alignCompBufFloat_t; + typedef unsigned short XBlendInfo; + + enum XSurfaceFlags : std::uint16_t + { + SURF_FLAG_VERTCOL_GREY = 0x1, + SURF_FLAG_VERTCOL_NONE = 0x2, + SURF_FLAG_SKINNED = 0x4, + SURF_FLAG_REACTIVE_MOTION = 0x8, + SURF_FLAG_LIGHTMAP_COORDS = 0x10, + SURF_FLAG_TENSION = 0x20, + }; + + struct XSurface + { + unsigned short flags; + unsigned short vertCount; + unsigned short triCount; + unsigned char rigidVertListCount; + unsigned char subdivLevelCount; + short blendVertCounts[8]; + GfxVertexUnion0 verts0; + Face* triIndices; + Face* triIndices2; + ID3D11Buffer* vb0; + ID3D11ShaderResourceView* vb0View; + ID3D11Buffer* indexBuffer; + XRigidVertList* rigidVertLists; + UnknownXSurface0* unknown0; + XBlendInfo* blendVerts; + BlendVertsUnknown* blendVertsTable; + ID3D11Buffer* blendVertsBuffer; + ID3D11ShaderResourceView* blendVertsView; + alignVertBufFloat16Vec2_t* lmapUnwrap; + ID3D11Buffer* vblmapBuffer; + ID3D11ShaderResourceView* vblmapView; + XSurfaceSubdivInfo* subdiv; + alignCompBufFloat_t* tensionData; + alignCompBufUShort_t* tensionAccumTable; + ID3D11Buffer* tensionAccumTableBuffer; + ID3D11ShaderResourceView* tensionAccumTableView; + ID3D11Buffer* tensionDataBuffer; + ID3D11ShaderResourceView* tensionDataView; + ID3D11ShaderResourceView* indexBufferView; + BlendShape* blendShapes; + unsigned int blendShapesCount; + unsigned int vertexLightingIndex; + char __pad0[4]; + int partBits[8]; + char __pad1[4]; + }; static_assert(sizeof(XSurface) == 0x108); + + struct XModelSurfs + { + const char* name; + XSurface* surfs; + unsigned short numsurfs; + int partBits[8]; + }; static_assert(sizeof(XModelSurfs) == 0x38); + + struct ReactiveMotionModelPart + { + char __pad0[32]; + }; static_assert(sizeof(ReactiveMotionModelPart) == 32); + + struct XModelLodInfo + { + float dist; // 0 + unsigned short numsurfs; // 4 + unsigned short surfIndex; // 6 + XModelSurfs* modelSurfs; // 8 + int partBits[8]; // 16 20 24 28 32 36 40 44 + XSurface* surfs; // 48 + ReactiveMotionModelPart* reactiveMotionParts; // 56 (sizeof struct = 32) (reactiveMotionParts?) + char __pad0[5]; // 64 (something must be here) + char numReactiveMotionParts; // 69 (numReactiveMotionParts?) + char __pad1[2]; // 70 (padding?) + }; static_assert(sizeof(XModelLodInfo) == 72); + + struct XModelAngle + { + short x; + short y; + short z; + short base; + }; + + struct XModelTagPos + { + float x; + float y; + float z; + }; + + struct DObjAnimMat + { + float quat[4]; + float trans[3]; + float transWeight; + }; + + struct ReactiveMotionModelTweaks + { + float scale[4]; + }; + + struct XModelCollSurf_s + { + Bounds bounds; + int boneIdx; + int contents; + int surfFlags; + }; + + struct XBoneInfo + { + Bounds bounds; + union + { + float radiusSquared; + unsigned int radiusSquaredAsInt; + }; + }; + + struct BlendShapeWeightMap + { + unsigned short weightIndex; + unsigned short targetIndex; + float fullWeight; + }; + + struct ExtentBounds + { + vec3_t mins; + vec3_t maxs; + }; + + struct MdaoVolume + { + ExtentBounds bounds; + unsigned __int16 cellCount[3]; + unsigned __int16 parentBoneIndex; + GfxImage* volumeData; + }; static_assert(sizeof(MdaoVolume) == 0x28); + + struct XPhysBoneInfo + { + PhysPreset* physPreset; + PhysConstraint* physContraint; + PhysCollmap* physCollmap; + char __pad0[8]; + }; static_assert(sizeof(XPhysBoneInfo) == 0x20); + + enum XModelFlags : std::uint16_t + { + XMODEL_FLAG_COMPOSITE = 0x400, + }; + + struct XModel + { + const char* name; // 0 + unsigned char numBones; // 8 + unsigned char numRootBones; // 9 + unsigned char numsurfs; // 10 + unsigned char lodRampType; // 11 + unsigned char numBonePhysics; // 12 + unsigned char numCompositeModels; // 13 + char __pad0[2]; // 14-16 + float unk_float; // 16 + float scale; + unsigned int noScalePartBits[8]; // 20 + scr_string_t* boneNames; // 56 + unsigned char* parentList; // 64 + XModelAngle* tagAngles; // 72 + XModelTagPos* tagPositions; // 80 + unsigned char* partClassification; // 88 + DObjAnimMat* baseMat; // 96 + ReactiveMotionModelTweaks* reactiveMotionTweaks; // 104 + Material** materialHandles; // 112 + XModelLodInfo lodInfo[6]; // 120 + char numLods; // 552 + char collLod; // 553 + char __pad1[2]; // 554-556 + short flags; // 556 + short numCollSurfs; // 558 + XModelCollSurf_s* collSurfs; // 560 + XBoneInfo* boneInfo; // 568 + int contents; + float radius; + Bounds bounds; + unsigned short* invHighMipRadius; // 608 + MdaoVolume* mdaoVolumes; // 616 + unsigned short mdaoVolumeCount; // 624 + unsigned short targetCount; // 626 + unsigned short numberOfWeights; // 628 + unsigned short numberOfWeightMaps; // 630 + scr_string_t* weightNames; // 632 + BlendShapeWeightMap* blendShapeWeightMap; // 640 + PhysPreset* physPreset; // 648 + PhysCollmap* physCollmap; // 656 + float quantization; + int memUsage; + SkeletonScript* skeletonScript; // 672 + XModel** compositeModels; // 680 + XPhysBoneInfo* bonePhysics; // 688 + }; static_assert(sizeof(XModel) == 0x2B8); + + assert_offsetof(XModel, noScalePartBits, 24); + assert_offsetof(XModel, boneNames, 56); + assert_offsetof(XModel, bonePhysics, 688); + assert_offsetof(XModel, lodInfo, 120); + + enum activeReticleType_t : std::int32_t + { + VEH_ACTIVE_RETICLE_NONE = 0x0, + VEH_ACTIVE_RETICLE_PIP_ON_A_STICK = 0x1, + VEH_ACTIVE_RETICLE_BOUNCING_DIAMOND = 0x2, + VEH_ACTIVE_RETICLE_COUNT = 0x3, + }; + + enum playerAnimType_t : std::uint8_t + { + PLAYERANIMTYPE_NONE = 0x0, + PLAYERANIMTYPE_OTHER = 0x1, + PLAYERANIMTYPE_PISTOL = 0x2, + PLAYERANIMTYPE_SMG = 0x3, + PLAYERANIMTYPE_AUTORIFLE = 0x4, + PLAYERANIMTYPE_SNIPER = 0x5, + PLAYERANIMTYPE_ROCKET_LAUNCHER = 0x6, + PLAYERANIMTYPE_GRENADE = 0x7, + PLAYERANIMTYPE_M203 = 0x8, + PLAYERANIMTYPE_HOLD = 0x9, + PLAYERANIMTYPE_BRIEFCASE = 0xA, + PLAYERANIMTYPE_RIOTSHIELD = 0xB, + PLAYERANIMTYPE_LAPTOP = 0xC, + PLAYERANIMTYPE_THROWINGKNIFE = 0xD, + PLAYERANIMTYPE_MINIGUN = 0xE, + PLAYERANIMTYPE_SMG_BULLPUP = 0x1F, + PLAYERANIMTYPE_AUTOFILE_BULLPUP = 0x10, + PLAYERANIMTYPE_SNIPER_BULLPUP = 0x11, + PLAYERANIMTYPE_KILLSTREAKTRIGGER = 0x12, + PLAYERANIMTYPE_TROPHYSYSTEM = 0x13, + PLAYERANIMTYPE_COMBATKNIFE = 0x14, + PLAYERANIMTYPE_NUM = 0x15, + }; + + enum weapType_t : std::int32_t + { + WEAPCLASS_NONE = 0x0, + WEAPCLASS_BULLET = 0x1, + WEAPCLASS_GRENADE = 0x2, + WEAPCLASS_PROJECTILE = 0x3, + WEAPCLASS_RIOTSHIELD = 0x4, + WEAPCLASS_ENERGY = 0x5, + WEAPCLASS_NUM = 0x6, + }; + + enum weapClass_t : std::int32_t + { + WEAPTYPE_RIFLE = 0x1, + WEAPTYPE_SNIPER = 0x2, + WEAPTYPE_MG = 0x3, + WEAPTYPE_SMG = 0x4, + WEAPTYPE_SPREAD = 0x5, + WEAPTYPE_PISTOL = 0x6, + WEAPTYPE_ROCKETLAUNCHER = 0x7, + WEAPTYPE_TURRET = 0x8, + WEAPTYPE_THROWINGKNIFE = 0x9, + WEAPTYPE_NON_PLAYER = 0xA, + WEAPTYPE_ITEM = 0xB, + WEAPTYPE_CONE = 0xC, + WEAPTYPE_BEAM = 0xD, + WEAPTYPE_SHIELD = 0xE, + WEAPTYPE_HOVER = 0xF, + WEAPTYPE_CLOAK = 0x10, + WEAPTYPE_PING = 0x11, + WEAPTYPE_REPULSOR = 0x12, + WEAPTYPE_ADRENALINE = 0x13, + WEAPTYPE_HEALTH = 0x14, + WEAPTYPE_MUTE = 0x15, + WEAPTYPE_UNDERWATER = 0x16, + WEAPTYPE_BALL = 0x17, + WEAPTYPE_NUM = 0x18, + }; + + enum weapInventoryType_t : std::int32_t + { + WEAPINVENTORY_PRIMARY = 0x0, + WEAPINVENTORY_OFFHAND = 0x1, + WEAPINVENTORY_ITEM = 0x2, + WEAPINVENTORY_ALTMODE = 0x3, + WEAPINVENTORY_EXCLUSIVE = 0x4, + WEAPINVENTORY_SCAVENGER = 0x5, + WEAPINVENTORYCOUNT = 0x6, + }; + + enum weapFireType_t : std::int32_t + { + WEAPON_FIRETYPE_FULLAUTO = 0x0, + WEAPON_FIRETYPE_SINGLESHOT = 0x1, + WEAPON_FIRETYPE_BURSTFIRE2 = 0x2, + WEAPON_FIRETYPE_BURSTFIRE3 = 0x3, + WEAPON_FIRETYPE_BURSTFIRE4 = 0x4, + WEAPON_FIRETYPE_DOUBLEBARREL = 0x5, + WEAPON_FIRETYPECOUNT = 0x6, + WEAPON_FIRETYPE_BURSTFIRE_FIRST = 0x2, + WEAPON_FIRETYPE_BURSTFIRE_LAST = 0x4, + }; + + enum PenetrateType : std::uint32_t + { + PENETRATE_TYPE_NONE = 0x0, + PENETRATE_TYPE_SMALL = 0x1, + PENETRATE_TYPE_MEDIUM = 0x2, + PENETRATE_TYPE_LARGE = 0x3, + PENETRATE_TYPE_COUNT = 0x4, + }; + + enum ImpactType : std::int32_t + { + + }; + + enum weapStance_t : std::int32_t + { + WEAPSTANCE_STAND = 0x0, + WEAPSTANCE_DUCK = 0x1, + WEAPSTANCE_PRONE = 0x2, + WEAPSTANCE_NUM = 0x3, + }; + + enum OffhandClass : std::uint32_t + { + OFFHAND_CLASS_NONE = 0x0, + OFFHAND_CLASS_FRAG_GRENADE = 0x1, + OFFHAND_CLASS_SMOKE_GRENADE = 0x2, + OFFHAND_CLASS_FLASH_GRENADE = 0x3, + OFFHAND_CLASS_OTHER = 0x9, + OFFHAND_CLASS_COUNT = 0xA, + }; + + enum weapProjExposion_t : std::int32_t + { + WEAPPROJEXP_GRENADE = 0x0, + WEAPPROJEXP_ROCKET = 0x1, + WEAPPROJEXP_FLASHBANG = 0x2, + WEAPPROJEXP_NONE = 0x3, + WEAPPROJEXP_DUD = 0x4, + WEAPPROJEXP_SMOKE = 0x5, + WEAPPROJEXP_HEAVY = 0x6, + WEAPPROJEXP_NUM = 0x7, + }; + + enum weapAdsFireMode_t : std::int32_t + { + WEAPADSFIREMODE_NUM = 0x3, + }; + + enum weapGreebleType_t : std::int32_t + { + WEAPGREEBLE_NONE = 0x0, + WEAPGREEBLE_ACCURACYLEVEL1 = 0x1, + WEAPGREEBLE_ACCURACYLEVEL2 = 0x2, + WEAPGREEBLE_FIRERATELEVEL1 = 0x3, + WEAPGREEBLE_FIRERATELEVEL2 = 0x4, + WEAPGREEBLE_NUM = 0x5, + }; + + enum weapAutoReloadType_t : std::int32_t + { + + }; + + enum weapFireBarrels_t : std::int32_t + { + + }; + + enum weapFireTimeInterpolation_t : std::int32_t + { + + }; + + enum WeaponSlotRestriction : std::int32_t + { + SLOT_RESTRICTION_NONE = 0x0, + SLOT_RESTRICTION_OPEN = 0x1, + SLOT_RESTRICTION_PRESET = 0x2, + SLOT_RESTRICTION_COUNT = 0x3, + }; + + enum AttachmentType : std::int32_t + { + ATTACHMENT_SCOPE = 0x0, + ATTACHMENT_UNDERBARREL = 0x1, + ATTACHMENT_OTHER = 0x2, + ATTACHMENT_COUNT = 0x3, + }; + + struct AttChargeInfo + { + char __pad0[28]; + }; static_assert(sizeof(AttChargeInfo) == 28); + + struct AttHybridSettings + { + char __pad0[72]; + }; static_assert(sizeof(AttHybridSettings) == 72); + + union WAFieldParm + { + char p_char; + bool p_bool; + int p_int; + float p_float; + const char* string; + }; + + enum WAFieldType : std::uint8_t + { + WAFIELD_TYPE_STRING = 0, + WAFIELD_TYPE_INT = 4, + WAFIELD_TYPE_BOOL = 6, + WAFIELD_TYPE_FLOAT = 7, + WAFIELD_TYPE_FLOAT32 = 9, + WAFIELD_TYPE_FX = 10, + WAFIELD_TYPE_MODEL = 11, + WAFIELD_TYPE_ANIM = 12, + WAFIELD_TYPE_MATERIAL = 13, + WAFIELD_TYPE_SOUND = 15, + WAFIELD_TYPE_TRACER = 16, + }; + + enum WAFieldCode : std::uint8_t + { + FIELD_OP_STRING_SET = 0, + FIELD_OP_STRING_REPLACE = 1, + FIELD_OP_STRING_APPEND = 2, + FIELD_OP_NUMBER_BEGIN = 3, + FIELD_OP_NUMBER_SET = 3, + FIELD_OP_NUMBER_END = 6, + FIELD_OP_COUNT = 7, + }; + + struct WAField + { + unsigned char index; + unsigned char fieldType; //WAFieldType fieldType; + unsigned char code; // WAFieldCode code; + WAFieldParm parm; + }; static_assert(sizeof(WAField) == 16); + + struct WeaponAttachment + { + union + { + const char* szInternalName; + const char* name; + }; + const char* szDisplayName; // 8 + AttachmentType type; // 16 + weapType_t weaponType; // 20 + weapClass_t weapClass; // 24 + XModel** worldModels; // 32 (2 xmodels) + XModel** viewModels; // 40 (2 xmodels) + XModel** reticleViewModels; // 48 (64 xmodels) + snd_alias_list_t** bounceSounds; // 56 (53 sounds) + snd_alias_list_t** rollingSounds; // 64 (53 sounds) + AttChargeInfo* chargeInfo; // 72 + AttHybridSettings* hybridSettings; // 80 + scr_string_t* stringArray1; // 88 (4 strings) (hideTags?) + scr_string_t* stringArray2; // 96 (4 strings) (showTags?) + unsigned short* waFieldOffsets; // 104 + WAField* waFields; // 112 + unsigned int waFieldsCount; // 120 (MAX_ATTACH_FIELDS_PER_WEAPON = 256) + char __pad0[14]; + bool riotShield; // 138 + char __pad1[5]; + // size: 144 + }; static_assert(sizeof(WeaponAttachment) == 0x90); + static_assert(offsetof(WeaponAttachment, riotShield) == 138); + + struct AnimOverrideEntry + { + unsigned short attachment1; + unsigned short attachment2; + XAnimParts* overrideAnim; + XAnimParts* altmodeAnim; + //unsigned int animTreeType; + int animTime; + int altTime; + }; static_assert(sizeof(AnimOverrideEntry) == 32); + + struct SoundOverrideEntry + { + unsigned short attachment1; + unsigned short attachment2; + snd_alias_list_t* overrideSound; + snd_alias_list_t* altmodeSound; + //unsigned int soundType; + }; static_assert(sizeof(SoundOverrideEntry) == 24); + + struct FXOverrideEntry + { + unsigned short attachment1; + unsigned short attachment2; + FxEffectDef* overrideFX; + FxEffectDef* altmodeFX; + //unsigned int fxType; + }; static_assert(sizeof(FXOverrideEntry) == 24); + + struct ReloadStateTimerEntry + { + int attachment; + int reloadAddTime; + int reloadEmptyAddTime; + int reloadStartAddTime; + }; static_assert(sizeof(ReloadStateTimerEntry) == 16); + + struct NoteTrackToSoundEntry + { + int attachment; + scr_string_t* notetrackSoundMapKeys; + scr_string_t* notetrackSoundMapValues; + }; static_assert(sizeof(NoteTrackToSoundEntry) == 24); + + struct TracerDef + { + const char* name; + Material* material; + FxEffectDef* effect; + unsigned int drawInterval; + float speed; + float beamLength; + float beamWidth; + float screwRadius; + float screwDist; + float colors[5][4]; + }; static_assert(sizeof(TracerDef) == 0x80); + + struct LaserDef + { + const char* name; + Material* laserMaterial; + Material* laserLightMaterial; + FxEffectDef* effect; + LaserDef* altLaser; + scr_string_t value; + float float_values[17]; + char char_values[4]; + }; static_assert(sizeof(LaserDef) == 120); + + struct TurretHydraulicSettings + { + float minVelocity; + float maxVelocity; // unused or padding + snd_alias_list_t* verticalSound; + snd_alias_list_t* verticalStopSound; + snd_alias_list_t* horizontalSound; + snd_alias_list_t* horizontalStopSound; + }; static_assert(sizeof(TurretHydraulicSettings) == 40); + + enum weapOverlayReticle_t : std::int32_t + { + WEAPOVERLAYRETICLE_NONE = 0x0, + WEAPOVERLAYRETICLE_CROSSHAIR = 0x1, + WEAPOVERLAYRETICLE_NUM = 0x2, + }; + + struct ADSOverlay + { + Material* shader; + Material* shaderLowRes; + Material* shaderEMP; + Material* shaderEMPLowRes; + weapOverlayReticle_t reticle; + float xU_01; + float xU_02; + float width; + float height; + float widthSplitscreen; + float heightSplitscreen; + }; static_assert(sizeof(ADSOverlay) == 0x40); + + enum weaponIconRatioType_t : std::int32_t + { + WEAPON_ICON_RATIO_1TO1 = 0x0, + WEAPON_ICON_RATIO_2TO1 = 0x1, + WEAPON_ICON_RATIO_4TO1 = 0x2, + WEAPON_ICON_RATIO_COUNT = 0x3, + }; + + enum WeapStickinessType : std::int32_t + { + WEAPSTICKINESS_NONE = 0x0, + WEAPSTICKINESS_ALL = 0x1, + WEAPSTICKINESS_ALL_ORIENT = 0x2, + WEAPSTICKINESS_GROUND = 0x3, + WEAPSTICKINESS_GROUND_WITH_YAW = 0x4, + WEAPSTICKINESS_KNIFE = 0x5, + WEAPSTICKINESS_COUNT = 0x6, + }; + + enum guidedMissileType_t : std::int32_t + { + MISSILE_GUIDANCE_NONE = 0x0, + MISSILE_GUIDANCE_SIDEWINDER = 0x1, + MISSILE_GUIDANCE_HELLFIRE = 0x2, + MISSILE_GUIDANCE_JAVELIN = 0x3, + MISSILE_GUIDANCE_UNKNOWN0 = 0x4, + MISSILE_GUIDANCE_UNKNOWN1 = 0x5, + MISSILE_GUIDANCE_UNKNOWN2 = 0x6, + MISSILE_GUIDANCE_COUNT = 0x7, + }; + + enum WeapOverlayInteface_t : std::int32_t + { + WEAPOVERLAYINTERFACE_NONE = 0x0, + WEAPOVERLAYINTERFACE_JAVELIN = 0x1, + WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2, + WEAPOVERLAYINTERFACECOUNT = 0x3, + }; + + enum weapAnimFiles_t : std::int32_t + { + WEAP_ANIM_INVALID = -1, + NUM_WEAP_ANIMS = 202, + }; + + struct StateTimers + { + int fireDelay; // 1640 * x + int meleeDelay; // 1644 * x + int meleeChargeDelay; // 1648 * x + int detonateDelay; // 1652 * x + int fireTime; // 1656 * x + int rechamberTime; // 1660 * x + int rechamberTimeOneHanded; // 1664 * x + int rechamberBoltTime; // 1668 * x + int holdFireTime; // 1672 * x + int grenadePrimeReadyToThrowTime; // 1676 * x + int detonateTime; // 1680 * x + int meleeTime; // 1684 * x + int meleeChargeTime; // 1688 * x + int reloadTime; // 1692 * x + int reloadShowRocketTime; // 1696 * x + int reloadEmptyTime; // 1700 * x + int reloadAddTime; // 1704 * x + int reloadEmptyAddTime; // 1708 * x + int reloadStartTime; // 1712 * x + int reloadStartAddTime; // 1716 * x + int reloadEndTime; // 1720 * x + int reloadTimeDualWield; // 1724 * x + int reloadAddTimeDualWield; // 1728 * x + int reloadEmptyDualMag; // 1732 * x + int reloadEmptyAddTimeDualMag; // 1736 * x + int u25; // 1740 * x // (unused) + int u26; // 1744 * x // (unused) + int dropTime; // 1748 * x + int raiseTime; // 1752 * x + int altDropTime; // 1756 * x + int altRaiseTime; // 1760 * x + int quickDropTime; // 1764 * x + int quickRaiseTime; // 1768 * x + int firstRaiseTime; // 1772 * x + int breachRaiseTime; // 1776 * x + int emptyRaiseTime; // 1780 * x + int emptyDropTime; // 1784 * x + int sprintInTime; // 1788 * x + int sprintLoopTime; // 1792 * x + int sprintOutTime; // 1796 * x + int stunnedTimeBegin; // 1800 * x + int stunnedTimeLoop; // 1804 * x + int stunnedTimeEnd; // 1808 * x + int nightVisionWearTime; // 1812 * x + int nightVisionWearTimeFadeOutEnd; // 1816 * x + int nightVisionWearTimePowerUp; // 1820 * x + int nightVisionRemoveTime; // 1824 * x + int nightVisionRemoveTimePowerDown; // 1828 * x + int nightVisionRemoveTimeFadeInStart; // 1832 * x + int aiFuseTime; // 1836 * x + int fuseTime; // 1840 * x + int missileTime; // 1844 * x + int primeTime; // 1848 * x + bool bHoldFullPrime; // 1852 * x + int blastFrontTime; // 1856 * x + int blastRightTime; // 1860 * x + int blastBackTime; // 1864 * x + int blastLeftTime; // 1868 * x + int u58; // 1872 * x (unused) + int u59; // 1876 * x (unused) + int u60; // 1880 * x (unused) + int u61; // 1884 * x (unused) + int u62; // 1888 * x (unused) + int u63; // 1892 * x (unused) + int u64; // 1896 * x (unused) + int u65; // 1900 * x (unused) + int u66; // 1904 * x (unused) + int u67; // 1908 * x (unused) + int u68; // 1912 * x (unused) + int offhandSwitchTime; // 1916 * x + int u70; // 1920 * x (unknown) + int u71; // 1924 * x (unknown) + int u72; // 1928 * x (unknown) + int u73; // 1932 * x (unknown) + int u74; // 1936 * x (unknown) + int u75; // 1936 * x (unknown) + int u76; // 1936 * x (unknown) + int u77; // 1936 * x (unknown) + int u78; // 1936 * x (unknown) + }; static_assert(sizeof(StateTimers) == 316); + + struct WeaponDef + { + union + { + const char* szInternalName; + const char* name; + }; + const char* szDisplayName; // 8 + const char* szOverlayName; // 16 + const char* szAttachmentName; + const char* szUnknownName; + XModel** gunModel; // 24 (2 xmodels) + XModel* handModel; // 32 + XModel* unknownModel; // 40 + XModel** reticleViewModels; // 48 (64 xmodels) + const char* szModeName; // 56 + XAnimParts** szXAnimsRightHanded; // 64 (190 xanims) + XAnimParts** szXAnimsLeftHanded; // 72 (190 xanims) + scr_string_t* hideTags; // 80 (32 xstrings) + WeaponAttachment** attachments; // 88 (weaponDef + 1332 attachments) + XAnimParts** szXAnims; // 96 (190 xanims) + AnimOverrideEntry* animOverrides; // 104 (weaponDef + 1333 overrides) + SoundOverrideEntry* soundOverrides; // 112 (weaponDef + 1334 overrides) + FXOverrideEntry* fxOverrides; // 120 (weaponDef + 1335 overrides) + ReloadStateTimerEntry* reloadOverrides; // 128 (weaponDef + 1336 overrides) + NoteTrackToSoundEntry* notetrackOverrides; // 136 (weaponDef + 1337 overrides) + scr_string_t* notetrackSoundMapKeys; // 144 (36 xstrings) + scr_string_t* notetrackSoundMapValues; // 152 (36 xstrings) + scr_string_t* notetrackRumbleMapKeys; // 160 (16 xstrings) + scr_string_t* notetrackRumbleMapValues; // 168 (16 xstrings) + scr_string_t* notetrackFXMapKeys; // 176 (16 xstrings) + FxEffectDef** notetrackFXMapValues; // 184 (16 effects) + scr_string_t* notetrackFXMapTagValues; // 192 (16 xstrings) + scr_string_t* notetrackUnknownKeys; // 200 (16 xstrings) + char* notetrackUnknown; // 208 (16 chars) + scr_string_t* notetrackUnknownValues; // 216 (16 xstrings) + const char* szAltWeaponName; // 224 + FxEffectDef* viewFlashEffect; // 232 + FxEffectDef* viewBodyFlashEffect; // 240 + FxEffectDef* worldFlashEffect; // 248 + FxEffectDef* viewFlashADSEffect; // 256 + FxEffectDef* viewBodyFlashADSEffect; // 264 + FxEffectDef* effect06; // 272 + FxEffectDef* effect07; // 280 + FxEffectDef* effect08; // 288 + FxEffectDef* effect09; // 296 + FxEffectDef* effect10; // 304 + FxEffectDef* effect11; // 312 + FxEffectDef* effect12; // 320 + snd_alias_list_t* pickupSound; // 1 + snd_alias_list_t* pickupSoundPlayer; // 2 + snd_alias_list_t* ammoPickupSound; // 3 + snd_alias_list_t* ammoPickupSoundPlayer; // 4 + snd_alias_list_t* projectileSound; // 5 + snd_alias_list_t* pullbackSound; // 6 + snd_alias_list_t* pullbackSoundPlayer; // 7 + snd_alias_list_t* pullbackSoundQuick; // 8 + snd_alias_list_t* pullbackSoundQuickPlayer; // 9 + snd_alias_list_t* fireSound; // 10 + snd_alias_list_t* fireSoundPlayer; // 11 + snd_alias_list_t* fireSoundPlayerLeft; // 12 + snd_alias_list_t* fireSoundPlayerRight; // 13 + snd_alias_list_t* sound14; // 14 + snd_alias_list_t* sound15; // 15 + snd_alias_list_t* sound16; // 16 + snd_alias_list_t* sound17; // 17 + snd_alias_list_t* sound18; // 18 + snd_alias_list_t* fireLoopSound; // 19 + snd_alias_list_t* fireLoopSoundPlayer; // 20 + snd_alias_list_t* sound21; // 21 + snd_alias_list_t* sound22; // 22 + snd_alias_list_t* sound23; // 23 + snd_alias_list_t* sound24; // 24 + snd_alias_list_t* sound25; // 25 + snd_alias_list_t* sound26; // 26 + snd_alias_list_t* fireStopSound; // 27 + snd_alias_list_t* fireStopSoundPlayer; // 28 + snd_alias_list_t* sound29; // 29 + snd_alias_list_t* sound30; // 30 + snd_alias_list_t* sound31; // 31 + snd_alias_list_t* sound32; // 32 + snd_alias_list_t* sound33; // 33 + snd_alias_list_t* fireFirstSound; // 34 + snd_alias_list_t* fireFirstSoundPlayer; // 35 + snd_alias_list_t* fireSound2; // 36 + snd_alias_list_t* fireSoundPlayer2; // 37 + snd_alias_list_t* fireSpecialSound; // 38 + snd_alias_list_t* fireSpecialSoundPlayer; // 39 + snd_alias_list_t* emptyFireSound; // 40 + snd_alias_list_t* emptyFireSoundPlayer; // 41 + snd_alias_list_t* emptyFireSoundPlayerLeft; // 42 + snd_alias_list_t* emptyFireSoundPlayerRight; // 43 + snd_alias_list_t* emptyFireSoundReleasePlayer; // 44 + snd_alias_list_t* emptyFireSoundReleasePlayerLeft; // 45 + snd_alias_list_t* emptyFireSoundReleasePlayerRight; // 46 + snd_alias_list_t* sound47; // 47 + snd_alias_list_t* meleeSwipeSound; // 48 + snd_alias_list_t* meleeSwipeSoundPlayer; // 49 + snd_alias_list_t* meleeHitSound; // 50 + snd_alias_list_t* meleeHitSoundPlayer; // 51 + snd_alias_list_t* meleeMissSound; // 52 + snd_alias_list_t* meleeMissSoundPlayer; // 53 + snd_alias_list_t* sound54; // 54 + snd_alias_list_t* sound55; // 55 + snd_alias_list_t* sound56; // 56 + snd_alias_list_t* sound57; // 57 + snd_alias_list_t* sound58; // 58 + snd_alias_list_t* sound59; // 59 + snd_alias_list_t* sound60; // 60 + snd_alias_list_t* sound61; // 61 + snd_alias_list_t* sound62; // 62 + snd_alias_list_t* sound63; // 63 + snd_alias_list_t* sound64; // 64 + snd_alias_list_t* sound65; // 65 + snd_alias_list_t* nightVisionWearSound; // 66 + snd_alias_list_t* nightVisionWearSoundPlayer; // 67 + snd_alias_list_t* nightVisionRemoveSound; // 68 + snd_alias_list_t* nightVisionRemoveSoundPlayer; // 69 + snd_alias_list_t* raiseSound; // 70 + snd_alias_list_t* raiseSoundPlayer; // 71 + snd_alias_list_t* raiseSoundPlayerLeft; // 72 + snd_alias_list_t* raiseSoundPlayerRight; // 73 + snd_alias_list_t* sound74; // 74 + snd_alias_list_t* quickRaiseSoundPlayer; // 75 + snd_alias_list_t* quickRaiseSoundPlayerLeft; // 76 + snd_alias_list_t* quickRaiseSoundPlayerRight; // 77 + snd_alias_list_t* raiseSound2; // 78 + snd_alias_list_t* sound79; // 79 + snd_alias_list_t* sound80; // 80 + snd_alias_list_t* sound81; // 81 + snd_alias_list_t* putawaySound; // 82 + snd_alias_list_t* putawaySoundPlayer; // 83 + snd_alias_list_t* putawaySoundPlayerLeft; // 84 + snd_alias_list_t* putawaySoundPlayerRight; // 85 + snd_alias_list_t* sound86; // 86 + snd_alias_list_t* sound87; // 87 + snd_alias_list_t* adsEnterSoundPlayer; // 88 + snd_alias_list_t* adsLeaveSoundPlayer; // 89 + snd_alias_list_t* adsCrosshairEnemySound; // 90 + snd_alias_list_t** bounceSound; // 920 (53 sounds) + snd_alias_list_t** rollingSound; // 928 (53 sounds) + FxEffectDef* viewShellEjectEffect; // 936 + FxEffectDef* worldShellEjectEffect; // 944 + FxEffectDef* viewLastShotEjectEffect; // 952 + FxEffectDef* worldLastShotEjectEffect; // 960 + FxEffectDef* viewMagEjectEffect; // 968 + Material* reticleCenter; // 976 + Material* reticleSide; // 984 + XModel** worldModel; // 992 (2 xmodels) + XModel* worldClipModel; // 1000 + XModel* rocketModel; // 1008 + XModel* knifeModel; // 1016 + XModel* worldKnifeModel; // 1024 + Material* hudIcon; // 1032 + Material* pickupIcon; // 1040 + Material* unknownIcon2; // 1048 + Material* unknownIcon3; // 1056 + Material* unknownIcon4; // 1064 + Material* ammoCounterIcon; // 1072 + const char* szAmmoName; // 1080 + const char* szClipName; // 1088 + const char* szSharedAmmoCapName; // 1096 + PhysCollmap* physCollmap; // 1104 + PhysPreset* physPreset; // 1112 + const char* szUseHintString; // 1120 + const char* dropHintString; // 1128 + float* locationDamageMultipliers; // 1136 (22 floats) + const char* fireRumble; // 1144 + const char* fireMedRumble; // 1152 + const char* fireHighRumble; // 1160 + const char* meleeImpactRumble; // 1168 + TracerDef* tracer1; // 1176 + TracerDef* tracer2; // 1184 + LaserDef* laser; // 1192 + snd_alias_list_t* turretOverheatSound; // 1200 + FxEffectDef* turretOverheatEffect; // 1208 + const char* turretBarrelSpinRumble; // 1216 + snd_alias_list_t* turretBarrelSpinMaxSnd; // 1224 + snd_alias_list_t* turretBarrelSpinUpSnd[4]; // 1232 + snd_alias_list_t* turretBarrelSpinDownSnd[4]; // 1264 + snd_alias_list_t* missileConeSoundAlias; // 1296 + snd_alias_list_t* missileConeSoundAliasAtBase; // 1304 + XModel* stowOffsetModel; // 1312 + TurretHydraulicSettings* turretHydraulicSettings; // 1320 + int altWeapon; // 1328 + unsigned char numWeaponAttachments; // 1332 + unsigned char numAnimOverrides; // 1333 + unsigned char numSoundOverrides; // 1334 + unsigned char numFXOverrides; // 1335 + unsigned char numReloadStateTimerOverrides; // 1336 + unsigned char numNotetrackOverrides; // 1337 + playerAnimType_t playerAnimType; // 1338 + char __pad000[1]; + weapType_t weapType; // 1340 + weapClass_t weapClass; // 1344 + PenetrateType penetrateType; // 1348 + float penetrateDepth; // 1352 + ImpactType impactType; // 1356 + weapInventoryType_t inventoryType; // 1360 + weapFireType_t fireType; // 1364 + weapFireBarrels_t fireBarrels; // 1368 + weapAdsFireMode_t adsFireMode; // 1372 + float burstFireCooldown; // 1376 + weapGreebleType_t greebleType; // 1380 + weapAutoReloadType_t autoReloadType; // 1384 + WeaponSlotRestriction slotRestriction; // 1388 + OffhandClass offhandClass; // 1392 + weapStance_t stance; // 1396 + int reticleCenterSize; // 1400 + int reticleSideSize; // 1404 + int reticleMinOfs; // 1408 + activeReticleType_t activeReticleType; // 1412 + float standMove[3]; // 1416 1420 1424 + float standRot[3]; // 1428 1432 1436 + float strafeMove[3]; // 1440 1444 1448 + float strafeRot[3]; // 1452 1456 1460 + float duckedOfs[3]; // 1464 1468 1472 + float duckedMove[3]; // 1476 1480 1484 + float duckedRot[3]; // 1488 1492 1496 + float proneOfs[3]; // 1500 1504 1508 + float proneMove[3]; // 1512 1516 1520 + float proneRot[3]; // 1524 1528 1532 + float unkVec1[3]; + float unkVec2[3]; + float posMoveRate; // 1536 + float posProneMoveRate; // 1540 + float standMoveMinSpeed; // 1544 + float duckedMoveMinSpeed; // 1548 + float proneMoveMinSpeed; // 1552 + float posRotRate; // 1556 + float posProneRotRate; // 1560 + weaponIconRatioType_t hudIconRatio; // 1564 + weaponIconRatioType_t pickupIconRatio; // 1568 + weaponIconRatioType_t ammoCounterIconRatio; // 1572 + int ammoCounterClip; // 1576 + int startAmmo; // 1580 + int ammoIndex; // 1752 + char ammoIndexUnknown; // 1588 (runtime variable) + char __pad002[3]; // padding? + int clipIndex; // 1592 (runtime variable) + char clipIndexUnknown; // 1596 (runtime variable) + char __pad003[3]; // padding? + int maxAmmo; // 1600 + int minAmmoReq; // 1604 + int clipSize; // 1608 + int shotCount; // 1612 + int sharedAmmoCapIndex; // 1616 + int sharedAmmoCap; // 1620 + int damage; // 1624 + int playerDamage; // 1628 + int meleeDamage; // 1632 + int damageType; // 1636 + StateTimers stateTimers; // 1640 + StateTimers akimboStateTimers; // 1940 + float autoAimRange; // 2240 + float aimAssistRange; // 2244 + float aimAssistRangeAds; // 2248 + float aimPadding; // 2252 + float enemyCrosshairRange; // 2256 + float moveSpeedScale; // 2260 + float adsMoveSpeedScale; // 2264 + float sprintDurationScale; // 2268 + float adsZoomFov; // 2272 + float adsZoomInFrac; // 2276 + float adsZoomOutFrac; // 2280 + float adsSceneBlur; // 2284 (1401FC630) : float + float fU_007; // 2288 (1400CF870) : float (related to scene blur) + float xU_008; // 2292 X + ADSOverlay overlay; // 2296 + WeapOverlayInteface_t overlayInterface; // 2352 + float adsBobFactor; // 2356 + float adsViewBobMult; // 2360 + float hipSpreadStandMin; // 2364 + float hipSpreadDuckedMin; // 2368 + float hipSpreadProneMin; // 2372 + float hipSpreadStandMax; // 2376 + float xU_009; // 2380 X + float xU_010; // 2384 X + float hipSpreadDuckedMax; // 2388 + float hipSpreadProneMax; // 2392 + float hipSpreadDecayRate; // 2396 + float hipSpreadFireAdd; // 2400 + float hipSpreadTurnAdd; // 2404 + float hipSpreadMoveAdd; // 2408 + float hipSpreadDuckedDecay; // 2412 + float hipSpreadProneDecay; // 2416 + float hipReticleSidePos; // 2420 + float adsIdleAmount; // 2424 + float hipIdleAmount; // 2428 + float adsIdleSpeed; // 2432 + float hipIdleSpeed; // 2436f + float idleCrouchFactor; // 2440 + float idleProneFactor; // 2444 + float gunMaxPitch; // 2448 + float gunMaxYaw; // 2452 + float adsIdleLerpStartTime; // 2456 + float adsIdleLerpTime; // 2460 + int adsTransInTime; // 2464 + int xU_011; // 2468 X + int adsTransOutTime; // 2472 + float xU_012; // 2476 X + float swayMaxAngle; // 2480 + float swayLerpSpeed; // 2484 + float swayPitchScale; // 2488 + float swayYawScale; // 2492 + float swayVertScale; // 2496 + float swayHorizScale; // 2500 + float swayShellShockScale; // 2504 + float adsSwayMaxAngle; // 2508 + float adsSwayLerpSpeed; // 2512 + float adsSwayPitchScale; // 2516 + float adsSwayYawScale; // 2520 + float adsSwayHorizScale; // 2524 + float adsSwayVertScale; // 2528 + float adsViewErrorMin; // 2532 + float adsViewErrorMax; // 2536 + float adsFireAnimFrac; // 2540 + float dualWieldViewModelOffset; // 2544 + float scopeDriftDelay; // 2548 + float scopeDriftLerpInTime; // 2552 + float scopeDriftSteadyTime; // 2556 + float scopeDriftLerpOutTime; // 2560 + float scopeDriftSteadyFactor; // 2564 + float scopeDriftUnsteadyFactor; // 2568 + float bobVerticalFactor; // 2572 + float bobHorizontalFactor; // 2576 + float bobViewVerticalFactor; // 2580 + float bobViewHorizontalFactor; // 2584 + float stationaryZoomFov; // 2588 + float stationaryZoomDelay; // 2592 + float stationaryZoomLerpInTime; // 2596 + float stationaryZoomLerpOutTime; // 2600 + float adsDofStart; // 2604 + float adsDofEnd; // 2608 + float xU_020; // 2612 X + Material* killIcon; // 2616 + Material* dpadIcon; // 2624 + Material* hudProximityWarningIcon; // 2632 + weaponIconRatioType_t killIconRatio; // 2640 + weaponIconRatioType_t dpadIconRatio; // 2644 + int fireAnimLength; // 2648 + int fireAnimLengthAkimbo; // 2652 + int inspectAnimTime; // 2656 + int reloadAmmoAdd; // 2660 + int reloadStartAdd; // 2664 + int ammoDropStockMin; // 2668 + int ammoDropStockMax; // 2672 + int ammoDropClipPercentMin; // 2676 + int ammoDropClipPercentMax; // 2680 + int explosionRadius; // 2684 + int explosionRadiusMin; // 2688 + int explosionInnerDamage; // 2692 + int explosionOuterDamage; // 2696 + float damageConeAngle; // 2700 + float bulletExplDmgMult; // 2704 + float bulletExplRadiusMult; // 2708 + int projectileSpeed; // 2712 + int projectileSpeedUp; // 2716 + int projectileSpeedForward; // 2720 + int projectileActivateDist; // 2724 + float projLifetime; // 2728 + float timeToAccelerate; // 2732 + float projectileCurvature; // 2736 + float xU_021; // 2740 X + const char* projectileName; // 2744 + XModel* projectileModel; // 2752 + FxEffectDef* projExplosionEffect; // 2760 + FxEffectDef* projDudEffect; // 2768 + snd_alias_list_t* projExplosionSound; // 2776 + snd_alias_list_t* projDudSound; // 2784 + weapProjExposion_t projExplosion; // 2792 + WeapStickinessType stickiness; // 2796 + float lowAmmoWarningThreshold; // 2800 + float ricochetChance; // 2804 + int riotShieldHealth; // 2808 + float riotShieldDamageMult; // 2812 + float* parallelBounce; // 2816 (53 floats) + float* perpendicularBounce; // 2824 (53 floats) + FxEffectDef* projTrailEffect; // 2832 + FxEffectDef* projBeaconEffect; // 2840 + float projectileColor[3]; // 2848 2852 2856 + guidedMissileType_t guidedMissileType; // 2860 + float maxSteeringAccel; // 2864 + int projIgnitionDelay; // 2868 + FxEffectDef* projIgnitionEffect; // 2872 + snd_alias_list_t* projIgnitionSound; // 2880 + float adsAimPitch; // 2888 + float adsCrosshairInFrac; // 2892 + float adsCrosshairOutFrac; // 2896 + int adsGunKickReducedKickBullets; // 2900 + float adsGunKickReducedKickPercent; // 2904 + float adsGunKickPitchMin; // 2908 + float adsGunKickPitchMax; // 2912 + float adsGunKickYawMin; // 2916 + float adsGunKickYawMax; // 2920 + float adsGunKickMagMin; // 2924 + float adsGunKickAccel; // 2928 + float adsGunKickSpeedMax; // 2932 + float adsGunKickSpeedDecay; // 2936 + float adsGunKickStaticDecay; // 2940 + float adsViewKickPitchMin; // 2944 + float adsViewKickPitchMax; // 2948 + float adsViewKickYawMin; // 2952 + float adsViewKickYawMax; // 2956 + float adsViewKickMagMin; // 2960 + float adsViewKickCenterSpeed; // 2964 + float adsViewScatterMin; // 2968 X + float adsViewScatterMax; // 2972 X + float adsSpread; // 2976 + int hipGunKickReducedKickBullets; // 2980 + float hipGunKickReducedKickPercent; // 2984 + float hipGunKickPitchMin; // 2988 + float hipGunKickPitchMax; // 2992 + float hipGunKickYawMin; // 2996 + float hipGunKickYawMax; // 3000 + float hipGunKickMagMin; // 3004 + float hipGunKickAccel; // 3008 + float hipGunKickSpeedMax; // 3012 + float hipGunKickSpeedDecay; // 3016 + float hipGunKickStaticDecay; // 3020 + float hipViewKickPitchMin; // 3024 + float hipViewKickPitchMax; // 3028 + float hipViewKickYawMin; // 3032 + float hipViewKickYawMax; // 3036 + float hipViewKickMagMin; // 3040 + float hipViewKickCenterSpeed; // 3044 + float hipViewScatterMin; // 3048 //* + float hipViewScatterMax; // 3052 //* + float xU_043; // 3056 //* + int adsReloadTransTime; // 3060 + float fightDist; // 3064 + float maxDist; // 3068 + const char* accuracyGraphName[2]; // 3072 + vec2_t* accuracyGraphKnots[2]; // 3088 + vec2_t* originalAccuracyGraphKnots[2]; // 3104 + short accuracyGraphKnotCount[2]; // 3120 + int positionReloadTransTime; // 3124 X + float leftArc; // 3128 + float rightArc; // 3132 + float topArc; // 3136 + float bottomArc; // 3140 + float accuracy; // 3144 + float aiSpread; // 3148 + float playerSpread; // 3152 + float minTurnSpeed[2]; //3156 + float maxTurnSpeed[2]; // 3164 + float pitchConvergenceTime; // 3172 + float yawConvergenceTime; // 3176 + float suppressTime; // 3180 + float maxRange; // 3184 + float animHorRotateInc; // 3188 + float playerPositionDist; // 3192 + unsigned int useHintStringIndex; // 3196 (runtime variable) + unsigned int dropHintStringIndex; // 3200 (runtime variable) + float horizViewJitter; // 3204 + float vertViewJitter; // 3208 + float scanSpeed; // 3212 + float scanAccel; // 3216 + int scanPauseTime; // 3220 + char __pad[16]; + const char* szScript; // 3224 + int minDamage; // 3232 + int midDamage; // 3236 + int minPlayerDamage; // 3240 + int midPlayerDamage; // 3244 + float maxDamageRange; // 3248 + float minDamageRange; // 3252 + int iU_045; // 3256 X + int iU_046; // 3260 X + int iU_047; // 3264 X + int iU_048; // 3268 X + float fU_049; // 3272 X + float fU_050; // 3276 X + float destabilizationRateTime; // 3280 + float destabilizationCurvatureMax; // 3284 + int destabilizeDistance; // 3288 + float turretADSTime; // 3292 + float turretFov; // 3296 X + float turretFovADS; // 3300 X + float turretScopeZoomRate; // 3304 X + float turretScopeZoomMin; // 3308 X + float turretScopeZoomMax; // 3312 X + float xU_056; // 3316 X + float xU_057; // 3320 X + float xU_058; // 3324 X + float xU_059; // 3328 X + float turretBarrelSpinSpeed; // 3332 + float turretBarrelSpinUpTime; // 3336 + float turretBarrelSpinDownTime; // 3340 X + float missileConeSoundRadiusAtTop; // 3344 X + float missileConeSoundRadiusAtBase; // 3348 X + float missileConeSoundHeight; // 3352 X + float missileConeSoundOriginOffset; // 3356 X + float missileConeSoundVolumescaleAtCore; // 3360 X + float missileConeSoundVolumescaleAtEdge; // 3364 X + float missileConeSoundVolumescaleCoreSize; // 3368 X + float missileConeSoundPitchAtTop; // 3372 X + float missileConeSoundPitchAtBottom; // 3376 X + float missileConeSoundPitchTopSize; // 3380 X + float missileConeSoundPitchBottomSize; // 3384 X + float missileConeSoundCrossfadeTopSize; // 3388 X + float missileConeSoundCrossfadeBottomSize; // 3392 X + float aim_automelee_lerp; // 3396 + float aim_automelee_range; // 3400 + float aim_automelee_region_height; // 3404 + float aim_automelee_region_width; // 3408 + float player_meleeHeight; // 3412 + float player_meleeRange; // 3416 + float player_meleeWidth; // 3420 + float signatureFireTime; // 3424 + int signatureNumBullets; // 3428 + weapFireTimeInterpolation_t fireTimeInterpolationType; // 3432 + int xU_075; // 3436 X + int ammoUsedPerShot; // 3440 + int xU_076; // 3444 X + int xU_077; // 3448 X + int xU_078; // 3452 X + int iU_079; // 3456 // int numBulletTags (BG_ShowHideTagsBasedOnAltMode) + int iU_080; // 3460 // int tagForAmmo (1400C77D0) + scr_string_t stowTag; // 3464 + bool bU_081; // 3468 X + bool unknownReticleBooleanValue1; // 3469 (CG_DrawCrosshair) + bool unknownReticleBooleanValue2; // 3470 (CG_DrawCrosshair) + bool turretADSEnabled; // 3471 X + bool knifeAttachTagLeft; // 3472 + bool knifeAlwaysAttached; // 3473 + bool meleeOverrideValues; // 3474 + bool bU_083; // 3475 X + bool bU_084; // 3476 X + bool sharedAmmo; // 3477 + bool lockonSupported; // 3478 + bool requireLockonToFire; // 3479 + bool isAirburstWeapon; // 3480 X + bool bigExplosion; // 3481 X + bool noAdsWhenMagEmpty; // 3482 + bool avoidDropCleanup; // 3483 + bool inheritsPerks; // 3484 + bool crosshairColorChange; // 3485 + bool rifleBullet; // 3486 + bool armorPiercing; // 3487 + bool boltAction; // 3488 + bool aimDownSight; // 3489 + bool canHoldBreath; // 3490 + bool meleeOnly; // 3491 + bool bU_085; // 3492 bool isMeleeAnimDelayed;? (0x14009FDC0)(1401F2BC0) + bool bU_086; // 3493 X bool oldWeaponBot;? + bool canVariableZoom; // 3494 + bool rechamberWhileAds; // 3495 + bool bulletExplosiveDamage; // 3496 + bool cookOffHold; // 3497 + bool reticleSpin45; // 3498 X + bool reticleSideEnabled; // 3499 + bool clipOnly; // 3500 + bool noAmmoPickup; // 3501 + bool disableSwitchToWhenEmpty; // 3502 + bool bU_088; // 3503 (14017E520) bool hiddenAmmo;? + bool hasMotionTracker; // 3504 + bool bU_089; // 3505 X + bool noDualWield; // 3506 + bool flipKillIcon; // 3507 + bool actionSlotShowAmmo; // 3508 + bool noPartialReload; // 3509 + bool segmentedReload; // 3510 + bool multipleReload; // 3511 + bool blocksProne; // 3512 + bool silenced; // 3513 + bool isRollingGrenade; // 3514 + bool projExplosionEffectForceNormalUp; // 3515 + bool projExplosionEffectInheritParentDirection; // 3516 + bool projImpactExplode; // 3517 + bool projTrajectoryEvents; // 3518 X + bool projWhizByEnabled; // 3519 X + bool stickToPlayers; // 3520 X + bool stickToVehicles; // 3521 X + bool stickToTurrets; // 3522 X + bool thrownSideways; // 3523 X + bool hasDetonatorEmptyThrow; // 3524 + bool hasDetonatorDoubleTap; // 3525 + bool disableFiring; // 3526 + bool timedDetonation; // 3527 + bool bU_090; // 3528 (G_FireGrenade)(CheckCrumpleMissile) bool usesGrenadeTimer? + bool bU_091; // 3529 (G_FireRocket) bool usesRocketTimer? + bool rotate; // 3530 + bool holdButtonToThrow; // 3531 X + bool freezeMovementWhenFiring; // 3532 + bool thermalScope; // 3533 + bool thermalToggle; // 3534 + bool outlineEnemies; // 3535 + bool altModeSameWeapon; // 3536 + bool turretBarrelSpinEnabled; // 3537 + bool missileConeSoundEnabled; // 3538 X + bool missileConeSoundPitchshiftEnabled; // 3539 X + bool missileConeSoundCrossfadeEnabled; // 3540 X + bool offhandHoldIsCancelable; // 3541 + bool doNotAllowAttachmentsToOverrideSpread; // 3542 + bool useFastReloadAnims; // 3543 (140202800) + bool dualMagReloadSupported; // 3544 + bool reloadStopsAlt; // 3545 X + bool bU_092; // 3546 X + bool alwaysShatterGlassOnImpact; // + bool bU_093; // + bool oldWeapon; // 3773 !! + bool bU_094; // + bool xU_095; // + bool hasCounterSilencer; // + bool xU_097; // + bool xU_098; // + bool disableVariableAutosimRate; // + bool bU_100; // + bool bU_101; // + bool bU_102; // + bool bU_103; // + bool bU_104; // + bool bU_105; // + bool cloakedWeapon; // + bool adsHideWeapon; // + bool adsHideHands; // + bool bU_108; // + bool adsBlurSceneEnabled; // + bool usesSniperScope; // + bool bU_112; // + bool bU_113; // + bool bU_114; // + bool bU_115; // + float xU_03_1; + float adsDofPhysicalFStop; // + float adsDofPhysicalFocusDistance; // + float autosimSpeedScalar; // + float explosionReactiveMotionParts[5]; // + char __pad_unknown[12]; // + }; static_assert(sizeof(WeaponDef) == 0xF08); + + static_assert(offsetof(WeaponDef, viewFlashEffect) == 248); + static_assert(offsetof(WeaponDef, usesSniperScope) == 3791); + static_assert(offsetof(WeaponDef, adsHideWeapon) == 3787); + static_assert(offsetof(WeaponDef, adsHideHands) == 3788); + static_assert(offsetof(WeaponDef, oldWeapon) == 3773); + static_assert(offsetof(WeaponDef, gunModel) == 0x28); + static_assert(offsetof(WeaponDef, handModel) == 0x30); + static_assert(offsetof(WeaponDef, szModeName) == 0x48); + static_assert(offsetof(WeaponDef, szXAnimsLeftHanded) == 88); + static_assert(offsetof(WeaponDef, hideTags) == 0x60); + static_assert(offsetof(WeaponDef, attachments) == 104); + static_assert(offsetof(WeaponDef, numReloadStateTimerOverrides) == 1480); + static_assert(offsetof(WeaponDef, viewFlashADSEffect) == 272); + static_assert(offsetof(WeaponDef, viewBodyFlashADSEffect) == 280); + static_assert(offsetof(WeaponDef, reticleCenter) == 1120); + static_assert(offsetof(WeaponDef, reticleSide) == 1128); + static_assert(offsetof(WeaponDef, projTrailEffect) == 3040); + static_assert(offsetof(WeaponDef, projBeaconEffect) == 3048); + static_assert(offsetof(WeaponDef, projIgnitionEffect) == 3080); + static_assert(offsetof(WeaponDef, projIgnitionSound) == 3088); + static_assert(offsetof(WeaponDef, accuracyGraphName) == 3280); + static_assert(offsetof(WeaponDef, accuracyGraphKnots) == 3296); + static_assert(offsetof(WeaponDef, originalAccuracyGraphKnots) == 3312); + static_assert(offsetof(WeaponDef, accuracyGraphName[1]) == 3288); + static_assert(offsetof(WeaponDef, accuracyGraphKnots[1]) == 3304); + static_assert(offsetof(WeaponDef, originalAccuracyGraphKnots[1]) == 3320); + static_assert(offsetof(WeaponDef, szScript) == 3448); + static_assert(offsetof(WeaponDef, stowTag) == 3688); + + static_assert(offsetof(WeaponDef, ammoIndex) == 1752); + static_assert(offsetof(WeaponDef, standMoveMinSpeed) == 1712); + static_assert(offsetof(WeaponDef, weapType) == 1484); + static_assert(offsetof(WeaponDef, altWeapon) == 1472); + static_assert(offsetof(WeaponDef, clipIndex) == 1760); + static_assert(offsetof(WeaponDef, burstFireCooldown) == 1520); + static_assert(offsetof(WeaponDef, greebleType) == 1524); + + struct cplane_s + { + float normal[3]; + float dist; + unsigned char type; + //unsigned char pad[3]; + }; assert_sizeof(cplane_s, 20); + + enum CSurfaceFlags : std::uint32_t + { + SURF_FLAG_DEFAULT = 0x00000000, + SURF_FLAG_BARK = 0x00100000, + SURF_FLAG_BRICK = 0x00200000, + SURF_FLAG_CARPET = 0x00300000, + SURF_FLAG_CLOTH = 0x00400000, + SURF_FLAG_CONCRETE = 0x00500000, + SURF_FLAG_DIRT = 0x00600000, + SURF_FLAG_FLESH = 0x00700000, + SURF_FLAG_FOLIAGE_DEBRIS = 0x00800000, + SURF_FLAG_GLASS = 0x00900000, + SURF_FLAG_GRASS = 0x00A00000, + SURF_FLAG_GRAVEL = 0x00B00000, + SURF_FLAG_ICE = 0x00C00000, + SURF_FLAG_METAL_SOLID = 0x00D00000, + SURF_FLAG_METAL_GRATE = 0x00E00000, + SURF_FLAG_MUD = 0x00F00000, + SURF_FLAG_PAPER = 0x01000000, + SURF_FLAG_PLASTER = 0x01100000, + SURF_FLAG_ROCK = 0x01200000, + SURF_FLAG_SAND = 0x01300000, + SURF_FLAG_SNOW = 0x01400000, + SURF_FLAG_WATER_WAIST = 0x01500000, + SURF_FLAG_WOOD_SOLID = 0x01600000, + SURF_FLAG_ASPHALT = 0x01700000, + SURF_FLAG_CERAMIC = 0x01800000, + SURF_FLAG_PLASTIC_SOLID = 0x01900000, + SURF_FLAG_RUBBER = 0x01A00000, + SURF_FLAG_FRUIT = 0x01B00000, + SURF_FLAG_PAINTEDMETAL = 0x01C00000, + SURF_FLAG_RIOTSHIELD = 0x01D00000, + SURF_FLAG_SLUSH = 0x01E00000, + SURF_FLAG_ASPHALT_WET = 0x01F00000, + SURF_FLAG_ASPHALT_DEBRIS = 0x02000000, + SURF_FLAG_CONCRETE_WET = 0x02100000, + SURF_FLAG_CONCRETE_DEBRIS = 0x02200000, + SURF_FLAG_FOLIAGE_VEGETATION = 0x02300000, + SURF_FLAG_FOLIAGE_LEAVES = 0x02400000, + SURF_FLAG_GRASS_TALL = 0x02500000, + SURF_FLAG_METAL_HOLLOW = 0x02600000, + SURF_FLAG_METAL_VEHICLE = 0x02700000, + SURF_FLAG_METAL_THIN = 0x02800000, + SURF_FLAG_METAL_WET = 0x02900000, + SURF_FLAG_METAL_DEBRIS = 0x02A00000, + SURF_FLAG_PLASTIC_HOLLOW = 0x02B00000, + SURF_FLAG_PLASTIC_TARP = 0x02C00000, + SURF_FLAG_ROCK_WET = 0x02D00000, + SURF_FLAG_ROCK_DEBRIS = 0x02E00000, + SURF_FLAG_WATER_ANKLE = 0x02F00000, + SURF_FLAG_WATER_KNEE = 0x03000000, + SURF_FLAG_WATER_HOLLOW = 0x03100000, + SURF_FLAG_WOOD_HOLLOW = 0x03200000, + SURF_FLAG_WOOD_DEBRIS = 0x03300000, + SURF_FLAG_CUSHION = 0x03400000, + SURF_FLAG_CLIPMISSILE = 0x00000000, + SURF_FLAG_AI_NOSIGHT = 0x00000000, + SURF_FLAG_CLIPSHOT = 0x00000000, + SURF_FLAG_PLAYERCLIP = 0x00000000, + SURF_FLAG_MONSTERCLIP = 0x00000000, + SURF_FLAG_AICLIPALLOWDEATH = 0x00000000, + SURF_FLAG_VEHICLECLIP = 0x00000000, + SURF_FLAG_ITEMCLIP = 0x00000000, + SURF_FLAG_NODROP = 0x00000000, + SURF_FLAG_NONSOLID = 0x00004000, + SURF_FLAG_NOGRAPPLE = 0x00008000, + SURF_FLAG_DETAIL = 0x00000000, + SURF_FLAG_STRUCTURAL = 0x00000000, + SURF_FLAG_PORTAL = 0x80000000, + SURF_FLAG_CANSHOOTCLIP = 0x00000000, + SURF_FLAG_ORIGIN = 0x00000000, + SURF_FLAG_SKY = 0x00000004, + SURF_FLAG_NOCASTSHADOW = 0x00040000, + SURF_FLAG_PHYSICSGEOM = 0x00000000, + SURF_FLAG_LIGHTPORTAL = 0x00000000, + SURF_FLAG_OUTDOORBOUNDS = 0x00000000, + SURF_FLAG_SLICK = 0x00000002, + SURF_FLAG_NOIMPACT = 0x00000010, + SURF_FLAG_NOMARKS = 0x00000020, + SURF_FLAG_NOPENETRATE = 0x00000100, + SURF_FLAG_LADDER = 0x00000008, + SURF_FLAG_NODAMAGE = 0x00000001, + SURF_FLAG_MANTLEON = 0x04000000, + SURF_FLAG_MANTLEOVER = 0x08000000, + SURF_FLAG_STAIRS = 0x00000200, + SURF_FLAG_SOFT = 0x00001000, + SURF_FLAG_NOSTEPS = 0x00002000, + SURF_FLAG_NODRAW = 0x00000080, + SURF_FLAG_NOLIGHTMAP = 0x00000400, + SURF_FLAG_NODLIGHT = 0x00020000, + SURF_FLAG_TRANSSORT = 0x00080000, + }; + + struct ClipMaterial + { + const char* name; + int surfaceFlags; + int contents; + }; assert_sizeof(ClipMaterial, 16); + + struct cLeafBrushNodeLeaf_t + { + unsigned short* brushes; + }; + + struct cLeafBrushNodeChildren_t + { + float dist; + float range; + unsigned short childOffset[2]; + }; + + union cLeafBrushNodeData_t + { + cLeafBrushNodeLeaf_t leaf; + cLeafBrushNodeChildren_t children; + }; + + struct cLeafBrushNode_s + { + unsigned char axis; + short leafBrushCount; + int contents; + cLeafBrushNodeData_t data; + }; assert_sizeof(cLeafBrushNode_s, 24); + + typedef unsigned short LeafBrush; + + struct BrushesCollisionTree + { + unsigned int leafbrushNodesCount; + cLeafBrushNode_s* leafbrushNodes; + unsigned int numLeafBrushes; + LeafBrush* leafbrushes; + }; assert_sizeof(BrushesCollisionTree, 32); + + union CollisionAabbTreeIndex + { + int firstChildIndex; + int partitionIndex; + }; + + struct CollisionAabbTree + { + float midPoint[3]; + unsigned short materialIndex; + unsigned short childCount; + float halfSize[3]; + CollisionAabbTreeIndex u; + }; assert_sizeof(CollisionAabbTree, 32); + + struct PatchesCollisionTree + { + int aabbTreeCount; + CollisionAabbTree* aabbTrees; + }; assert_sizeof(PatchesCollisionTree, 16); + + struct SModelAabbNode + { + Bounds bounds; + unsigned short firstChild; + unsigned short childCount; + }; assert_sizeof(SModelAabbNode, 28); + + struct SModelsCollisionTree + { + unsigned short numStaticModels; + unsigned short smodelNodeCount; + SModelAabbNode* smodelNodes; + }; assert_sizeof(SModelsCollisionTree, 16); + + struct cbrushside_t + { + unsigned int planeIndex; + unsigned short materialNum; + unsigned char firstAdjacentSideOffset; + unsigned char edgeCount; + }; assert_sizeof(cbrushside_t, 8); + + typedef unsigned char cbrushedge_t; + + struct cbrush_t + { + unsigned short numsides; + unsigned short glassPieceIndex; + cbrushside_t* sides; + cbrushedge_t* baseAdjacentSide; + short axialMaterialNum[2][3]; + unsigned char firstAdjacentSideOffsets[2][3]; + unsigned char edgeCount[2][3]; + }; assert_sizeof(cbrush_t, 48); + assert_offsetof(cbrush_t, sides, 8); + + struct BrushesCollisionData + { + unsigned int numBrushSides; + cbrushside_t* brushSides; + unsigned int numBrushEdges; + cbrushedge_t* brushEdges; + unsigned int numBrushes; + cbrush_t* brushes; + Bounds* brushBounds; + int* brushContents; + }; + + static_assert(sizeof(BrushesCollisionData) == 0x40); + + struct CollisionBorder + { + float distEq[3]; + float zBase; + float zSlope; + float start; + float length; + }; assert_sizeof(CollisionBorder, 28); + + struct CollisionPartition + { + unsigned char triCount; + unsigned char borderCount; + unsigned char firstVertSegment; + int firstTri; + CollisionBorder* borders; + }; assert_sizeof(CollisionPartition, 16); + + struct PatchesCollisionData + { + unsigned int vertCount; + vec3_t* verts; + int triCount; + unsigned short* triIndices; + unsigned char* triEdgeIsWalkable; + int borderCount; + CollisionBorder* borders; + int partitionCount; + CollisionPartition* partitions; + }; assert_sizeof(PatchesCollisionData, 72); + + struct cStaticModel_s + { + XModel* xmodel; + float origin[3]; + float invScaledAxis[3][3]; + Bounds absBounds; + int lightingHandle; + }; assert_sizeof(cStaticModel_s, 88); + + struct SModelsCollisionData + { + unsigned int numStaticModels; + cStaticModel_s* staticModelList; + }; assert_sizeof(SModelsCollisionData, 16); + + struct ClipInfo + { + int planeCount; + cplane_s* planes; + unsigned int numMaterials; + ClipMaterial* materials; + BrushesCollisionTree bCollisionTree; + PatchesCollisionTree pCollisionTree; + SModelsCollisionTree sCollisionTree; + BrushesCollisionData bCollisionData; + PatchesCollisionData pCollisionData; + SModelsCollisionData sCollisionData; + }; assert_sizeof(ClipInfo, 0xF8); + assert_offsetof(ClipInfo, planes, 8); + assert_offsetof(ClipInfo, bCollisionTree, 32); + assert_offsetof(ClipInfo, pCollisionTree, 64); + assert_offsetof(ClipInfo, sCollisionTree, 80); + assert_offsetof(ClipInfo, bCollisionData, 96); + assert_offsetof(ClipInfo, pCollisionData, 160); + assert_offsetof(ClipInfo, sCollisionData, 232); + assert_offsetof(ClipInfo, bCollisionData.brushes, 136); + + struct cNode_t + { + cplane_s* plane; + short children[2]; + }; assert_sizeof(cNode_t, 16); + + struct cLeaf_t + { + unsigned int firstCollAabbIndex; + unsigned int collAabbCount; + int brushContents; + int terrainContents; + Bounds bounds; + int leafBrushNode; + }; assert_sizeof(cLeaf_t, 44); + + struct cmodel_t + { + Bounds bounds; + float radius; + ClipInfo* info; + cLeaf_t leaf; + }; assert_sizeof(cmodel_t, 88); + + assert_offsetof(cmodel_t, info, 32); + + struct Stage + { + const char* name; + float origin[3]; + unsigned short triggerIndex; + unsigned char sunPrimaryLightIndex; + unsigned int unk; + }; assert_sizeof(Stage, 32); + + enum DynEntityType : std::int32_t + { + DYNENT_TYPE_INVALID = 0x0, + DYNENT_TYPE_CLUTTER = 0x1, + DYNENT_TYPE_DESTRUCT = 0x2, + DYNENT_TYPE_HINGE = 0x3, + DYNENT_TYPE_SCRIPTABLEINST = 0x4, + DYNENT_TYPE_SCRIPTABLEPHYSICS = 0x5, + DYNENT_TYPE_LINKED = 0x6, + DYNENT_TYPE_LINKED_NOSHADOW = 0x7, + DYNENT_TYPE_COUNT = 0x8, + }; + + struct GfxPlacement + { + float quat[4]; + float origin[3]; + }; + + struct DynEntityHingeDef + { + float axisOrigin[3]; + float axisDir[3]; + bool isLimited; + float angleMin; + float angleMax; + float momentOfInertia; + float friction; + }; assert_sizeof(DynEntityHingeDef, 44); + + struct DynEntityLinkToDef + { + int anchorIndex; + float originOffset[3]; + float angleOffset[3]; + }; assert_sizeof(DynEntityLinkToDef, 28); + + struct DynEntityDef + { + DynEntityType type; + GfxPlacement pose; + XModel* baseModel; + unsigned short brushModel; + unsigned short physicsBrushModel; + unsigned short scriptableIndex; + unsigned short health; + FxEffectDef* destroyFx; + snd_alias_list_t* sound; + PhysPreset* physPreset; + DynEntityHingeDef* hinge; + DynEntityLinkToDef* linkTo; + PhysMass mass; + int contents; + char __pad0[8]; + }; assert_sizeof(DynEntityDef, 136); + + struct DynEntityPose + { + GfxPlacement pose; + float radius; + char __pad0[4]; + }; assert_sizeof(DynEntityPose, 36); + + struct Hinge + { + float angle; + float quat[4]; + float angularVel; + float torqueAccum; + bool active; + float autoDisableTimeLeft; + DynEntityHingeDef* def; + PhysPreset* physPreset; + float centerOfMassRelToAxisOriginAtAngleZero[3]; + }; + + struct DynEntityClient + { + __int64 physObjId; + unsigned short flags; + unsigned short lightingHandle; + unsigned short health; + Hinge* hinge; + XModel* activeModel; + int contents; + }; assert_sizeof(DynEntityClient, 40); + + struct DynEntityColl + { + unsigned short sector; + unsigned short nextEntInSector; + float linkMins[2]; + float linkMaxs[2]; + }; assert_sizeof(DynEntityColl, 20); + + enum ScriptableEventType : std::int32_t + { + SCRIPTABLE_EVENT_MODEL = 0x0, + SCRIPTABLE_EVENT_FX = 0x1, + SCRIPTABLE_EVENT_STOP_FX = 0x2, + SCRIPTABLE_EVENT_SOUND = 0x3, + SCRIPTABLE_EVENT_ANIMATION = 0x4, + SCRIPTABLE_EVENT_EXPLODE = 0x5, + SCRIPTABLE_EVENT_HEALTHDRAIN = 0x6, + SCRIPTABLE_EVENT_PHYSICSLAUNCH = 0x7, + SCRIPTABLE_EVENT_LIGHTSETTINGS = 0x8, + SCRIPTABLE_EVENT_SUNLIGHTSETTINGS = 0x9, + SCRIPTABLE_EVENT_SHAKE = 0xA, + SCRIPTABLE_EVENT_TRANSLATE = 0xB, + SCRIPTABLE_EVENT_ROTATE = 0xC, + SCRIPTABLE_EVENT_STATECHANGE = 0xD, + SCRIPTABLE_EVENT_COUNT = 0xE, + }; + + struct ScriptableEventModelDef + { + XModel* model; + }; assert_sizeof(ScriptableEventModelDef, 8); + + struct ScriptableEventFxDef + { + FxEffectDef* handle; + scr_string_t tagName; + unsigned short loopTime; + unsigned char loopTimeStreamIndex; + bool tagUseAngles; + }; assert_sizeof(ScriptableEventFxDef, 16); + + struct ScriptableEventStopFxDef + { + FxEffectDef* handle; + scr_string_t tagName; + unsigned short loopTime; + unsigned char loopTimeStreamIndex; + bool tagUseAngles; + }; assert_sizeof(ScriptableEventFxDef, 16); + + struct ScriptableEventSoundDef + { + snd_alias_list_t* alias; + bool looping; + }; assert_sizeof(ScriptableEventSoundDef, 16); + + struct ScriptableEventAnimationDef + { + const char* animName; + bool override; + bool stateful; + unsigned char animEntryIndex; + unsigned char animPlaybackStreamIndex; + unsigned short timeOffsetMin; + unsigned short timeOffsetMax; + unsigned short playbackRateMin; + unsigned short playbackRateMax; + unsigned short blendTime; + }; assert_sizeof(ScriptableEventAnimationDef, 24); + + struct ScriptableEventExplodeDef + { + unsigned short forceMin; + unsigned short forceMax; + unsigned short radius; + unsigned short damageMin; + unsigned short damageMax; + bool aiAvoid; + }; assert_sizeof(ScriptableEventExplodeDef, 12); + + struct ScriptableEventHealthDef + { + unsigned short amount; + unsigned short interval; + unsigned short badPlaceRadius; + unsigned char streamIndex; + }; assert_sizeof(ScriptableEventHealthDef, 8); + + struct ScriptableEventPhysicsDef + { + XModel* model; + unsigned char launchDirX; + unsigned char launchDirY; + unsigned char launchDirZ; + unsigned short explForceScale; + unsigned short bulletForceScale; + }; assert_sizeof(ScriptableEventPhysicsDef, 16); + + struct ScriptableEventLightSettingsDef + { + unsigned char color[4]; + unsigned char lightIndexConstIndex; + unsigned char transStateStreamIndex; + unsigned char useColor; + unsigned char useStateTransitionTime; + unsigned short intensityScaleMin; + unsigned short intensityScaleMax; + unsigned short radiusScaleMin; + unsigned short radiusScaleMax; + unsigned short transitionTimeMin; + unsigned short transitionTimeMax; + const char* noteworthy; + }; assert_sizeof(ScriptableEventLightSettingsDef, 32); + assert_offsetof(ScriptableEventLightSettingsDef, noteworthy, 24); + + struct ScriptableEventSunlightSettingsDef + { + unsigned char color[4]; + unsigned char transStateStreamIndex; + unsigned char flags; + unsigned short intensityScaleMin; + unsigned short intensityScaleMax; + unsigned short pitchMin; + unsigned short pitchMax; + unsigned short headingMin; + unsigned short headingMax; + unsigned short transitionTimeMin; + unsigned short transitionTimeMax; + char __pad0[6]; + }; assert_sizeof(ScriptableEventSunlightSettingsDef, 28); + + struct ScriptableEventShakeDef + { + const char* rumbleName; + unsigned short duration; + unsigned short durationFadeUp; + unsigned short durationFadeDown; + unsigned short radius; + unsigned short exponent; + unsigned short scaleEarthquake; + unsigned char scalePitch; + unsigned char scaleYaw; + unsigned char scaleRoll; + unsigned char frequencyPitch; + unsigned char frequencyYaw; + unsigned char frequencyRoll; + unsigned char flags; + }; assert_sizeof(ScriptableEventShakeDef, 32); + + struct ScriptableEventTranslateDef + { + char __pad0[24]; + const char* str; + }; assert_sizeof(ScriptableEventTranslateDef, 32); + + struct ScriptableEventRotateDef + { + char __pad0[24]; + const char* str; + }; assert_sizeof(ScriptableEventTranslateDef, 32); + + struct ScriptableEventStateChangeDef + { + unsigned char targetIndex; + unsigned char delayStreamIndex; + unsigned short delayMin; + unsigned short delayMax; + }; assert_sizeof(ScriptableEventStateChangeDef, 6); + + union ScriptableEventDataUnion + { + ScriptableEventModelDef setModel; + ScriptableEventFxDef playFx; + ScriptableEventStopFxDef stopFx; + ScriptableEventSoundDef playSound; + ScriptableEventAnimationDef playAnim; + ScriptableEventExplodeDef doExplosion; + ScriptableEventHealthDef healthDrain; + ScriptableEventPhysicsDef physicsLaunch; + ScriptableEventLightSettingsDef lightSettings; + ScriptableEventSunlightSettingsDef sunlightSettings; + ScriptableEventShakeDef shake; + ScriptableEventTranslateDef translate; + ScriptableEventRotateDef rotate; + ScriptableEventStateChangeDef stateChange; + }; + + struct ScriptableEventDef + { + ScriptableEventType type; + ScriptableEventDataUnion data; + }; + + struct ScriptableStateDef + { + scr_string_t name; + scr_string_t tagName; + ScriptableEventDef* onEnterEvents; + unsigned char onEnterEventCount; + unsigned char damageFlags; + unsigned char damageParentTransferRate; + unsigned char damageParentReceiveRate; + unsigned short maxHealth; + }; assert_sizeof(ScriptableStateDef, 24); + + struct ScriptablePartDef + { + ScriptableStateDef* states; + scr_string_t name; + unsigned char stateCount; + unsigned char flags; + unsigned char eventStreamTimeRemainIndex; + unsigned char eventStreamNextChangeTimeIndex; + }; assert_sizeof(ScriptablePartDef, 16); + + enum ScriptableNotetrackType : std::int32_t + { + SCRIPTABLE_NT_FX = 0x0, + SCRIPTABLE_NT_SOUND = 0x1, + SCRIPTABLE_NT_COUNT = 0x2, + }; + + struct ScriptableNotetrackFxDef + { + FxEffectDef* handle; + scr_string_t tagName; + bool useAngles; + }; + + struct ScriptableNotetrackSoundDef + { + snd_alias_list_t* alias; + }; + + union ScriptableNotetrackDataUnion + { + ScriptableNotetrackFxDef playFx; + ScriptableNotetrackSoundDef playSound; + }; + + struct ScriptableNotetrackDef + { + scr_string_t name; + ScriptableNotetrackType type; + ScriptableNotetrackDataUnion data; + }; + + enum ScriptableType : std::int32_t + { + SCRIPTABLE_TYPE_GENERAL = 0x0, + SCRIPTABLE_TYPE_CHARACTER = 0x1, + SCRIPTABLE_TYPE_COUNT = 0x2, + }; + + struct ScriptableDef + { + const char* name; + XModel* baseModel; + const char* baseCollisionBrush; + const char* destroyedCollisionBrush; + ScriptablePartDef* parts; + ScriptableNotetrackDef* notetracks; + ScriptableType type; + unsigned char flags; + unsigned char partCount; + unsigned char serverInstancePartCount; + unsigned char serverControlledPartCount; + unsigned char notetrackCount; + unsigned char eventStreamSize; + unsigned char eventConstantsSize; + }; assert_sizeof(ScriptableDef, 0x40); + assert_offsetof(ScriptableDef, partCount, 53); + assert_offsetof(ScriptableDef, eventConstantsSize, 58); + + struct ScriptableInstanceTargetData + { + char __pad0[68]; + }; assert_sizeof(ScriptableInstanceTargetData, 68); + + struct ScriptableInstancePartState + { + unsigned short curHealth; + unsigned char lastExecutedStateIndex; + unsigned char stateIndex; + }; assert_sizeof(ScriptableInstancePartState, 4); + + struct ScriptableInstance + { + ScriptableDef* def; + unsigned char* eventConstantsBuf; + ScriptableInstanceTargetData* targetData; + float origin[3]; + float angles[3]; + char __pad0[24]; + scr_string_t targetname; + unsigned short preBrushModel; + unsigned short postBrushModel; + unsigned char flags; + unsigned char targetDataCount; + char __pad1[6]; + XModel* currentModel; + ScriptableInstancePartState* partStates; + unsigned char* eventStreamBuf; + unsigned int currentPartBits[8]; + unsigned int damageOwnerEntHandle; + unsigned short updateNextInstance; + unsigned short linkedObject; + }; assert_sizeof(ScriptableInstance, 152); + assert_offsetof(ScriptableInstance, targetData, 16); + assert_offsetof(ScriptableInstance, targetname, 72); + assert_offsetof(ScriptableInstance, currentModel, 88); + assert_offsetof(ScriptableInstance, partStates, 96); + assert_offsetof(ScriptableInstance, eventStreamBuf, 104); + + struct ScriptableAnimationEntry + { + const char* animName; + unsigned __int64 runtimeBuf; + }; assert_sizeof(ScriptableAnimationEntry, 16); + + struct ScriptableMapEnts + { + unsigned int instanceStateSize; + unsigned int instanceCount; + unsigned int reservedInstanceCount; + ScriptableInstance* instances; + unsigned int animEntryCount; + ScriptableAnimationEntry* animEntries; + unsigned int replicatedInstanceCount; + }; assert_sizeof(ScriptableMapEnts, 48); + assert_offsetof(ScriptableMapEnts, instances, 16); + assert_offsetof(ScriptableMapEnts, animEntries, 32); + + struct sphere_tree_t + { + char __pad0[8]; + int unk_count; + char __pad1[4]; + unsigned int* unk; + char __pad2[8]; + }; assert_sizeof(sphere_tree_t, 32); + assert_offsetof(sphere_tree_t, unk_count, 8); + assert_offsetof(sphere_tree_t, unk, 16); + + struct sphere_tree_obj_t + { + char __pad0[20]; + }; assert_sizeof(sphere_tree_obj_t, 20); + + struct sphere_tree_data_t + { + int sphereTreeCount; + sphere_tree_t* sphereTree; + int sphereTreeObjCount; + sphere_tree_obj_t* sphereTreeObj; + }; assert_sizeof(sphere_tree_data_t, 32); + + struct grapple_magnet_t + { + char __pad0[40]; + }; assert_sizeof(grapple_magnet_t, 40); + + struct grapple_data_t + { + sphere_tree_data_t sphereTreeData; + grapple_magnet_t* magnet; + unsigned int magnetCount; + char __pad0[4]; + }; assert_sizeof(grapple_data_t, 48); + + struct /*alignas(128)*/ clipMap_t + { + const char* name; // 0 + int isInUse; // 8 + ClipInfo info; // 16 + ClipInfo* pInfo; // 264 + unsigned int numNodes; // 272 + cNode_t* nodes; // 280 + unsigned int numLeafs; // 288 + cLeaf_t* leafs; // 296 + unsigned int numSubModels; // 304 + cmodel_t* cmodels; // 312 + MapEnts* mapEnts; // 320 + Stage* stages; // 328 + unsigned char stageCount; // 336 + MapTriggers stageTrigger; // 344 + unsigned short dynEntCount[2]; + DynEntityDef* dynEntDefList[2]; + DynEntityPose* dynEntPoseList[2]; + DynEntityClient* dynEntClientList[2]; + DynEntityColl* dynEntCollList[2]; + unsigned int dynEntAnchorCount; // 464 + scr_string_t* dynEntAnchorNames; // 472 + ScriptableMapEnts scriptableMapEnts; // 480 + grapple_data_t grappleData; // 528 + unsigned int checksum; + char __pad0[60]; // alignment padding + }; assert_sizeof(clipMap_t, 0x280); + assert_offsetof(clipMap_t, info, 16); + assert_offsetof(clipMap_t, pInfo, 264); + assert_offsetof(clipMap_t, nodes, 280); + assert_offsetof(clipMap_t, leafs, 296); + assert_offsetof(clipMap_t, cmodels, 312); + assert_offsetof(clipMap_t, stageTrigger, 344); + assert_offsetof(clipMap_t, scriptableMapEnts, 480); + assert_offsetof(clipMap_t, grappleData, 528); + + + enum GfxLightType : std::uint8_t + { + GFX_LIGHT_TYPE_NONE = 0x0, + GFX_LIGHT_TYPE_DIR = 0x1, + GFX_LIGHT_TYPE_SPOT = 0x2, + GFX_LIGHT_TYPE_OMNI = 0x3, + GFX_LIGHT_TYPE_COUNT = 0x4, + GFX_LIGHT_TYPE_DIR_SHADOWMAP = 0x4, + GFX_LIGHT_TYPE_SPOT_SHADOWMAP = 0x5, + GFX_LIGHT_TYPE_OMNI_SHADOWMAP = 0x6, + GFX_LIGHT_TYPE_COUNT_WITH_SHADOWMAP_VERSIONS = 0x7, + GFX_LIGHT_TYPE_SPOT_SHADOWMAP_CUCOLORIS = 0x7, + GFX_LIGHT_TYPE_COUNT_WITH_ALL_VERSIONS = 0x8, + }; + + struct ComPrimaryLight + { + GfxLightType type; // 0 + unsigned char canUseShadowMap; // 1 + unsigned char needsDynamicShadows; // 2 + unsigned char exponent; // 3 + unsigned char isVolumetric; // 4 + char __pad0[3]; + float color[3]; // 8 12 16 + float color2[3]; // 8 12 16 + float dir[3]; // 20 24 28 + float up[3]; // 32 36 40 + float origin[3]; // 44 48 52 + float fadeOffset[2]; + float bulbRadius; + float bulbLength[3]; + float radius; // 80 + float cosHalfFovOuter; // 84 + float cosHalfFovInner; // 88 + float cosHalfFovExpanded; // 92 + float rotationLimit; // 96 + float translationLimit; // 100 + float cucRotationOffsetRad; // 104 + float cucRotationSpeedRad; // 108 + float cucScrollVector[2]; // 112 116 + float cucScaleVector[2]; // 120 124 + float cucTransVector[2]; // 128 132 + const char* defName; // 136 + }; + + assert_sizeof(ComPrimaryLight, 160); + assert_offsetof(ComPrimaryLight, defName, 152); + assert_offsetof(ComPrimaryLight, origin, 56); + assert_offsetof(ComPrimaryLight, dir, 32); + assert_offsetof(ComPrimaryLight, cosHalfFovOuter, 96); + assert_offsetof(ComPrimaryLight, rotationLimit, 108); + + struct ComPrimaryLightEnv + { + unsigned short primaryLightIndices[4]; + unsigned char numIndices; + }; assert_sizeof(ComPrimaryLightEnv, 10); + + struct ComWorld + { + const char* name; + int isInUse; + unsigned int primaryLightCount; + ComPrimaryLight* primaryLights; + unsigned int primaryLightEnvCount; + ComPrimaryLightEnv* primaryLightEnvs; + }; assert_sizeof(ComWorld, 0x28); + + struct G_GlassPiece + { + unsigned short damageTaken; + unsigned short collapseTime; + int lastStateChangeTime; + unsigned char impactDir; + unsigned char impactPos[2]; + }; assert_sizeof(G_GlassPiece, 12); + + struct G_GlassName + { + char* nameStr; + scr_string_t name; // set during runtime from nameStr, G_InitGlass + unsigned short pieceCount; + unsigned short* pieceIndices; + }; assert_sizeof(G_GlassName, 24); + + struct G_GlassData + { + G_GlassPiece* glassPieces; + unsigned int pieceCount; + unsigned short damageToWeaken; + unsigned short damageToDestroy; + unsigned int glassNameCount; + G_GlassName* glassNames; + unsigned char pad[108]; + }; assert_sizeof(G_GlassData, 0x90); + + struct GlassWorld + { + const char* name; + G_GlassData* g_glassData; + }; assert_sizeof(GlassWorld, 0x10); + + struct FxGlassDef + { + float halfThickness; + float texVecs[2][2]; + GfxColor color; + Material* material; + Material* materialShattered; + PhysPreset* physPreset; + FxEffectDef* pieceBreakEffect; + FxEffectDef* shatterEffect; + FxEffectDef* shatterSmallEffect; + FxEffectDef* crackDecalEffect; + snd_alias_list_t* damagedSound; + snd_alias_list_t* destroyedSound; + snd_alias_list_t* destroyedQuietSound; + char __pad[8]; + int numCrackRings; + bool isOpaque; + }; assert_sizeof(FxGlassDef, 120); + + struct FxSpatialFrame + { + float quat[4]; + float origin[3]; + }; + + struct $03A8A7B39FA20F64B5AB79125E07CD62 + { + FxSpatialFrame frame; + float radius; + float unk; + }; + + union FxGlassPiecePlace + { + $03A8A7B39FA20F64B5AB79125E07CD62 __s0; + unsigned int nextFree; + }; assert_sizeof(FxGlassPiecePlace, 36); + + struct FxGlassPieceState + { + float texCoordOrigin[2]; + unsigned int supportMask; + unsigned short initIndex; + unsigned short geoDataStart; + unsigned short lightingIndex; + unsigned char defIndex; + unsigned char pad[3]; + unsigned char vertCount; + unsigned char holeDataCount; + unsigned char crackDataCount; + unsigned char fanDataCount; + unsigned short flags; + float areaX2; + }; assert_sizeof(FxGlassPieceState, 32); + + struct FxGlassPieceDynamics + { + int fallTime; + __int64 physObjId; + __int64 physJointId; + float vel[3]; + float avel[3]; + }; assert_sizeof(FxGlassPieceDynamics, 48); + + struct FxGlassVertex + { + short x; + short y; + }; + + struct FxGlassHoleHeader + { + unsigned short uniqueVertCount; + unsigned char touchVert; + unsigned char pad[1]; + }; + + struct FxGlassCrackHeader + { + unsigned short uniqueVertCount; + unsigned char beginVertIndex; + unsigned char endVertIndex; + }; + + union FxGlassGeometryData + { + FxGlassVertex vert; + FxGlassHoleHeader hole; + FxGlassCrackHeader crack; + unsigned char asBytes[4]; + short anonymous[2]; + }; assert_sizeof(FxGlassGeometryData, 4); + + struct FxGlassInitPieceState + { + FxSpatialFrame frame; + float radius; + float texCoordOrigin[2]; + unsigned int supportMask; + unsigned int unkMask; + float areaX2; + unsigned short lightingIndex; + unsigned char defIndex; + unsigned char vertCount; + unsigned char fanDataCount; + unsigned char pad[1]; + }; assert_sizeof(FxGlassInitPieceState, 60); + + struct FxGlassSystem + { + int time; + int prevTime; + unsigned int defCount; + unsigned int pieceLimit; + unsigned int pieceWordCount; + unsigned int cellCount; + unsigned int activePieceCount; // + unsigned int firstFreePiece; // + unsigned int geoDataLimit; + unsigned int geoDataCount; + unsigned int initGeoDataCount; + // + FxGlassDef* defs; + FxGlassPiecePlace* piecePlaces; + FxGlassPieceState* pieceStates; + FxGlassPieceDynamics* pieceDynamics; + FxGlassGeometryData* geoData; + unsigned int* isInUse; + unsigned int* cellBits; + unsigned char* visData; + float(*linkOrg)[3]; + float* halfThickness; + unsigned short* lightingHandles; + FxGlassGeometryData* initGeoData; + bool needToCompactData; // + unsigned char initCount; // + float effectChanceAccum; // + int lastPieceDeletionTime; // + unsigned int initPieceCount; + FxGlassInitPieceState* initPieceStates; + }; assert_sizeof(FxGlassSystem, 168); + assert_offsetof(FxGlassSystem, initPieceStates, 160); + + struct FxWorld + { + const char* name; + FxGlassSystem glassSys; + }; assert_sizeof(FxWorld, 0xB0); + + struct GfxSky + { + int skySurfCount; + int* skyStartSurfs; + GfxImage* skyImage; + unsigned char skySamplerState; + Bounds bounds; + }; assert_sizeof(GfxSky, 56); + + struct mnode_t + { + unsigned short unk0; + unsigned short unk1; + }; + + struct GfxWorldDpvsPlanes + { + int cellCount; + cplane_s* planes; + mnode_t* nodes; + unsigned int* sceneEntCellBits; + }; assert_sizeof(GfxWorldDpvsPlanes, 32); + + assert_offsetof(GfxWorldDpvsPlanes, planes, 8); + assert_offsetof(GfxWorldDpvsPlanes, nodes, 16); + assert_offsetof(GfxWorldDpvsPlanes, sceneEntCellBits, 24); + + struct GfxCellTreeCount + { + int aabbTreeCount; + }; + + struct GfxAabbTree + { + Bounds bounds; + int childrenOffset; + unsigned short childCount; + unsigned short smodelIndexCount; + unsigned short* smodelIndexes; + int startSurfIndex; + unsigned short surfaceCount; + unsigned short pad; + }; assert_sizeof(GfxAabbTree, 48); + assert_offsetof(GfxAabbTree, childrenOffset, 24); + assert_offsetof(GfxAabbTree, childCount, 28); + assert_offsetof(GfxAabbTree, smodelIndexCount, 30); + assert_offsetof(GfxAabbTree, smodelIndexes, 32); + assert_offsetof(GfxAabbTree, startSurfIndex, 40); + assert_offsetof(GfxAabbTree, surfaceCount, 44); + + struct GfxCellTree + { + GfxAabbTree* aabbTree; + }; + + struct GfxPortal; + struct GfxPortalWritable + { + bool isQueued; + bool isAncestor; + unsigned char recursionDepth; + unsigned char hullPointCount; + float(*hullPoints)[2]; + GfxPortal* queuedParent; + }; + + struct DpvsPlane + { + float coeffs[4]; + }; + + struct GfxPortal + { + GfxPortalWritable writable; + DpvsPlane plane; + float(*vertices)[3]; + unsigned short cellIndex; + unsigned short closeDistance; + unsigned char vertexCount; + float hullAxis[2][3]; + }; assert_sizeof(GfxPortal, 80); + assert_offsetof(GfxPortal, vertices, 40); + assert_offsetof(GfxPortal, vertexCount, 52); + + struct GfxCell + { + Bounds bounds; + short portalCount; + unsigned char reflectionProbeCount; + unsigned char reflectionProbeReferenceCount; + GfxPortal* portals; + unsigned char* reflectionProbes; + unsigned char* reflectionProbeReferences; + }; assert_sizeof(GfxCell, 56); + assert_offsetof(GfxCell, portalCount, 24); + assert_offsetof(GfxCell, reflectionProbeCount, 26); + assert_offsetof(GfxCell, reflectionProbeReferenceCount, 27); + assert_offsetof(GfxCell, portals, 32); + assert_offsetof(GfxCell, reflectionProbes, 40); + assert_offsetof(GfxCell, reflectionProbeReferences, 48); + + struct GfxPortalGroupInfo + { + char __pad0[4]; + }; + + struct GfxPortalGroup + { + const char* group; + GfxPortalGroupInfo* info; + char __pad0[8]; + int infoCount; + }; + + assert_sizeof(GfxPortalGroup, 32); + assert_offsetof(GfxPortalGroup, infoCount, 24); + + struct GfxReflectionProbeVolume + { + unsigned short* data; + unsigned int count; + }; assert_sizeof(GfxReflectionProbeVolume, 16); + + struct GfxReflectionProbe + { + float origin[3]; + GfxReflectionProbeVolume* probeVolumes; + unsigned int probeVolumeCount; + }; assert_sizeof(GfxReflectionProbe, 32); + assert_offsetof(GfxReflectionProbe, probeVolumeCount, 24); + + struct GfxReflectionProbeReferenceOrigin + { + float origin[3]; + }; + + struct GfxReflectionProbeReference + { + unsigned char index; + }; + + struct GfxRawTexture + { + char __pad0[32]; + }; assert_sizeof(GfxRawTexture, 32); + + struct GfxLightmapArray + { + GfxImage* primary; + GfxImage* secondary; + }; + + struct GfxWorldVertex + { + float xyz[3]; + float binormalSign; + GfxColor color; + float texCoord[2]; + float lmapCoord[2]; + PackedUnitVec normal; + PackedUnitVec tangent; + }; assert_sizeof(GfxWorldVertex, 44); + + union GfxWorldVertex0Union + { + GfxWorldVertex* vertices; + }; + + struct GfxWorldVertexData + { + GfxWorldVertex* vertices; + ID3D11Buffer* worldVb; + ID3D11ShaderResourceView* worldVbView; + }; assert_sizeof(GfxWorldVertexData, 24); + + struct GfxWorldVertexLayerData + { + unsigned char* data; + ID3D11Buffer* layerVb; + ID3D11ShaderResourceView* layerVbView; + }; assert_sizeof(GfxWorldVertexLayerData, 24); + + struct GfxDisplacementParms + { + char __pad0[16]; + }; assert_sizeof(GfxDisplacementParms, 16); + + struct GfxWorldDraw + { + unsigned int reflectionProbeCount; + GfxImage** reflectionProbes; + GfxReflectionProbe* reflectionProbeOrigins; + GfxRawTexture* reflectionProbeTextures; + unsigned int reflectionProbeReferenceCount; + GfxReflectionProbeReferenceOrigin* reflectionProbeReferenceOrigins; + GfxReflectionProbeReference* reflectionProbeReferences; + int lightmapCount; + GfxLightmapArray* lightmaps; + GfxRawTexture* lightmapPrimaryTextures; + GfxRawTexture* lightmapSecondaryTextures; + GfxImage* lightmapOverridePrimary; + GfxImage* lightmapOverrideSecondary; + int u1[2]; + int u2[2]; + int u3; + unsigned int trisType; + unsigned int vertexCount; + GfxWorldVertexData vd; + unsigned int vertexLayerDataSize; + GfxWorldVertexLayerData vld; + unsigned int indexCount; + unsigned short* indices; + ID3D11Buffer* indexBuffer; + ID3D11ShaderResourceView* indexBufferView; + int displacementParmsCount; + GfxDisplacementParms* displacementParms; + ID3D11Buffer* displacementParmsBuffer; + ID3D11ShaderResourceView* displacementParmsBufferView; + }; assert_sizeof(GfxWorldDraw, 256); + assert_offsetof(GfxWorldDraw, reflectionProbeTextures, 24); + assert_offsetof(GfxWorldDraw, lightmaps, 64); + assert_offsetof(GfxWorldDraw, lightmapOverrideSecondary, 96); + assert_offsetof(GfxWorldDraw, vertexCount, 128); + assert_offsetof(GfxWorldDraw, vd, 136); + assert_offsetof(GfxWorldDraw, vld, 168); + assert_offsetof(GfxWorldDraw, indexCount, 192); + assert_offsetof(GfxWorldDraw, indices, 200); + assert_offsetof(GfxWorldDraw, displacementParmsCount, 224); + assert_offsetof(GfxWorldDraw, displacementParms, 232); + + struct GfxLightGridEntry + { + unsigned int colorsIndex; + unsigned short primaryLightEnvIndex; + unsigned char unused; + unsigned char needsTrace; + }; assert_sizeof(GfxLightGridEntry, 8); + + struct GfxLightGridColors + { + unsigned char colorVec6[56][6]; + }; assert_sizeof(GfxLightGridColors, 336); + + struct GfxLightGridColorsHDR + { + unsigned char colorVec6[56][6]; + }; assert_sizeof(GfxLightGridColorsHDR, 336); + + struct GfxLightGridTree + { + unsigned char maxDepth; + int nodeCount; + int leafCount; + int coordMinGridSpace[3]; + int coordMaxGridSpace[3]; + int coordHalfSizeGridSpace[3]; + int defaultColorIndexBitCount; + int defaultLightIndexBitCount; + unsigned int* p_nodeTable; + int leafTableSize; + unsigned char* p_leafTable; + }; assert_sizeof(GfxLightGridTree, 80); + + struct GfxLightGrid + { + bool hasLightRegions; + bool useSkyForLowZ; + unsigned int lastSunPrimaryLightIndex; + unsigned short mins[3]; + unsigned short maxs[3]; + unsigned int rowAxis; + unsigned int colAxis; + unsigned short* rowDataStart; + unsigned int rawRowDataSize; + unsigned char* rawRowData; + unsigned int entryCount; + GfxLightGridEntry* entries; + unsigned int colorCount; + GfxLightGridColors* colors; + char __pad0[24]; + int tableVersion; + int paletteVersion; + char rangeExponent8BitsEncoding; + char rangeExponent12BitsEncoding; + char rangeExponent16BitsEncoding; + unsigned char stageCount; + float* stageLightingContrastGain; + unsigned int paletteEntryCount; + int* paletteEntryAddress; + unsigned int paletteBitstreamSize; + unsigned char* paletteBitstream; + GfxLightGridColorsHDR skyLightGridColors; + GfxLightGridColorsHDR defaultLightGridColors; + GfxLightGridTree tree[3]; + }; assert_sizeof(GfxLightGrid, 1080); + assert_offsetof(GfxLightGrid, rowDataStart, 32); + assert_offsetof(GfxLightGrid, rawRowData, 48); + assert_offsetof(GfxLightGrid, entries, 64); + assert_offsetof(GfxLightGrid, colors, 80); + assert_offsetof(GfxLightGrid, paletteVersion, 116); + assert_offsetof(GfxLightGrid, rangeExponent8BitsEncoding, 120); + assert_offsetof(GfxLightGrid, stageCount, 123); + assert_offsetof(GfxLightGrid, stageLightingContrastGain, 128); + assert_offsetof(GfxLightGrid, paletteEntryCount, 136); + assert_offsetof(GfxLightGrid, paletteEntryAddress, 144); + assert_offsetof(GfxLightGrid, paletteBitstreamSize, 152); + assert_offsetof(GfxLightGrid, paletteBitstream, 160); + assert_offsetof(GfxLightGrid, tree, 840); + + struct GfxBrushModelWritable + { + Bounds bounds; + vec3_t origin; + vec4_t quat; + int mdaoVolumeProcessed; + }; + + struct GfxBrushModel + { + GfxBrushModelWritable writable; + Bounds bounds; + float radius; + unsigned int startSurfIndex; + unsigned short surfaceCount; + int mdaoVolumeIndex; + }; assert_sizeof(GfxBrushModel, 96); + + struct MaterialMemory + { + Material* material; + int memory; + }; assert_sizeof(MaterialMemory, 16); + + struct sunflare_t + { + bool hasValidData; + Material* spriteMaterial; + Material* flareMaterial; + float spriteSize; + float flareMinSize; + float flareMinDot; + float flareMaxSize; + float flareMaxDot; + float flareMaxAlpha; + int flareFadeInTime; + int flareFadeOutTime; + float blindMinDot; + float blindMaxDot; + float blindMaxDarken; + int blindFadeInTime; + int blindFadeOutTime; + float glareMinDot; + float glareMaxDot; + float glareMaxLighten; + int glareFadeInTime; + int glareFadeOutTime; + float sunFxPosition[3]; + }; assert_sizeof(sunflare_t, 112); + + struct XModelDrawInfo + { + unsigned char hasGfxEntIndex; + unsigned char lod; + unsigned short surfId; + }; + + struct GfxSceneDynModel + { + XModelDrawInfo info; + unsigned short dynEntId; + }; assert_sizeof(GfxSceneDynModel, 6); + + struct BModelDrawInfo + { + unsigned short surfId; + }; + + struct GfxSceneDynBrush + { + BModelDrawInfo info; + unsigned short dynEntId; + }; assert_sizeof(GfxSceneDynBrush, 4); + + struct GfxShadowGeometry + { + unsigned short surfaceCount; + unsigned short smodelCount; + unsigned int* sortedSurfIndex; + unsigned short* smodelIndex; + }; assert_sizeof(GfxShadowGeometry, 24); + + struct GfxLightRegionAxis + { + float dir[3]; + float midPoint; + float halfSize; + }; assert_sizeof(GfxLightRegionAxis, 20); + + struct GfxLightRegionHull + { + float kdopMidPoint[9]; + float kdopHalfSize[9]; + unsigned int axisCount; + GfxLightRegionAxis* axis; + }; assert_sizeof(GfxLightRegionHull, 88); + + struct GfxLightRegion + { + unsigned int hullCount; + GfxLightRegionHull* hulls; + }; assert_sizeof(GfxLightRegion, 16); + + struct GfxStaticModelInst + { + float mins[3]; + float maxs[3]; + float lightingOrigin[3]; + }; assert_sizeof(GfxStaticModelInst, 36); + + struct srfTriangles_t + { + unsigned int vertexLayerData; + unsigned int firstVertex; + float maxEdgeLength; + int unk; + unsigned short vertexCount; + unsigned short triCount; + unsigned int baseIndex; + }; + + struct GfxSurfaceLightingAndFlagsFields + { + unsigned char lightmapIndex; + unsigned char reflectionProbeIndex; + unsigned short primaryLightEnvIndex; + unsigned char flags; + unsigned char unused[3]; + }; + + union GfxSurfaceLightingAndFlags + { + GfxSurfaceLightingAndFlagsFields fields; + unsigned __int64 packed; + }; + + struct GfxSurface + { + srfTriangles_t tris; + Material* material; + GfxSurfaceLightingAndFlags laf; + }; assert_sizeof(GfxSurface, 40); + assert_offsetof(GfxSurface, material, 24); + + struct GfxSurfaceBounds + { + Bounds bounds; + char __pad0[11]; + char flags; + }; assert_sizeof(GfxSurfaceBounds, 36); + + struct GfxPackedPlacement + { + float origin[3]; + float axis[3][3]; + float scale; + }; + + enum StaticModelFlag : std::int16_t + { + STATIC_MODEL_FLAG_NO_CAST_SHADOW = 0x10, + STATIC_MODEL_FLAG_GROUND_LIGHTING = 0x20, + STATIC_MODEL_FLAG_LIGHTGRID_LIGHTING = 0x40, + STATIC_MODEL_FLAG_VERTEXLIT_LIGHTING = 0x80, + STATIC_MODEL_FLAG_LIGHTMAP_LIGHTING = 0x100, + STATIC_MODEL_FLAG_ALLOW_FXMARK = 0x200, + STATIC_MODEL_FLAG_REACTIVEMOTION = 0x400, + STATIC_MODEL_FLAG_ANIMATED_VERTS = 0x800, + }; + + struct GfxStaticModelDrawInst + { + XModel* model; + GfxPackedPlacement placement; + unsigned short cullDist; + unsigned short flags; + unsigned short lightingHandle; + unsigned short staticModelId; + short pad; + unsigned short primaryLightEnvIndex; + char unk; + unsigned char reflectionProbeIndex; + unsigned char firstMtlSkinIndex; + unsigned char sunShadowFlags; + }; + assert_sizeof(GfxStaticModelDrawInst, 80); + assert_offsetof(GfxStaticModelDrawInst, model, 0); + assert_offsetof(GfxStaticModelDrawInst, cullDist, 60); + assert_offsetof(GfxStaticModelDrawInst, flags, 62); + assert_offsetof(GfxStaticModelDrawInst, lightingHandle, 64); + assert_offsetof(GfxStaticModelDrawInst, primaryLightEnvIndex, 70); + assert_offsetof(GfxStaticModelDrawInst, reflectionProbeIndex, 73); // maybe wrong + assert_offsetof(GfxStaticModelDrawInst, firstMtlSkinIndex, 74); + + struct GfxStaticModelVertexLighting + { + unsigned char visibility[4]; + unsigned short ambientColorFloat16[4]; + unsigned short highlightColorFloat16[4]; + }; assert_sizeof(GfxStaticModelVertexLighting, 20); + + struct GfxStaticModelVertexLightingInfo + { + GfxStaticModelVertexLighting* lightingValues; + ID3D11Buffer* lightingValuesVb; + int numLightingValues; + }; + + struct GfxStaticModelLightmapInfo + { + unsigned short smodelCacheIndex[4]; + unsigned short unk1; + unsigned short unk2; + float unk3; + int unk4; + int unk5; + /* + unsigned short V0[4]; + unsigned short V1[4]; + unsigned short V2[4]; + */ + }; + + struct GfxStaticModelLighting + { + union + { + GfxStaticModelVertexLightingInfo info; + GfxStaticModelLightmapInfo info2; + }; + }; assert_sizeof(GfxStaticModelLighting, 24); + + struct GfxSubdivVertexLightingInfo + { + int vertexLightingIndex; + ID3D11Buffer* vb; + GfxSubdivCache cache; + }; assert_sizeof(GfxSubdivVertexLightingInfo, 40); + + struct GfxDepthAndSurf + { + char __pad0[8]; + }; assert_sizeof(GfxDepthAndSurf, 8); + + typedef char* GfxWorldDpvsVoid; + + struct GfxWorldDpvsUnk + { + char __pad0[8]; + GfxStaticModelVertexLightingInfo info; + char __pad1[24]; + }; + + assert_sizeof(GfxWorldDpvsUnk, 56); + + struct GfxWorldDpvsStatic + { + unsigned int smodelCount; // 0 + unsigned int subdivVertexLightingInfoCount; // 4 + unsigned int staticSurfaceCount; // 8 + unsigned int litOpaqueSurfsBegin; // 12 + unsigned int litOpaqueSurfsEnd; // 16 + unsigned int unkSurfsBegin; + unsigned int unkSurfsEnd; + unsigned int litDecalSurfsBegin; // 28 + unsigned int litDecalSurfsEnd; // 32 + unsigned int litTransSurfsBegin; // 36 + unsigned int litTransSurfsEnd; // 40 + unsigned int shadowCasterSurfsBegin; // 44 + unsigned int shadowCasterSurfsEnd; // 48 + unsigned int emissiveSurfsBegin; // 52 + unsigned int emissiveSurfsEnd; // 56 + unsigned int smodelVisDataCount; // 60 + unsigned int surfaceVisDataCount; // 64 + unsigned int unkCount1; // 68 + unsigned int* smodelVisData[4]; // 72 80 88 96 + unsigned int* smodelUnknownVisData[27]; + unsigned int* surfaceVisData[4]; // 320 328 336 344 + unsigned int* surfaceUnknownVisData[27]; + unsigned int* smodelUmbraVisData[4]; // 568 576 584 592 + unsigned int* surfaceUmbraVisData[4]; // 600 608 616 624 + unsigned int unkCount2; // 632 + unsigned int* lodData; // 640 + unsigned int* tessellationCutoffVisData; // 648 + unsigned int* sortedSurfIndex; // 656 + GfxStaticModelInst* smodelInsts; // 664 + GfxSurface* surfaces; // 672 + GfxSurfaceBounds* surfacesBounds; // 680 + GfxStaticModelDrawInst* smodelDrawInsts; // 688 + unsigned int* unknownSModelVisData1; // 696 + unsigned int* unknownSModelVisData2; // 704 + GfxStaticModelLighting* smodelLighting; // 712 (array) + GfxSubdivVertexLightingInfo* subdivVertexLighting; // 720 (array) + GfxDrawSurf* surfaceMaterials; // 728 + unsigned int* surfaceCastsSunShadow; // 736 + unsigned int sunShadowOptCount; // 744 + unsigned int sunSurfVisDataCount; // 748 + unsigned int* surfaceCastsSunShadowOpt; // 752 + GfxDepthAndSurf* surfaceDeptAndSurf; // 760 + GfxWorldDpvsVoid* constantBuffersLit; // 768 + GfxWorldDpvsVoid* constantBuffersAmbient; // 776 + GfxWorldDpvsUnk* gfx_unk; // 784 + int usageCount; // 792 + }; + static_assert(sizeof(GfxWorldDpvsStatic) == 800); + assert_offsetof(GfxWorldDpvsStatic, smodelDrawInsts, 688); + assert_offsetof(GfxWorldDpvsStatic, surfaces, 672); + assert_offsetof(GfxWorldDpvsStatic, lodData, 640); + assert_offsetof(GfxWorldDpvsStatic, sortedSurfIndex, 656); + assert_offsetof(GfxWorldDpvsStatic, tessellationCutoffVisData, 648); + assert_offsetof(GfxWorldDpvsStatic, gfx_unk, 784); + assert_offsetof(GfxWorldDpvsStatic, sunShadowOptCount, 744); + assert_offsetof(GfxWorldDpvsStatic, sunSurfVisDataCount, 748); + assert_offsetof(GfxWorldDpvsStatic, surfaceCastsSunShadowOpt, 752); + assert_offsetof(GfxWorldDpvsStatic, surfaceDeptAndSurf, 760); + assert_offsetof(GfxWorldDpvsStatic, subdivVertexLighting, 720); + assert_offsetof(GfxWorldDpvsStatic, constantBuffersLit, 768); + assert_offsetof(GfxWorldDpvsStatic, constantBuffersAmbient, 776); + assert_offsetof(GfxWorldDpvsStatic, usageCount, 792); + assert_offsetof(GfxWorldDpvsStatic, unknownSModelVisData1, 696); + assert_offsetof(GfxWorldDpvsStatic, unkCount1, 68); + assert_offsetof(GfxWorldDpvsStatic, unkCount2, 632); + assert_offsetof(GfxWorldDpvsStatic, surfaceUmbraVisData, 600); + assert_offsetof(GfxWorldDpvsStatic, smodelInsts, 664); + + struct GfxWorldDpvsDynamic + { + unsigned int dynEntClientWordCount[2]; // 0 4 + unsigned int dynEntClientCount[2]; // 8 12 + unsigned int* dynEntCellBits[2]; // 16 24 + unsigned char* dynEntVisData[2][4]; // 32 40 48 56 64 72 80 88 + }; assert_sizeof(GfxWorldDpvsDynamic, 96); + + struct GfxHeroOnlyLight + { + unsigned char type; + unsigned char unused[3]; + float color[3]; + float dir[3]; + float up[3]; + float origin[3]; + float radius; + float cosHalfFovOuter; + float cosHalfFovInner; + int exponent; + }; assert_sizeof(GfxHeroOnlyLight, 68); + + typedef void* umbraTomePtr_t; + + struct GfxBuildInfo + { + const char* args0; + const char* args1; + const char* buildStartTime; + const char* buildEndTime; + }; assert_sizeof(GfxBuildInfo, 32); + + struct GfxWorld + { + const char* name; // 0 + const char* baseName; // 8 + unsigned int bspVersion; // 16 + int planeCount; // 20 + int nodeCount; // 24 + unsigned int surfaceCount; // 28 + int skyCount; // 32 + GfxSky* skies; // 40 + unsigned int portalGroupCount; // 48 + char __pad0[16]; + unsigned int lastSunPrimaryLightIndex; // 68 + unsigned int primaryLightCount; // 72 + unsigned int primaryLightEnvCount; // 76 + unsigned int sortKeyLitDecal; // 80 + unsigned int sortKeyEffectDecal; // 84 + unsigned int sortKeyTopDecal; // 88 + unsigned int sortKeyEffectAuto; // 92 + unsigned int sortKeyDistortion; // 96 + unsigned int sortKeyHair; // 100 + unsigned int sortKeyEffectBlend; // 104 + char __pad1[4]; // 108 + GfxWorldDpvsPlanes dpvsPlanes; // 112 + GfxCellTreeCount* aabbTreeCounts; // 144 + GfxCellTree* aabbTrees; // 152 + GfxCell* cells; // 160 + GfxPortalGroup* portalGroup; // 168 + int unk_vec4_count_0; // 176 + char __pad2[4]; // 180 + vec4_t* unk_vec4_0; // 184 + GfxWorldDraw draw; // 192 + GfxLightGrid lightGrid; // 448 + int modelCount; // 1528 + GfxBrushModel* models; // 1536 + Bounds unkBounds; + Bounds shadowBounds; + unsigned int checksum; // 1592 + int materialMemoryCount; // 1596 + MaterialMemory* materialMemory; // 1600 + sunflare_t sun; // 1608 + float outdoorLookupMatrix[4][4]; // 1720 + GfxImage* outdoorImage; // 1784 + unsigned int* cellCasterBits; // 1792 + unsigned int* cellHasSunLitSurfsBits; // 1800 + GfxSceneDynModel* sceneDynModel; // 1808 + GfxSceneDynBrush* sceneDynBrush; // 1816 + unsigned int* primaryLightEntityShadowVis; // 1824 + unsigned int* primaryLightDynEntShadowVis[2]; // 1832 1840 + unsigned short* nonSunPrimaryLightForModelDynEnt; // 1848 + GfxShadowGeometry* shadowGeom; // 1856 + GfxShadowGeometry* shadowGeomOptimized; // 1864 + GfxLightRegion* lightRegion; // 1872 + GfxWorldDpvsStatic dpvs; // 1880 + GfxWorldDpvsDynamic dpvsDyn; // 2680 + unsigned int mapVtxChecksum; // 2776 + unsigned int heroOnlyLightCount; // 2780 + GfxHeroOnlyLight* heroOnlyLights; // 2784 + unsigned char fogTypesAllowed; // 2792 + unsigned int umbraTomeSize; // 2796 + char* umbraTomeData; // 2800 + umbraTomePtr_t umbraTomePtr; // 2808 + unsigned int mdaoVolumesCount; // 2816 + MdaoVolume* mdaoVolumes; // 2824 + char __pad3[32]; + GfxBuildInfo buildInfo; // 2864 + }; + + assert_offsetof(GfxWorld, skies, 40); + assert_offsetof(GfxWorld, sortKeyEffectBlend, 104); + assert_offsetof(GfxWorld, aabbTreeCounts, 144); + assert_offsetof(GfxWorld, portalGroup, 168); + assert_offsetof(GfxWorld, lightGrid, 448); + assert_offsetof(GfxWorld, modelCount, 1528); + assert_offsetof(GfxWorld, models, 1536); + assert_offsetof(GfxWorld, checksum, 1592); + assert_offsetof(GfxWorld, materialMemoryCount, 1596); + assert_offsetof(GfxWorld, sun, 1608); + assert_offsetof(GfxWorld, outdoorLookupMatrix, 1720); + assert_offsetof(GfxWorld, dpvsPlanes.nodes, 112 + 16); + assert_offsetof(GfxWorld, dpvs, 1880); + assert_offsetof(GfxWorld, dpvsPlanes, 112); + assert_offsetof(GfxWorld, primaryLightCount, 72); + assert_offsetof(GfxWorld, lastSunPrimaryLightIndex, 68); + assert_offsetof(GfxWorld, aabbTreeCounts, 144); + assert_offsetof(GfxWorld, portalGroupCount, 48); + assert_offsetof(GfxWorld, portalGroupCount, 48); + assert_offsetof(GfxWorld, mdaoVolumesCount, 2816); + assert_offsetof(GfxWorld, mdaoVolumes, 2824); + assert_offsetof(GfxWorld, umbraTomeData, 2800); + assert_offsetof(GfxWorld, umbraTomeSize, 2796); + assert_offsetof(GfxWorld, sceneDynBrush, 1816); + assert_offsetof(GfxWorld, models, 1536); + assert_offsetof(GfxWorld, umbraTomeSize, 2796); + assert_offsetof(GfxWorld, fogTypesAllowed, 2792); + assert_offsetof(GfxWorld, umbraTomeData, 2800); + assert_offsetof(GfxWorld, dpvsDyn, 2680); + assert_offsetof(GfxWorld, buildInfo, 2864); + assert_offsetof(GfxWorld, mdaoVolumesCount, 2816); + assert_offsetof(GfxWorld, mdaoVolumes, 2824); + + static_assert(sizeof(GfxWorld) == 0xB50); + + enum VehicleType + { + VEH_WHEELS_4 = 0x0, + VEH_TANK = 0x1, + VEH_PLANE = 0x2, + VEH_BOAT = 0x3, + VEH_ARTILLERY = 0x4, + VEH_HELICOPTER = 0x5, + VEH_SNOWMOBILE = 0x6, + VEH_SUBMARINE = 0x7, + VEH_UGV = 0x8, + VEH_TYPE_COUNT = 0x9, + }; + + enum VehicleAxleType + { + VEH_AXLE_FRONT = 0x0, + VEH_AXLE_REAR = 0x1, + VEH_AXLE_ALL = 0x2, + VEH_AXLE_COUNT = 0x3, + }; + + struct VehicleUnknown + { + char __pad[36]; + }; + + static_assert(sizeof(VehicleUnknown) == 36); + + struct VehiclePhysDef + { + int physicsEnabled; + const char* physPresetName; + PhysPreset* physPreset; + const char* unkString01; + VehicleUnknown* vehicleUnknown01; + const char* accelGraphName; + VehicleAxleType steeringAxle; + VehicleAxleType powerAxle; + VehicleAxleType brakingAxle; + float floatValues01[53]; + }; + + static_assert(offsetof(VehiclePhysDef, physPreset) == 16); + static_assert(offsetof(VehiclePhysDef, unkString01) == 24); + static_assert(offsetof(VehiclePhysDef, physPresetName) == 8); + static_assert(offsetof(VehiclePhysDef, vehicleUnknown01) == 32); + static_assert(offsetof(VehiclePhysDef, accelGraphName) == 40); + static_assert(sizeof(VehiclePhysDef) == 0x110); + + enum VehicleTurretFireType + { + VEH_TURRET_SINGLE_FIRE = 0x0, + VEH_TURRET_DUAL_FIRE = 0x1, + VEH_TURRET_ALT_FIRE = 0x2, + VEH_TURRET_FIRE_TYPE_COUNT = 0x3, + }; + + struct VehicleDef + { + const char* internalName; + VehicleType vehicleType; + const char* useHintString; + int health; + float floatValues01[37]; // 184 + int intValues01[8]; + VehiclePhysDef vehPhysDef; + float floatValues02[12]; // 48 + const char* unkString01; + FxEffectDef* effect01; // 536 + FxEffectDef* effect02; + FxEffectDef* effect03; + FxEffectDef* effect04; + FxEffectDef* effect05; + float floatValues03[7]; // 168 + int intValues02[1]; + float floatValues04[32]; // 168 + int vehHelicopterSoftCollisions; + int vehHelicopterUseGroundFX; + FxEffectDef* vehHelicopterGroundFx; + FxEffectDef* vehHelicopterGroundWaterFx; + float floatValues05[78]; + const char* unkString02; + float floatValues06[82]; + const char* turretWeaponName; + WeaponDef* turretWeapon; + float turretHorizSpanLeft; + float turretHorizSpanRight; + float turretVertSpanUp; + float turretVertSpanDown; + float turretHorizResistLeft; + float turretHorizResistRight; + float turretVertResistUp; + float turretVertResistDown; + float turretRotRate; + VehicleTurretFireType turretFireType; + snd_alias_list_t* turretSpinSnd; + snd_alias_list_t* turretStopSnd; + int trophyEnabled; + float trophyRadius; + float trophyInactiveRadius; + int trophyAmmoCount; + float trophyReloadTime; + scr_string_t trophyTags[4]; + FxEffectDef* trophyExplodeFx; + FxEffectDef* trophyFlashFx; + Material* compassFriendlyIcon; + Material* compassEnemyIcon; + Material* compassFriendlyAltIcon; + Material* compassEnemyAltIcon; + int compassIconWidth; + int compassIconHeight; + snd_alias_list_t* idleLowSnd; + snd_alias_list_t* idleHighSnd; + snd_alias_list_t* engineLowSnd; + snd_alias_list_t* engineHighSnd; + snd_alias_list_t* sound01; // rename + float engineSndSpeed; + scr_string_t audioOriginTag; + snd_alias_list_t* idleLowSndAlt; + snd_alias_list_t* idleHighSndAlt; + snd_alias_list_t* engineLowSndAlt; + snd_alias_list_t* engineHighSndAlt; + float engineSndSpeedAlt; + scr_string_t audioOriginTagAlt; + snd_alias_list_t* turretSpinSndAlt; + snd_alias_list_t* turretStopSndAlt; + snd_alias_list_t* engineStartUpSnd; + int engineStartUpLength; + snd_alias_list_t* engineShutdownSnd; + snd_alias_list_t* engineIdleSnd; + snd_alias_list_t* engineSustainSnd; + snd_alias_list_t* engineRampUpSnd; + int engineRampUpLength; + snd_alias_list_t* engineRampDownSnd; + int engineRampDownLength; + snd_alias_list_t* suspensionSoftSnd; + float suspensionSoftCompression; + snd_alias_list_t* suspensionHardSnd; + float suspensionHardCompression; + snd_alias_list_t* collisionSnd; + float collisionBlendSpeed; + snd_alias_list_t* speedSnd; + float speedSndBlendSpeed; + const char* surfaceSndPrefix; + snd_alias_list_t* surfaceSnds[53]; + float surfaceSndBlendSpeed; + float slideVolume; + float slideBlendSpeed; + float inAirPitch; + const char* soundTriggerOverrideZone; + bool soundTriggerOverrideReverb; + bool soundTriggerOverrideMix; + bool soundTriggerOverrideFilter; + bool soundTriggerOverrideOcclusion; + bool soundTriggerOverrideAmbient; + bool soundTriggerOverrideAmbientEvents; + bool soundTriggerOverrideADSR; + }; + + static_assert(offsetof(VehicleDef, unkString01) == 528); + static_assert(offsetof(VehicleDef, unkString02) == 1072); + static_assert(offsetof(VehicleDef, turretWeaponName) == 1408); + static_assert(offsetof(VehicleDef, turretSpinSnd) == 1464); + static_assert(offsetof(VehicleDef, turretStopSnd) == 1472); + static_assert(offsetof(VehicleDef, effect01) == 536); + static_assert(offsetof(VehicleDef, compassFriendlyIcon) == 1536); + static_assert(offsetof(VehicleDef, compassEnemyAltIcon) == 1560); + //static_assert(offsetof(VehicleDef, effect07) == 752); + static_assert(offsetof(VehicleDef, trophyTags) == 1500); + static_assert(offsetof(VehicleDef, trophyExplodeFx) == 1520); + static_assert(offsetof(VehicleDef, idleLowSnd) == 1576); + static_assert(offsetof(VehicleDef, sound01) == 1608); + static_assert(offsetof(VehicleDef, audioOriginTag) == 1620); + static_assert(offsetof(VehicleDef, idleLowSndAlt) == 1624); + static_assert(offsetof(VehicleDef, engineHighSndAlt) == 1648); + static_assert(offsetof(VehicleDef, audioOriginTagAlt) == 1660); + static_assert(offsetof(VehicleDef, turretSpinSndAlt) == 1664); + static_assert(offsetof(VehicleDef, engineStartUpSnd) == 1680); + static_assert(offsetof(VehicleDef, engineShutdownSnd) == 1696); + static_assert(offsetof(VehicleDef, engineIdleSnd) == 1704); + static_assert(offsetof(VehicleDef, engineSustainSnd) == 1712); + static_assert(offsetof(VehicleDef, engineRampUpSnd) == 1720); + static_assert(offsetof(VehicleDef, engineRampDownSnd) == 1736); + static_assert(offsetof(VehicleDef, suspensionSoftSnd) == 1752); + static_assert(offsetof(VehicleDef, suspensionHardSnd) == 1768); + static_assert(offsetof(VehicleDef, collisionSnd) == 1784); + static_assert(offsetof(VehicleDef, speedSnd) == 1800); + static_assert(offsetof(VehicleDef, surfaceSndPrefix) == 1816); + static_assert(offsetof(VehicleDef, surfaceSnds) == 1824); + +#define sizeofmember(__struct__, __member__) sizeof(reinterpret_cast<__struct__*>(0)->__member__) + + static_assert(sizeofmember(VehicleDef, surfaceSnds) == 0x1A8); + static_assert(offsetof(VehicleDef, soundTriggerOverrideZone) == 2264); + static_assert(sizeof(VehicleDef) == 0x8E8); + + union XAssetHeader + { + void* data; + PhysPreset* physPreset; + PhysCollmap* physCollmap; + PhysWaterPreset* physWaterPreset; + PhysWorld* physWorld; + PhysConstraint* physConstraint; + XAnimParts* parts; + XModelSurfs* modelSurfs; + XModel* model; + Material* material; + ComputeShader* computeShader; + MaterialVertexShader* vertexShader; + MaterialHullShader* hullShader; + MaterialDomainShader* domainShader; + MaterialPixelShader* pixelShader; + MaterialVertexDeclaration* vertexDecl; + MaterialTechniqueSet* techniqueSet; + GfxImage* image; + snd_alias_list_t* sound; + SndCurve* sndCurve; + SndCurve* lpfCurve; + SndCurve* reverbCurve; + SndContext* sndContext; + LaserDef* laser; + LoadedSound* loadSnd; + LocalizeEntry* localize; + MapEnts* mapEnts; + GfxLightDef* lightDef; + WeaponAttachment* attachment; + WeaponDef* weapon; + VehicleDef* vehicle; + FxEffectDef* fx; + RawFile* rawfile; + ScriptFile* scriptfile; + StringTable* stringTable; + StructuredDataDefSet* structuredDataDefSet; + NetConstStrings* netConstStrings; + TracerDef* tracerDef; + LuaFile* luaFile; + DopplerPreset* doppler; + FxParticleSimAnimation* particleSimAnimation; + SkeletonScript* skeletonScript; + Clut* clut; + TTFDef* ttfDef; + PathData* aipaths; + }; + + struct XAsset + { + XAssetType type; + XAssetHeader header; + }; + + struct XAssetEntry + { + XAsset asset; + char zoneIndex; + volatile char inuseMask; + unsigned int nextHash; + unsigned int nextOverride; + unsigned int nextPoolEntry; + }; + + struct ScriptStringList + { + int count; + const char** strings; + }; + + union GfxZoneTableEntry + { + char* dataPtr; + void* voidPtr; + ID3D11Buffer* buffer; + ID3D11DepthStencilState* depthStencilState; + ID3D11BlendState* blendState; + }; + + typedef std::uint32_t GfxBlendStateBits[3]; + + struct XGfxGlobals + { + unsigned int depthStencilStateCount; + unsigned int blendStateCount; + std::uint64_t* depthStencilStateBits; + GfxBlendStateBits* blendStateBits; + GfxZoneTableEntry* depthStencilStates; + GfxZoneTableEntry* blendStates; + unsigned int perPrimConstantBufferCount; + unsigned int perObjConstantBufferCount; + unsigned int stableConstantBufferCount; + unsigned int* perPrimConstantBufferSizes; + unsigned int* perObjConstantBufferSizes; + unsigned int* stableConstantBufferSizes; + GfxZoneTableEntry* perPrimConstantBuffers; + GfxZoneTableEntry* perObjConstantBuffers; + GfxZoneTableEntry* stableConstantBuffers; + }; + + struct XGlobals + { + XGfxGlobals* gfxGlobals; + }; + + struct XAssetList + { + ScriptStringList stringList; + int assetCount; + XAsset* assets; + XGlobals* globals; + }; + + enum DBSyncMode + { + DB_LOAD_ASYNC = 0x0, + DB_LOAD_SYNC = 0x1, + DB_LOAD_ASYNC_WAIT_ALLOC = 0x2, + DB_LOAD_ASYNC_FORCE_FREE = 0x3, + DB_LOAD_ASYNC_NO_SYNC_THREADS = 0x4, + DB_LOAD_SYNC_SKIP_ALWAYS_LOADED = 0x5, + }; + + enum DBAllocFlags : std::int32_t + { + DB_ZONE_NONE = 0x0, + DB_ZONE_COMMON = 0x1, + DB_ZONE_UI = 0x2, + DB_ZONE_GAME = 0x4, + DB_ZONE_LOAD = 0x8, + DB_ZONE_DEV = 0x10, + DB_ZONE_BASEMAP = 0x20, + DB_ZONE_TRANSIENT_POOL = 0x40, + DB_ZONE_TRANSIENT_MASK = 0x40, + DB_ZONE_CUSTOM = 0x1000 // added for custom zone loading + }; + + struct XZoneInfo + { + const char* name; + int allocFlags; + int freeFlags; + }; + + struct XZoneInfoInternal + { + char name[64]; + int flags; + int isBaseMap; + }; +} \ No newline at end of file diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index e03627c1..027f97f9 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -6,6 +6,8 @@ namespace dvars { + std::unordered_map dvar_map; + game::dvar_t* con_inputBoxColor = nullptr; game::dvar_t* con_inputHintBoxColor = nullptr; game::dvar_t* con_outputBarColor = nullptr; @@ -28,8 +30,6 @@ namespace dvars game::dvar_t* g_enableElevators = nullptr; - game::dvar_t** cg_draw_2d = reinterpret_cast(0x141E39EC0); - std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain) { if (domain.vector.min == -FLT_MAX) @@ -132,10901 +132,54 @@ namespace dvars } } - constexpr int generate_hash(const char* string) + std::int32_t generate_hash(const std::string& string) { - const char* v1; - char v2, v6; - int v4, v5, v7; - char* end_ptr; - - v1 = string; - v2 = *string; - - if (v2 == 48 && v1[1] == 120) - { - return strtoul(v1 + 2, &end_ptr, 16); - } - - v4 = v2; - - if ((v2 - 65) <= 0x19u) - { - v4 = v2 + 32; - } - - v5 = 0xB3CB2E29 * static_cast(v4 ^ 0x319712C3); - - if (v2) - { - do - { - v6 = *++v1; - v7 = v6; - if ((v6 - 65) <= 0x19u) - { - v7 = v6 + 32; - } - - v5 = 0xB3CB2E29 * static_cast(v5 ^ v7); - } while (v6); - } - - return v5; + return generate_hash(string.data()); } - dvar_info::dvar_info(const std::string& name, const std::string& description) - : name(name) - , description(description) + void insert_dvar_info(const std::int32_t hash, const std::string& name, const std::string& description) { - this->hash = generate_hash(name.data()); + dvar_info info{}; + info.hash = hash; + info.name = name; + info.description = description; + dvar_map.insert(std::make_pair(hash, info)); } - std::vector dvar_list = + void insert_dvar_info(const std::string& name, const std::string& description) { - { - "ac_test_value", - "Test functionality", - }, - { - "accessToSubscriberContent", - "Whether to display the subscriber maps.", - }, - { - "actionSlotsHide", - "Hide the actionslots.", - }, - { - "actor_spaceLightingOffset", - "Offset from a Space Actor's origin used to determine what lights effect this actor.", - }, - { - "actor_trace_bound_offset", - "Will offset the actor's hit box in the bullet trace logic.", - }, - { - "actorVisibilityCheckAngleDistMax", - "Distance above which we set angle to actorVisibilityMinCheckAngle.", - }, - { - "actorVisibilityCheckAngleDistMin", - "Distance below which we set angle to 90.", - }, - { - "actorVisibilityMinCheckAngle", - "Angle outside which we don't check for actor visibility.", - }, - { - "ai_accuracy_attackerCountDecrease", - "Accuracy multiplied by this number for each additional attacker upto ai_accuracy_attackerCountMax", - }, - { - "ai_accuracy_attackerCountMax", - "Accuracy multiplied by ai_accuracy_attackerCountDecrease for each additional attacker upto this", - }, - { - "ai_accuracyDistScale", - "Distance scale for AI accuracy calculations. Higher = less accurate", - }, - { - "ai_allowOverTrim", - "Whether to allow trimming beyond the lookahead node, which should not be a safe action", - }, - { - "ai_backtrackCheckPathDir", - "Whether to abort backtracking unless the offset to the current node aligns with that node's path dir", - }, - { - "ai_badPathSpam", - "Write debugging information for a bad AI paths of suppressed actors. Non-suppressed actors will still print, but see ai_disableAllPathSpam", - }, - { - "ai_badPlace_clearSeveredPath", - "If set, AI will have their path cleared if the first link runs through a bad place", - }, - { - "ai_busyEventDistBullet", - "", - }, - { - "ai_busyEventDistDeath", - "", - }, - { - "ai_busyEventDistExplosion", - "", - }, - { - "ai_busyEventDistFootstep", - "", - }, - { - "ai_busyEventDistFootstepSprint", - "", - }, - { - "ai_busyEventDistFootstepWalk", - "", - }, - { - "ai_busyEventDistGrenadePing", - "", - }, - { - "ai_busyEventDistGunShot", - "", - }, - { - "ai_busyEventDistGunShotTeam", - "", - }, - { - "ai_busyEventDistNewEnemy", - "", - }, - { - "ai_busyEventDistPain", - "", - }, - { - "ai_busyEventDistProjImpact", - "", - }, - { - "ai_busyEventDistProjPing", - "", - }, - { - "ai_busyEventDistSilencedShot", - "", - }, - { - "ai_corpseCount", - "Scriptable maximum number of AI corpses", - }, - { - "ai_corpseLimit", - "Archived maximum number of AI corpses - for PC config files", - }, - { - "ai_count", - "Maximum number of AI", - }, - { - "ai_coverScore_coverType", - "Cover node score used when weighting based on distance to node", - }, - { - "ai_coverScore_dangerousNode", - "Cover node score used for nodes that are dangerous to use (someone died there). This value is subtracted", - }, - { - "ai_coverScore_distance", - "Cover node score used when weighting based on distance to node", - }, - { - "ai_coverScore_engagement", - "How much AI prefer cover nodes that are within the engagement distance ranges", - }, - { - "ai_coverScore_nodeAngle", - "Cover node score used when weighting based on distance to node", - }, - { - "ai_coverScore_playerLos", - "Cover node score used when weighting based on distance to node", - }, - { - "ai_coverScore_priority", - "Cover node score used when weighting based on distance to node", - }, - { - "ai_coverScore_targetDir", - "How strongly an AI will want to move to correct engagement distance", - }, - { - "ai_coverScore_visibility", - "Cover node score used when weighting based on distance to node", - }, - { - "ai_coverSearchInterval", - "AI cover search interval when the don't have cover, in milliseconds", - }, - { - "ai_dangerReactGoalRadius", - "Goal radius to use when reacting to danger", - }, - { - "ai_debugAccuracy", - "Enable debugging information for accuracy", - }, - { - "ai_debugAnimDeltas", - "Display animation delta debug information", - }, - { - "ai_debugCorpsePlant", - "Display debug information for AI corpse planting", - }, - { - "ai_debugCoverEntityNum", - "Display debug info for cover", - }, - { - "ai_debugCoverSelection", - "Enable debugging information for cover selection", - }, - { - "ai_debugEngagementDist", - "Show the engagement distances for currently selected AI", - }, - { - "ai_debugEntIndex", - "Entity index of an entity to debug", - }, - { - "ai_debugFindPath", - "Display AI 'find path' debugging information", - }, - { - "ai_debugFindPathDirect", - "Display AI 'find direct path' debugging information", - }, - { - "ai_debugFindPathLock", - "Find path lock", - }, - { - "ai_debugFindPathWidth", - "Display paths with the given width", - }, - { - "ai_debugGrenadeFailSafe", - "Display grenade fail safe debug information", - }, - { - "ai_debugGrenadeHintArc", - "Grenade hint arc in degrees", - }, - { - "ai_debugGunBlocked", - "Show gun blocked by wall traces", - }, - { - "ai_debugMayMove", - "Display debug information for AI 'may move' calculations", - }, - { - "ai_debugMeleeAttackSpots", - "Enable debugging information for melee attack spots", - }, - { - "ai_debugOverlay", - "Display AI debug overlay", - }, - { - "ai_debugPlayerLOS", - "Debug information for AI staying out of player LOS", - }, - { - "ai_debugTargetChange", - "Enable debugging information for target changes", - }, - { - "ai_debugTargets", - "Show primary and secondary targets", - }, - { - "ai_debugThreatSelection", - "Enable debugging information for threat selection", - }, - { - "ai_debugVolume", - "Show volume entity", - }, - { - "ai_disableAllPathSpam", - "Disable any ai path debugging information, even for non-suppressed actors", - }, - { - "ai_disableSpawn", - "Do not spawn AI", - }, - { - "ai_dodgeCheckPathDir", - "Whether to abort a dodge attempt if the path segment created between the dodge end node and the next regular path node goes against the path direction", - }, - { - "ai_dog_sharpTurnAngleRun", - "Dog will always try a sharp-turn when running a turn at this min angle.", - }, - { - "ai_dropAkimboChance", - "Chance that an AI will drop akimbo weapons if available for the weapon", - }, - { - "ai_eventDistBadPlace", - "", - }, - { - "ai_eventDistBullet", - "", - }, - { - "ai_eventDistDeath", - "", - }, - { - "ai_eventDistExplosion", - "", - }, - { - "ai_eventDistFootstep", - "", - }, - { - "ai_eventDistFootstepSprint", - "", - }, - { - "ai_eventDistFootstepWalk", - "", - }, - { - "ai_eventDistGrenadePing", - "", - }, - { - "ai_eventDistGunShot", - "", - }, - { - "ai_eventDistGunShotTeam", - "", - }, - { - "ai_eventDistNewEnemy", - "", - }, - { - "ai_eventDistPain", - "", - }, - { - "ai_eventDistProjImpact", - "", - }, - { - "ai_eventDistProjPing", - "", - }, - { - "ai_eventDistSilencedShot", - "", - }, - { - "ai_foliageSeeThroughDist", - "Maximum distance AI ignore foliage for sight trace to targets", - }, - { - "ai_friendlyFireBlockDuration", - "Friendly fire movement block duration", - }, - { - "ai_friendlySuppression", - "Whether AI fire will suppression teammates or not.", - }, - { - "ai_friendlySuppressionDist", - "Max distance at which AI suppress teammates", - }, - { - "ai_frontShieldDamageReduction", - "Non bullet damage reduction for AI with front shield getting hit within shield angle. (bullets do 0 damage if blocked by shield)", - }, - { - "ai_grenadeReturn_approachMinDot", - "Minimal dot product between the approach and throw vectors to perform a grenade return", - }, - { - "ai_grenadeReturn_debug", - "Turns on debug info for AI grenade returns", - }, - { - "ai_grenadeReturn_extraFuseTime", - "The amount of time (in ms) to add to a grenade fuse when trying to return grenade that's below minFuseTime", - }, - { - "ai_grenadeReturn_minDistSqr", - "Minimal distance to a grenade to consider it for a return so that transition anims will play", - }, - { - "ai_grenadeReturn_minFuseTime", - "If the fuse time drops below this value when an ally is attempting to return a grenade, add extra fuse time", - }, - { - "ai_grenadeReturn_stationary", - "If set, AI will attempt to return grenades that they are within pickup distance - regardless of min dist", - }, - { - "ai_grenadeReturn_traceToGrenade", - "If set, AI will only attempt to return grenades when they have a clear sight trace to the grenade", - }, - { - "ai_hardTurn_traceFromOrigin", - "Whether to trace from the origin or from the lookaheadPos when triggering a hard turn based on a future collision", - }, - { - "ai_markDangerousNodes", - "If set, AI will mark nodes as dangerous when they're pinned down in cover or have been killed", - }, - { - "ai_maxGrenadeThrowSpeed", - "Maximum AI grenade throw speed", - }, - { - "ai_moveOrientMode", - "Debug AI Orient Mode", - }, - { - "ai_noDodge", - "AI won't dodge to the side", - }, - { - "ai_pathChokePointCost", - "The distance AI would travel around to randomly avoid going through a choke point.", - }, - { - "ai_pathLookaheadMinDistance", - "Minimum 2D valid distance to continue using the path lookahead position, otherwise it will uses a newly computed lookahead position", - }, - { - "ai_pathMomentum", - "Momentum factor for continuing motion in previous direction. 0 for no momentum carry over", - }, - { - "ai_pathNegotiationOverlapCost", - "The distance AI would travel around to randomly avoid going through a choke point.", - }, - { - "ai_pathRandomPercent", - "Amount of random cost percent to add to each path node so AI always take slightly different routes", - }, - { - "ai_pathSmoothFromNoncodeMove", - "Whether to perform path smoothing when freshly transitioned from animation-driven motion to code movement", - }, - { - "ai_pathSmoothFromStationary", - "Whether to perform path smoothing based on the actor's facing direction when movement begins for a stationary actor", - }, - { - "ai_pathsmoothing", - "Toggle pathsmoothing on all AI.", - }, - { - "ai_playerADSTargetTime", - "Duration which the AI will not step in front of the player ADS'ing at a target (millisec)", - }, - { - "ai_playerFarAccuracy", - "Accuracy for AI far away from the player", - }, - { - "ai_playerFarRange", - "Minimum range for AI to use 'far' accuracy", - }, - { - "ai_playerLOSHalfWidth", - "Friendly AI will try not to claim cover nodes in this width of player's line of sight", - }, - { - "ai_playerLOSMinTime", - "Player line of sight effect will take effect after player is almost stationary for this time (millisec)", - }, - { - "ai_playerLOSRange", - "Friendly AI will try not to claim cover nodes in this width of player's line of sight", - }, - { - "ai_playerNearAccuracy", - "Accuracy for an AI near to a player", - }, - { - "ai_playerNearRange", - "Maximum range for AI to use 'near' accuracy", - }, - { - "ai_showAmbushNodes", - "Show ambush nodes AI is considering", - }, - { - "ai_showBadPlaces", - "Display debug information for 'bad places'", - }, - { - "ai_ShowCanshootChecks", - "Display debugging information for 'can shoot' checks", - }, - { - "ai_showDodge", - "Display debug information for AI dodging", - }, - { - "ai_showLastKnownEnemyPos", - "Shows the last known position of enemies", - }, - { - "ai_showLikelyEnemyPathNode", - "Show likely enemy path node", - }, - { - "ai_showNearbyNodes", - "Show nearby nodes", - }, - { - "ai_showNearestNodes", - "Show nearest node of AI", - }, - { - "ai_showNodes", - "Show AI navigation node debug information", - }, - { - "ai_showNodesDist", - "Maximum distance from the camera at which AI nodes are shown", - }, - { - "ai_showPathFindAnomalies", - "0 = off, 1 = show failsafe path anomalies(GREEN), 2 = show backtracking path anomalies(BLUE), 3 = show all anomalies", - }, - { - "ai_showPathFindNodes", - "Show nodes consider in latest path find", - }, - { - "ai_showPaths", - "Show AI navigation paths", - }, - { - "ai_showPotentialThreatDir", - "Display AI potential threat direction", - }, - { - "ai_showRegion", - "Draw all the cover in a volume for debugging", - }, - { - "ai_showSuppression", - "Draw the suppression planes for this entity", - }, - { - "ai_showTeamMove", - "Display debug information for AI team movement", - }, - { - "ai_showVisData", - "Display debug information for visibility data", - }, - { - "ai_showVisDataDist", - "Maximum distance for visibility data debugging information to be shown", - }, - { - "ai_threatUpdateInterval", - "AI target threat update interval in milliseconds", - }, - { - "ai_turnAnim_checkIntervalMinLookahead", - "Minimum lookaheadDist to check for turn anims on an interval - if the lookahead is shorter, turns will be checked for every frame", - }, - { - "ai_turnAnim_defaultCheckIntervalDist", - "Base distance covered after a prediction trace failure to try another turn anim", - }, - { - "ai_turnAnim_defaultCheckIntervalSpeed", - "Base speed used to scale the default check interval distance - faster speeds will check more frequently", - }, - { - "ai_turnAnim_maxLookaheadDist", - "Maximum lookahead distance where an actor may consider performing a preemptive turn animation (because they're about to round a corner)", - }, - { - "ai_turnAnim_minAfterTurnLookaheadDist", - "Minimum distance between the turn anim end point and the lookaheadPos", - }, - { - "ai_turnAnim_newPathTurnMaxLookahead", - "Maximum lookahead where we will turn from the lookahead position to the next node; when the lookahead is above this threshold, just turn to face the lookahead (since the next node beyond it is so far away)", - }, - { - "aim_accel_turnrate_debug", - "Turn on debugging info for the acceleration", - }, - { - "aim_accel_turnrate_enabled", - "Enable/disable acceleration of the turnrates", - }, - { - "aim_accel_turnrate_lerp", - "The acceleration of the turnrates", - }, - { - "aim_aimAssistRangeScale", - "Scales the weapon's aim assist range", - }, - { - "aim_autoaim_debug", - "Turn on auto aim debugging", - }, - { - "aim_autoaim_enabled", - "Turn on auto aim", - }, - { - "aim_autoaim_lerp", - "The rate in degrees per second that the auto aim will converge to its target", - }, - { - "aim_autoaim_region_height", - "The height of the auto aim region in virtual screen coordinates(0-480)", - }, - { - "aim_autoaim_region_width", - "The width of the auto aim region in virtual screen coordinates(0-640)", - }, - { - "aim_autoAimRangeScale", - "Scales the weapon's auto aim range", - }, - { - "aim_automelee_debug", - "Turn on auto melee debugging", - }, - { - "aim_automelee_enabled", - "Turn on auto melee", - }, - { - "aim_automelee_lerp", - "The rate in degrees per second that the auto aim will converge to its target", - }, - { - "aim_automelee_range", - "The range of the auto melee", - }, - { - "aim_automelee_region_height", - "The height of the auto melee region in virtual screen coordinates (0 - 480)", - }, - { - "aim_automelee_region_width", - "The width of the auto melee region in virtual screen coordinates (0 - 640)", - }, - { - "aim_input_graph_debug", - "Debug the view input graphs", - }, - { - "aim_input_graph_enabled", - "Use graph for adjusting view input", - }, - { - "aim_input_graph_index", - "Which input graph to use", - }, - { - "aim_lockon_debug", - "Turn on debugging info for aim lock on", - }, - { - "aim_lockon_deflection", - "The amount of stick deflection for the lockon to activate", - }, - { - "aim_lockon_enabled", - "Aim lock on helps the player to stay on target", - }, - { - "aim_lockon_region_height", - "The height of the auto aim region in virtual screen coordinates(0-480)", - }, - { - "aim_lockon_region_width", - "The width of the auto aim region in virtual screen coordinates(0-640)", - }, - { - "aim_lockon_strength", - "The amount of aim assistance given by the target lock on", - }, - { - "aim_resist_pitch_enabled", - "Aim resist pitch applies resistance to the input at the edges of the view cone when the view cone is locked", - }, - { - "aim_resist_view_threshold", - "The minimum input threshold to apply resistance to (0-1)", - }, - { - "aim_resist_yaw_enabled", - "Aim resist yaw applies resistance to the input at the edges of the view cone when the view cone is locked", - }, - { - "aim_scale_view_axis", - "Scale the influence of each input axis so that the major axis has more influence on the control", - }, - { - "aim_slowdown_debug", - "Turn on debugging info for aim slowdown", - }, - { - "aim_slowdown_enabled", - "Slowdown the turn rate when the cross hair passes over a target", - }, - { - "aim_slowdown_pitch_scale", - "The vertical aim assist slowdown ratio from the hip", - }, - { - "aim_slowdown_pitch_scale_ads", - "The vertical aim assist slowdown ratio from the hip", - }, - { - "aim_slowdown_prioritization_crosshair_dist_prop", - "Auto aim prioritization - entities considered close if within this proportion of distance", - }, - { - "aim_slowdown_prioritization_dist_prop", - "Auto aim prioritization - entities considered close if within this proportion of distance", - }, - { - "aim_slowdown_prioritization_non_character_neg", - "Auto aim prioritization - amount of negation applied to non characters considered close to other entities", - }, - { - "aim_slowdown_region_height", - "The screen height of the aim assist slowdown region", - }, - { - "aim_slowdown_region_width", - "The screen width of the aim slowdown region", - }, - { - "aim_slowdown_yaw_scale", - "The horizontal aim assist slowdown ratio from the hip", - }, - { - "aim_slowdown_yaw_scale_ads", - "The horizontal aim assist slowdown ratio from the hip", - }, - { - "aim_target_sentient_radius", - "The radius used to calculate target bounds for a sentient(actor or player)", - }, - { - "aim_turnrate_pitch", - "The vertical turn rate for aim assist when firing from the hip", - }, - { - "aim_turnrate_pitch_ads", - "The turn rate up and down for aim assist when aiming down the sight", - }, - { - "aim_turnrate_yaw", - "The horizontal turn rate for aim assist when firing from the hip", - }, - { - "aim_turnrate_yaw_ads", - "The horizontal turn rate for aim assist when firing from the hip", - }, - { - "airburstAdjustDistance", - "Distance to append to airburst locked in distance.", - }, - { - "ammoCounterHide", - "Hide the Ammo Counter", - }, - { - "arcademode", - "arcade mode", - }, - { - "arcademode_full", - "arcade mode full", - }, - { - "arcademode_lives", - "arcade mode lives", - }, - { - "armory_contentpacks_enabled", - "Allowed armory content packs. 0: none , 1: first armory content pack enabled, 2: first and second armory content pack enabled", - }, - { - "autobolt_explosions_to_vehicles", - "Turns on system to automatically bolt explosions to vehicles. Used for chase scenes.", - }, - { - "autoexit", - "Time to spend in match before shutting down the exe (in ms).", - }, - { - "automatedTester", - "Whether we are currently running an automated tester.", - }, - { - "avi_DontUseMemcardStorage", - "Prevent usage of local mem cards for avi rendering and uploading", - }, - { - "band_12players", - "12 player bandwidth req'd", - }, - { - "band_18players", - "18 player bandwidth req'd", - }, - { - "band_2players", - "2 player bandwidth req'd", - }, - { - "band_4players", - "4 player bandwidth req'd", - }, - { - "band_8players", - "8 player bandwidth req'd", - }, - { - "bg_aimSpreadMoveSpeedThreshold", - "When player is moving faster than this speed, the aim spread will increase", - }, - { - "bg_allowScuffFootsteps", - "If true, scuff sounds will be played when the player rotates in place.", - }, - { - "bg_animUnspeedScaledDuration", - "How long into the start of a speed_scaled_transition anim that speed scaling should be ignored.", - }, - { - "bg_audioHeatLevelHighThreshold", - "Minimum heat level to start playing the high heat start/loop/stop fire sounds.", - }, - { - "bg_audioHeatLevelMedThreshold", - "Minimum heat level to start playing the high heat start/loop/stop fire sounds.", - }, - { - "bg_bulletExplDmgFactor", - "Weapon damage multiplier that will be applied at the center of the slash damage area.", - }, - { - "bg_bulletExplRadius", - "The radius of the bullet splash damage, where the damage gradually falls off to 0.", - }, - { - "bg_checkPlayerOutsideSolid", - "Turn on assert that player is outside collision", - }, - { - "bg_compassShowEnemies", - "Whether enemies are visible on the compass at all times", - }, - { - "bg_debugProne", - "Show prone debug information", - }, - { - "bg_fallDamageMaxHeight", - "The height that a player will take maximum damage when falling", - }, - { - "bg_fallDamageMinHeight", - "The height that a player will start to take minimum damage if they fall", - }, - { - "bg_foliagesnd_fastinterval", - "The time between each foliage sound when moving slowly", - }, - { - "bg_foliagesnd_maxspeed", - "The speed that a player must be going to make minimum noise while moving through foliage", - }, - { - "bg_foliagesnd_minspeed", - "The speed that a player must be going to make minimum noise while moving through foliage", - }, - { - "bg_foliagesnd_resetinterval", - "The time interval before foliage sounds are reset after the player has stopped moving", - }, - { - "bg_foliagesnd_slowinterval", - "The time between each foliage sound when moving slowly", - }, - { - "bg_forceDualWield", - "Force akimbo for all possible weapons", - }, - { - "bg_forceExplosiveBullets", - "When set, all bullet weapons will fire explosive rounds (Simulates Perk)", - }, - { - "bg_ladder_yawcap", - "The maximum angle that a player can look around while on a ladder", - }, - { - "bg_landFXLightHeight", - "The max height that a player will play light land FX and camera shakes", - }, - { - "bg_landFXMediumHeight", - "The max height that a player will play light land FX and camera shakes", - }, - { - "bg_lowGravity", - "Low gravity for slow or floaty objects, in inches per second per second", - }, - { - "bg_maxGrenadeIndicatorSpeed", - "Maximum speed of grenade that will show up in indicator and can be thrown back.", - }, - { - "bg_prone_yawcap", - "The maximum angle that a player can look around while on a ladder", - }, - { - "bg_radiusDamageMax", - "The maximum radius damage radius for non-client and non-actor entities", - }, - { - "bg_shieldHitEncodeHeightVM", - "The decoding range, in height, of a client's viewmodel shield.", - }, - { - "bg_shieldHitEncodeHeightWorld", - "The encoding range, in height, of a client's world shield. A hit in this range is encoded into one of 8 rows.", - }, - { - "bg_shieldHitEncodeWidthVM", - "The decoding range, in width, of a client's viewmodel shield.", - }, - { - "bg_shieldHitEncodeWidthWorld", - "The encoding range, in width, of a client's world shield. A hit in this range is encoded into one of 16 collumns.", - }, - { - "bg_shock_lookControl", - "Alter player control during shellshock", - }, - { - "bg_shock_lookControl_fadeTime", - "The time for the shellshock player control to fade in seconds", - }, - { - "bg_shock_lookControl_maxpitchspeed", - "Maximum pitch movement rate while shellshocked in degrees per second", - }, - { - "bg_shock_lookControl_maxyawspeed", - "Maximum yaw movement rate while shell shocked in degrees per second", - }, - { - "bg_shock_lookControl_mousesensitivityscale", - "Sensitivity scale to apply to a shellshocked player", - }, - { - "bg_shock_movement", - "Affect player's movement speed duringi shellshock", - }, - { - "bg_shock_screenBlurBlendFadeTime", - "The amount of time in seconds for the shellshock effect to fade", - }, - { - "bg_shock_screenBlurBlendTime", - "The amount of time in seconds for the shellshock effect to fade", - }, - { - "bg_shock_screenFlashShotFadeTime", - "In seconds, how soon from the end of the effect to start blending out the whiteout layer.", - }, - { - "bg_shock_screenFlashWhiteFadeTime", - "In seconds, how soon from the end of the effect to start blending out the whiteout layer.", - }, - { - "bg_shock_screenType", - "Shell shock screen effect type", - }, - { - "bg_shock_sound", - "Play shell shock sound", - }, - { - "bg_shock_soundDryLevel", - "Shell shock sound dry level", - }, - { - "bg_shock_soundEnd", - "Shellshock end sound alias", - }, - { - "bg_shock_soundEndAbort", - "Shellshock aborted end sound alias", - }, - { - "bg_shock_soundFadeInTime", - "Shell shock sound fade in time in seconds", - }, - { - "bg_shock_soundFadeOutTime", - "Shell shock sound fade out time in seconds", - }, - { - "bg_shock_soundLoop", - "Shellshock loop alias", - }, - { - "bg_shock_soundLoopEndDelay", - "Sound loop end offset time from the end of the shellshock in seconds", - }, - { - "bg_shock_soundLoopFadeTime", - "Shell shock sound loop fade time in seconds", - }, - { - "bg_shock_soundLoopSilent", - "The sound that gets blended with the shellshock loop alias", - }, - { - "bg_shock_soundModEndDelay", - "The delay from the end of the shell shock to the end of the sound modification", - }, - { - "bg_shock_soundRoomType", - "Shell shock sound reverb room type", - }, - { - "bg_shock_soundSubmix", - "Shell shock submix to apply", - }, - { - "bg_shock_soundWetLevel", - "Shell shock sound wet level", - }, - { - "bg_shock_viewKickFadeTime", - "The time for the shellshock kick effect to fade", - }, - { - "bg_shock_viewKickPeriod", - "The period of the shellshock view kick effect", - }, - { - "bg_shock_viewKickRadius", - "Shell shock kick radius", - }, - { - "bg_softLandingMaxDamage", - "The max amount of damage (as % of max health) if soft landing is in effect", - }, - { - "bg_softLandingMaxHeight", - "The height that a player will start to take minimum damage if they fall", - }, - { - "bg_softLandingMinHeight", - "The height that a player will start to take minimum damage if they fall", - }, - { - "bg_viewBobAmplitudeBase", - "The base speed-based view bob amplitude", - }, - { - "bg_viewBobAmplitudeRoll", - "The amplitude applied to the roll for view bobbing", - }, - { - "bg_viewBobMax", - "The maximum allowed bob amplitude", - }, - { - "bg_viewBobMocap", - "Use new mocap motion for viewmodel bob", - }, - { - "bg_viewKickMax", - "The maximum view kick", - }, - { - "bg_viewKickMin", - "The minimum view kick", - }, - { - "bg_viewKickRandom", - "The random direction scale view kick", - }, - { - "bg_viewKickScale", - "The scale to apply to the damage done to calculate damage view kick", - }, - { - "bg_weaponBobAmplitudeBase", - "The base speed-based weapon bob amplitude", - }, - { - "bg_weaponBobAmplitudeRoll", - "The amplitude applied to the roll for weapon bobbing", - }, - { - "bg_weaponBobLag", - "The lag that will be applied the weapon bob cycle", - }, - { - "bg_weaponBobMax", - "The maximum allowed weapon/viewmodel bob amplitude", - }, - { - "bullet_penetration_damage", - "When false, bullets that have penetrated an object will not do damage to AI.", - }, - { - "bullet_penetration_enabled", - "When false, disables bullet penetration completely.", - }, - { - "bullet_penetrationActorHitsActors", - "When false, bullets shot by actors that have penetrated an object will not do damage to other actors.", - }, - { - "bullet_penetrationHitsClients", - "When false, bullets that have penetrated an object will not do damage to AI.", - }, - { - "bullet_penetrationMinFxDist", - "Min distance a penetrated bullet must travel before it'll trigger the effects", - }, - { - "bullet_ricochetBaseChance", - "The base chance a bullet has of ricocheting off of a riot shield.", - }, - { - "ca_auto_signin", - "CoD Anywhere start sign-in task automatically on startup or first party sign-in", - }, - { - "ca_do_mlc", - "CoD Anywhere Do Multi Login check", - }, - { - "ca_intra_only", - "CoD Anywhere Intra Network Only", - }, - { - "ca_require_signin", - "CoD Anywhere require sign in to enter MP", - }, - { - "ca_show_signup_request", - "CoD Anywhere should you show new users a popup requesting they create a CoD Account?", - }, - { - "cameraShakeRemoteHelo_Angles", - "Remote helicopter gunner cam, range to shake the view.", - }, - { - "cameraShakeRemoteHelo_Freqs", - "Remote helicopter gunner cam, how fast to shake.", - }, - { - "cameraShakeRemoteHelo_SpeedRange", - "Remote helicopter gunner cam, range of missile speed to scale the shaking.", - }, - { - "cameraShakeRemoteMissile_Angles", - "Remote missile-cam, range to shake the view.", - }, - { - "cameraShakeRemoteMissile_Freqs", - "Remote missile-cam, how fast to shake.", - }, - { - "cameraShakeRemoteMissile_SpeedRange", - "Remote missile-cam, range of missile speed to scale the shaking.", - }, - { - "capturePlaybackDisableSRE", - "Disable the SRE pop up.", - }, - { - "cg_autosimAllowVariableTime", - "Allow the weapon to do speed up and slow down timing.", - }, - { - "cg_autosimFireSpeedScale", - "1.0: normal speed, 2.0: 200%% speed, 0.5: 50%% speed", - }, - { - "cg_autosimMinWeaponSpeed", - "Minimum distance between autosimmed weapon shots", - }, - { - "cg_autosimStopPreviousShot", - "Always try to stop the previous autosim shot", - }, - { - "cg_blood", - "Show blood effects", - }, - { - "cg_bloodLimit", - "Limit blood effects (to 'prevent excess blood stacking')", - }, - { - "cg_bloodLimitMsec", - "When limiting blood effects, number of milliseconds between effects.", - }, - { - "cg_bloodThickColor", - "Color of the blood overlay's thick blood splatter", - }, - { - "cg_bloodThinColor", - "Color of the blood overlay's thin blood splatter", - }, - { - "cg_brass", - "Weapons eject brass", - }, - { - "cg_breathingSoundLvl1Cutoff", - "", - }, - { - "cg_breathingSoundLvl2Cutoff", - "", - }, - { - "cg_breathingSoundsEnabled", - "Enable sprint breathing sounds.", - }, - { - "cg_bulletForce", - "Force applied from bullet hit", - }, - { - "cg_camAngleOffset", - "Pitch, Yaw, and Roll offsets in degrees", - }, - { - "cg_camAngleOverride", - "If true angle offsets override the actual view angles instead of modifying them.", - }, - { - "cg_camOffset", - "Position offset", - }, - { - "cg_centertime", - "The time for a center printed message to fade", - }, - { - "cg_cinematicCanPause", - "Ingame cinematics can be paused", - }, - { - "cg_cinematicFullscreen", - "Draw ingame cinematics full screen", - }, - { - "cg_ColorBlind_EnemyTeam", - "Enemy team color for color blind people", - }, - { - "cg_ColorBlind_MyTeam", - "Player team color for color blind people", - }, - { - "cg_constantSizeHeadIcons", - "Head icons are the same size regardless of distance from the player", - }, - { - "cg_crawlBlendOutTimeFiring", - "Milleseconds to blend out of crawl anims to firing weapon", - }, - { - "cg_crawlBlendTime", - "Milleseconds to blend in and out of crawl anims", - }, - { - "cg_crawlMaxSpeed", - "At this speed, the crawl anim will play at an anim rate of 1", - }, - { - "cg_crawlMinSpeed", - "Minimum speed before player will start crawl anim", - }, - { - "cg_crosshairAlpha", - "The alpha value of the crosshair", - }, - { - "cg_crosshairAlphaMin", - "The minimum alpha value of the crosshair when it fades in", - }, - { - "cg_crosshairDynamic", - "Crosshair is Dynamic", - }, - { - "cg_crosshairEnemyColor", - "The crosshair color when over an enemy", - }, - { - "cg_crosshairVerticalOffset", - "Amount to vertically offset the crosshair from the center.", - }, - { - "cg_cullBulletAngle", - "Cull bullet trajectories that don't fall within this fov", - }, - { - "cg_cullBullets", - "Whether to cull bullet fire prediction if trajectory doesn't pass your view or anywhere near you", - }, - { - "cg_cursorHints", - "Draw cursor hints where:\n 0: no hints", - }, - { - "cg_damageIndicatorMinAngleDiffMax", - "", - }, - { - "cg_damageIndicatorMinAngleDiffMin", - "", - }, - { - "cg_debug_overlay_viewport", - "Remove the sniper overlay so you can check that the scissor window is correct.", - }, - { - "cg_debugDrawHandDragInfo", - "Draw info about hand drag when swimming", - }, - { - "cg_debugDrawHitBox", - "Display character hit boxes", - }, - { - "cg_debugevents", - "Output event debug information. EV_NONE turns it off. EV_MAX_EVENTS shows all events. Otherwise, show only specified value.", - }, - { - "cg_debugInfoCornerOffset", - "Offset from top-right corner, for cg_drawFPS, etc", - }, - { - "cg_debugLookAt", - "Debug look at information", - }, - { - "cg_disableScreenShake", - "Turns off screen shakes when turned on. Dev-only", - }, - { - "cg_dobjdump", - "Output dobj info for the given entity id", - }, - { - "cg_draw2D", - "Draw 2D screen elements", - }, - { - "cg_drawBreathHint", - "Draw a 'hold breath to steady' hint", - }, - { - "cg_drawBuildName", - "Draw build name", - }, - { - "cg_drawCenterLines", - "Draw a horizontal line and a vertical line through the center of the screen", - }, - { - "cg_drawCrosshair", - "Turn on weapon crosshair", - }, - { - "cg_drawDamageDirection", - "Draw hit direction arrow.", - }, - { - "cg_drawDamageFlash", - "Draw flash when hit.", - }, - { - "cg_drawDebugAudioClientTriggers", - "Display client side trigger audio debug information", - }, - { - "cg_drawDebugBones", - "Draw bones for entity number.", - }, - { - "cg_drawDebugBonesBind", - "Draw bind pose when drawing bones with cg_drawDebugBones.", - }, - { - "cg_drawDebugBonesClosest", - "updates cg_drawDebugBones to closest entity to camera.", - }, - { - "cg_drawDebugClientTriggers", - "Display client side trigger debug information", - }, - { - "cg_drawDebugTags", - "Draw tags for entity number.", - }, - { - "cg_drawDebugVisionClientTriggers", - "Display client side trigger vision debug information", - }, - { - "cg_drawEffectNum", - "Draw counts of effects and elements", - }, - { - "cg_drawFPS", - "Draw frames per second", - }, - { - "cg_drawFPSLabels", - "Draw FPS Info Labels", - }, - { - "cg_drawFriendlyFireCrosshair", - "draw the friendly fire crosshair (friendly move)", - }, - { - "cg_drawGun", - "Draw the view model", - }, - { - "cg_drawHealth", - "Draw health bar", - }, - { - "cg_drawHUD", - "Draw HUD elements", - }, - { - "cg_drawImagecache", - "Draw imagecache/streaming state", - }, - { - "cg_drawMantleHint", - "Draw a 'press key to mantle' hint", - }, - { - "cg_drawMapBuildInfo", - "Draw timestamps and command line options from the compile process", - }, - { - "cg_drawMapBuildInfoX", - "X offset for the BSP debug info string", - }, - { - "cg_drawMapBuildInfoY", - "Y offset for the BSP debug info string", - }, - { - "cg_drawMaterial", - "Draw debugging information for materials", - }, - { - "cg_drawpaused", - "Draw paused screen", - }, - { - "cg_drawPlayerBoundingBox", - "Draw a red bounding box at player's server position", - }, - { - "cg_drawPlayerPosInFreeMove", - "Draw an orange box at the player's pos in noclip/ufo.", - }, - { - "cg_drawrumbledebug", - "Display rumble debug information", - }, - { - "cg_drawScriptUsage", - "Draw debugging information for scripts", - }, - { - "cg_drawShellshock", - "Draw shellshock & flashbang screen effects.", - }, - { - "cg_drawTransients", - "Draw transient fastfile state", - }, - { - "cg_drawTurretCrosshair", - "Draw a cross hair when using a turret", - }, - { - "cg_drawVersion", - "Draw the game version", - }, - { - "cg_drawVersionX", - "X offset for the version string", - }, - { - "cg_drawVersionY", - "Y offset for the version string", - }, - { - "cg_drawViewpos", - "Draw viewpos", - }, - { - "cg_dumpAnims", - "Output animation info for the given entity id", - }, - { - "cg_dumpAnimsToScreen", - "Output animation info for the given entity id", - }, - { - "cg_dumpAnimsToScreenAllNodes", - "Show all animations for cg_dumpAnimsToScreen entity, even if the animation has no weight.", - }, - { - "cg_enableWaterSurfaceTransitionFx", - "Turns on water surface transition fx system.", - }, - { - "cg_equipmentSounds", - "Play equipment sounds", - }, - { - "cg_errordecay", - "Decay for predicted error", - }, - { - "cg_explodeForce", - "Force applied from explosion hit", - }, - { - "cg_explodeMinForce", - "Force below which dynents won't even bother waking up", - }, - { - "cg_explodeSpinScale", - "Scale of the random offset from the center of mass for explosion forces.", - }, - { - "cg_explodeUpbias", - "Upward bias applied to force directions from explosion hits", - }, - { - "cg_explodingBulletForce", - "Force applied from bullet explosion hit", - }, - { - "cg_explodingBulletMinForce", - "Force below which dynents won't even bother waking up", - }, - { - "cg_explodingBulletSpinScale", - "Scale of the random offset from the center of mass for explosion forces.", - }, - { - "cg_explodingBulletUpbias", - "Upward bias applied to force directions from explosion hits", - }, - { - "cg_foliagesnd_alias", - "The sound that plays when an actor or player enters a foliage clip brush.", - }, - { - "cg_followEnt", - "Entity number to follow when in cg_ufo", - }, - { - "cg_footsteps", - "Play footstep sounds that are NOT sprint", - }, - { - "cg_footstepsSprint", - "Play sprint footstep sounds", - }, - { - "cg_fov", - "The field of view angle in degrees for client 0", - }, - { - "cg_fov1", - "The field of view angle in degrees for client 0", - }, - { - "cg_fovMin", - "The minimum possible field of view", - }, - { - "cg_fovNonVehAdd", - "The field of view angle added in degrees when not in a vehicle", - }, - { - "cg_fovScale", - "Scale applied to the field of view", - }, - { - "cg_gameBoldMessageWidth", - "The maximum character width of the bold game messages", - }, - { - "cg_gameMessageWidth", - "The maximum character width of the game messages", - }, - { - "cg_gun_x", - "Forward position of the viewmodel", - }, - { - "cg_gun_y", - "Right position of the viewmodel", - }, - { - "cg_gun_z", - "Up position of the viewmodel", - }, - { - "cg_headIconMinScreenRadius", - "The minumum radius of a head icon on the screen", - }, - { - "cg_hintFadeTime", - "Time in milliseconds for the cursor hint to fade", - }, - { - "cg_hudDamageIconHeight", - "The height of the damage icon", - }, - { - "cg_hudDamageIconInScope", - "Draw damage icons when aiming down the sight of a scoped weapon", - }, - { - "cg_hudDamageIconOffset", - "The offset from the center of the damage icon", - }, - { - "cg_hudDamageIconOverlayTime", - "The amount of time (in ms) for the overlay portion of the damage icon to stay on screen", - }, - { - "cg_hudDamageIconStartFadeTime", - "The amount of time (in ms) before the damage icon begins to fade", - }, - { - "cg_hudDamageIconTime", - "The total amount of time (in ms) for the damage icon to stay on screen after damage is taken", - }, - { - "cg_hudDamageIconWidth", - "The width of the damage icon", - }, - { - "cg_hudGrenadeIconEnabledFlash", - "Show the grenade indicator for flash grenades", - }, - { - "cg_hudGrenadeIconHeight", - "The height of the grenade indicator icon", - }, - { - "cg_hudGrenadeIconInScope", - "Show the grenade indicator when aiming down the sight of a scoped weapon", - }, - { - "cg_hudGrenadeIconMaxRangeFlash", - "The maximum distance that a flashbang can be from a player in order to be shown on the grenade indicator", - }, - { - "cg_hudGrenadeIconMaxRangeFrag", - "The maximum distance that a grenade can be from a player in order to be shown on the grenade indicator", - }, - { - "cg_hudGrenadeIconOffset", - "The offset from the center of the screen for a grenade icon", - }, - { - "cg_hudGrenadeIconWidth", - "The width of the grenade indicator icon", - }, - { - "cg_hudGrenadePointerHeight", - "The height of the grenade indicator pointer", - }, - { - "cg_hudGrenadePointerPivot", - "The pivot point of th grenade indicator pointer", - }, - { - "cg_hudGrenadePointerPulseFreq", - "The number of times per second that the grenade indicator flashes in Hertz", - }, - { - "cg_hudGrenadePointerPulseMax", - "The maximum alpha of the grenade indicator pulse. Values higher than 1 will cause the indicator to remain at full brightness for longer", - }, - { - "cg_hudGrenadePointerPulseMin", - "The minimum alpha of the grenade indicator pulse. Values lower than 0 will cause the indicator to remain at full transparency for longer", - }, - { - "cg_hudGrenadePointerWidth", - "The width of the grenade indicator pointer", - }, - { - "cg_hudLighting_basic_additiveLumOffset", - "[basic] Offset applied to additive light color.", - }, - { - "cg_hudLighting_basic_additiveLumScale", - "[basic] Scale applied to additive light color.", - }, - { - "cg_hudLighting_basic_ambientLumOffset", - "[basic] Offset applied to ambient light color.", - }, - { - "cg_hudLighting_basic_ambientLumScale", - "[basic] Scale applied to ambient light color.", - }, - { - "cg_hudLighting_basic_diffuseLumOffset", - "[basic] Offset applied to diffuse light color.", - }, - { - "cg_hudLighting_basic_diffuseLumScale", - "[basic] Scale applied to diffuse light color.", - }, - { - "cg_hudLighting_basic_specExponent", - "[basic] Specular exponent. Higher values result in sharper highlights.", - }, - { - "cg_hudLighting_basic_specLumOffset", - "[basic] Offset applied to spec light luminance.", - }, - { - "cg_hudLighting_basic_specLumScale", - "[basic] Scale applied to spec light luminance.", - }, - { - "cg_hudLighting_blood_additiveLumOffset", - "[blood] Offset applied to additive light color.", - }, - { - "cg_hudLighting_blood_additiveLumScale", - "[blood] Scale applied to additive light color.", - }, - { - "cg_hudLighting_blood_ambientLumOffset", - "[blood] Offset applied to ambient light color.", - }, - { - "cg_hudLighting_blood_ambientLumScale", - "[blood] Scale applied to ambient light color.", - }, - { - "cg_hudLighting_blood_diffuseLumOffset", - "[blood] Offset applied to diffuse light color.", - }, - { - "cg_hudLighting_blood_diffuseLumScale", - "[blood] Scale applied to diffuse light color.", - }, - { - "cg_hudLighting_blood_specExponent", - "[blood] Specular exponent. Higher values result in sharper highlights.", - }, - { - "cg_hudLighting_blood_specLumOffset", - "[blood] Offset applied to spec light luminance.", - }, - { - "cg_hudLighting_blood_specLumScale", - "[blood] Scale applied to spec light luminance.", - }, - { - "cg_hudLighting_fadeSharpness", - "This controls how sharp the lines are when fading using the mask alpha. Higher values are sharper.", - }, - { - "cg_hudMapBorderWidth", - "The size of the full map's border, filled by the CG_PLAYER_FULLMAP_BORDER ownerdraw", - }, - { - "cg_hudMapFriendlyHeight", - "", - }, - { - "cg_hudMapFriendlyWidth", - "", - }, - { - "cg_hudMapPlayerHeight", - "", - }, - { - "cg_hudMapPlayerWidth", - "", - }, - { - "cg_hudMapRadarLineThickness", - "Thickness, relative to the map width, of the radar texture that sweeps across the full screen map", - }, - { - "cg_hudStanceFlash", - "The background color of the flash when the stance changes", - }, - { - "cg_hudStanceHintPrints", - "Draw helpful text to say how to change stances", - }, - { - "cg_invalidCmdHintBlinkInterval", - "Blink rate of an invalid command hint", - }, - { - "cg_invalidCmdHintDuration", - "Duration of an invalid command hint", - }, - { - "cg_jumpADSShakeReductionMax", - "Max percentage that ADS can reduce jump/land additive anims", - }, - { - "cg_landingSounds", - "Play landing on surface sounds", - }, - { - "cg_mantleSounds", - "Play mantle equipment sounds", - }, - { - "cg_mapLocationSelectionCursorSpeed", - "Speed of the cursor when selecting a location on the map", - }, - { - "cg_marks_ents_player_only", - "Marks on entities from player's bullets only.", - }, - { - "cg_minCullBulletDist", - "Don't cull bullet trajectories that are within this distance to you.", - }, - { - "cg_modPrvDrawAxis", - "Draw Axes in the model previewer", - }, - { - "cg_modPrvMruAnims", - "", - }, - { - "cg_modPrvMruModels", - "", - }, - { - "cg_objectiveListWrapCountStandard", - "The amount of on-screen length to wrap an objective in wide-screen mode", - }, - { - "cg_objectiveListWrapCountWidescreen", - "The amount of on-screen length to wrap an objective in wide-screen mode", - }, - { - "cg_player_shield_quickraise_override", - "Overrides all weapon quickraise state timers after using exo-shield. 0 disables the override.", - }, - { - "cg_playerCollideWithPhysics", - "Enable player collision with client-side physics objects.", - }, - { - "cg_playerFovScale0", - "Scale applied to player 0 field of view", - }, - { - "cg_playerFovScale1", - "Scale applied to player 1 field of view", - }, - { - "cg_rumble_devgui_duration", - "Duration of rumble", - }, - { - "cg_rumble_devgui_loop", - "Enable a looping rumble", - }, - { - "cg_scriptIconSize", - "Size of Icons defined by script", - }, - { - "cg_shoulderFollowEnt", - "When set to true follow the ent set in cg_followEnt in a fixed position, over the shoulder cam.", - }, - { - "cg_shoulderFollowOffsets", - "Set the offsets for the shoulder cam. Usage cg_shoulderFollowOffsets [dist] [height]", - }, - { - "cg_showmiss", - "Show prediction errors", - }, - { - "cg_silencedWeaponPingRangeSquared", - "Square of the range at which the firing of a silenced weapon will ping on the compass.", - }, - { - "cg_skipDObjFilterIntoCells", - "Skips CPU logic to push entities into visible set cells. Helps situations where there are large amounts of moving entities that are mostly visible.", - }, - { - "cg_small_dev_string_fontscale", - "Font scale for a small development only display string", - }, - { - "cg_sprintMeterDisabledColor", - "The color of the sprint meter when the sprint meter is full", - }, - { - "cg_sprintMeterEmptyColor", - "The color of the sprint meter when the sprint meter is full", - }, - { - "cg_sprintMeterFullColor", - "The color of the sprint meter when the sprint meter is full", - }, - { - "cg_subtitleMinTime", - "The minimum time that the subtitles are displayed on screen in seconds", - }, - { - "cg_subtitleWidthStandard", - "The width of the subtitles on a non wide-screen", - }, - { - "cg_subtitleWidthWidescreen", - "The width of the subtitle on a wide-screen", - }, - { - "cg_testVar", - "For random development usage.", - }, - { - "cg_traceProfilingDist", - "If non-negative then length of trace from camera to measure cost of CG_LocationalTrace.", - }, - { - "cg_vectorFieldsDraw", - "Enables debug drawing of vector field instances. (0=off, 1=no depth test, 2=depth test)", - }, - { - "cg_vectorFieldsForceUniform", - "Forces all vector field assets to represent a single, uniform direction", - }, - { - "cg_viewmodelAnimatedCrawl", - "Toggle anim play viewmodel crawl anims rather than procedural", - }, - { - "cg_viewmodelAnimatedJumps", - "Toggle anim play viewmodel jump anims rather than procedural", - }, - { - "cg_viewmodelAnimBlending", - "Toggle anim blending for viewmodel anims", - }, - { - "cg_viewVehicleInfluence", - "The influence on the view angles from being in a vehicle", - }, - { - "cg_viewZSmoothingMax", - "Threshold for the maximum smoothing distance we'll do", - }, - { - "cg_viewZSmoothingMin", - "Threshold for the minimum smoothing distance it must move to smooth", - }, - { - "cg_viewZSmoothingTime", - "Amount of time to spread the smoothing over", - }, - { - "cg_waterSheeting_distortionScaleFactor", - "Distortion uv scales (Default to 1)", - }, - { - "cg_waterSheeting_magnitude", - "Distortion magnitude", - }, - { - "cg_waterSheeting_radius", - "Tweak dev var; Glow radius in pixels at 640x480", - }, - { - "cg_waterSurfaceTransition_BlockingFxMoveRate", - "Rate at which the surface blocking efx moves across the screen.", - }, - { - "cg_waterSurfaceTransition_FastVelocityThreshold", - "Water surface transitions at velocities above this threshold are considered fast.", - }, - { - "cg_waterSurfaceTransition_TransitionDepthTop", - "Upper-bound of the depth over which the surface blocking efx is on screen.", - }, - { - "cg_waterSurfaceTransition_VisionBlendBottom", - "Lower-bound of the depth over which underwater vision set blends in.", - }, - { - "cg_waterSurfaceTransition_VisionBlendTop", - "Upper-bound of the depth over which underwater vision set blends in.", - }, - { - "cg_weapHitCullAngle", - "Angle of cone within which to cull back facing weapon hit effects", - }, - { - "cg_weapHitCullEnable", - "When true, cull back facing weapon hit fx.", - }, - { - "cg_weaponCycleDelay", - "The delay after cycling to a new weapon to prevent holding down the cycle weapon button from cycling too fast", - }, - { - "cg_weaponHintsCoD1Style", - "Draw weapon hints in CoD1 style: with the weapon name, and with the icon below", - }, - { - "chaplinCheat", - "", - }, - { - "cl_accessibilityAkimboEnabled", - "True if accessibility configurations adjust input for akimbo weapons", - }, - { - "cl_accessibilityTurboEnabled", - "True if accessibility configurations do continuous fire for akimbo weapons", - }, - { - "cl_analog_attack_threshold", - "The threshold before firing", - }, - { - "cl_anglespeedkey", - "Multiplier for max angle speed for gamepad and keyboard", - }, - { - "cl_cinematicUnpaused", - "Allows cinematics to play while the client is paused", - }, - { - "cl_dirSelConvergenceTime", - "Time to converge to the new direction when selecting a direction on the map.", - }, - { - "cl_disable_pause", - "Disable Pause", - }, - { - "cl_force_paused", - "Force the client to be paused. Can't be overridden by LUA scripts, the start button, etc.", - }, - { - "cl_forceFoVEnabled", - "Force a modified FoV calculation for capture", - }, - { - "cl_forceFoVx", - "Force the X FoV - auto calculate it from aspect ratio and Y FoV if less than 1", - }, - { - "cl_forceFoVy", - "Force the Y FoV - auto calculate it from aspect ratio and X FoV if less than 1", - }, - { - "cl_freelook", - "Enable looking with mouse", - }, - { - "cl_freemove", - "Fly about the level", - }, - { - "cl_freemoveScale", - "Scale how fast you move in cl_freemove mode", - }, - { - "cl_lessprint", - "Print less to the console by filtering out certain spammy channels", - }, - { - "cl_modifiedDebugPlacement", - "Modify the location of debug output (outside of safe area)", - }, - { - "cl_mouseAccel", - "Mouse acceleration", - }, - { - "cl_noprint", - "Print nothing to the console", - }, - { - "cl_paused", - "Pause the game", - }, - { - "cl_paused_simple", - "Toggling pause won't do any additional special processing if true.", - }, - { - "cl_pitchspeed", - "Max pitch speed in degrees for game pad", - }, - { - "cl_showmouserate", - "Print mouse rate debugging information to the console", - }, - { - "cl_shownet", - "Display network debugging information", - }, - { - "cl_showServerCommands", - "Enable debug prints for server commands", - }, - { - "cl_spawnDebug", - "Turn on debug lines for spawning traces", - }, - { - "cl_stanceHoldTime", - "The time to hold the stance button before the player goes prone", - }, - { - "cl_testAnimWeight", - "test animation weighting", - }, - { - "cl_waterMarkEnabled", - "", - }, - { - "cl_waterMarkText", - "", - }, - { - "cl_yawspeed", - "Max yaw speed in degrees for game pad and keyboard", - }, - { - "client_trigger_draw", - "Draw client trigger geometry", - }, - { - "client_trigger_drawDepthTest", - "Display client trigger geo with depth information", - }, - { - "client_trigger_drawDistance", - "Client trigger draw distance", - }, - { - "com_animCheck", - "Check anim tree", - }, - { - "com_attractmode", - "Run attract mode", - }, - { - "com_attractmodeduration", - "Time when controller is unused before attract mode is enabled", - }, - { - "com_cinematicEndInWhite", - "Set by script. True if cinematic ends with a white screen.", - }, - { - "com_completionResolveCommand", - "Command to run when the message box successfully closes", - }, - { - "com_errorMessage", - "Most recent error message", - }, - { - "com_errorRemoveKeyCatcher", - "True if clearing the error message should also remove the ui focus", - }, - { - "com_errorResolveCommand", - "Command to run when they close the error box", - }, - { - "com_errorTitle", - "Title of the most recent error message", - }, - { - "com_filter_output", - "Use console filters for filtering output.", - }, - { - "com_maxfps", - "Cap frames per second", - }, - { - "com_maxFrameTime", - "Time slows down if a frame takes longer than this many milliseconds", - }, - { - "com_playerProfile", - "Set to the name of the profile", - }, - { - "com_reconDumpFrameStats", - "Dump frame stats for Recon", - }, - { - "com_reconDumpGpuTimings", - "Dump GPU timings for Recon", - }, - { - "com_statmon", - "Draw stats monitor", - }, - { - "com_timescale", - "", - }, - { - "commerce_dl_retry_step", - "Step in m/s for the commerce download retry", - }, - { - "commerce_manifest_file_max_retry_time", - "Max time that the commerce manifest can retry", - }, - { - "commerce_manifest_file_retry_step", - "Step in m/s for the commerce manifest retry", - }, - { - "commerce_max_dl_retry_time", - "Max time that the commerce download can retry", - }, - { - "commerce_max_retry_time", - "Max time that the commerce upload can retry", - }, - { - "commerce_retry_step", - "Step in m/s for the commerce upload retry", - }, - { - "compass", - "Display Compass", - }, - { - "compassClampIcons", - "If true, friendlies and enemy pings clamp to the edge of the radar. If false, they disappear off the edge.", - }, - { - "compassCoords", - "x = North-South coord base value, \ny = East-West coord base value, \nz = scale (game units per coord unit)", - }, - { - "compassDebug", - "Compass Debugging Mode", - }, - { - "compassECoordCutoff", - "Left cutoff for the scrolling east-west coords", - }, - { - "compassEnemyFootstepEnabled", - "Enables enemies showing on the compass because of moving rapidly nearby.", - }, - { - "compassEnemyFootstepMaxRange", - "The maximum distance at which an enemy may appear on the compass due to 'footsteps'", - }, - { - "compassEnemyFootstepMaxZ", - "The maximum vertical distance enemy may be from the player and appear on the compass due to 'footsteps'", - }, - { - "compassEnemyFootstepMinSpeed", - "The minimum speed an enemy must be moving to appear on the compass due to 'footsteps'", - }, - { - "compassFastRadarUpdateTime", - "Time between radar updates for the fast radar mode", - }, - { - "compassFriendlyHeight", - "", - }, - { - "compassFriendlyWidth", - "", - }, - { - "compassHideSansObjectivePointer", - "Hide the compass, but leave the obective pointer visible.", - }, - { - "compassHideVehicles", - "When enabled, disables the CG_PLAYER_COMPASS_VEHICLES ownerdraw.", - }, - { - "compassMaxRange", - "The maximum range from the player in world space that objects will be shown on the compass", - }, - { - "compassMinRadius", - "The minimum radius from the center of the compass that objects will appear.", - }, - { - "compassMinRange", - "The minimum range from the player in world space that objects will appear on the compass", - }, - { - "compassObjectiveArrowHeight", - "", - }, - { - "compassObjectiveArrowOffset", - "The offset of the objective arrow inward from the edge of the compass map", - }, - { - "compassObjectiveArrowRotateDist", - "Distance from the corner of the compass map at which the objective arrow rotates to 45 degrees", - }, - { - "compassObjectiveArrowWidth", - "", - }, - { - "compassObjectiveDetailDist", - "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape.", - }, - { - "compassObjectiveDrawLines", - "Draw horizontal and vertical lines to the active target, if it is within the minimap boundries", - }, - { - "compassObjectiveHeight", - "", - }, - { - "compassObjectiveIconHeight", - "", - }, - { - "compassObjectiveIconWidth", - "", - }, - { - "compassObjectiveMaxHeight", - "The maximum height that an objective is considered to be on this level", - }, - { - "compassObjectiveMaxRange", - "The maximum range at which an objective is visible on the compass", - }, - { - "compassObjectiveMinAlpha", - "The minimum alpha for an objective at the edge of the compass", - }, - { - "compassObjectiveMinDistRange", - "The distance that objective transition effects play over, centered on compassObjectiveNearbyDist.", - }, - { - "compassObjectiveMinHeight", - "The minimum height that an objective is considered to be on this level", - }, - { - "compassObjectiveNearbyDist", - "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape.", - }, - { - "compassObjectiveNumRings", - "The number of rings when a new objective appears", - }, - { - "compassObjectiveRingSize", - "The maximum objective ring sige when a new objective appears on the compass", - }, - { - "compassObjectiveRingTime", - "The amount of time between each ring when an objective appears", - }, - { - "compassObjectiveTextHeight", - "Objective text height", - }, - { - "compassObjectiveTextScale", - "Scale to apply to hud objectives", - }, - { - "compassObjectiveWidth", - "", - }, - { - "compassObjectiveWraparoundTime", - "How long it takes for the objective to wrap around the compass from one edge to the other", - }, - { - "compassPlayerHeight", - "", - }, - { - "compassPlayerWidth", - "", - }, - { - "compassRadarLineThickness", - "Thickness, relative to the compass size, of the radar texture that sweeps across the map", - }, - { - "compassRadarPingFadeTime", - "How long an enemy is visible on the compass after it is detected by radar", - }, - { - "compassRadarUpdateTime", - "Time between radar updates for the normal radar mode", - }, - { - "compassRotation", - "Style of compass", - }, - { - "compassSize", - "Scale the compass", - }, - { - "compassSoundPingFadeTime", - "The time in seconds for the sound overlay on the compass to fade", - }, - { - "compassTickertapeStretch", - "How far the tickertape should stretch from its center.", - }, - { - "comscore_active", - "Are we allowed to enable ComScore tracking or not", - }, - { - "con_default_console_filter", - "Default channel filter for the console destination.", - }, - { - "con_errormessagetime", - "Onscreen time for error messages in seconds", - }, - { - "con_inputBoxColor", - "Color of the console input box", - }, - { - "con_inputHintBoxColor", - "Color of the console input hint box", - }, - { - "con_matchPrefixOnly", - "Only match the prefix when listing matching Dvars", - }, - { - "con_minicon", - "Display the mini console on screen", - }, - { - "con_miniconlines", - "Number of lines in the minicon message window", - }, - { - "con_minicontime", - "Onscreen time for minicon messages in seconds", - }, - { - "con_outputBarColor", - "Color of the console output slider bar", - }, - { - "con_outputSliderColor", - "Color of the console slider", - }, - { - "con_outputWindowColor", - "Color of the console output", - }, - { - "con_subtitleLeading", - "Leading for subtitles, calculated as a percentage of the font height", - }, - { - "con_typewriterColorGlowCheckpoint", - "", - }, - { - "con_typewriterColorGlowCompleted", - "", - }, - { - "con_typewriterColorGlowFailed", - "", - }, - { - "con_typewriterColorGlowUpdated", - "", - }, - { - "con_typewriterColorInteriorCheckpoint", - "", - }, - { - "con_typewriterColorInteriorCompleted", - "", - }, - { - "con_typewriterColorInteriorFailed", - "", - }, - { - "con_typewriterColorInteriorUpdated", - "", - }, - { - "con_typewriterDecayDuration", - "Time (in milliseconds) to spend disolving the line away.", - }, - { - "con_typewriterDecayStartTime", - "Time (in milliseconds) to spend between the build and disolve phases.", - }, - { - "con_typewriterPrintSpeed", - "Time (in milliseconds) to print each letter in the line.", - }, - { - "consoleGame", - "True if running on a console", - }, - { - "content_download_should_auto_download", - "Checks whether we should auto download PS4 content not already downloaded or not.", - }, - { - "content_download_timer_ms", - "Number of milliseconds between calls to submit met players to the rest system.", - }, - { - "contentEnumerationAuto", - "poll enumeration", - }, - { - "contentEnumerationTimer", - "time between 2 automatic enumerations", - }, - { - "coop_matching_type_search", - "Is the matching type set to search", - }, - { - "coop_showing_game_error_popup", - "Are we showing a game error popup", - }, - { - "coopNameFontSize", - "", - }, - { - "coopNameFontSizeSplitscreen", - "", - }, - { - "counterDownloadInterval", - "Number of minutes before all the global counters are uploaded", - }, - { - "counterUploadInterval", - "Number of minutes before all the global counters are uploaded", - }, - { - "cSplineDebugRender", - "Debug Render the csplines.", - }, - { - "cSplineDebugRenderCorridor", - "Debug Render the cspline corridor.", - }, - { - "cSplineDebugRenderData", - "Debug Render the cspline data.", - }, - { - "cSplineDebugRenderSplineId", - "Select a cspline - 0 for all.", - }, - { - "damage_actorRangeFalloff", - "When true, the damage the NPCs deal falls off the further their shot travels. Otherwise it deals basedamage regardless of range.", - }, - { - "damage_rangeLerp", - "When true, lerp damage in between the max/min range by the max/min damage, otherwise just use the mid damage when in between max/min range.", - }, - { - "db_disableImageCacheEvictionQueue", - "Disables image cache streaming queued eviction", - }, - { - "dc_lobbymerge", - "Allows lobby merging across data centres", - }, - { - "debug_onlinePlayEvenIfDown", - "Whether to allow people to play even if PSN is down", - }, - { - "debugOverlay", - "Toggles the display of various debug info.", - }, - { - "debugOverlayOnly", - "Toggles whether debug Overlay hides the rest of the UI.", - }, - { - "dedicated_dhclient", - "True if we're a client playing on a DH server", - }, - { - "demigod_healthFloor", - "Sets the health floor during demigod mode.", - }, - { - "depthSortViewmodel", - "Enable depth sorting on the viewmodel.", - }, - { - "DEV_PROTOCOL_VERSION", - "Dev only: temporarily override protocol version so as not to join other dev games in progress.", - }, - { - "developer", - "Enable development options", - }, - { - "developer_looseFiles", - "Enable loose file loading for gsc/lui (PC)", - }, - { - "developer_script", - "Enable developer script comments: 0 disabled, 1 full developer script, 2 only dev scripts required by art/lighting tweaks.", - }, - { - "devgui_allowMouse", - "Devgui allow mouse input", - }, - { - "devgui_bevelShade", - "Bevel shade for the devgui", - }, - { - "devgui_colorBgnd", - "Color background for the devgui", - }, - { - "devgui_colorBgndFocus", - "Button color while the mouse hovers over it.", - }, - { - "devgui_colorBgndGray", - "Grayed out background color for the devgui", - }, - { - "devgui_colorBgndGraySel", - "Greyed out, selected background color for the devgui", - }, - { - "devgui_colorBgndHeld", - "Button color when pressed by the mouse.", - }, - { - "devgui_colorBgndSel", - "Selection background color for the devgui", - }, - { - "devgui_colorGraphKnotEditing", - "Devgui color graph knot editing color", - }, - { - "devgui_colorGraphKnotNormal", - "Devgiu Color graph knot normal color", - }, - { - "devgui_colorGraphKnotSelected", - "Devgui color graph knot selected color", - }, - { - "devgui_colorSliderBgnd", - "Color slider background for the devgui", - }, - { - "devgui_colorSliderBgndFocus", - "Focused color slider background for the devgui", - }, - { - "devgui_colorSliderBgndHeld", - "Held color slider background for the devgui", - }, - { - "devgui_colorSliderKnob", - "Knob color for the devgui", - }, - { - "devgui_colorSliderKnobFocus", - "Focused knob color for the devgui", - }, - { - "devgui_colorSliderKnobHeld", - "Held knob color for the devgui", - }, - { - "devgui_colorSliderKnobSel", - "Selected knob color for the devgui", - }, - { - "devgui_colorText", - "Text color for the devgui", - }, - { - "devgui_colorTextGray", - "Greyed out text color for the devgui", - }, - { - "devgui_colorTextGraySel", - "Greyed out, selected text color for the devgui", - }, - { - "devgui_colorTextSel", - "Selection text color for the devgui", - }, - { - "devgui_mouseScrollDelay", - "Delay before scrolling when holding the slider bar with the left mouse button.", - }, - { - "devgui_mouseScrollSpeed", - "Scroll speed when holding the slider bar with the left mouse button.", - }, - { - "disableDLC", - "", - }, - { - "disableEliteDLCCheck", - "", - }, - { - "discard_playerstats_on_suspend", - "Forces stats discard on suspend", - }, - { - "disconnectOnSignOut", - "If true, the player will be kicked back to the main menu if they sign out of their profile\n", - }, - { - "dw_addrHandleTimeout", - "Delay before destroying an addrHandle after the connection is lost\n", - }, - { - "dw_environment_server", - "Choose which Demonware environment to connect to. Use No Preference if you want to keep the default logic.", - }, - { - "dw_ignore_hack", - "Which DemonWare ignore hack fix mode to use", - }, - { - "dw_leaderboard_write_active", - "Are leaderboard writes enabled", - }, - { - "dw_memory_display_time", - "Number of seconds between high watermark display.", - }, - { - "dw_neverDisconnect", - "Set to true to avoid getting kick back to main menu when losing connection to dw.", - }, - { - "dw_presence_active", - "Is the demonware presence system enabled", - }, - { - "dw_presence_coop_join_active", - "Do we allow players to join on presence for private coop matches (post session to demonware", - }, - { - "dw_presence_get_delay", - "Number of milliseconds to wait after booting the game to fetch demonware presence", - }, - { - "dw_presence_get_rate", - "Number of milliseconds to wait between sending presence state to demonware", - }, - { - "dw_presence_put_delay", - "Number of milliseconds to wait in a presence state before sending to demonware", - }, - { - "dw_presence_put_rate", - "Number of milliseconds to wait between sending presence state to demonware", - }, - { - "dw_shared_presence_active", - "Is the demonware shared presence system enabled", - }, - { - "dw_shared_presence_get_delay", - "Number of milliseconds to wait after booting the game to fetch demonware presence", - }, - { - "dw_shared_presence_get_rate", - "Number of milliseconds to wait between sending presence state to demonware", - }, - { - "dw_shared_presence_put_delay", - "Number of milliseconds to wait in a shared presence state before sending to demonware", - }, - { - "dw_shared_presence_put_rate", - "Number of milliseconds to wait between sending presence state to demonware", - }, - { - "dw_test_disconnect", - "Simulate a demonware disconnect", - }, - { - "dw_test_retry_disconnect", - "Simulate a demonware disconnect at the end of every connection retry", - }, - { - "dwBandwidthTestTaskTimeout", - "default timeout for the bandwidth test task (in ms). 0 means no timeout", - }, - { - "dwInfoLogEnabled", - "Toggle Demonware Info log", - }, - { - "dwStorageFakeError", - "Fake errors from dwStorage", - }, - { - "dynEnt_bulletForce", - "Force applied from bullet hit", - }, - { - "dynEnt_damageScale", - "Scales damage applied to destructible dynents", - }, - { - "dynEnt_explodeForce", - "Force applied from explosion hit", - }, - { - "dynEnt_explodeMaxEnts", - "The maximum number of dynents that can be awakened by one explosion", - }, - { - "dynEnt_explodeMinForce", - "Force below which dynents won't even bother waking up", - }, - { - "dynEnt_explodeSpinScale", - "Scale of the random offset from the center of mass for explosion forces.", - }, - { - "dynEnt_explodeUpbias", - "Upward bias applied to force directions from explosion hits", - }, - { - "dynEnt_explodingBulletForce", - "Force applied from bullet explosion hit", - }, - { - "dynEnt_explodingBulletMaxEnts", - "The maximum number of dynents that can be awakened by one explosion", - }, - { - "dynEnt_explodingBulletMinForce", - "Force below which dynents won't even bother waking up", - }, - { - "dynEnt_explodingBulletSpinScale", - "Scale of the random offset from the center of mass for explosion forces.", - }, - { - "dynEnt_explodingBulletUpbias", - "Upward bias applied to force directions from explosion hits", - }, - { - "dynEnt_playerWakeUpRadius", - "Determines threshold distance from player within which all dynents are woken up.", - }, - { - "dynEnt_playerWakeUpZOffset", - "Determines vertical distance from player's feet from which wake up sphere is centered.", - }, - { - "dynEnt_showWakeUpSphere", - "Shows the wakeup spheres that are trigger by WakeUpPhysicsSphere.", - }, - { - "elite_clan_active", - "Are we allowed to show Elite Clans or not", - }, - { - "elite_clan_cool_off_time", - "Cool off time between calls to fetch the elite clan", - }, - { - "elite_clan_delay", - "Delay before the bdTeams calls start to Demonware. -1 means On-Demand and it will wait until the 'starteliteclan' menu call", - }, - { - "elite_clan_division_icon_active", - "Are we allowed to show Elite Clan division icon or not", - }, - { - "elite_clan_get_blob_profile_max_retry_time", - "Max time that the Elite Clan get private profile can retry", - }, - { - "elite_clan_get_blob_profile_retry_step", - "Step in m/s for the Elite Clan get private profile retry", - }, - { - "elite_clan_get_clan_max_retry_time", - "Max time that the Elite Clan get clan can retry", - }, - { - "elite_clan_get_clan_retry_step", - "Step in m/s for the Elite Clan get clan retry", - }, - { - "elite_clan_get_members_max_retry_time", - "Max time that the Elite Clan get members can retry", - }, - { - "elite_clan_get_members_retry_step", - "Step in m/s for the Elite Clan get members retry", - }, - { - "elite_clan_get_private_member_profile_max_retry_time", - "Max time that the Elite Clan get private profile can retry", - }, - { - "elite_clan_get_private_member_profile_retry_step", - "Step in m/s for the Elite Clan get private profile retry", - }, - { - "elite_clan_get_public_profile_max_retry_time", - "Max time that the Elite Clan get public profile can retry", - }, - { - "elite_clan_get_public_profile_retry_step", - "Step in m/s for the Elite Clan get public profile retry", - }, - { - "elite_clan_get_team_stats_max_retry_time", - "Max time that the Elite Clan get team stats can retry", - }, - { - "elite_clan_get_team_stats_retry_step", - "Step in m/s for the Elite Clan get team stats retry", - }, - { - "elite_clan_motd_throttle_time", - "Throttle time between motd update calls", - }, - { - "elite_clan_send_message_to_members_max_retry_time", - "Max time that the Elite Clan send message to members can retry", - }, - { - "elite_clan_send_message_to_members_retry_step", - "Step in m/s for the Elite Clan send message to members retry", - }, - { - "elite_clan_set_private_member_profile_max_retry_time", - "Max time that the Elite Clan set private member profile can retry", - }, - { - "elite_clan_set_private_member_profile_retry_step", - "Step in m/s for the Elite Clan set private member profile retry", - }, - { - "elite_clan_single_task_popup_text", - "String to be displayed on popup when a single task is being performed", - }, - { - "elite_clan_using_title", - "Stores whether the Elite Clan title is in use by the user", - }, - { - "enable_recordRecentActivity", - "records the timestamp of when the player was recently active to the tracker leaderboards", - }, - { - "energyWeaponDebugDraw", - "Draw energy weapon areas.", - }, - { - "entitlements_active", - "Are we allowed to show Entitlements or not", - }, - { - "entitlements_config_file_max_retry_time", - "Max time that the Entitlements config file read can retry", - }, - { - "entitlements_config_file_retry_step", - "Step in m/s for the Entitlements config file read retry", - }, - { - "entitlements_cool_off_time", - "Cool off time between calls to fetch the elite clan", - }, - { - "entitlements_delay", - "Delay before the entitlement calls start to Demonware. -1 means On-Demand and it will wait until the 'startentitlements' menu call", - }, - { - "entitlements_key_archive_max_retry_time", - "Max time that the Entitlements key archive read can retry", - }, - { - "entitlements_key_archive_retry_step", - "Step in m/s for the Entitlements key archive read retry", - }, - { - "entitlementSystemOk", - "Set by the game to inform that the entitlement system is initialised", - }, - { - "facebook_active", - "Are we allowed to show Facebook or not", - }, - { - "facebook_delay", - "Delay before the Facebook calls start to Demonware. -1 means On-Demand and it will wait until the 'startfacebook' menu call", - }, - { - "facebook_friends_active", - "Are we allowed to show Facebook Friends or not", - }, - { - "facebook_friends_max_retry_time", - "Max time that the Facebook friends read can retry", - }, - { - "facebook_friends_refresh_time", - "Time in seconds between Facebook friend refreshes", - }, - { - "facebook_friends_retry_step", - "Step in m/s for the Facebook friends read retry", - }, - { - "facebook_friends_showing_count", - "Contains how many facebook friends are being shown in the UI.", - }, - { - "facebook_friends_throttle_time", - "Throttle time between Facebook friend pages", - }, - { - "facebook_max_retry_time", - "Max time that the Facebook authentication can retry", - }, - { - "facebook_password", - "Facebook Password", - }, - { - "facebook_password_asterisk", - "Facebook Password (Asterisk Version)", - }, - { - "facebook_popup_text", - "Facebook Popup Text", - }, - { - "facebook_retry_step", - "Step in m/s for the Facebook authentication retry", - }, - { - "facebook_upload_photo_active", - "Are we allowed to Upload Photos to Facebook or not", - }, - { - "facebook_upload_video_active", - "Are we allowed to Upload Videos to Facebook or not", - }, - { - "facebook_username", - "Facebook Username", - }, - { - "fastfile_loadDevelopment", - "Enable/Disable loading of the development fast file.", - }, - { - "fixedtime", - "Use a fixed time rate for each frame", - }, - { - "FoFIconMaxSize", - "Maximum size a Friend-or-Foe icon should ever grow to.", - }, - { - "FoFIconMinSize", - "Minimum size a Friend-or-Foe icon should ever shrink to.", - }, - { - "FoFIconScale", - "Base scale of Friend-or-Foe icons.", - }, - { - "force_ranking", - "Set to true to allow private or system link games to use the ranking system", - }, - { - "friction", - "Player friction", - }, - { - "friendlyNameFontColor", - "", - }, - { - "friendlyNameFontGlowColor", - "", - }, - { - "friendlyNameFontSize", - "Fontsize of the popup friendly names.", - }, - { - "friendlyNameFontSizeSplitscreen", - "Fontsize of the popup friendly names, in splitscreen.", - }, - { - "fs_basegame", - "Base game name", - }, - { - "fs_basepath", - "Base game path", - }, - { - "fs_basepath_output", - "Base game path", - }, - { - "fs_cdpath", - "CD path", - }, - { - "fs_copyfiles", - "Copy all used files to another location", - }, - { - "fs_debug", - "Enable file system debugging information", - }, - { - "fs_game", - "Game data directory. Must be \"\" or a sub directory of 'mods/'.", - }, - { - "fs_homepath", - "Game home path", - }, - { - "fs_ignoreLocalized", - "Ignore localized assets", - }, - { - "fx_alphaThreshold", - "Don't draw billboard sprites, oriented sprites or tails with alpha below this threshold (0-256).", - }, - { - "fx_cast_shadow", - "Enable transparency shadow mapping from script", - }, - { - "fx_count", - "Debug effects count", - }, - { - "fx_cull_elem_draw", - "Culls effect elems for drawing", - }, - { - "fx_cull_elem_draw_flicker", - "Flicker DPVS culled effect elems", - }, - { - "fx_cull_elem_spawn", - "Culls effect elems for spawning", - }, - { - "fx_debug3D", - "Turn on effect system debug information, parameter is culling distance", - }, - { - "fx_debugAssertQuat", - "Turn on/off debug asserts for quaternions in the fx system", - }, - { - "fx_debugBolt", - "Debug effects bolt", - }, - { - "fx_deferelem", - "Toggles deferred processing of elements instead of effects", - }, - { - "fx_dpvs_cull_elem_draw", - "Culls effect elems for drawing using DPVS(2: ignore per-effect portal culling flag)", - }, - { - "fx_draw", - "", - }, - { - "fx_draw_omniLight", - "", - }, - { - "fx_draw_simd", - "Draw effects using SIMD / Vector code.", - }, - { - "fx_draw_spotLight", - "", - }, - { - "fx_drawClouds", - "Toggles the drawing of particle clouds", - }, - { - "fx_dump", - "Sends debug info on PlayFX and PlayFXToTag calls within units of player to the console", - }, - { - "fx_enable", - "Toggles all effects processing", - }, - { - "fx_flare", - "Toggles fx flare", - }, - { - "fx_forceEffectPass", - "Forces effects to render in trans, emissive, or default mode", - }, - { - "fx_freeze", - "Freeze effects", - }, - { - "fx_killEffectOnRewind", - "Causes effects that have been marked for a soft kill (fade out) to be killed immediately on a rewind.", - }, - { - "fx_lightGridSampleOffset", - "the length of effect sample's offset along X Axis", - }, - { - "fx_mark_profile", - "Turn on FX profiling for marks (specify which local client, with '1' being the first.)", - }, - { - "fx_marks", - "Toggles whether bullet hits leave marks", - }, - { - "fx_marks_ents", - "Toggles whether bullet hits leave marks", - }, - { - "fx_marks_nearlimit", - "Sets limit of number of decals that can exist at the same location (0 for unlimited)", - }, - { - "fx_marks_smodels", - "Toggles whether bullet hits leave marks", - }, - { - "fx_overrideLightFrac", - "Overrides every lighting-frac value, 0 is all unlit, to 1 that is 100% lit - the default of -1 restores segment lighting-frac values", - }, - { - "fx_physicsImpactVelocityThreshold", - "Set the min normal velocity threshold in order for model physics fx to generate child impact effects.", - }, - { - "fx_profile", - "Turn on FX profiling (specify which local client, with '1' being the first.)", - }, - { - "fx_profileFilter", - "Only show effects with this as a substring in FX profile", - }, - { - "fx_profileFilterElemCountZero", - "Do not include FX that have a zero element count", - }, - { - "fx_profileSkip", - "Skip the first n lines in FX profile (to see ones off bottom of screen)", - }, - { - "fx_profileSort", - "Choose sort criteria for FX profiling", - }, - { - "fx_showLightGridSampleOffset", - "show light grid sample offset in CreateFX mode", - }, - { - "fx_visMinTraceDist", - "Minimum visibility trace size", - }, - { - "g_ai", - "Enable AI", - }, - { - "g_aiAnimscript", - "Enable AI animscript", - }, - { - "g_aiEventDump", - "Print AI events happening for this entity", - }, - { - "g_aiEventListenerDump", - "Dump the AI event listeners once. Automatically reset to false after dump", - }, - { - "g_allowUnusedPak", - "enable loading of texture mips from unused pak", - }, - { - "g_anim_mp_idle_turn_angle", - "Rotation amount of 3rd-person pivot when player rotates in place while standing.", - }, - { - "g_anim_mp_idle_turn_anim_duration", - "Duration of 3rd-person pivot animation.", - }, - { - "g_anim_mp_idle_turn_rotate_crouch_end", - "Time during 3rd-person crouched pivot at which the player stops rotating in place.", - }, - { - "g_anim_mp_idle_turn_rotate_crouch_start", - "Time during 3rd-person crouched pivot at which the player stops rotating in place.", - }, - { - "g_anim_mp_idle_turn_rotate_prone_end", - "Time during 3rd-person prone pivot at which the player stops rotating in place.", - }, - { - "g_anim_mp_idle_turn_rotate_prone_start", - "Time during 3rd-person prone pivot at which the player stops rotating in place.", - }, - { - "g_anim_mp_idle_turn_rotate_stand_end", - "Time during 3rd-person standing pivot at which the player stops rotating in place.", - }, - { - "g_anim_mp_idle_turn_rotate_stand_start", - "Time during 3rd-person standing pivot at which the player stops rotating in place.", - }, - { - "g_anim_mp_idle_turn_trigger_angle", - "Aim yaw angle at which 3rd-person pivot triggers.", - }, - { - "g_animated_lean_blends", - "Toggles between procedural (0) and blended (1) MP lean animation techniques.", - }, - { - "g_animsCommandsVerbose", - "Dump all animation commands. If false, calls marked as verbose will not be printed", - }, - { - "g_atmosFogDistanceScaleReadOnly", - "scale applied to scene distance used for atmospheric fog calculation", - }, - { - "g_atmosFogEnabledReadOnly", - "use atmospheric fog", - }, - { - "g_atmosFogExtinctionStrengthReadOnly", - "scale out scatter contribution of atmospheric fog", - }, - { - "g_atmosFogHalfPlaneDistanceReadOnly", - "distance at which atmospheric fog contributes half the pixels color", - }, - { - "g_atmosFogHazeSpreadReadOnly", - "directionality of haze (1ReadOnly = all forward scatter, 0ReadOnly = all back scatter)", - }, - { - "g_atmosFogHazeStrengthReadOnly", - "portion of atmospheric fog density that is haze (0ReadOnly = all fog, 1ReadOnly = all haze)", - }, - { - "g_atmosFogHeightFogBaseHeightReadOnly", - "height fog is full density at this world height and below", - }, - { - "g_atmosFogHeightFogEnabledReadOnly", - "use height for atmospheric fog", - }, - { - "g_atmosFogHeightFogHalfPlaneDistanceReadOnly", - "at this distance above g_atmosFogHeightFogBaseHeight, height fog density is half", - }, - { - "g_atmosFogInScatterStrengthReadOnly", - "scale in scatter contribution of atmospheric fog", - }, - { - "g_atmosFogSkyAngularFalloffEnabledReadOnly", - "use angular sky falloff for atmospheric fog", - }, - { - "g_atmosFogSkyDistanceReadOnly", - "distance used for sky box when applying atmospheric fog", - }, - { - "g_atmosFogSkyFalloffAngleRangeReadOnly", - "sky fog angular falloff angle range sky fog falls off over this range from the start angle", - }, - { - "g_atmosFogSkyFalloffStartAngleReadOnly", - "sky fog angular falloff start angle (full strength fog at this angle)", - }, - { - "g_atmosFogStartDistanceReadOnly", - "distance from camera at which fog contribution begins", - }, - { - "g_atmosFogSunDirectionReadOnly", - "sun direction used when calculating atmospheric fog", - }, - { - "g_changelevel_time", - "Time for change level fade out", - }, - { - "g_deathDelay", - "Delay a level restart on death", - }, - { - "g_debugBullets", - "Show debug information for bullets", - }, - { - "g_debugDamage", - "Turn on debug information for damage", - }, - { - "g_debugLocDamage", - "Display locational damage debug information for an entity", - }, - { - "g_debugLocHit", - "Display locational damage info for an entity when the entity is hit", - }, - { - "g_debugLocHitTime", - "Time duration of g_debugLocHit lines", - }, - { - "g_disableAnimTransitions", - "Turns off the animation transition control tables", - }, - { - "g_disableBulletPenetration", - "Removes all bullet penetration.", - }, - { - "g_dobjdump", - "Write dobj debug info for this entity", - }, - { - "g_drawDefaultStaticModels", - "Static default xmodels (the big red FX placeholder) are not rendered by default. Enabling this affects transient performance.", - }, - { - "g_drawEntBBoxes", - "Draw entity bounding boxes", - }, - { - "g_drawGrenadeHints", - "Draw debug information for grenades", - }, - { - "g_dumpAnims", - "Write animation debug info for this entity", - }, - { - "g_dumpAnimsCommands", - "Write animation commands debug info for this entity", - }, - { - "g_dumpAnimTransitions", - "Write animation transition debug info for this entity", - }, - { - "g_earthquakeEnable", - "Enable camera shake", - }, - { - "g_enableAccurateTrace", - "Turn on accurate trace, for actors", - }, - { - "g_entinfo", - "Display entity information", - }, - { - "g_entinfo_AItext", - "Type of text information for AI entinfo", - }, - { - "g_entinfo_maxdist", - "Maximum distance of an entity from the camera at which to show entity information", - }, - { - "g_entinfo_scale", - "Scale of the entity information text", - }, - { - "g_entinfo_type", - "Type of entities to display information", - }, - { - "g_fogColorIntensityReadOnly", - "HDR Fog color intensity that was set in the most recent call to \"setexpfog\"", - }, - { - "g_fogColorReadOnly", - "Fog color that was set in the most recent call to \"setexpfog\"", - }, - { - "g_fogHalfDistReadOnly", - "", - }, - { - "g_fogMaxOpacityReadOnly", - "Fog max opacity that was set in the most recent call to \"setexpfog\"", - }, - { - "g_fogStartDistReadOnly", - "", - }, - { - "g_friendlyfireDamageScale", - "Scales player damage from other players", - }, - { - "g_friendlyfireDist", - "Maximum distance at which the player channot shoot while the crosshair is over a friendly", - }, - { - "g_friendlyNameDist", - "Maximum distance at which a friendly name shows when the crosshairs is over them", - }, - { - "g_gameskill", - "Game skill level", - }, - { - "g_giveAll", - "Give all weapons", - }, - { - "g_gravity", - "Gravity in inches per second per second", - }, - { - "g_grenadeDamageMaxHeight", - "Maximum vertical distance at which a grenade will do damage when exploding", - }, - { - "g_heightFogBaseHeightReadOnly", - "height fog is full density at this world height and below", - }, - { - "g_heightFogEnabledReadOnly", - "use height for normal/sun fog, set in the most recent call to \"setexpfog\"", - }, - { - "g_heightFogHalfPlaneDistanceReadOnly", - "at this distance above g_heightFogBaseHeight, height fog density is half, set in the most recent call to \"setexpfog\"", - }, - { - "g_hideMissingXmodels", - "Hide missing xmodels, instead of drawing a big red FX. Must be set on boot command-line, not at runtime.", - }, - { - "g_knockback", - "Maximum player knockback", - }, - { - "g_listEntity", - "list all of the current entities", - }, - { - "g_minGrenadeDamageSpeed", - "Minimum speed at which getting hit be a grenade will do damage (not the grenade explosion damage)", - }, - { - "g_notifydump", - "Write notify debug info for this entity", - }, - { - "g_onlyPlayerAreaEntities", - "Only checks client entities with movers. SP only.", - }, - { - "g_player_maxhealth", - "Player's maximum health", - }, - { - "g_recordScriptPlace", - "Records the file and line of the current script command", - }, - { - "g_reloading", - "True if the game is reloading", - }, - { - "g_singleplayerAntilag", - "Enable singleplayer/co-op antilag", - }, - { - "g_spawnai", - "Enable AI spawning", - }, - { - "g_speed", - "Maximum player speed", - }, - { - "g_streamingEnable", - "enable loading of textures (priorities will still be calculated)", - }, - { - "g_sunFogBeginFadeAngleReadOnly", - "Angle from the sun direction to start fade away from the sun fog color that was set in the most recent call to \"setexpfog\"", - }, - { - "g_sunFogColorIntensityReadOnly", - "HDR Sun fog color intensity that was set in the most recent call to \"setexpfog\"", - }, - { - "g_sunFogColorReadOnly", - "Sun fog color that was set in the most recent call to \"setexpfog\"", - }, - { - "g_sunFogDirReadOnly", - "Sun fog direction that was set in the most recent call to \"setexpfog\"", - }, - { - "g_sunFogEnabledReadOnly", - "Sun fog was enabled in the most recent call to \"setexpfog\"", - }, - { - "g_sunFogEndFadeAngleReadOnly", - "Angle from the sun direction to end fade away from the sun fog color that was set in the most recent call to \"setexpfog\"", - }, - { - "g_sunFogScaleReadOnly", - "Distance scale in the sun fog direction that was set in the most recent call to \"setexpfog\"", - }, - { - "g_useholdtime", - "The time to hold down the 'use' button to activate a 'use' command on a gamepad", - }, - { - "g_vehicleDebug", - "Turn on debug information for vehicles", - }, - { - "g_vehicleDrawPath", - "Turn on debug information for vehicle paths", - }, - { - "gamedate", - "The date compiled", - }, - { - "gamedvr_active", - "Are we allowed to enable GameDVR or not", - }, - { - "gamedvr_prohibitrecording", - "Allow user to capture video", - }, - { - "gamedvr_prohibitscreenshot", - "Allow user to capture screenshots", - }, - { - "gamedvr_screenshotcomment", - "Comment embedded in user screenshot", - }, - { - "gamedvr_screenshotgametitle", - "Game name embedded in user screenshot", - }, - { - "gamedvr_screenshottitle", - "Photo title embedded in user screenshot", - }, - { - "gamedvr_videocomment", - "", - }, - { - "gamedvr_videocopyright", - "", - }, - { - "gamedvr_videodescription", - "", - }, - { - "gamedvr_videotitle", - "Subtitle for recorded video", - }, - { - "gameMode", - "Current gameMode", - }, - { - "glass_angular_vel", - "Sets the range of angular velocities used by new glass pieces", - }, - { - "glass_beamDamage", - "The amount of damage beam attacks do to glass", - }, - { - "glass_break", - "Toggle whether or not glass breaks when shot", - }, - { - "glass_crack_pattern_scale", - "The scale applied to the radius used for the crack pattern", - }, - { - "glass_damageToDestroy", - "The amount of damage a piece of glass must take to look damaged", - }, - { - "glass_damageToWeaken", - "The amount of damage a piece of glass must take to look damaged", - }, - { - "glass_debug", - "Shows debug info for glass", - }, - { - "glass_edge_angle", - "Sets the range of angle deflections used by new glass pieces on a supported edge", - }, - { - "glass_fall_delay", - "Sets how long a heavy piece supported by a single edge waits before falling, based on glass_fall_ratio", - }, - { - "glass_fall_gravity", - "Gravity for falling pieces of glass", - }, - { - "glass_fall_ratio", - "Ratio of piece area to supporting edge length squared. Below the min, the piece never falls.", - }, - { - "glass_fringe_maxcoverage", - "The maximum portion of the original piece of glass that is allowed to remain after the glass shatters", - }, - { - "glass_fringe_maxsize", - "The maximum area for an edge piece of glass when shattering. Pieces larger than this will be broken into smaller ones", - }, - { - "glass_fx_chance", - "Chance to play an effect on a small piece of glass when it hits the ground", - }, - { - "glass_hinge_friction", - "Friction used by moving glass pieces when joined like a hinge to a frame", - }, - { - "glass_linear_vel", - "Sets the range of linear velocities used by new glass pieces", - }, - { - "glass_max_pieces_per_frame", - "Maximum number of pieces to create in one frame. This is a guideline and not a hard limit.", - }, - { - "glass_max_shatter_fx_per_frame", - "Maximum number of shatter effects to play in one frame This is a guideline and not a hard limit.", - }, - { - "glass_meleeDamage", - "The amount of damage melee attacks do to glass", - }, - { - "glass_physics_chance", - "The chance for a given shard of glass to use physics", - }, - { - "glass_physics_maxdist", - "The maximum distance of a glass piece from the player to do physics", - }, - { - "glass_radiusDamageMultiplier", - "The amount to scale damage to glass from grenades and other explosions", - }, - { - "glass_shard_maxsize", - "The maximum area for a flying piece of glass when shattering. Pieces larger than this will be broken into smaller ones", - }, - { - "glass_shattered_scale", - "The scale of the shattered glass material", - }, - { - "glass_simple_duration", - "The time (in ms) that simple (non-physics) glass pieces live for", - }, - { - "glass_spam", - "Toggle extra spam to help repro glass asserts", - }, - { - "glass_trace_interval", - "The length of time, in milliseconds, between glass piece traces", - }, - { - "gpad_button_deadzone", - "Game pad button deadzone threshhold", - }, - { - "gpad_button_rstick_deflect_max", - "Maximum right stick deflection", - }, - { - "gpad_dpadDebounceTime", - "", - }, - { - "gpad_menu_scroll_delay_first", - "Menu scroll key-repeat delay, for the first repeat, in milliseconds", - }, - { - "gpad_menu_scroll_delay_rest_accel", - "Menu scroll key-repeat delay acceleration from start to end, for repeats after the first, in milliseconds per repeat", - }, - { - "gpad_menu_scroll_delay_rest_end", - "Menu scroll key-repeat delay end, for repeats after the first, in milliseconds", - }, - { - "gpad_menu_scroll_delay_rest_start", - "Menu scroll key-repeat delay start, for repeats after the first, in milliseconds", - }, - { - "gpad_rumbleHighThreshold", - "Game pad activation threshold for the high frequency rumble", - }, - { - "gpad_stick_deadzone_max", - "Game pad maximum stick deadzone", - }, - { - "gpad_stick_deadzone_min", - "Game pad minimum stick deadzone", - }, - { - "gpad_stick_pressed", - "Game pad stick pressed threshhold", - }, - { - "gpad_stick_pressed_hysteresis", - "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing", - }, - { - "gpad_touchpad_deadzone_max", - "Touch pad maximum deadzone", - }, - { - "gpad_touchpad_deadzone_min", - "Touch pad minimum deadzone", - }, - { - "gpad_vita_sensitivity", - "Vita sensitivity scale", - }, - { - "grapple_magnet_draw", - "Draw grapple magnet points", - }, - { - "grapple_magnet_draw_dist", - "Draw grapple magnet point max range", - }, - { - "grapple_magnet_draw_fov", - "Draw grapple magnet point max fov", - }, - { - "grapple_surface_dot_limit", - "Surface normal dot limit that can be grappled to [cos(angle limit)]", - }, - { - "grenadeBounceRestitutionMax", - "Cap to keep code from increasing bounce restitution too high.", - }, - { - "grenadeBumpFreq", - "How likely (per server frame) a bump will occur", - }, - { - "grenadeBumpMag", - "Size of bumps (as a fraction of the grenade's current speed)", - }, - { - "grenadeBumpMax", - "Maximum upward speed of a bump (inches/sec)", - }, - { - "grenadeCurveMax", - "Largest rolling curvature (will be random between +/- this value)", - }, - { - "grenadeFrictionHigh", - "The amount of friction (0 to 1) for fast-moving grenades", - }, - { - "grenadeFrictionLow", - "The amount of friction (0 to 1) for slower/rolling grenades", - }, - { - "grenadeFrictionMaxThresh", - "The speed threshold that determines whether to use grenadeFrictionLow/High", - }, - { - "grenadeRestThreshold", - "The speed threshold below which grenades will come to rest", - }, - { - "grenadeRollingEnabled", - "Enables the new \"rolling\" grenade behavior", - }, - { - "grenadeWobbleFreq", - "Wobble cycles per inch of rolling distance (approx)", - }, - { - "grenadeWobbleFwdMag", - "The forward rolling speed will oscillate +/- this amount", - }, - { - "grenadeWobbleSideDamp", - "The rate at which the amount of side-to-side wobbling decreases as overall grenade speed increases", - }, - { - "grenadeWobbleSideMag", - "The distance to wobble left and right", - }, - { - "groupDownloadInterval", - "Minimum interval to wait before getting new group counts", - }, - { - "groupUploadInterval", - "Minimum interval to wait before setting new group counts", - }, - { - "hiDef", - "True if the game video is running in high-def.", - }, - { - "hostileNameFontColor", - "", - }, - { - "hostileNameFontGlowColor", - "", - }, - { - "httpnetfs", - "Stream fastfiles from the specified http server", - }, - { - "hud_bloodOverlayLerpRate", - "Rate at which blood overlay fades out", - }, - { - "hud_deathQuoteFadeTime", - "The time for the death quote to fade", - }, - { - "hud_drawHUD", - "Draw HUD elements. Controlled from non-UI script", - }, - { - "hud_fade_ammodisplay", - "The time for the ammo display to fade in seconds", - }, - { - "hud_fade_compass", - "The time for the compass to fade in seconds", - }, - { - "hud_fade_healthbar", - "The time for the health bar to fade in seconds", - }, - { - "hud_fade_offhand", - "The time for the offhand weapons to fade in seconds", - }, - { - "hud_fade_sprint", - "The time for the sprint meter to fade in seconds", - }, - { - "hud_fade_stance", - "The time for the stance to fade in seconds", - }, - { - "hud_flash_period_offhand", - "Offhand weapons flash period on changing weapon", - }, - { - "hud_flash_time_offhand", - "Offhand weapons flash duration on changing weapon", - }, - { - "hud_forceMantleHint", - "When true, forces the display of the mantle hint. Can still be overridden by, for example, hud drawing being off.", - }, - { - "hud_health_pulserate_critical", - "The pulse rate of the 'critical' pulse effect", - }, - { - "hud_health_pulserate_injured", - "The pulse rate of the 'injured' pulse effect", - }, - { - "hud_health_startpulse_critical", - "The health level at which to start the 'injured' pulse effect", - }, - { - "hud_health_startpulse_injured", - "The health level at which to start the 'injured' pulse effect", - }, - { - "hud_letterBoxFadeTime", - "The time for the letter box to fade after slam zoom", - }, - { - "hud_lui_hideshow_debug", - "Debug the hide/show debug info", - }, - { - "hud_missionFailed", - "Intended to be set by script and referenced by hud.menu elements.", - }, - { - "hud_showStance", - "When true, allow player's stance indicator to draw.", - }, - { - "hudElemPausedBrightness", - "Brightness of the hudelems when the game is paused.", - }, - { - "hudOutlineDuringADS", - "Turn on the HUD outline (green for friendly, red for enemy) when you are pointing at a player while in ADS.", - }, - { - "igs_sosp", - "Show Original Season Pass", - }, - { - "igs_td", - "Show Trial DLC", - }, - { - "imageCache_allocationLimit", - "Limit in GB image cache is allowed to allocate", - }, - { - "imageCache_ShowDebugPrints", - "Enable image cache debug prints to aid in following images through the system.", - }, - { - "intro", - "Intro movie should play", - }, - { - "inventoryHasAllItems", - "Simulate all items being in the inventory", - }, - { - "inviteText", - "Text to display for the game invite", - }, - { - "jump_auto_mantle", - "Auto mantle when jumping", - }, - { - "jump_auto_mantle_max_z_vel", - "Auto mantle when high jumping", - }, - { - "jump_height", - "The maximum height of a player's jump", - }, - { - "jump_ladderPushVel", - "The velocity of a jump off of a ladder", - }, - { - "jump_slowdownEnable", - "Slow player movement after jumping", - }, - { - "jump_spreadAdd", - "The amount of spread scale to add as a side effect of jumping", - }, - { - "jump_stepSize", - "The maximum step up to the top of a jump arc", - }, - { - "laserDebug", - "Enables the display of various debug info.", - }, - { - "laserForceOn", - "Force laser sights on in all possible places (for debug purposes).", - }, - { - "lb_file", - "Current Spec Ops leaderboard file", - }, - { - "lb_filter", - "Filter applied to the leaderboard display: ('none','friends','facebook_friends')", - }, - { - "lb_filter_duration", - "Current Spec Ops leaderboard filter duration", - }, - { - "lb_group", - "GroupID applied to the leaderboard display", - }, - { - "lb_maxrows", - "Maximum number of rows to fetch", - }, - { - "lb_minrefresh", - "Minimum time (in seconds) between leaderboard fetches", - }, - { - "lb_readDelay", - "Delay time between reads(in milliseconds) between leaderboard fetches", - }, - { - "lb_throttle_time", - "Lobby throttling amount", - }, - { - "lb_times_in_window", - "Lobby throttling window amount", - }, - { - "lb_window", - "Lobby throttling window", - }, - { - "le_verbose", - "Light edit system verbosity", - }, - { - "limited_mode", - "", - }, - { - "live_qosec_firstupdatems", - "MS to wait before deciding to early out qos", - }, - { - "live_qosec_lastupdatems", - "MS since last update required to early out qos", - }, - { - "live_qosec_maxtime", - "Maximum time to allow before qos early out, even if no results", - }, - { - "live_qosec_minpercent", - "Minimum percentage of probe results required before early outing qos", - }, - { - "live_qosec_minprobes", - "Minimum probe results required before early outing qos", - }, - { - "live_test_onlinedataoff", - "Bit flags corresponding enum OnlineDataSyncFlags that indicate we do not have that piece of data", - }, - { - "liveanticheatunknowndvar", - "Live Anti Cheat Unknown Dvar", - }, - { - "livestreaming_active", - "Are we allowed to enable LiveStreaming or not", - }, - { - "livestreaming_bitrate", - "Maximum bitrate of the stream", - }, - { - "livestreaming_enable", - "Enable streaming video output. Stream displays standin audio/video when disabled.", - }, - { - "livestreaming_enablearchive", - "Allow live stream to be archived by the streaming service.", - }, - { - "livestreaming_metadata", - "Metadata for livestreaming, visible to viewers.", - }, - { - "lmc", - "Load my changes fast file on devmap.", - }, - { - "loading_sre_fatal", - "Loading errors prevent level from loading.", - }, - { - "loc_language", - "Language", - }, - { - "loc_translate", - "Enable translations", - }, - { - "loc_warnings", - "Enable localization warnings", - }, - { - "loc_warningsAsErrors", - "Throw an error for any unlocalized string", - }, - { - "loc_warningsUI", - "Enable localization warnings for UI", - }, - { - "lockAllItems", - "Simulate all items being locked", - }, - { - "log_host_migration_chance", - "The % chance of host migration results telemetry", - }, - { - "log_ImageLoadTime", - "Toggle the output of images loading time", - }, - { - "log_mapvote_chance", - "The % chance of sending map vote telemetry", - }, - { - "log_teambalance_chance", - "The % chance of team balance results telemetry", - }, - { - "logfile", - "Write to log file - 0 = disabled, 1 = async file write, 2 = Sync every write", - }, - { - "logScriptTimes", - "Log times for every print called from script", - }, - { - "lowAmmoWarningColor1", - "Color 1 of 2 to oscilate between", - }, - { - "lowAmmoWarningColor2", - "Color 2 of 2 to oscilate between", - }, - { - "lowAmmoWarningNoAmmoColor1", - "Like lowAmmoWarningColor1, but when no ammo.", - }, - { - "lowAmmoWarningNoAmmoColor2", - "lowAmmoWarningColor2, but when no ammo.", - }, - { - "lowAmmoWarningNoReloadColor1", - "Like lowAmmoWarningColor1, but when no ammo.", - }, - { - "lowAmmoWarningNoReloadColor2", - "lowAmmoWarningColor2, but when no ammo.", - }, - { - "lowAmmoWarningPulseFreq", - "Frequency of the pulse (oscilation between the 2 colors)", - }, - { - "lowAmmoWarningPulseMax", - "Min of oscilation range: 0 is color1 and 1.0 is color2. Can be < 0, and the wave will clip at 0.", - }, - { - "lowAmmoWarningPulseMin", - "Max of oscilation range: 0 is color1 and 1.0 is color2. Can be > 1.0, and the wave will clip at 1.0.", - }, - { - "ls_enableLevelStatTracking", - "if true, level stat tracking can be turned on/off. Set this on the command line before startup.", - }, - { - "lsp_enumertion_max_retry_time", - "Max time that the LSP enumeration can retry", - }, - { - "lsp_enumertion_retry_step", - "Step in m/s for the LSP enumeration retry", - }, - { - "lui_demoMode", - "Check if the game is in demo mode.", - }, - { - "lui_disable_blur", - "Disable LUI blur", - }, - { - "lui_drawdesigngrid", - "Show design grid.", - }, - { - "lui_drawmemreport", - "Show information about memory usage of the LUI system", - }, - { - "lui_enabled", - "Enables LUI", - }, - { - "lui_FFotDLocalLoadEnabled", - "Load the ffotd.lua file from the local patch for testing (Dev Only)", - }, - { - "lui_FFotDSupportEnabled", - "Enables lui to update itself via the ffotd", - }, - { - "lui_forcelinedraws", - "Force the minimum size of a quad to be at least 1 pixel", - }, - { - "lui_hud_motion_angle_ease_speed", - "Hud motion ease percentage of degrees per second", - }, - { - "lui_hud_motion_bob_scale", - "Hud motion bob scale", - }, - { - "lui_hud_motion_enabled", - "Enable hud motion", - }, - { - "lui_hud_motion_perspective", - "value for hud motion perspective transform in pixels", - }, - { - "lui_hud_motion_rotation_max", - "Hud motion rotation max", - }, - { - "lui_hud_motion_rotation_scale", - "Hud motion rotation scale", - }, - { - "lui_hud_motion_trans_ease_speed", - "Hud motion ease percentage of pixels per second", - }, - { - "lui_hud_motion_translation_max", - "Hud motion translation max", - }, - { - "lui_hud_motion_translation_scale", - "Hud motion translation scale", - }, - { - "LUI_MemErrorsFatal", - "Out of memory errors cause drops when true, reinits the UI system if false", - }, - { - "lui_menuFlowEnabled", - "Enables LUI menu flow", - }, - { - "lui_pausemenu", - "Use the lui version of the pausemenu", - }, - { - "lui_ReloadMenuRestore", - "Restore the menu state after luiReload", - }, - { - "lui_splitscreenExtraMemory", - "Increase the memory grab in splitscreen", - }, - { - "lui_splitscreensignin_menu", - "Enables the LUI splitscreensignin menu", - }, - { - "lui_splitscreenupscaling", - "Force splitscreen upscaling off/on (-1 off, 1 on) -- requires map change", - }, - { - "lui_systemlink_menu", - "Enables the LUI systemlink menu", - }, - { - "lui_timescale", - "Scale time of each frame of LUI animation", - }, - { - "lui_waitingforgavelmessagesconfirmed", - "", - }, - { - "lui_waitingfornetworktype", - "value is LuiWaitingForNetworkType enum", - }, - { - "lui_waitingforonlinedatafetch_controller", - "the controller index that is fetching the online stats data", - }, - { - "LUI_WorkerCmdGC", - "Dev-only flag to enable/disable LUI workerCmd GC thread", - }, - { - "lui_xboxlive_menu", - "Enables the LUI xboxlive menu", - }, - { - "m_filter", - "Allow mouse movement smoothing", - }, - { - "m_forward", - "Forward speed in units per second", - }, - { - "m_pitch", - "Default pitch", - }, - { - "m_side", - "Sideways motion in units per second", - }, - { - "m_vehMouseSteerSensitivity", - "Vehicle mouse steering sensitivity", - }, - { - "m_yaw", - "Default yaw", - }, - { - "mangleDWStats", - "0=do nothing, 1=pretend file doesn't exist--reset, 2=pretend file is corrupted--reset, 3=pretend you're a hacker and we reset your stats", - }, - { - "manifestfs", - "Use a manifest file to read segmented fastfiles", - }, - { - "mantle_anim_rate_max", - "Max anim rate when sprinting at mantle", - }, - { - "mantle_anim_rate_min", - "Min anim rate when mantling.", - }, - { - "mantle_check_angle", - "The minimum angle from the player to a mantle surface to allow a mantle", - }, - { - "mantle_check_radius", - "The player radius to test against while mantling", - }, - { - "mantle_check_range", - "", - }, - { - "mantle_check_range_smooth", - "", - }, - { - "mantle_debug", - "Show debug information for mantling", - }, - { - "mantle_debugLineTime", - "How long to show lines when mantle_debug lines", - }, - { - "mantle_enable", - "Enable player mantling", - }, - { - "mantle_max_time", - "Max time (ms) to mantle. Can take less time depending on speed when approaching mantle. Must be greater than mantle_min_time", - }, - { - "mantle_min_over_dist", - "The min mantle over distance a player can traverse horizontally. The over distance can increase depending on speed.", - }, - { - "mantle_on_dist_override", - "If non-zero, overrides the minimum mantle on distance", - }, - { - "mantle_over_dist_21", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_over_dist_27", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_over_dist_33", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_over_dist_39", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_over_dist_45", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_over_dist_51", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_over_dist_57", - "The max mantle over distance a player can traverse horizontally when sprinting for 57 height", - }, - { - "mantle_pitch_clamp_enabled", - "Enable pitch clamping code", - }, - { - "mantle_pitch_default_contact_time", - "When 3p animation doesn't have 'contact' notetrack, use this time to lerp into a fixed pitch", - }, - { - "mantle_pitch_default_return_time_on", - "When 3p animation doesn't have 'return_pitch' notetrack on a mantle up, use this time to start lerping back to original pitch", - }, - { - "mantle_pitch_default_return_time_over", - "When 3p animation doesn't have 'return_pitch' notetrack on a mantle up, use this time to start lerping back to original pitch", - }, - { - "mantle_pitch_return_lerp_time", - "Time for pitch to return to original pitch when mantle started", - }, - { - "mantle_use_approach_angle", - "Use the approach angle when mantling instead of surface normal", - }, - { - "mantle_view_yawcap", - "The angle at which to restrict a sideways turn while mantling", - }, - { - "mapname", - "current map name", - }, - { - "mapPackMask", - "Mask of map packs that are available for debugging", - }, - { - "mapPackTwoEnabled", - "", - }, - { - "marketing_active", - "Are we allowed to enable Marketing Comms or not", - }, - { - "marketing_autorefresh", - "automatically download new messages after reporting any message read", - }, - { - "marketing_refresh_time", - "time in seconds to wait before refreshing marketing messages from demonware", - }, - { - "marketing_simulatefakemotd", - "Simulate a fake Marketing MOTD", - }, - { - "match_making_telemetry_chance", - "The % chance of sending match making telemetry", - }, - { - "matchdata_active", - "Are match data uploads enabled", - }, - { - "matchdata_maxcompressionbuffer", - "", - }, - { - "max_ping_threshold_good", - "max ping value to be considered as good", - }, - { - "max_ping_threshold_medium", - "max ping value to be considered as medium", - }, - { - "maxPrestigeOverride", - "Overrides the maximum prestige level, disabled if 0.", - }, - { - "mdsd", - "enable match data stat delta logging?", - }, - { - "meetPlayer_ListUpdateInterval", - "Time in milliseconds since uploaded recent met player list.", - }, - { - "meetPlayer_ListUploadInterval", - "This dvar is used to make sure that recent met player list get updates only when it changes.", - }, - { - "melee_debug", - "Turn on debug lines for melee traces", - }, - { - "mis_cheat", - "Set when level unlock cheat is performed", - }, - { - "missileCoastingSpeed", - "Speed of missiles when coasting.", - }, - { - "missileDebugAttractors", - "Draw the attractors and repulsors. Attractors are green, and repulsors are yellow. 0 = off, 1 = show origin, 2 = draw sphere, 3 = draw sphere depth checked", - }, - { - "missileDebugDraw", - "Draw guided missile trajectories.", - }, - { - "missileDebugText", - "Print debug missile info to console.", - }, - { - "missileExplosionLiftDistance", - "Distance to lift the explosion off the surface for \"big explosion\" weapons", - }, - { - "missileGlassShatterVel", - "Velocity needed by a grenade or missile to shatter glass instead of bouncing off.", - }, - { - "missileHellfireMaxSlope", - "This limits how steeply the hellfire missile can turn upward when climbing", - }, - { - "missileHellfireUpAccel", - "The rate at which the hellfire missile curves upward", - }, - { - "missileJavAccelClimb", - "Rocket acceleration when climbing.", - }, - { - "missileJavAccelDescend", - "Rocket acceleration when descending towards target.", - }, - { - "missileJavClimbAngleDirect", - "In direct-fire mode, the minimum angle between the rocket and target until the rocket stops climbing. Smaller angles make for higher climbs.", - }, - { - "missileJavClimbAngleTop", - "In top-fire mode, the minimum angle between the rocket and target until the rocket stops climbing. Smaller angles make for higher climbs.", - }, - { - "missileJavClimbCeilingDirect", - "In direct-fire mode, how high the missile needs to reach before it descends.", - }, - { - "missileJavClimbCeilingTop", - "In top-fire mode, how high the missile needs to reach before it descends.", - }, - { - "missileJavClimbHeightDirect", - "In direct-fire mode, how far above the target the rocket will aim for when climbing.", - }, - { - "missileJavClimbHeightTop", - "In top-fire mode, how far above the target the rocket will aim for when climbing.", - }, - { - "missileJavClimbToOwner", - "", - }, - { - "missileJavDuds", - "If true, javelins that impact before their booster ignites will not explode, they will play their dud effects instead.", - }, - { - "missileJavSpeedLimitClimb", - "Rocket's speed limit when climbing.", - }, - { - "missileJavSpeedLimitDescend", - "Rocket's speed limit when descending towards target.", - }, - { - "missileJavTurnDecel", - "", - }, - { - "missileJavTurnRateDirect", - "In direct-fire mode, how sharp the rocket can turn, in angles/sec.", - }, - { - "missileJavTurnRateTop", - "In top-fire mode, how sharp the rocket can turn, in angles/sec.", - }, - { - "missileMacross", - "Swarmy goodness.", - }, - { - "missileRemoteFOV", - "Remote missile-cam, FOV to use.", - }, - { - "missileRemoteSpeedDown", - "Remote-controlled missile slowdown-factor.", - }, - { - "missileRemoteSpeedTargetRange", - "Remote-controlled missile speeds.", - }, - { - "missileRemoteSpeedUp", - "Remote-controlled missile speedup-factor.", - }, - { - "missileRemoteSteerPitchRange", - "Remote-controlled missile allowed up/down range. To keep players from steering missiles above the horizon.", - }, - { - "missileRemoteSteerPitchRate", - "Remote-controlled missile up/down steering speed.", - }, - { - "missileRemoteSteerYawRate", - "Remote-controlled missile left/right steering speed.", - }, - { - "missileWaterMaxDepth", - "If a missile explodes deeper under water than this, they explosion effect/sound will not play.", - }, - { - "modPrvAnimApplyDelta", - "Model previewer animation apply delta", - }, - { - "modPrvAnimBlendMode", - "Model previewer animation blending mode", - }, - { - "modPrvAnimBlendWeight", - "Model previewer animation blend weight", - }, - { - "modPrvAnimCrossBlendDuration", - "Model previewer animation cross blend duration", - }, - { - "modPrvAnimCrossBlendTime", - "Model previewer animation cross blending time", - }, - { - "modPrvAnimForceLoop", - "Model Previewer - Force an animation loop", - }, - { - "modPrvAnimMruName0", - "Model previewer most recently used anim name 0", - }, - { - "modPrvAnimMruName1", - "Model previewer most recently used anim name 0", - }, - { - "modPrvAnimMruName2", - "Model previewer most recently used anim name 0", - }, - { - "modPrvAnimMruName3", - "Model previewer most recently used anim name 0", - }, - { - "modPrvAnimRate", - "Model previewer - animation rate", - }, - { - "modPrvCenterOffset", - "Model previewer center offset", - }, - { - "modPrvDisplayToggle", - "Show model previewer overlay", - }, - { - "modPrvDrawAxis", - "Draw the model previewer axes", - }, - { - "modPrvDrawBoneInfo", - "Draw model previewer bone information", - }, - { - "modPrvDrawDistanceToModel", - "Print viewer's distance to model.", - }, - { - "modPrvForceUpdate", - "Force modPrvLoadModel to be re-evaluated.", - }, - { - "modPrvFromAnimMru", - "Model previewer most recently used 'from' animation", - }, - { - "modPrvGamepadControlSpeed", - "Model previewer game pad control speed", - }, - { - "modPrvHideModel", - "Skip drawing the model.", - }, - { - "modPrvLoadFromAnim", - "Model previewer loaded 'from' animation", - }, - { - "modPrvLoadModel", - "Model previewer loaded model", - }, - { - "modPrvLoadToAnim", - "Model previewer loaded 'to' animation", - }, - { - "modPrvLod", - "Model previewer level of detail", - }, - { - "modPrvMatOverrideFrom", - "This material in the current model will be replaced by modPrvMatOverrideTo", - }, - { - "modPrvMatOverrideTo", - "This material will replace the material specified by modPrvMatOverrideFrom in the current model", - }, - { - "modPrvMatReplace", - "Model previewer material replace", - }, - { - "modPrvMatSelect", - "Model previewer material select", - }, - { - "modPrvModelMru", - "Model previewer most recently used model", - }, - { - "modPrvModelMruName0", - "Model previewer most recently used model", - }, - { - "modPrvModelMruName1", - "Model previewer most recently used model", - }, - { - "modPrvModelMruName2", - "Model previewer most recently used model", - }, - { - "modPrvModelMruName3", - "Model previewer most recently used model", - }, - { - "modPrvOrigin", - "Model previewer origin", - }, - { - "modPrvRotationAngles", - "Model previwer rotation angles", - }, - { - "modPrvToAnimMru", - "Model previewer most recently used 'to' animation", - }, - { - "monkeytoy", - "Restrict console access", - }, - { - "motd", - "Message of the day", - }, - { - "motd_store_link", - "Add a link to the in-game store in the MOTD popup", - }, - { - "motionTrackerBlurDuration", - "The motion blur duration for motion tracker dots", - }, - { - "motionTrackerCenterX", - "", - }, - { - "motionTrackerCenterY", - "", - }, - { - "motionTrackerPingFadeTime", - "How long an enemy is visible on the motion tracker after being detected", - }, - { - "motionTrackerPingPitchAddPerEnemy", - "The added percentage of pitch for each additional enemy that is detected (final pitch = base pitch * (1 + enemy count * this))", - }, - { - "motionTrackerPingPitchBase", - "The pitch of the motion tracker sound for a nearby enemy", - }, - { - "motionTrackerPingPitchNearby", - "The pitch of the motion tracker sound for a nearby enemy", - }, - { - "motionTrackerPingSize", - "The width and height of the motion tracker's enemy indicators as a percentage of motion tracker scale", - }, - { - "motionTrackerRange", - "The range, in world units, that the motion tracker displays", - }, - { - "motionTrackerSweepAngle", - "The maximum angle from straight forward that the motion tracker detects enemies", - }, - { - "motionTrackerSweepInterval", - "The time between motion tracker sweeps", - }, - { - "motionTrackerSweepSpeed", - "The speed, in world units per second, of the motion tracker sweep", - }, - { - "moving_platform_display_antilag", - "Displays mover parent entities that will be included in the antilag calculation for moving platforms. Children are not displayed.", - }, - { - "moving_platform_improved_aim", - "Turns on improved moving platform aim system.", - }, - { - "moving_platform_keep_previous", - "Allows jumping between moving platforms by remembering the player's previous platform while in mid-air.", - }, - { - "moving_platform_rotational_antilag", - "Applies rotational antilag to script movers for moving platform system.", - }, - { - "nextmap", - "The next map name", - }, - { - "nightVisionDisableEffects", - "", - }, - { - "nightVisionFadeInOutTime", - "How long the fade to/from black lasts when putting on or removing night vision goggles.", - }, - { - "nightVisionPowerOnTime", - "How long the black-to-nightvision fade lasts when turning on the goggles.", - }, - { - "np_plus_callback_interval_allowed", - "Amount of time we allow before a missed callback means a person no longer has plus access.\n", - }, - { - "np_status_callback_interval", - "Amount of time between regular calls to sceNpCheckNpAvailability.\n", - }, - { - "np_status_retry_callback_interval", - "Amount of time to wait after a failure in sceNpCheckNpAvailability before retrying.\n", - }, - { - "num_available_map_packs", - "Number of map packs available for this platform", - }, - { - "objectiveAlpha", - "Alpha value for objective waypoints.", - }, - { - "objectiveAlphaEnabled", - "When true, dvar \"objectiveAlpha\" takes effect.", - }, - { - "objectiveArrowHeight", - "Height of the objective pointer.", - }, - { - "objectiveArrowWidth", - "Width of the objective pointer.", - }, - { - "objectiveFadeTimeGoingOff", - "Onscreen Objective Pointer - How long to take to fade out.", - }, - { - "objectiveFadeTimeGoingOn", - "Onscreen Objective Pointer - How long to take to fade out.", - }, - { - "objectiveFadeTimeWaitOff", - "Onscreen Objective Pointer - How long to take to fade out.", - }, - { - "objectiveFadeTimeWaitOn", - "Onscreen Objective Pointer - How long to take to fade out.", - }, - { - "objectiveFadeTooClose", - "Onscreen Objective Pointer - Will not fade out if target ent is farther than this.", - }, - { - "objectiveFadeTooFar", - "Onscreen Objective Pointer - Will not fade out if target ent is farther than this.", - }, - { - "objectiveFontSize", - "Onscreen Objective Pointer - Fontsize of the icon's text.", - }, - { - "objectiveHide", - "When enabled, objectives will not show.", - }, - { - "objectiveHideIcon", - "When true, hides the objective pointer's icon, but will still show the arrow.", - }, - { - "objectiveTextOffsetY", - "Onscreen Objective Pointer - Offset of the icon's text.", - }, - { - "overrideNVGModelWithKnife", - "When true, nightvision animations will attach the weapDef's knife model instead of the night vision goggles.", - }, - { - "painVisionLerpInRate", - "Rate at which pain vision effect lerps in", - }, - { - "painVisionLerpOutRate", - "Rate at which pain vision effect lerps in", - }, - { - "partyChatDisallowed", - "Whether to disallow ps4 Live Party Chat", - }, - { - "partyChatDisconnectTimer", - "Time to wait after user responds to Party Chat dialog before kicking (msec)", - }, - { - "past_title_data_active", - "Is the past title data system enabled", - }, - { - "past_title_data_read_failure_interval_hours", - "default interval in which to try and read past title data if kicked off read failed.", - }, - { - "past_title_data_read_success_interval_hours", - "default interval in which to try and read past title data if kicked off read failed.", - }, - { - "path_nodeInfoType", - "Path node information type", - }, - { - "perk_armorVestDamageMultiplier", - "Multiplier affecting damage while wearing armor vest", - }, - { - "perk_bulletPenetrationMultiplier", - "Multiplier for extra bullet penetration", - }, - { - "perk_extendedMagsMGAmmo", - "Number of extra bullets per clip for machine gun weapons with the extended mags perk.", - }, - { - "perk_extendedMagsPistolAmmo", - "Number of extra bullets per clip for pistol weapons with the extended mags perk.", - }, - { - "perk_extendedMagsSMGAmmo", - "Number of extra bullets per clip for sub machine gun weapons with the extended mags perk.", - }, - { - "perk_extendedMagsSpreadAmmo", - "Number of extra bullets per clip for spread weapons with the extended mags perk.", - }, - { - "perk_extendedMeleeRange", - "The range of the auto melee with the extened perk", - }, - { - "perk_extraBreath", - "Number of extra seconds a player can hold his breath", - }, - { - "perk_fastOffhandMultiplier", - "Percentage of switching and using offhand weapon time to use", - }, - { - "perk_fastSnipeScale", - "Scales the recovery speed of the view kick when using a sniper.", - }, - { - "perk_flinchMultiplier", - "Multiplier affecting flinch", - }, - { - "perk_footstepVolumeAlly", - "", - }, - { - "perk_footstepVolumeEnemy", - "", - }, - { - "perk_footstepVolumePlayer", - "", - }, - { - "perk_footstepVolumeSelectiveHearingMin", - "", - }, - { - "perk_improvedExtraBreath", - "Number of extra seconds a player can hold his breath", - }, - { - "perk_lightWeightViewBobScale", - "Scale for first person view movement while lightweight.", - }, - { - "perk_mantleSpeedMultiplier", - "Multiplier affecting mantling speed", - }, - { - "perk_numExtraLethal", - "Number of extra lethal grenades", - }, - { - "perk_numExtraTactical", - "Number of extra tactical grenades", - }, - { - "perk_parabolicAngle", - "Eavesdrop perk's effective FOV angle", - }, - { - "perk_parabolicIcon", - "Eavesdrop icon to use when displaying eavesdropped voice chats", - }, - { - "perk_parabolicRadius", - "Eavesdrop perk's effective radius", - }, - { - "perk_quickDrawSpeedScale", - "Scales the 'Hip to ADS' transition speed.", - }, - { - "perk_recoilMultiplier", - "Multiplier affecting recoil", - }, - { - "perk_resistExplosionDamageMultiplier", - "Multiplier affecting damage with resist explosion", - }, - { - "perk_resistShellShockMultiplier", - "Multiplier affecting damage with resist explosion", - }, - { - "perk_sprintMultiplier", - "Multiplier for player_sprinttime", - }, - { - "perk_sprintRecoveryMultiplierActual", - "", - }, - { - "perk_sprintRecoveryMultiplierVisual", - "", - }, - { - "perk_weapRateMultiplier", - "Percentage of weapon firing rate to use", - }, - { - "perk_weapReloadMultiplier", - "Percentage of weapon reload time to use", - }, - { - "perk_weapSpreadMultiplier", - "Percentage of weapon spread to use", - }, - { - "perk_weapSwapMultiplier", - "Percentage of weapon swap time to use", - }, - { - "phsyVeh_enableBalanceLoad", - "Force the load at each wheel to share the entire weight of the vehicle equally. (Requires map restart)", - }, - { - "phys_autoDisableLinear", - "A body must have linear velocity less than this to be considered idle.", - }, - { - "phys_autoDisableTime", - "The amount of time a body must be idle for it to go to sleep.", - }, - { - "phys_bulletSpinScale", - "Scale of the effective offset from the center of mass for the bullet impacts.", - }, - { - "phys_bulletUpBias", - "Up Bias for the direction of the bullet impact.", - }, - { - "phys_dragAngular", - "The amount of angular drag, applied globally", - }, - { - "phys_dragLinear", - "The amount of linear drag, applied globally", - }, - { - "phys_drawAwake", - "Debug draw a box indicating which bodies are disabled", - }, - { - "phys_drawBroadPhase", - "Debug draw broadphase AABBs", - }, - { - "phys_drawCenterOfMass", - "Debug draw center of masses", - }, - { - "phys_drawCollision", - "Draw collision for specified world", - }, - { - "phys_drawContacts", - "Debug draw contact points", - }, - { - "phys_drawDebugInfo", - "Print info about the physics objects", - }, - { - "phys_drawDistance", - "Size of region centered around player to draw debug physics information", - }, - { - "phys_drawJoints", - "Debug draw joints", - }, - { - "phys_dumpWorld", - "Debug dump out physics world", - }, - { - "phys_earthquakeStrengthScale", - "The earthquake force overall strength multiplier. Multiplies the scale passed into Earthquake script function.", - }, - { - "phys_earthquakeWaveFrequency", - "The earthquake force wave frequency of oscillation", - }, - { - "phys_earthquakeWaveLength", - "The earthquake force wave length", - }, - { - "phys_enableContinuousCollision", - "Enable continuous collision detection", - }, - { - "phys_enablePicking", - "Enable picking up physics bodies. Hover over dynamic physics body, then press and hold L3 to activate.", - }, - { - "phys_enableSleep", - "Enable rigid body deactivation", - }, - { - "phys_gravity", - "Physics gravity in units/sec^2.", - }, - { - "phys_gravity_ragdoll", - "Physics gravity used by ragdolls in units/sec^2.", - }, - { - "phys_gravityChangeWakeupRadius", - "The radius around the player within which objects get awakened when gravity changes", - }, - { - "phys_jitterMaxMass", - "Maximum mass to jitter - jitter will fall off up to this mass", - }, - { - "phys_maxTimeStep", - "Max physics time step in seconds", - }, - { - "phys_rollingResistance", - "The amount of rolling resistance, applied globally", - }, - { - "phys_solverPositionIterations", - "Number of solver position iterations used for constraint solving.", - }, - { - "phys_solverVelocityIterations", - "Number of solver velocity iterations used for constraint solving.", - }, - { - "phys_solverWarmStarting", - "Enable solver warm starting for better stability", - }, - { - "physVeh_antiRollScale", - "Amount to scale antiroll force (Requires map restart)", - }, - { - "physVeh_dampingCoefficientScale", - "Scale applied to the suspension damping strength. (Requires map restart)", - }, - { - "physVeh_downForceScale", - "Max amount of downforce proportional to gravity that is applied. (Requires map restart)", - }, - { - "physVeh_explodeForce", - "The force applied to physics vehicles due to explosions", - }, - { - "physVeh_explodeSpinScale", - "The max (random) offset from the center of mass at which splash damage applies its force", - }, - { - "physVeh_jump", - "Set to 1 to make a vehicle jump.", - }, - { - "physVeh_lateralFrictionScale", - "Scale applied to lateral/side friction. (Requires map restart)", - }, - { - "physVeh_minContactImpulse", - "The minimum impulse needed to register a contact notification", - }, - { - "physVeh_minImpactMomentum", - "The minimum collision momentum needed to register an impact", - }, - { - "physVeh_sideToFrontFrictionScale", - "Ratio between longitudinal friction and lateral friction. (Requires map restart)", - }, - { - "physVeh_speedIntegralMaxError", - "The absolute accumulated error between desired - current speed over time is clamped by this value over time. Lower this value to limit overshoot of target speed due to integral windup.", - }, - { - "physVeh_springCoefficientScale", - "Scale applied to the suspension spring strength. (Requires map restart)", - }, - { - "physVeh_StepsPerFrame", - "The number of physics timesteps that the server frame will be divided into.", - }, - { - "pickupPrints", - "Print a message to the game window when picking up ammo, etc.", - }, - { - "player_adsExitDelayGamepad", - "Delay before exiting aim down sight with mouse", - }, - { - "player_adsExitDelayMouse", - "Delay before exiting aim down sight with mouse", - }, - { - "player_backSpeedScale", - "The scale applied to the player speed when strafing", - }, - { - "player_breath_fire_delay", - "The amount of time subtracted from the player remaining breath time when a weapon is fired", - }, - { - "player_breath_gasp_lerp", - "The interpolation rate for the target waver amplitude when gasping", - }, - { - "player_breath_gasp_scale", - "Scale value to apply to the target waver during a gasp", - }, - { - "player_breath_gasp_time", - "The amount of time a player will gasp once they can breath again", - }, - { - "player_breath_hold_lerp", - "The interpolation rate for the target waver amplitude when gasping", - }, - { - "player_breath_hold_time", - "The maximum time a player can hold his breath", - }, - { - "player_breath_snd_delay", - "The delay before playing the breathe in sound", - }, - { - "player_breath_snd_lerp", - "The interpolation rate for the player hold breath sound", - }, - { - "player_damageMultiplier", - "Player damage is scaled by this amount; used by script for setting difficulty level", - }, - { - "player_deathInvulnerableToMelee", - "The player is invulnerable to melee attacks during death invulnerability", - }, - { - "player_deathInvulnerableToProjectile", - "The player is invulnerable to projectile attacks during death invulnerability", - }, - { - "player_debugHealth", - "Turn on debugging info for player health", - }, - { - "player_debugTrace", - "Show player trace debug planes", - }, - { - "player_dmgtimer_flinchTime", - "Maximum time to play flinch animations", - }, - { - "player_dmgtimer_maxTime", - "The maximum time that the player is slowed due to damage", - }, - { - "player_dmgtimer_minScale", - "The minimum scale value to slow the player by when damaged", - }, - { - "player_dmgtimer_stumbleTime", - "Maximum time to play stumble animations", - }, - { - "player_dmgtimer_timePerPoint", - "The time in milliseconds that the player is slowed down per point of damage", - }, - { - "player_footstepsThreshhold", - "The minimum speed at which the player makes loud footstep noises", - }, - { - "player_footstepsThreshholdCrouch", - "The minimum speed at which the player makes loud footstep noises", - }, - { - "player_footstepsThreshholdProne", - "The minimum speed at which the player makes loud footstep noises", - }, - { - "player_lastStandCrawlSpeedScale", - "The scale applied to the player speed when strafing", - }, - { - "player_lastStandDebug", - "Forces players into last stand for debugging purposes.", - }, - { - "player_lateralPlane", - "The plane used for the player's lateral movement.", - }, - { - "player_meleeChargeFriction", - "Friction used during melee charge", - }, - { - "player_meleeChargeHeightTolerance", - "Height tolerance to allow charging to a victim. If victim and attacker heights are greater than this value, attack will always do swipe", - }, - { - "player_meleeChargeMaxSpeed", - "Max speed to clamp when doing a charge melee", - }, - { - "player_meleeChargeMaxSpeedUp", - "Max vertical (up) speed to clamp when doing a charge melee", - }, - { - "player_meleeChargePlayerLockTime", - "The amount of time, in milliseconds, to lock the player's movement when performing a melee charge", - }, - { - "player_meleeDamageMultiplier", - "Melee damage to the player is scaled by this amount; used by script for setting difficulty level", - }, - { - "player_meleeForceAlternate", - "Forces the player to use alternate melee even if the PWF is not set.", - }, - { - "player_meleeForceServerMiss", - "Force the server to always miss melee", - }, - { - "player_meleeHeight", - "The height of the player's melee attack", - }, - { - "player_meleeIdealEndDistance", - "Ideal distance that the melee attacker and victim should be apart from each other when melee ends. -1 means off", - }, - { - "player_meleeMaxQuickRaiseTime", - "After melee is done, max quickraise time. Allows raising weapon quicker to give more responsive feel after melee.", - }, - { - "player_meleeMinimumResponseGraceTime", - "Melee Combo: max input roundtrip time (ms) before considering player to have skipped combo input", - }, - { - "player_meleeRange", - "The maximum range of the player's melee attack", - }, - { - "player_meleeRangeCharge", - "The maximum range of the player's melee attack", - }, - { - "player_meleeSwipePlayerLockTime", - "When swiping, lock player view and movement for this number of milliseconds", - }, - { - "player_meleeSwipeViewLockReleaseTime", - "When swiping, lock player view until this much weapon time left.", - }, - { - "player_meleeWidth", - "The width of the player's melee attack", - }, - { - "player_MGUseRadius", - "The radius within which a player can mount a machine gun", - }, - { - "player_moveThreshhold", - "The speed at which the player is considered to be moving for the purposes of \nview model bob and multiplayer model movement", - }, - { - "player_on_vehicle_aim_fix", - "Turns on/off aim fix while player is on a vehicle or platform. Defaults to on.", - }, - { - "player_prone_view_pitch_down", - "Maximum angle that the player can look up", - }, - { - "player_prone_view_pitch_up", - "Maximum angle that the player can look up", - }, - { - "player_radiusDamageMultiplier", - "Radius damage to the player is scaled by this amount; used by script for setting difficulty level", - }, - { - "player_runThreshhold", - "The speed threshold before a player is considered to be running forwards", - }, - { - "player_scope_prototype", - "Enables the 'scope drift' system that takes the place of the current 'hold breath' system", - }, - { - "player_scopeExitOnDamage", - "Exit the scope if the player takes damage", - }, - { - "player_shield_postUseWeaponDelay", - "The delay between putting down the exo-shield and being able to fire your weapon again.", - }, - { - "player_spaceCapsuleHeight", - "Player capsule height. 70 = standing, 50 = crouch, 30 = prone", - }, - { - "player_spaceEnabled", - "True if player space logic is enabled. (Player must also be swim enabled)", - }, - { - "player_spaceViewHeight", - "Camera view height. 60 = standing, 40 = crouch, 11 = prone", - }, - { - "player_spectateSpeedScale", - "The scale applied to the player speed when strafing", - }, - { - "player_sprintCameraBob", - "The speed the camera bobs while you sprint", - }, - { - "player_sprintForwardMinimum", - "The minimum forward deflection required to maintain a sprint", - }, - { - "player_sprintJumpAnimRate", - "If > 0, allow sprint to persist through jumps. The value also determins anim rate to play sprint loop at while jumping.", - }, - { - "player_sprintJumpDropWeaponScaler", - "If 'player_sprintJumpAnimRate' is set, this dvar scales down the time sprint drop timer when player is in the air and wants to fire.", - }, - { - "player_sprintMinTime", - "The minimum sprint time needed in order to start sprinting", - }, - { - "player_sprintRechargePause", - "The length of time the meter will pause before starting to recharge after a player sprints", - }, - { - "player_sprintSpeedScale", - "The scale applied to the player speed when strafing", - }, - { - "player_sprintStrafeSpeedScale", - "The speed at which you can strafe while sprinting", - }, - { - "player_sprintTime", - "The base length of time a player can sprint", - }, - { - "player_sprintUnlimited", - "Whether players can sprint forever or not", - }, - { - "player_strafeAnimCosAngle", - "Cosine of the angle which player starts using strafe animations", - }, - { - "player_strafeSpeedScale", - "The scale applied to the player speed when strafing", - }, - { - "player_sustainAmmo", - "Firing weapon will not decrease clip ammo.", - }, - { - "player_swimAcceleration", - "Forward/lateral swim acceleration", - }, - { - "player_swimCombatTimer", - "Time (ms) at which viewmodel switches from combat to relaxed animation state when not firing", - }, - { - "player_swimDragHandEnabled", - "Enable/disable left hand drag during swimming", - }, - { - "player_swimDragHandFrictionMax", - "Max friction value to bring the dragging hand back to default idle position", - }, - { - "player_swimDragHandFrictionMin", - "Min friction value to bring the dragging hand back to default idle position", - }, - { - "player_swimDragHandLookAtOffset", - "Forward axis offset to compare against last look at position for hand drag anims", - }, - { - "player_swimForwardAnimCatchupMax", - "Lerped max speed to extend or retract arms if player is moving forward or back", - }, - { - "player_swimForwardAnimCatchupMin", - "Lerped min speed to extend or retract arms if player is moving forward or back", - }, - { - "player_swimForwardMinAngle", - "Min angle (relative to forward axis) for player to be in swim forward state", - }, - { - "player_swimForwardMinSpeed", - "Min speed (relative to forward axis) for player to be in swim forward state", - }, - { - "player_swimForwardSettleTime", - "Time (ms) that player will stay in swim forward state even if outside parameters when already in forward state", - }, - { - "player_swimForwardWarmupTime", - "Time (ms) that player has to wait before moving into swim forward state once speed and angle are met", - }, - { - "player_swimFriction", - "Friction value applied to velocity when swimming and no input is given", - }, - { - "player_swimSpeed", - "Max forward/lateral swim speed", - }, - { - "player_swimVerticalAcceleration", - "Vertical swim acceleration", - }, - { - "player_swimVerticalFriction", - "Vertical friction value applied to velocity when swimming and no input is given", - }, - { - "player_swimVerticalSpeed", - "Max vertical swim speed", - }, - { - "player_swimWaterSurface", - "Water surface Z value", - }, - { - "player_swimWaterSurfaceEnabled", - "Water surface Z value movement restriction enabled", - }, - { - "player_throwbackInnerRadius", - "The radius to a live grenade player must be within initially to do a throwback", - }, - { - "player_throwbackOuterRadius", - "The radius player is allow to throwback a grenade once the player has been in the inner radius", - }, - { - "player_useRadius", - "The radius within which a player can use things", - }, - { - "player_view_pitch_down", - "Maximum angle that the player can look up", - }, - { - "player_view_pitch_up", - "Maximum angle that the player can look up", - }, - { - "player_walkCameraBob", - "The speed the camera bobs while you walk.", - }, - { - "playercard_cache_download_max_retry_time", - "Max time that the player cache download can retry", - }, - { - "playercard_cache_download_retry_step", - "Step in m/s for the player cache download retry", - }, - { - "playercard_cache_show_cached", - "Shows whether a playercard is in the cache or not", - }, - { - "playercard_cache_upload_max_retry_time", - "Max time that the player cache upload can retry", - }, - { - "playercard_cache_upload_retry_step", - "Step in m/s for the player cache upload retry", - }, - { - "playercard_cache_validity_life", - "The life of a cached gamercard (it can be re-downloaded after this)", - }, - { - "playerPositionRecordSampleTime", - "How often to sample player positions and save them into match data.", - }, - { - "prestige_shop_active", - "Are we allowed to show the Prestige Shop or not", - }, - { - "prestige30EasterEggEnabled", - "Enables the easter egg for prestige 30 if 1, disabled if 0.", - }, - { - "printSnapshotDetails", - "Log snapshot details (can slow down the game a lot)", - }, - { - "prof_probe0", - "", - }, - { - "prof_probe1", - "", - }, - { - "prof_probe2", - "", - }, - { - "prof_probe3", - "", - }, - { - "prof_probe4", - "", - }, - { - "prof_probeMaxMsec", - "Height of each profile probe graph, in milliseconds", - }, - { - "prof_sortTime", - "Time in seconds between resort profiles", - }, - { - "profile", - "", - }, - { - "profile_rowcount", - "Profile row count", - }, - { - "profile_script", - "Enable profile scripts", - }, - { - "profile_script_by_file", - "Enable profile scripts by source file", - }, - { - "profile_script_hierarchical", - "Toggle hierarchical drawing of script profiling", - }, - { - "profile_show_loading", - "Show map load profiler", - }, - { - "profile_thread", - "Thread being profiled", - }, - { - "profile2", - "", - }, - { - "profile2_frames", - "Profile frame count", - }, - { - "profile2_mode", - "Reporting mode", - }, - { - "profileMenuOption_blacklevel", - "", - }, - { - "profileMenuOption_offensiveContentMode", - "Mode of the offensive content warning at startup - 0, skip and turn on; 1, skip and turn off; 2, ask user", - }, - { - "profileMenuOption_safeAreaHorz", - "", - }, - { - "profileMenuOption_safeAreaVert", - "", - }, - { - "profileMenuOption_sensitivity", - "", - }, - { - "profileMenuOption_volume", - "", - }, - { - "prologue_select", - "Toggles intro.map between the prologue and the persona non grata setup.", - }, - { - "ps4_dw_disconnect_test", - "Turns on automatic random disconnects from demonware to test connectivity code.\n", - }, - { - "ps4_how_long_to_wait_on_join_ms", - "Delay in milliseconds we're willing to wait before shutting down a join in progress due to lack of friend.", - }, - { - "ps4_meetplayer_rest_submit_delay", - "Number of milliseconds between calls to submit met players to the rest system.", - }, - { - "ps4_num_session_slots_override", - "Override the max number of player slots in a ps4 session. 0 will use the proper number.", - }, - { - "ps4_presence_put_delay", - "Delay in milliseconds after presence changes before sending updated presence through np", - }, - { - "ps4_presence_put_rate", - "Minimum delay in milliseconds before sending updated presence through np", - }, - { - "ps4_signin_notify_delay", - "Delay in milliseconds after a sign in status change before we change our sign-in status (in-game)", - }, - { - "ps4Game", - "True if running on PS4", - }, - { - "publisherFileFetchTimeout", - "default timeout for publisher files FETCH tasks (in seconds)", - }, - { - "r_adaptiveSubdiv", - "Enables screen space Catmull Clark adaptive tessellation. If disabled, models tessellate to their designed subdivision level.", - }, - { - "r_adaptiveSubdivBaseFactor", - "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation.", - }, - { - "r_adaptiveSubdivPatchFactor", - "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation.", - }, - { - "r_allCells", - "Draw all cells. Most useful for seeing if portals or cells are hiding things they should not..", - }, - { - "r_animBoundsScale", - "Scale animated xmodel bounds by the given factor", - }, - { - "r_animBoundsWarn", - "Warn when model bounds are estimated far off from their actual animated values.", - }, - { - "r_animEstimatedBoundsScale", - "Scale animated xmodel estimated bounds by the given factor", - }, - { - "r_aoBlurSharpness", - "Controls the tolerance for depth discontinuities during the bilateral blur step. Larger values reduce the depth tolerance and effectively sharpen more edges.", - }, - { - "r_aoBlurStep", - "Step scale applied to sample offsets during the bilateral blur. A value of 1 results in a normal gaussian blur. Increasing it to 2 or 3 makes the filter larger but causes fine dithering patterns.", - }, - { - "r_aoDiminish", - "Decrease the effect of occlusion on brighter colors", - }, - { - "r_aoPower", - "Power curve applied to AO factor", - }, - { - "r_aoStrength", - "Strength of Ambient Occlusion effect", - }, - { - "r_aoUseTweaks", - "Use r_ao* dvars instead of the current light set values for AO common params", - }, - { - "r_artTweaksLastVisionSet", - "Tells the script which vision set was last set in code", - }, - { - "r_artUseTweaks", - "Tells the game that art tweaks is enabled and script is in control (as opposed to ColorEd).", - }, - { - "r_asyncCompute", - "Enables scheduling GPU compute shader work prior to the graphics frame, improving overlap.", - }, - { - "r_atlasAnimFPS", - "Speed to animate atlased 2d materials", - }, - { - "r_balanceLightmapOpaqueLists", - "Split lightmap opaque into multiple draw lists.", - }, - { - "r_balanceOpaqueLists", - "Split opaque into multiple draw lists.", - }, - { - "r_blacklevel", - "Black level (negative brightens output)", - }, - { - "r_blendshape_debug", - "Entity number to debug blendshape weights", - }, - { - "r_blendshape_debug_index", - "Blendshape weight index to debug/force; all others will be 0", - }, - { - "r_blendshape_debug_value", - "Blendshape weight value to use for debug/force", - }, - { - "r_blendshape_emulation", - "Enables blendshape emulation", - }, - { - "r_blendshape_enable", - "Toggles blendshapes", - }, - { - "r_blur", - "Dev tweak to blur the screen", - }, - { - "r_blurdstGaussianBlurLevel", - "MIP level to start gaussian blur at", - }, - { - "r_blurdstGaussianBlurRadius", - "Amount to gaussian blur blur distortion render target", - }, - { - "r_blurdstShowOverlay", - "Toggles blur distortion overlay", - }, - { - "r_brightness", - "Brightness adjustment", - }, - { - "r_cacheModelLighting", - "Speed up model lighting by caching previous results", - }, - { - "r_cacheSModelLighting", - "Speed up static model lighting by caching previous results", - }, - { - "r_clampLodScale", - "Clamps the amount that the engine can adjust the LOD distance. 0 the engine can fully adjust. 1 the engine cannot adjust it at all. 0.5 the maximum the engine can adjust the LOD distance is 50% or the default.", - }, - { - "r_clear", - "Controls how the color buffer is cleared", - }, - { - "r_clearColor", - "Color to clear the screen to when clearing the frame buffer", - }, - { - "r_clearColor2", - "Color to clear every second frame to (for use during development)", - }, - { - "r_clutCompositeVisionSet", - "Composite clut with vision set.", - }, - { - "r_clutDebugOverlay", - "Enable Clut Debug Overlay", - }, - { - "r_clutDumpAssets", - "Dump Assets", - }, - { - "r_clutEnable", - "Enable/Disable Clut", - }, - { - "r_cmdbuf_handoff", - "Allow the backend thread to take over partially executed command buffer jobs.", - }, - { - "r_cmdbuf_worker", - "Process command buffer in a separate thread", - }, - { - "r_colorblindMode", - "Selects the Colorblind simulation mode", - }, - { - "r_colorGradingEnable", - "Enable color grading.", - }, - { - "r_colorGradingFilmTweaks", - "Enable/Disable Vision Set Film Tweaks", - }, - { - "r_colorGradingForceReinhard", - "Enable/Disable Force Reinhard", - }, - { - "r_colorMap", - "Replace all color maps with pure black or pure white", - }, - { - "r_colorScaleUseTweaks", - "Override color scale LightSet settings with tweak dvar values. (MP)", - }, - { - "r_combinePostOpaqueFx", - "", - }, - { - "r_contrast", - "Contrast adjustment", - }, - { - "r_daltonizeIntensity", - "Daltonize correction strength.", - }, - { - "r_daltonizeMode", - "Selects the Daltonize mode", - }, - { - "r_darkBlur", - "Apply blur (decrease of visual acuity) when dark", - }, - { - "r_darkBlurPower", - "Power curve of blurring (decrease of visual acuity) when dark", - }, - { - "r_darkBlurRadius", - "Radius of blurring (decrease of visual acuity) when dark", - }, - { - "r_darkColor", - "Reduce color sensitivity when dark", - }, - { - "r_darkColorPower", - "Power curve of color sensitivity when dark", - }, - { - "r_debugDrawLights", - "Draw light debug info", - }, - { - "r_debugDrawLightsDrawRadius", - "Max distance from camera to draw debug light info", - }, - { - "r_debugDrawLightsIndex", - "Draw light index", - }, - { - "r_debugLineWidth", - "Width of server side debug lines", - }, - { - "r_debugRefHeight", - "Reference Image's Height", - }, - { - "r_debugRefImageLeft", - "Reference Image's Left Screen Pos.", - }, - { - "r_debugRefImagePrePostFx", - "Draw Debug Reference before postFx.", - }, - { - "r_debugRefImageTop", - "Reference Image's Top Screen Pos.", - }, - { - "r_debugRefWidth", - "Reference Image's Width ", - }, - { - "r_debugShader", - "Enable shader debugging information", - }, - { - "r_defaultPatchCount", - "Patches per thread group for all other surfaces.", - }, - { - "r_delayAddSceneModels", - "Add DObjs and brushes to GfxScene in a separate worker command", - }, - { - "r_depthPrepass", - "Enable depth prepass for various geometries", - }, - { - "r_depthSortDebug", - "Enable depth sort debug visualization.", - }, - { - "r_depthSortEnable", - "Enable sorting of transparent surfaces.", - }, - { - "r_depthSortRange", - "Range to consider depth sort,", - }, - { - "r_desaturation", - "Desaturation adjustment", - }, - { - "r_detailMap", - "Replace all detail maps with an image that effectively disables them", - }, - { - "r_diffuseColorScale", - "Globally scale the diffuse color of all point lights", - }, - { - "r_disableLightSets", - "Disable LightSets", - }, - { - "r_displacementMap", - "Replace all displacement maps with an image that effectively disables them", - }, - { - "r_displacementPatchCount", - "Patches per thread group for displacement surfaces.", - }, - { - "r_distortion", - "Enable distortion", - }, - { - "r_distortion_script_force_off", - "Force distortion off in script", - }, - { - "r_dlightLimit", - "Maximum number of dynamic lights drawn simultaneously", - }, - { - "r_dof_bias", - "Depth of field bias as a power function (like gamma); less than 1 is sharper", - }, - { - "r_dof_enable", - "Enable the depth of field effect", - }, - { - "r_dof_farBlur", - "", - }, - { - "r_dof_farEnd", - "Depth of field far end distance, in inches", - }, - { - "r_dof_farStart", - "Depth of field far start distance, in inches", - }, - { - "r_dof_nearBlur", - "", - }, - { - "r_dof_nearEnd", - "Depth of field near end distance, in inches", - }, - { - "r_dof_nearStart", - "Depth of field near start distance, in inches", - }, - { - "r_dof_physical_accurateFov", - "Enable physical fov (but still based on cg_fov). This will make the fov to subtlety change depending on the focus distance", - }, - { - "r_dof_physical_adsFocusSpeed", - "ADS focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)", - }, - { - "r_dof_physical_adsMaxFstop", - "ADS maximum f-stop (optimal aperture and focus distance are automatically calculated for this mode)", - }, - { - "r_dof_physical_adsMinFstop", - "ADS minimum f-stop (optimal aperture and focus distance are automatically calculated for this mode)", - }, - { - "r_dof_physical_bokehEnable", - "Enable the bokeh depth of field effect", - }, - { - "r_dof_physical_bokehPreset", - "Changes dof sampling quality", - }, - { - "r_dof_physical_bokehRotation", - "Bokeh shape rotation in degrees (hexagonal and octogonal only)", - }, - { - "r_dof_physical_bokehShape", - "Changes the bokeh shape", - }, - { - "r_dof_physical_bokehSharpness", - "Bokeh shape sharpness, trades sharpness for stability (circular only)", - }, - { - "r_dof_physical_distanceMeter", - "Enable physical depth of field debug information", - }, - { - "r_dof_physical_enable", - "enable physical camera controls (using aperture priority)", - }, - { - "r_dof_physical_filmDiagonal", - "Diagonal size of the film/sensor (mm). The bigger the sensor size, the bigger the circle of confusion (which means stronger blurring at all distances). Defaults to full-frame 35mm", - }, - { - "r_dof_physical_focusDistance", - "Distance to the plane in focus for the scene", - }, - { - "r_dof_physical_fstop", - "Aperture of the camera for the scene. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32", - }, - { - "r_dof_physical_hipEnable", - "Enable hyperfocal mode", - }, - { - "r_dof_physical_hipFocusSpeed", - "Hyperfocal mode focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)", - }, - { - "r_dof_physical_hipFstop", - "Aperture of the camera for the scene in the hyperfocal mode", - }, - { - "r_dof_physical_hipSharpCocDiameter", - "Defines what circle of confusion can be considered sharp (mm). Defaults to 0.03mm, generally accepted value for 35mm", - }, - { - "r_dof_physical_maxCocDiameter", - "Maximum circle of confusion diameter (virtual units, might be clamped for bokeh dof)", - }, - { - "r_dof_physical_minFocusDistance", - "Minimum focus distance (inches)", - }, - { - "r_dof_physical_viewModelFocusDistance", - "Distance to the plane in focus for the scene", - }, - { - "r_dof_physical_viewModelFstop", - "Aperture of the camera for the view model. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32", - }, - { - "r_dof_tweak", - "Use dvars to set the depth of field effect; overrides r_dof_enable", - }, - { - "r_dof_viewModelEnd", - "Depth of field viewmodel end distance, in inches", - }, - { - "r_dof_viewModelStart", - "Depth of field viewmodel start distance, in inches", - }, - { - "r_dpvsFilterDebug", - "Filter all entities to all cells (debug)", - }, - { - "r_draw_frustum", - "Draw the frustum using debug lines", - }, - { - "r_drawBModels", - "Enable brush model rendering", - }, - { - "r_drawDebugRefImage", - "Draw Debug Reference Image.", - }, - { - "r_drawDynEnts", - "Enable dynamic entity rendering", - }, - { - "r_drawEntities", - "Enable entity rendering", - }, - { - "r_drawPoly", - "Enable poly rendering", - }, - { - "r_drawPrimHistogram", - "Draws a histogram of the sizes of each primitive batch", - }, - { - "r_drawRigidModels", - "Enable rigid model rendering", - }, - { - "r_drawSkinnedModels", - "Enable skinned model rendering", - }, - { - "r_drawSModels", - "Fraction of static models to render", - }, - { - "r_drawStreaming", - "Makes materials with textures that are not yet loaded draw in pink", - }, - { - "r_drawSun", - "Enable sun effects", - }, - { - "r_drawTessellatedWorld", - "Draw tessellated world surfaces", - }, - { - "r_drawWater", - "Enable water animation", - }, - { - "r_drawWorld", - "Enable world rendering", - }, - { - "r_drawXModels", - "Enable xmodel rendering", - }, - { - "r_dumpViewInfo", - "Dump all the info in the GfxViewInfo structure", - }, - { - "r_dynamicLight", - "Toggle VFX ( omni & spot ) light, debug only", - }, - { - "r_dynamicOPL", - "Enable drawing vfx lights as overlapping primary light for saving gpu performance.", - }, - { - "r_dynamicSpotLightShadows", - "Enable shadows for dynamic/VFX spot lights, you should set this dvar then spawn the new light.", - }, - { - "r_emblemBrightnessScale", - "Modifier that scales the brightness of the emblem on model materials", - }, - { - "r_emissiveMap", - "Replace all emissive maps with pure black or pure white", - }, - { - "r_enableNoTessBuckets", - "Enables placing triangles that don't need tessellation into additional draw calls using non-tessellated shaders.", - }, - { - "r_envBrdfLutMap", - "Replace environment BRDF lookup table with pure black (no secondary specular) or pure white (maximum secondary specular)", - }, - { - "r_envMapExponent", - "Reflection exponent.", - }, - { - "r_envMapMaxIntensity", - "Max reflection intensity based on glancing angle.", - }, - { - "r_envMapMinIntensity", - "", - }, - { - "r_envMapOverride", - "", - }, - { - "r_envMapSunIntensity", - "Max sun specular intensity intensity with env map materials.", - }, - { - "r_eyePupil", - " Change eye's pupil Size.", - }, - { - "r_eyeRedness", - " Change eye's redness.", - }, - { - "r_eyeWetness", - " Change eye's wetness.", - }, - { - "r_fastModelPrimaryLightCheck", - "Reduce R_GetNonSunPrimaryLightForSphere/R_GetNonSunPrimaryLightForBox function calls", - }, - { - "r_fastModelPrimaryLightLink", - "Speed up R_LinkSphereEntityToPrimaryLights and R_LinkBoxEntityToPrimaryLights.", - }, - { - "r_filmAltShader", - "Use alternate shader (with middle tint and dark desat) for film color.", - }, - { - "r_filmTweakBrightness", - "Tweak dev var; film color brightness", - }, - { - "r_filmTweakContrast", - "Tweak dev var; film color contrast", - }, - { - "r_filmTweakDesaturation", - "Tweak dev var; Desaturation applied after all 3D drawing to light areas", - }, - { - "r_filmTweakDesaturationDark", - "Tweak dev var; Additional desaturation applied after all 3D drawing to dark areas", - }, - { - "r_filmTweakEnable", - "Tweak dev var; enable film color effects", - }, - { - "r_filmTweakInvert", - "Tweak dev var; enable inverted video", - }, - { - "r_filmUseTweaks", - "Overide film effects with tweak dvar values.", - }, - { - "r_floatzCopyCompressed", - "Use a compute shader to copy compressed depth data to $floatz", - }, - { - "r_fog", - "Set to 0 to disable fog", - }, - { - "r_fog_depthhack_scale", - "Fog scale for depth hack surfaces", - }, - { - "r_fog_ev_adjust", - "Fog color ev adjustment (+2 means fog color is 2 stops brighter)", - }, - { - "r_fogDebugOverlay", - "Fog Debug Overlay", - }, - { - "r_font_cache_debug_display", - "Display the current fontcache texture on the HUD for debug purposes", - }, - { - "r_forceLetterbox4x3", - "Force 16:9 -> 4:3 letterbox mode on, regardless of aspect ratio.", - }, - { - "r_forceLod", - "Force all level of detail to this level", - }, - { - "r_fullbright", - "Toggles rendering without lighting", - }, - { - "r_fxaaSubpixel", - "FXAA sub-pixel amount, lower values have more aliasing and less blur", - }, - { - "r_FXAverageColorFunc", - "How to compute FX system average color? 0 = use IWrad equation, 1 = legacy equation, 2 = spherical harmonics 1 coefficient.", - }, - { - "r_globalGenericMaterialScale", - "Hack global generic material constants", - }, - { - "r_glow", - "Enable glow.", - }, - { - "r_glow_allowed", - "Allow glow.", - }, - { - "r_glow_allowed_script_forced", - "Force 'allow glow' to be treated as true, by script.", - }, - { - "r_glowTweakAltColorScaleB", - "Tweak dev var; Alt cutoff intensity B", - }, - { - "r_glowTweakAltColorScaleG", - "Tweak dev var; Alt cutoff intensity G", - }, - { - "r_glowTweakAltColorScaleR", - "Tweak dev var; Alt cutoff intensity R", - }, - { - "r_glowTweakAltCutoff", - "Tweak dev var; Alt cutoff", - }, - { - "r_glowTweakBloomCutoff", - "Tweak dev var; Glow bloom cut off fraction", - }, - { - "r_glowTweakBloomDesaturation", - "Tweak dev var; Glow bloom desaturation", - }, - { - "r_glowTweakBloomIntensity0", - "Tweak dev var; Glow bloom intensity", - }, - { - "r_glowTweakBloomPinch", - "Tweak dev var; Pinch the bloom horizontally ( positive ) or vertically ( negative )", - }, - { - "r_glowTweakEnable", - "Tweak dev var; Enable glow", - }, - { - "r_glowTweakRadius0", - "Tweak dev var; Glow radius in pixels at 640x480", - }, - { - "r_glowTweakUseAltCutoff", - "Tweak dev var; Enable glow alt cutoff", - }, - { - "r_glowUseTweaks", - "Overide glow with tweak dvar values.", - }, - { - "r_gpuFrameHistogram", - "Enables a visual histogram of time between page flips.", - }, - { - "r_gpuTimers", - "GPU Timers to display", - }, - { - "r_gpuTimersShowPrepass", - "Show prepass in GPU Timers", - }, - { - "r_gradientAdjust", - "Enable mipmap gradient adjust (required by checkerboard upsample)", - }, - { - "r_gunSightColorEntityScale", - "Scale the gun sight color when over an entity.", - }, - { - "r_gunSightColorNoneScale", - "Scale the gun sight color when not over an entity.", - }, - { - "r_hdrSkyIntensity", - "Vision set intensity for HDR sky.", - }, - { - "r_hdrSkyIntensityUseTweaks", - "Enables HDR sky intensity tweaks", - }, - { - "r_hdrSpotmeter", - "Perform HDR spot meter measurement of luminance and color in center of screen", - }, - { - "r_hemiAoBlurTolerance", - "Hemi SSAO Blur Tolerance (log10)", - }, - { - "r_hemiAoCombineResolutionsBeforeBlur", - "The higher quality modes blend wide and narrow sampling patterns. The wide pattern is due to deinterleaving and requires blurring. The narrow pattern is not on a deinterleaved buffer, but it only samples every other pixel. The blur on it is optional. If you combine the two before blurring, the narrow will get blurred as well. This creates a softer effect but can remove any visible noise from having 50% sample coverage.", - }, - { - "r_hemiAoCombineResolutionsWithMul", - "When combining the wide and narrow patterns, a mul() operation can be used or a min() operation. Multiplication exaggerates the result creating even darker creases. This is an artistic choice. I think it looks less natural, but often art teams prefer more exaggerated contrast. For me, it's more about having the right AO falloff so that it's a smooth gradient rather than falling off precipitously and forming overly dark recesses.", - }, - { - "r_hemiAoDepthSquash", - "Hemi SSAO depth squash. Value is rcp.", - }, - { - "r_hemiAoEnable", - "Enable Hemi SSAO", - }, - { - "r_hemiAoHierarchyDepth", - "Hemi SSAO recursion depth (filter width)", - }, - { - "r_hemiAoMaxDepthDownsample", - "Use max depth value when downsampling, instead of pseudo-randomly picking a depth sample? Leaving this at the default false may produce more stable results.", - }, - { - "r_hemiAoNoiseFilterTolerance", - "This is necessary to filter out pixel shimmer due to bilateral upsampling with too much lost resolution. High frequency detail can sometimes not be reconstructed, and the noise filter fills in the missing pixels with the result of the higher resolution SSAO. Value is log10.", - }, - { - "r_hemiAoPower", - "Power curve applied to Hemi SSAO factor, not applied in game yet", - }, - { - "r_hemiAoQualityLevel", - "Hemi SSAO quality setting", - }, - { - "r_hemiAoRejectionFalloff", - "Controls how aggressive to fade off samples that occlude spheres but by so much as to be unreliable. This is what gives objects a dark halo around them when placed in front of a wall. If you want to fade off the halo, boost your rejection falloff. The tradeoff is that it reduces overall AO. Value is rcp.", - }, - { - "r_hemiAoStrength", - "Strength of Hemi Screen Space Ambient Occlusion effect", - }, - { - "r_hemiAoUpsampleTolerance", - "Hemi SSAO Upsample Tolerance (log10)", - }, - { - "r_heroLighting", - "Enable hero-only lighting", - }, - { - "r_hideAmbientSModels", - "Hide ambient static models.", - }, - { - "r_hideDepthHack", - "Hide depth hackS to make it easier to find floating decals.", - }, - { - "r_hideLitTSplit0", - "Hide lit transparent prior to split", - }, - { - "r_hideLitTSplit1", - "Hide lit transparent post split", - }, - { - "r_hideModelLMapSModels", - "Hide model lightmap static models.", - }, - { - "r_hideOpaque", - "Hide opaque to make it easier to find floating decals.", - }, - { - "r_hideReactiveMotionSModels", - "Hide reactive motion static models.", - }, - { - "r_hideVertexLitSModels", - "Hide vertex lit static models.", - }, - { - "r_highLodDist", - "Distance for high level of detail", - }, - { - "r_hudFx", - "Draw HUD Effects", - }, - { - "r_ignore", - "", - }, - { - "r_ignoreDoplFlags", - "Debug only dvar: Enable it then all vfx spot light becomes dopls depend on r_dynamicOPL.", - }, - { - "r_ignoref", - "", - }, - { - "r_inGameVideo", - "Allow in game cinematics", - }, - { - "r_lateAllocParamCacheAllowed", - "Enable late allocation of parameter cache for VS stage.", - }, - { - "r_lateAllocParamCacheDefault", - "Late allocation of parameter cache value for sub-div materials.", - }, - { - "r_lateAllocParamCacheDisplacement", - "Late allocation of parameter cache value for sub-div materials.", - }, - { - "r_lateAllocParamCacheSubdiv", - "Late allocation of parameter cache value for sub-div materials.", - }, - { - "r_letterbox4x3", - "Use 16:9 aspect ratio always, with conversion to letterbox 4:3 if necessary.", - }, - { - "r_lightCacheLessFrequentMaxDistance", - "Adjust the distance fx models (and models tagged as less-frequently-lit by script) move before immediately being relit", - }, - { - "r_lightCacheLessFrequentPeriod", - "Adjust how frequently fx models (and models tagged as less-frequently-lit by script) get relit on average (1 is every frame, 8 is every 8th frame)", - }, - { - "r_lightGridAvgApplyPrimaryLight", - "apply primary light color onto r_showLightGridAvgProbes boxes", - }, - { - "r_lightGridAvgFollowCamera", - "allow the r_showLightGridAvgProbes boxes following current camera position", - }, - { - "r_lightGridAvgProbeCount", - "how many light grid avg color probes will show up)", - }, - { - "r_lightGridAvgTraceGround", - " lock boxes to ground ", - }, - { - "r_lightGridContrast", - "Adjust the contrast of light color from the light grid", - }, - { - "r_lightGridDefaultFXLightingLookup", - "Default FX lighting lookup location\n", - }, - { - "r_lightGridDefaultModelLightingLookup", - "Default model lighting lookup location", - }, - { - "r_lightGridEnableTweaks", - "Enable tweaks of the light color from the light grid", - }, - { - "r_lightGridIntensity", - "Adjust the intensity of light color from the light grid", - }, - { - "r_lightGridSHBands", - "Spherical harmonics bands being used for evaluating current-gen light grids colors. 0 = default, 1 = 1 band, 2 = 2 bands, 3 = 3 bands.\n", - }, - { - "r_lightGridUseTweakedValues", - "Use tweaked values instead of default", - }, - { - "r_lightMap", - "Replace all lightmaps with pure black or pure white", - }, - { - "r_lightSetDebugOverlay", - "Enable LightSets Debug Overlay", - }, - { - "r_lightTweakBoneSpaceIndex", - "Tweak origin and angles appear in the space of this entity", - }, - { - "r_lightTweakColor", - "Light color", - }, - { - "r_lightTweakEnable", - "Apply light tweaks to the active primary light", - }, - { - "r_lightTweakEntSpaceIndex", - "Tweak origin and angles appear in the space of this entity", - }, - { - "r_lightTweakHeading", - "Light heading in degrees", - }, - { - "r_lightTweakIndex", - "Light index to tweak. Works with r_lightTweakEnable.", - }, - { - "r_lightTweakInnerCone", - "Light tweak inner cone angle", - }, - { - "r_lightTweakIntensity", - "Light strength", - }, - { - "r_lightTweakOuterCone", - "Light tweak outer cone angle", - }, - { - "r_lightTweakPitch", - "Light pitch in degrees", - }, - { - "r_lightTweakRadius", - "Light radius", - }, - { - "r_limitCUCount", - "1 limits the PS4 CU count to 12 matching Xbox One, 0 restores default CU limit.", - }, - { - "r_litSurfaceHDRScalar", - "Vision set based scalar applied to lit surfaces", - }, - { - "r_lockPvs", - "Lock the viewpoint used for determining what is visible to the current position and direction", - }, - { - "r_lod4Dist", - "Distance for lowest level of detail 4", - }, - { - "r_lod5Dist", - "Distance for lowest level of detail 5", - }, - { - "r_lowestLodDist", - "Distance for lowest level of detail", - }, - { - "r_lowLodDist", - "Distance for low level of detail", - }, - { - "r_mbEnable", - "Set of objects which will be enabled for motion blur", - }, - { - "r_mbFastEnable", - "Toggle on/off fast high quality motion blur", - }, - { - "r_mbFastPreset", - "Changes motion blur quality", - }, - { - "r_mdao", - "Enable the medium distance ambient occlusion feature", - }, - { - "r_mdaoAsyncOccluderGen", - "The occluder generation step is performed via async compute", - }, - { - "r_mdaoBoneInfluenceRadiusScale", - "Scale for the bone influence radius for mdao", - }, - { - "r_mdaoCapsuleStrength", - "MDAO strength for capsule occluders", - }, - { - "r_mdaoDrawOccluders", - "Draws the entity occluder ellipsoids used as MDAO casters", - }, - { - "r_mdaoMinBoneBoundsToOcclude", - "Minimum volume of the bone collider to create occluders for", - }, - { - "r_mdaoOccluderCullDistance", - "Culling distance for mdao occluders", - }, - { - "r_mdaoOccluderFadeOutStartDistance", - "Fade out distance for mdao occluders", - }, - { - "r_mdaoUseTweaks", - "Use r_mdao* dvars instead of the current light set values for MDAO", - }, - { - "r_mdaoVolumeStrength", - "MDAO strength for volume occluders", - }, - { - "r_mediumLodDist", - "Distance for medium level of detail", - }, - { - "r_mode", - "Display mode", - }, - { - "r_modelLightingMap", - "Replace all model lighting maps (light grid) with pure black", - }, - { - "r_mpRimColor", - "Change character's rim color for multiplayer", - }, - { - "r_mpRimDiffuseTint", - "Change character's rim diffuse tint for multiplayer.", - }, - { - "r_mpRimStrength", - "Change character's rim color for multiplayer", - }, - { - "r_mrtEnable", - "Enable setting of multiple render targets.", - }, - { - "r_normalMap", - "Replace all normal maps with a flat normal map", - }, - { - "r_occlusionQueryDebugOverlay", - "Enable OcclusionQuery Debug Overlay", - }, - { - "r_offchipTessellationAllowed", - "Enable off-chip tessellation support.", - }, - { - "r_offchipTessellationTfThreshold", - "Tessellation factor threshold for off-chip.", - }, - { - "r_offchipTessellationWaveThreshold", - "Domain shader wave threshold for off-chip.", - }, - { - "r_opaqueUnlit", - "Toggles opaque rendering without lighting", - }, - { - "r_outdoor", - "Prevents snow from going indoors", - }, - { - "r_outdoorDebugOverlay", - "Enable Outdoor Debug Overlay", - }, - { - "r_outdoorFeather", - "Outdoor z-feathering value", - }, - { - "r_overrideDrawList", - "Replace textures for this draw list", - }, - { - "r_p4xCapture", - "P4X capture", - }, - { - "r_particleHdr", - "Enable Hdr Particle Features", - }, - { - "r_patchCountAllowed", - "Enable run-time setting of patch count per draw call.", - }, - { - "r_pix_material", - "Enable profile material names. Set to 1 to see material and technique names as markers. Set to 2 to also see shader names.", - }, - { - "r_polygonOffsetBias", - "Offset bias for decal polygons; bigger values z-fight less but poke through walls more", - }, - { - "r_polygonOffsetClamp", - "Offset clamp for decal polygons; bigger values z-fight less but poke through walls more", - }, - { - "r_polygonOffsetScale", - "Offset scale for decal polygons; bigger values z-fight less but poke through walls more", - }, - { - "r_portalBevels", - "Helps cull geometry by angles of portals that are acute when projected onto the screen, value is the cosine of the angle", - }, - { - "r_portalBevelsOnly", - "Use screen-space bounding box of portals rather than the actual shape of the portal projected onto the screen", - }, - { - "r_portalMinClipArea", - "Don't clip child portals by a parent portal smaller than this fraction of the screen area.", - }, - { - "r_portalMinRecurseDepth", - "Ignore r_portalMinClipArea for portals with fewer than this many parent portals.", - }, - { - "r_portalWalkLimit", - "Stop portal recursion after this many iterations. Useful for debugging portal errors.", - }, - { - "r_postAA", - "Post process antialiasing mode", - }, - { - "r_postfx_enable", - "Enable post-processing effects such as color correction, bloom, depth-of-field, etc.", - }, - { - "r_primaryLightTweakDiffuseStrength", - "Tweak the diffuse intensity for primary lights", - }, - { - "r_primaryLightTweakSpecularStrength", - "Tweak the specular intensity for primary lights", - }, - { - "r_primaryLightUseTweaks", - "", - }, - { - "r_primBegin", - "Beginning of the range of drawn primitives, inclusive.", - }, - { - "r_primBisect", - "Enables limiting the range of drawn primitives, for debugging.", - }, - { - "r_primEnd", - "End of the range range of drawn primitives, inclusive.", - }, - { - "r_PS4HardwareGamma", - "Controls the hardware gamma curve used (higher is darker)", - }, - { - "r_randomFailCommandBuffer", - "Command buffer failure rate", - }, - { - "r_randomFailConstantBuffer", - "Constant buffer failure rate", - }, - { - "r_reactiveMotionActorRadius", - "Radial distance from the ai characters that influences reactive motion models (inches)", - }, - { - "r_reactiveMotionActorVelocityMax", - "AI velocity considered the maximum when determining the length of motion tails (inches/sec)", - }, - { - "r_reactiveMotionActorZOffset", - "Distance from the actor origin along Z direction where the actor's reactive motion effector sphere is centered at.", - }, - { - "r_reactiveMotionEffectorDebugDraw", - "Enable debug drawing of effector spheres", - }, - { - "r_reactiveMotionEffectorStrengthScale", - "Additional scale for the effector influence, as a factor of the model part distance from the effector center and model part extents", - }, - { - "r_reactiveMotionHelicopterLimit", - "Maximum number of helicopter entities that actively influence reactive motion. Can increase CPU cost of the scene.", - }, - { - "r_reactiveMotionHelicopterRadius", - "Radial distance from the helicopter that influences reactive motion models (inches)", - }, - { - "r_reactiveMotionHelicopterStrength", - "Scales the influence of helicopter wind tunnel motion", - }, - { - "r_reactiveMotionPlayerHeightAdjust", - "Amount to adjust the vertical distance of the effector from the player position (inches)", - }, - { - "r_reactiveMotionPlayerRadius", - "Radial distance from the player that influences reactive motion models (inches)", - }, - { - "r_reactiveMotionPlayerZOffset", - "Distance from the player origin along Z direction where the player's reactive motion effector sphere is centered at.", - }, - { - "r_reactiveMotionVelocityTailScale", - "Additional scale for the velocity-based motion tails, as a factor of the effector radius", - }, - { - "r_reactiveMotionWindAmplitudeScale", - "Scales amplitude of wind wave motion", - }, - { - "r_reactiveMotionWindAreaScale", - "Scales distribution of wind motion", - }, - { - "r_reactiveMotionWindDir", - "Controls the global wind direction", - }, - { - "r_reactiveMotionWindFrequencyScale", - "Scales frequency of wind wave motion", - }, - { - "r_reactiveMotionWindStrength", - "Scale of the global wind direction (inches/sec)", - }, - { - "r_reflectionProbeMap", - "Replace all reflection probes with pure black", - }, - { - "r_reflectionProbeNmlLuminance", - "Enable/disable shader code for computing luminance during reflection probe denormalization. This is just an experiment.\n", - }, - { - "r_rimLight0Heading", - "Rim Light 0 heading in degrees", - }, - { - "r_rimLight0Pitch", - "Rim Light 0 pitch in degrees -90 is noon.", - }, - { - "r_rimLightBias", - "How much to bias the n.l calculation", - }, - { - "r_rimLightDiffuseIntensity", - "Strength of the diffuse component of the rim light.", - }, - { - "r_rimLightFalloffMaxDistance", - "Distance at which the rim light hits intensity of 100%.", - }, - { - "r_rimLightFalloffMinDistance", - "Distance at which the rim light hits intensity of 100%.", - }, - { - "r_rimLightFalloffMinIntensity", - "Intensity of the effect at and before minDistance.", - }, - { - "r_rimLightPower", - "Power to raise the n.l calculation", - }, - { - "r_rimLightSpecIntensity", - "Strength of the spec ( additive) component of the rim light", - }, - { - "r_rimLightUseTweaks", - "Turn on rim lighting tweaks", - }, - { - "r_scaleViewport", - "Scale 3D viewports by this fraction. Use this to see if framerate is pixel shader bound.", - }, - { - "r_sceneMipShowOverlay", - "Toggles scene mip rendertarget overlay", - }, - { - "r_showAabbTrees", - "Show axis-aligned bounding box trees used in potentially visibile set determination. 1 shows hierarchy, 2 shows world surfaces, 3 shows both.", - }, - { - "r_showCollision", - "Show the collision surfaces for the selected mask types", - }, - { - "r_showCollisionDepthTest", - "Select whether to use depth test in collision surfaces display", - }, - { - "r_showCollisionDist", - "Maximum distance to show collision surfaces", - }, - { - "r_showCollisionGroups", - "Select whether to show the terrain, brush or all collision surface groups", - }, - { - "r_showCollisionPolyType", - "Select whether to display the collision surfaces as wireframe, poly interiors, or both", - }, - { - "r_showCullBModels", - "Show culled brush models", - }, - { - "r_showCullSModels", - "Show culled static models", - }, - { - "r_showCullXModels", - "Show culled xmodels", - }, - { - "r_showFbColorDebug", - "Show front buffer color debugging information", - }, - { - "r_showFloatZDebug", - "Show float z buffer used to eliminate hard edges on particles near geometry", - }, - { - "r_showLightGrid", - "Show light grid debugging information (2: detailed, 3: detailed for this box only)", - }, - { - "r_showLightGridAvgProbes", - "show an array of boxes which are using the light grid average color at its location", - }, - { - "r_showLightGridDetailInfo", - "Show more details for light grid debugging.", - }, - { - "r_showLightProbes", - "Show the light probes at the light grid sample locations in world space centered around the camera.", - }, - { - "r_showMissingLightGrid", - "Use rainbow colors for entities that are outside the light grid", - }, - { - "r_showModelLightingLowWaterMark", - "", - }, - { - "r_showModelList", - "Display models that are in the ShowModelList.txt", - }, - { - "r_showModelLods", - "Currently drawn LOD displayed with each model", - }, - { - "r_showModelNames", - "Model names displayed with each model", - }, - { - "r_showPortals", - "Show portals for debugging", - }, - { - "r_showPortalsOverview", - "Render 2d XY portal overlay scaled to fit to this distance. Useful for debugging portal errors.", - }, - { - "r_showPrimCounts", - "Prim count for each rendered entity", - }, - { - "r_showReflectionProbeSelection", - "Show reflection probe selection", - }, - { - "r_showSModelNames", - "Show static model names", - }, - { - "r_showSurfCounts", - "Surface count for each rendered entity", - }, - { - "r_showTess", - "Show details for each surface", - }, - { - "r_showTexelDensity", - "Enable shader overrides for texel density.", - }, - { - "r_showTriCountMin", - "Minimum triangle count to show when showing tri counts", - }, - { - "r_showTriCounts", - "Triangle count for each rendered entity", - }, - { - "r_showTris", - "Show triangle outlines", - }, - { - "r_showVertCountMin", - "Minimum vertex count to show when showing vert counts", - }, - { - "r_showVertCounts", - "", - }, - { - "r_singleCell", - "Only draw things in the same cell as the camera. Most useful for seeing how big the current cell is.", - }, - { - "r_skipPvs", - "Skipt the determination of what is in the potentially visible set (disables most drawing)", - }, - { - "r_sky_fog_intensity", - "Amount of sky fog fading", - }, - { - "r_sky_fog_max_angle", - "End of angular sky fog fading", - }, - { - "r_sky_fog_min_angle", - "Start of angular sky fog fading", - }, - { - "r_skyFogUseTweaks", - "Enable dvar control of sky fog", - }, - { - "r_smodelInstancedRenderer", - "Render static models with instanced renderer", - }, - { - "r_smodelInstancedThreshold", - "Minimum number of static model instances before instanced rendering is used", - }, - { - "r_smp_backend", - "Process renderer back end in a separate thread", - }, - { - "r_smp_worker", - "Process renderer front end in a separate thread", - }, - { - "r_smp_worker_thread0", - "", - }, - { - "r_smp_worker_thread1", - "", - }, - { - "r_smp_worker_thread2", - "", - }, - { - "r_specOccMap", - "Replace all specular occlusion maps with pure black (fully occluded) or pure white (not occluded)", - }, - { - "r_specularColorScale", - "Set greater than 1 to brighten specular highlights", - }, - { - "r_specularMap", - "Replace all specular maps with pure black (off) or pure white (super shiny)", - }, - { - "r_spotLightEntityShadows", - "Enable entity shadows for spot lights.", - }, - { - "r_spotLightShadows", - "Enable shadows for spot lights.", - }, - { - "r_ssao", - "Screen Space Ambient Occlusion mode", - }, - { - "r_ssaoDebug", - "Render calculated or blurred Screen Space Ambient Occlusion values", - }, - { - "r_ssaoDebugMip", - "Selects which mip level to render when r_ssaoDebug is enabled. If 0 and r_ssaoDownsample is enabled, will render mip 1.", - }, - { - "r_ssaoDepthScale", - "Scale applied to depth values used for occlusion tests.", - }, - { - "r_ssaoDepthScaleViewModel", - "Scale applied to depth values used for occlusion tests.", - }, - { - "r_ssaoDownsample", - "Screen Space Ambient Occlusion calculation occurs at half linear resolution", - }, - { - "r_ssaoFadeDepth", - "Depth at which the SSAO begins to fade out. It fades at even increments of this distance (e.g. it's at 1 for depth r_ssaoFadeDepth, 1/2 for depth 2*r_ssaoFadeDepth, etc.)", - }, - { - "r_ssaoGapFalloff", - "Falloff used to blend between creases (that should darken) and silhouettes (that should not darken). Lower values falloff more quickly.", - }, - { - "r_ssaoGradientFalloff", - "Falloff used to fade out the effect for steep depth gradients (i.e. surfaces nearly parallel to the camera direction). This fixes sampling artifacts that appear for surfaces nearly parallel to the camera direction (commonly occuring for flat ground planes).", - }, - { - "r_ssaoMaxStrengthDepth", - "Depth at which SSAO strength is at its maximum", - }, - { - "r_ssaoMethod", - "Screen Space Ambient Occlusion method (original or IW6, both are volumetric obscurance)", - }, - { - "r_ssaoMinPixelWidth", - "Minimum pixel width of the effect. When the effect is smaller than this, it is culled entirely.", - }, - { - "r_ssaoMinStrengthDepth", - "Depth at which SSAO strength is zero, effectively disabled", - }, - { - "r_ssaoMultiRes", - "Screen Space Ambient Occlusion calculation occurs at half linear resolution", - }, - { - "r_ssaoPower", - "Power curve applied to SSAO factor", - }, - { - "r_ssaoRejectDepth", - "Depth at which the SSAO is disabled. Smaller values result in more rejected pixels which is faster, but limits the distance at which the effect is visible.", - }, - { - "r_ssaoSampleCount", - "Selects the number of samples used for SSAO", - }, - { - "r_ssaoScriptScale", - "Allows script to lerp to disable or enable the SSAO. This applies a scalar value to the SSAO strength. When set to 0, this effectively disables SSAO.", - }, - { - "r_ssaoStrength", - "Strength of Screen Space Ambient Occlusion effect", - }, - { - "r_ssaoUseTweaks", - "Use r_ssao* dvars instead of the current light set values for SSAO", - }, - { - "r_ssaoWidth", - "The width of the SSAO effect, in pixels at 720p. Larger values increase area but lower effective quality.", - }, - { - "r_ssrBlendScale", - "Add extra scale to ssr weight versus reflection probe weight, >1 value will make ssr more obvious.", - }, - { - "r_ssrDepthTraceFakeOff", - "toggle on/off to see ssr depth trace material performance impact.", - }, - { - "r_ssrFadeInDuration", - "Duration of the screen-space reflection fade-in, which occurs whenever the reflection source buffer is invalidated due to view changes (in particular, dual-view scope transitions).", - }, - { - "r_ssrRoughnessMipParameters", - "X: mirror mip; Y: roughest mip; Z: roughness middle point, may need different value for different screen resolution on PC.", - }, - { - "r_ssrShowOverlay", - "Toggles overlay drawing of screen space reflection occlusion buffers.", - }, - { - "r_sssBlendWeight", - "Controls the blend between the wide (zero) and narrow (one) gaussians", - }, - { - "r_sssDebugMaterial", - "Debug Feature: toggle materials with SSS", - }, - { - "r_sssEnable", - "Enables the subsurface scattering effect (note that disabling SSS will not prevent the filter from running)", - }, - { - "r_sssGlobalRadius", - "Controls the global radius (in inches)", - }, - { - "r_sssJitterRadius", - "Percentage of the kernel to be jittered", - }, - { - "r_sssNarrowRadius", - "Controls the narrow Gaussian radius", - }, - { - "r_sssPreset", - "Changes subsurface scattering quality", - }, - { - "r_sssWideRadius", - "Controls the wide Gaussian radius", - }, - { - "r_staticModelDumpLodInfo", - "Dump static model info for the next frame.", - }, - { - "r_subdiv", - "Enables Catmull Clark surface subdivision.", - }, - { - "r_subdivLimit", - "Set the maximum Catmull Clark subdivision level.", - }, - { - "r_subdivPatchCount", - "Patches per thread group for sub-division surfaces.", - }, - { - "r_subdomainLimit", - "Maximum number of extra tessellation subdivisions using instancing (max tess amts are 0:64, 1:128, 2:192, 3:256, max instances used are 0:1, 1:4, 2:9, 3:12)", - }, - { - "r_subdomainScale", - "Debug only: Scales the extra subdivision amount (for values < 1, not all instanced sub triangles will draw).", - }, - { - "r_subwindow", - "subwindow to draw: left, right, top, bottom", - }, - { - "r_sun_from_dvars", - "Set sun flare values from dvars rather than the level", - }, - { - "r_sun_fx_position", - "Position in degrees of the sun effect", - }, - { - "r_sunblind_fadein", - "time in seconds to fade blind from 0% to 100%", - }, - { - "r_sunblind_fadeout", - "time in seconds to fade blind from 100% to 0%", - }, - { - "r_sunblind_max_angle", - "angle from sun in degrees inside which effect is max", - }, - { - "r_sunblind_max_darken", - "0-1 fraction for how black the world is at max blind", - }, - { - "r_sunblind_min_angle", - "angle from sun in degrees outside which effect is 0", - }, - { - "r_sunflare_fadein", - "time in seconds to fade alpha from 0% to 100%", - }, - { - "r_sunflare_fadeout", - "time in seconds to fade alpha from 100% to 0%", - }, - { - "r_sunflare_max_alpha", - "0-1 vertex color and alpha of sun at max effect", - }, - { - "r_sunflare_max_angle", - "angle from sun in degrees inside which effect is max", - }, - { - "r_sunflare_max_size", - "largest size of flare effect in pixels at 640x480", - }, - { - "r_sunflare_min_angle", - "angle from sun in degrees outside which effect is 0", - }, - { - "r_sunflare_min_size", - "smallest size of flare effect in pixels at 640x480", - }, - { - "r_sunflare_shader", - "name for flare effect; can be any material", - }, - { - "r_sunglare_fadein", - "time in seconds to fade glare from 0% to 100%", - }, - { - "r_sunglare_fadeout", - "time in seconds to fade glare from 100% to 0%", - }, - { - "r_sunglare_max_angle", - "angle from sun in degrees inside which effect is max", - }, - { - "r_sunglare_max_lighten", - "0-1 fraction for how white the world is at max glare", - }, - { - "r_sunglare_min_angle", - "angle from sun in degrees inside which effect is max", - }, - { - "r_sunInfDist", - "Sun infinite distance used to place sun fx", - }, - { - "r_sunshadowmap_cmdbuf_worker", - "Process shadowmap command buffer in a separate thread", - }, - { - "r_sunsprite_shader", - "name for static sprite; can be any material", - }, - { - "r_sunsprite_size", - "diameter in pixels at 640x480 and 80 fov", - }, - { - "r_sunsprite_size_override", - "override the .sun file for the sunsprite size; diameter in pixels at 640x480 and 80 fov, -1 means off", - }, - { - "r_surfaceHDRScalarUseTweaks", - "Enables lit and unlit surface scalar tweaks", - }, - { - "r_tension_enable", - "Toggles tension", - }, - { - "r_tessellation", - "Enables tessellation of world geometry, with an optional cutoff distance.", - }, - { - "r_tessellationCutoffDistance", - "Distance at which world geometry ceases to tessellate.", - }, - { - "r_tessellationCutoffFalloff", - "Range over which tessellation is faded out, up to the cutoff.", - }, - { - "r_tessellationEyeScale", - "Scale applied due to eye * object normal for less tessellation on facing polygons.", - }, - { - "r_tessellationFactor", - "Target edge length, based on dividing full window height by this factor, for dynamic tessellation. Use zero to disable tessellation.", - }, - { - "r_tessellationGPUSync", - "Sync GPU between tessellated world surfaces (temporary hack for GPU hang)", - }, - { - "r_tessellationHeightAuto", - "Correctly auto scale displacement heights for layers to grow as texture is stretched over larger surface areas to preserve feature proportions.", - }, - { - "r_tessellationHeightScale", - "Displacement height scale factor.", - }, - { - "r_tessellationHybrid", - "Hybrid per pixel displacement scale.", - }, - { - "r_tessellationLodBias", - "Displacement map lod bias.", - }, - { - "r_texFilterAnisoBias", - "Bias used when computing anisotropy ratio. Lower values are more efficient at the expense of filtering quality.", - }, - { - "r_texFilterAnisoMax", - "Maximum anisotropy to use for texture filtering", - }, - { - "r_texFilterAnisoMin", - "Minimum anisotropy to use for texture filtering (overridden by max)", - }, - { - "r_texFilterDisable", - "Disables all texture filtering (uses nearest only.)", - }, - { - "r_texFilterMipBias", - "Change the mipmap bias", - }, - { - "r_texFilterMipMode", - "Forces all mipmaps to use a particular blend between levels (or disables mipping.)", - }, - { - "r_texFilterProbeBilinear", - "Force reflection probe to use bilinear filter", - }, - { - "r_texFilterTrilinearWindow", - "Window over which trilinear filtering blends between mips. A value of 1.0 is a linear blend, and a value of 0 is the minimal blend. Smaller values are more efficient but result in a sharper transition between mip levels.", - }, - { - "r_texShowMipMode", - "Forces textures with the specified mip filtering to draw black.", - }, - { - "r_thermal", - "Select thermal effect mode", - }, - { - "r_thermalColorOffset", - "Offset of the thermal colors (offset + scale*color)", - }, - { - "r_thermalColorScale", - "Scale of the thermal colors (offset + scale*color)", - }, - { - "r_thermalDetailScale", - "Scale of the detail that is added to the thermal map from the normal map (multiplies the detail amount from AssetManager)", - }, - { - "r_thermalFadeColor", - "Color the thermal fades to at distance.", - }, - { - "r_thermalFadeControl", - "Select thermal fade mode", - }, - { - "r_thermalFadeMax", - "Distance at which thermal stops fading", - }, - { - "r_thermalFadeMin", - "Distance at which thermal starts fading", - }, - { - "r_tonemap", - "HDR Tonemapping mode", - }, - { - "r_tonemapAdaptSpeed", - "HDR Tonemap exposure adaptation speed", - }, - { - "r_tonemapAuto", - "HDR Tonemapping performs auto-exposure", - }, - { - "r_tonemapAutoExposureAdjust", - "HDR Tonemap Auto Exposure Adjust value (set to 0.0 for automatic adjustment)", - }, - { - "r_tonemapBlack", - "HDR Filmic Tonemap black point", - }, - { - "r_tonemapBlend", - "HDR Tonemapping blends between exposures", - }, - { - "r_tonemapCaptureExposurePoint", - "Capture the specified exposure point (Negative value means no capture).", - }, - { - "r_tonemapCaptureMode", - "Tonemap Exposure Capture Mode.", - }, - { - "r_tonemapCaptureTweakExposureAdjust", - "HDR Tonemap Exposure Adjust Tweak", - }, - { - "r_tonemapCrossover", - "HDR Filmic Tonemap crossover point", - }, - { - "r_tonemapDarkEv", - "HDR Tonemap Dark EV", - }, - { - "r_tonemapDarkExposureAdjust", - "HDR Tonemap Dark Exposure Adjust", - }, - { - "r_tonemapDebug", - "Tonemap curve debug", - }, - { - "r_tonemapExposure", - "HDR Tonemap exposure (in EV) override (only works in non-auto mode)", - }, - { - "r_tonemapExposureAdjust", - "HDR Tonemap exposure adjustment (in EV, 0 is no adjustment, works like a camera where +1 reduces EV by 1)", - }, - { - "r_tonemapGamma", - "HDR Tonemap gamma curve power", - }, - { - "r_tonemapHighlightRange", - "HDR Tonemap dynamic range, which determines white point luminance", - }, - { - "r_tonemapLightEv", - "HDR Tonemap Light EV", - }, - { - "r_tonemapLightExposureAdjust", - "HDR Tonemap Light Exposure Adjust", - }, - { - "r_tonemapLockAutoExposureAdjust", - "HDR Tonemapping lock auto exposure adjust", - }, - { - "r_tonemapMaxExposure", - "HDR Tonemap maximum exposure (in EV)", - }, - { - "r_tonemapMaxExposureAdjust", - "HDR Tonemap Max Exposure Adjust", - }, - { - "r_tonemapMidEv", - "HDR Tonemap Mid EV", - }, - { - "r_tonemapMidExposureAdjust", - "HDR Tonemap Mid Exposure Adjust", - }, - { - "r_tonemapMinExposureAdjust", - "HDR Tonemap Min Exposure Adjust", - }, - { - "r_tonemapShoulder", - "HDR Filmic Tonemap shoulder control (0 is linear)", - }, - { - "r_tonemapToe", - "HDR Filmic Tonemap toe control (0 is linear)", - }, - { - "r_tonemapUseCS", - "HDR Tonemapping uses compute shader.", - }, - { - "r_tonemapUseTweaks", - "Override tone map LightSet settings with tweak dvar values.", - }, - { - "r_tonemapWhite", - "HDR Filmic Tonemap white point", - }, - { - "r_trace", - "Razor GPU trace capture", - }, - { - "r_uhdMode", - "UHD up-scale mode", - }, - { - "r_ui3d_debug_display", - "Show UI3D debug overlay", - }, - { - "r_ui3d_h", - "ui3d texture window height", - }, - { - "r_ui3d_use_debug_values", - "Use UI debug values", - }, - { - "r_ui3d_w", - "ui3d texture window width", - }, - { - "r_ui3d_x", - "ui3d texture window x", - }, - { - "r_ui3d_y", - "ui3d texture window y", - }, - { - "r_uiBlurDstMode", - "UI blur distortion mode. Fast uses the scene mip map render target, PostSun uses a downsampled post sun resolve buffer, PostSun HQ uses a gaussian blurred post sun resolve buffer.", - }, - { - "r_umbra", - "Enables Umbra-based portal culling.", - }, - { - "r_umbraAccurateOcclusionThreshold", - "The distance (in inches) to which accurate occlusion information is gathered. -1.0 = deduced automatically.", - }, - { - "r_umbraExclusive", - "Toggle Umbra for exclusive static culling (disables static portal dpvs)", - }, - { - "r_umbraQueryParts", - "The number of parts the Umbra query frustum is broken into for async query processing as an M x N grid (0, 0 = all queries are synchronous).", - }, - { - "r_umbraUseDpvsCullDist", - "Use cull distance from the DPVS instead of the far plane distance.", - }, - { - "r_unlitSurfaceHDRScalar", - "Vision set based scalar applied to unlit surfaces to balance those surfaces with the luminance of the scene", - }, - { - "r_upsampleMode", - "Checkerboard upsample mode", - }, - { - "r_useComputeSkinning", - "Enables compute shader (GPU) skinning.", - }, - { - "r_useLightGridDefaultFXLightingLookup", - "Enable/disable default fx lighting lookup\n", - }, - { - "r_useLightGridDefaultModelLightingLookup", - "Enable/disable default model lighting lookup\n", - }, - { - "r_useShadowGeomOpt", - "Enable iwRad shadow geometry optimization. It only works when we have the data generated in iwRad.", - }, - { - "r_useSunShadowPortals", - "Enable sun shadow portals when dir light change and not using cached shadow.", - }, - { - "r_useXAnimIK", - "Enables IK animation.", - }, - { - "r_validateCmdBuf", - "Enable validation of command buffer during kick.", - }, - { - "r_vc_makelog", - "Enable logging of light grid points for the vis cache. 1 starts from scratch, 2 appends.", - }, - { - "r_vc_showlog", - "Show this many rows of light grid points for the vis cache", - }, - { - "r_veil", - "Apply veiling luminance (HDR glow)", - }, - { - "r_veilAntialiasing", - "Veil antialiasing mode (downsample technique used for first mip).", - }, - { - "r_veilBackgroundStrength", - "Strength of background when applying veiling luminance (HDR glow)", - }, - { - "r_veilFalloffScale1", - "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", - }, - { - "r_veilFalloffScale2", - "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", - }, - { - "r_veilFalloffWeight1", - "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", - }, - { - "r_veilFalloffWeight2", - "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", - }, - { - "r_veilFilter", - "Changes the veil filtering mode", - }, - { - "r_veilPreset", - "Changes veil sampling quality", - }, - { - "r_veilRadius", - "Controls the radius of the first Gaussian in virtual pixels (remaining Gaussians follow proportionally).", - }, - { - "r_veilStrength", - "Strength of veiling luminance (HDR glow)", - }, - { - "r_veilUseTweaks", - "Override veil LightSet settings with tweak dvar values.", - }, - { - "r_velocityPrepass", - "Perform velocity rendering during the depth prepass", - }, - { - "r_viewModelPrimaryLightTweakDiffuseStrength", - "Tweak the diffuse intensity for view model primary lights", - }, - { - "r_viewModelPrimaryLightTweakSpecularStrength", - "Tweak the specular intensity for view model primary lights", - }, - { - "r_viewModelPrimaryLightUseTweaks", - "", - }, - { - "r_volumeLightScatter", - "Enables volumetric light scattering", - }, - { - "r_volumeLightScatterAngularAtten", - "Distance of sun from center of screen before angular attenuation starts for god rays", - }, - { - "r_volumeLightScatterBackgroundDistance", - "Distance at which pixels are considered background for volume light scatter effect", - }, - { - "r_volumeLightScatterDebug", - "Enables volumetric light scattering debug rendering", - }, - { - "r_volumeLightScatterDepthAttenFar", - "Pixels >= than this depth recieve full volume light scatter.", - }, - { - "r_volumeLightScatterDepthAttenNear", - "Pixels <= than this depth recieve no volume light scatter.", - }, - { - "r_volumeLightScatterEv", - "Light intensity (in EV) for volumetric light scattering", - }, - { - "r_volumeLightScatterLinearAtten", - "Coefficient of linear attenuation of god rays", - }, - { - "r_volumeLightScatterQuadraticAtten", - "Coefficient of quadratic attenuation of god rays)", - }, - { - "r_volumeLightScatterUseTweaks", - "Enables volumetric light scattering tweaks", - }, - { - "r_vsync", - "Enable v-sync before drawing the next frame to avoid 'tearing' artifacts.", - }, - { - "r_warningRepeatDelay", - "Number of seconds after displaying a \"per-frame\" warning before it will display again", - }, - { - "r_wideTessFactorsThreshold", - "If a surface has more than this many triangles, process triangles in parallel instead of surfaces.", - }, - { - "r_xdebug", - "xmodel/xanim debug rendering", - }, - { - "r_zfar", - "Change the distance at which culling fog reaches 100% opacity; 0 is off", - }, - { - "r_znear", - "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance.", - }, - { - "r_znear_depthhack", - "Viewmodel near clip plane", - }, - { - "radarjamDistMax", - "", - }, - { - "radarjamDistMin", - "", - }, - { - "radarjamSinCurve", - "", - }, - { - "radius_damage_debug", - "Turn on debug lines for radius damage traces", - }, - { - "ragdoll_baselerp_time", - "Default time ragdoll baselerp bones take to reach the base pose", - }, - { - "ragdoll_bullet_force", - "Bullet force applied to ragdolls", - }, - { - "ragdoll_bullet_upbias", - "Upward bias applied to ragdoll bullet effects", - }, - { - "ragdoll_debug_trace", - "Draw traces from penetration test", - }, - { - "ragdoll_dump_anims", - "Dump animation data when ragdoll fails", - }, - { - "ragdoll_enable", - "Turn on ragdoll death animations", - }, - { - "ragdoll_explode_force", - "Explosive force applied to ragdolls", - }, - { - "ragdoll_explode_upbias", - "Upwards bias applied to ragdoll explosion effects", - }, - { - "ragdoll_exploding_bullet_force", - "Force applied to ragdolls from explosive bullets", - }, - { - "ragdoll_exploding_bullet_upbias", - "Upwards bias applied to ragdoll from explosive bullets", - }, - { - "ragdoll_idle_min_velsq", - "Minimum squared speed a ragdoll body needs to be moving before it will shut down due to time", - }, - { - "ragdoll_jitter_scale", - "Scale up or down the effect of physics jitter on ragdolls", - }, - { - "ragdoll_jointlerp_time", - "Default time taken to lerp down ragdoll joint friction", - }, - { - "ragdoll_max_life", - "Max lifetime of a ragdoll system in msec", - }, - { - "ragdoll_max_simulating", - "Max number of simultaneous active ragdolls - archived", - }, - { - "ragdoll_max_stretch_pct", - "Force ragdoll limbs to not stretch more than this percentage in one frame", - }, - { - "ragdoll_resolve_penetration_bias", - "Bias value on force to push ragdolls out of environment.", - }, - { - "ragdoll_rotvel_scale", - "Ragdoll rotational velocity estimate scale", - }, - { - "ragdoll_self_collision_scale", - "Scale the size of the collision capsules used to prevent ragdoll limbs from interpenetrating", - }, - { - "ragdoll_stretch_iters", - "Iterations to run the alternate limb solver", - }, - { - "rankedPlayEndMatchKeepLobby", - "keep the lobby if the lobby host is in our private party.", - }, - { - "recon_serverPort", - "Recon Server Port (IP:Port)", - }, - { - "RemoteCameraSounds_DryLevel", - "", - }, - { - "RemoteCameraSounds_RoomType", - "", - }, - { - "RemoteCameraSounds_WetLevel", - "", - }, - { - "replay_asserts", - "Enable/Disable replay aborts due to inconsistency", - }, - { - "replay_autosave", - "Use autosaves as part of demos - will make demo access faster but will cause hitches", - }, - { - "replay_autosaveOnError", - "Auto save replay on error", - }, - { - "replay_time", - "Draw replay time", - }, - { - "reportUserVoteInterval", - "The interval in minutes you wait before getting another vote on this console as long as the console is turned on.", - }, - { - "requirestats", - "Whether stats are currently required", - }, - { - "reset_mm_data", - "reset data with dlc popup", - }, - { - "riotshield_bullet_damage_scale", - "Value to scale bullet damage to deployed riotshield.", - }, - { - "riotshield_debug", - "Riotshield debug.", - }, - { - "riotshield_deploy_extents", - "Trace extents of the riotshield when planting", - }, - { - "riotshield_deploy_forward_offset", - "Forward offset from the player when planting", - }, - { - "riotshield_deploy_limit_radius", - "Min distance deployed riotshields must be from each other.", - }, - { - "riotshield_deploy_pitch_max", - "Max surface pitch angle to allow riotshield deployment", - }, - { - "riotshield_deploy_roll_max", - "Max surface roll angle to allow riotshield deployment", - }, - { - "riotshield_deploy_trace_parallel", - "Report collisions when riotshield traces are parallel to plane of triangle. If disabled traces parallel to triangle planes do not report collisions at all.", - }, - { - "riotshield_deploy_trigger_yoffset", - "Y offset from the shield to place the trigger", - }, - { - "riotshield_deploy_trigger_zoffset", - "Z offset from the shield to place the trigger", - }, - { - "riotshield_deploy_zdiff_max", - "Max height difference allowed between plant surface and player origin", - }, - { - "riotshield_deployed_health", - "Deployed riotshield health.", - }, - { - "riotshield_destroyed_cleanup_time", - "Time (in seconds) destroyed riotshield model persists before disappearing", - }, - { - "riotshield_explosive_damage_scale", - "Value to scale explosive damage to deployed riotshield..", - }, - { - "riotshield_melee_damage_scale", - "Value to scale melee damage to deployed riotshield.", - }, - { - "riotshield_projectile_damage_scale", - "Value to scale projectile damage to deployed riotshield.", - }, - { - "riotshield_use_mindot", - "The minimum angle dot in order to pick up a deployed riot shield", - }, - { - "riotshield_use_radius", - "The radius within which the player can pick up a deployed riot shield", - }, - { - "RunForTime", - "Time for the server to run", - }, - { - "s_scriptable_physBaseExplosionScale", - "Base multiplier applied to the explosion force calculations (consider this a 'range scaler').", - }, - { - "safeArea_adjusted_horizontal", - "User-adjustable horizontal safe area as a fraction of the screen width", - }, - { - "safeArea_adjusted_vertical", - "User-adjustable vertical safe area as a fraction of the screen height", - }, - { - "safeArea_horizontal", - "Horizontal safe area as a fraction of the screen width", - }, - { - "safeArea_vertical", - "Vertical safe area as a fraction of the screen height", - }, - { - "savegame_profile", - "Profile the size of savegames. Prints results to console after every save.", - }, - { - "scr_dof_enable", - "enable dof", - }, - { - "screenshots_active", - "Are we allowed to enable Screenshots or not", - }, - { - "scriptable_debug", - "Debug mode for scriptables", - }, - { - "scriptable_enable", - "Debug option to enable/disable spawning scriptable instances at run time.", - }, - { - "scriptable_explCamShakeDuration", - "Duration, in MS, that a camera shake should last for during an explosion", - }, - { - "scriptable_explCamShakeRadiusMultiplier", - "Multiplier applied to the outer radius of an explosion event to trigger the shake within.", - }, - { - "scriptable_explCamShakeScale", - "Scale applied to the camera shake. Higher means more shaking.", - }, - { - "scriptIgnoreInfiniteLoops", - "Allows script to loop infinitely without any script errors or warnings.", - }, - { - "sensitivity", - "Mouse sensitivity", - }, - { - "sentry_placement_debug", - "Enables sentry placement debug lines", - }, - { - "sentry_placement_feet_offset", - "Position of the feet from the center axis.", - }, - { - "sentry_placement_feet_trace_dist_z", - "Max distance for a foot to be considered touching the ground", - }, - { - "sentry_placement_trace_dist", - "Distance along the trace axis where the sentry will attempt to position itself", - }, - { - "sentry_placement_trace_min_normal", - "Minimum normal to accept a sentry position", - }, - { - "sentry_placement_trace_parallel", - "Enable turret traces that are parallel to plane of triangle. If 0, traces parallel to triangle planes do not report collisions at all. If 2 (debug-only), then trace code ping pongs between new and old.", - }, - { - "sentry_placement_trace_pitch", - "Pitch used for the trace axis", - }, - { - "sentry_placement_trace_radius", - "Radius of the bound used for the placement trace", - }, - { - "sentry_placement_trace_radius_canon_safety", - "Extra radius used in the forward direction to compensate for the canon length", - }, - { - "serverCulledSounds", - "Enable culling of sounds on the server thread", - }, - { - "session_join_min_time", - "Minimum number of milliseconds between join attempts", - }, - { - "session_nonblocking", - "Non-blocking Session code", - }, - { - "shieldBlastDamageProtection_120", - "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield.", - }, - { - "shieldBlastDamageProtection_180", - "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield.", - }, - { - "shieldBlastDamageProtection_30", - "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield.", - }, - { - "shieldBlastDamageProtection_60", - "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield.", - }, - { - "shieldDeployShakeDuration", - "Viewmodel shake duration for riotshield deploy.", - }, - { - "shieldDeployShakeScale", - "Viewmodel shake scale for riotshield deploy.", - }, - { - "shieldImpactBulletShakeDuration", - "Viewmodel shake duration for bullet impacts.", - }, - { - "shieldImpactBulletShakeScale", - "Viewmodel shake scale for bullet impacts.", - }, - { - "shieldImpactExplosionHighShakeDuration", - "Viewmodel shake duration for strong splash damage.", - }, - { - "shieldImpactExplosionHighShakeScale", - "Viewmodel shake scale for strong splash damage.", - }, - { - "shieldImpactExplosionLowShakeDuration", - "Viewmodel shake duration for weak splash damage.", - }, - { - "shieldImpactExplosionLowShakeScale", - "Viewmodel shake scale for weak splash damage.", - }, - { - "shieldImpactExplosionThreshold", - "Pre-shield splash damage that is above this will be 'strong'.", - }, - { - "shieldImpactMissileShakeDuration", - "Viewmodel shake duration for direct missile impacts.", - }, - { - "shieldImpactMissileShakeScale", - "Viewmodel shake scale for direct missile impacts.", - }, - { - "shieldPlayerBulletProtectionDegrees", - "Bullets fired at a riotshield-bearing player will be blocked if they are within this many degrees of the player's forward direction. Higher value means wider protection.", - }, - { - "showDebugAmmoCounter", - "Show the debug ammo counter when unable to show ar ammo counter", - }, - { - "showPlaylistTotalPlayers", - "Toggle the display of the total number of players in a playlist and online", - }, - { - "si_validateFileAccess", - "Validate accessed files against install file list.", - }, - { - "sm_cacheSpotShadows", - "Cache spot shadow maps, improves shadow map performance at the cost of memory (requires vid_restart)", - }, - { - "sm_cacheSpotShadowsEnabled", - "Enables caching of spot shadows.", - }, - { - "sm_cacheSunShadow", - "Cache sun shadow map, improves shadow map performance at the cost of memory (requires vid_restart)", - }, - { - "sm_cacheSunShadowEnabled", - "Enables caching of sun-based shadows.", - }, - { - "sm_cameraOffset", - "", - }, - { - "sm_debugFastSunShadow", - "Debug fast sun shadow", - }, - { - "sm_dynlightAllSModels", - "Enable, from script, rendering all static models in dynamic light volume when shadow mapping", - }, - { - "sm_enable", - "Enable shadow mapping", - }, - { - "sm_fastSunShadow", - "Fast sun shadow", - }, - { - "sm_forceLinear", - "Force shadow sampling to be linear", - }, - { - "sm_lightScore_eyeProjectDist", - "When picking shadows for primary lights, measure distance from a point this far in front of the camera.", - }, - { - "sm_lightScore_spotProjectFrac", - "When picking shadows for primary lights, measure distance from a point this far in front of the camera.", - }, - { - "sm_maxLightsWithShadows", - "Limits how many primary lights can have shadow maps", - }, - { - "sm_minSpotLightScore", - "Minimum score (based on intensity, radius, and position relative to the camera) for a spot light to have shadow maps.", - }, - { - "sm_polygonOffsetBias", - "Shadow map offset bias", - }, - { - "sm_polygonOffsetClamp", - "Shadow map offset clamp", - }, - { - "sm_polygonOffsetPreset", - "Shadow map polygon offset preset.", - }, - { - "sm_polygonOffsetScale", - "Shadow map offset scale", - }, - { - "sm_projStepSize", - "", - }, - { - "sm_qualitySpotShadow", - "Fast spot shadow", - }, - { - "sm_shadowUseTweaks", - "Override shadow LightSet settings with tweak dvar values.", - }, - { - "sm_showCachedSunOverlay", - "Show cached sun shadow map overlay; dvar value picks the partition.", - }, - { - "sm_showOverlay", - "Show shadow map overlay", - }, - { - "sm_showOverlayDepthBounds", - "Near and far depth values for the shadow map overlay", - }, - { - "sm_showOverlayTrans", - "Show transparency shadow map overlay", - }, - { - "sm_spotDistCull", - "Distance cull spot shadows", - }, - { - "sm_spotEnable", - "Enable spot shadow mapping from script", - }, - { - "sm_spotFilterRadius", - "Spot soft shadows filter radius", - }, - { - "sm_spotLightScoreModelScale", - "Scale the calculated spot light score by this value if the light currently only affects static or script brush models.", - }, - { - "sm_spotLightScoreRadiusPower", - "Power to apply to light radius when determining spot light shadowing score (1.0 means radius scales up score a lot, 0.0 means don't scale score using radius)", - }, - { - "sm_spotLimit", - "Limit number of spot shadows from script", - }, - { - "sm_spotShadowFadeTime", - "How many seconds it takes for a primary light shadow map to fade in or out", - }, - { - "sm_strictCull", - "Strict shadow map cull", - }, - { - "sm_sunEnable", - "Enable sun shadow mapping from script", - }, - { - "sm_sunFilterRadius", - "Sun soft shadows filter radius", - }, - { - "sm_sunSampleSizeNear", - "Shadow sample size", - }, - { - "sm_sunShadowBoundsMax", - "Max Shadow Bounds", - }, - { - "sm_sunShadowBoundsMin", - "Min Shadow Bounds", - }, - { - "sm_sunShadowBoundsOverride", - "Override Shadow Bounds", - }, - { - "sm_sunShadowCenter", - "Sun shadow center, 0 0 0 means don't override", - }, - { - "sm_sunShadowCenterMode", - "When false center value only used for far map, when true sets both maps", - }, - { - "sm_sunShadowScale", - "Sun shadow scale optimization", - }, - { - "sm_usedSunCascadeCount", - "How many shadow cascade we are using", - }, - { - "snd_allowHeadphoneHRTF", - "Enable HRTF over headphones", - }, - { - "snd_announcerVoicePrefix", - "Local mp announcer voice to use", - }, - { - "snd_autoSim", - "turn on client side simulation of automatic gun sounds", - }, - { - "snd_cinematicVolumeScale", - "Scales the volume of Bink videos.", - }, - { - "snd_debugAlias", - "Print out tracking information about a particular alias", - }, - { - "snd_debugReplace", - "Print out information about when we stop a playing sound to play another", - }, - { - "snd_detectedSpeakerConfig", - "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround", - }, - { - "snd_dolbyPanning", - "Enables experimental Dolby-standard -3dB pan laws and speaker angles", - }, - { - "snd_dopplerAuditionEnable", - "Enables doppler calculation preview mode", - }, - { - "snd_dopplerBaseSpeedOfSound", - "The base speed of sound used in doppler calculation", - }, - { - "snd_dopplerEnable", - "Enables doppler calculation", - }, - { - "snd_dopplerPitchMax", - "Maximum pitch that can be legally applied by doppler", - }, - { - "snd_dopplerPitchMin", - "Minimum pitch that can be legally applied by doppler", - }, - { - "snd_dopplerPlayerVelocityScale", - "The scale of the player velocity, relative the the sound source velocity, when applied to the doppler calculation", - }, - { - "snd_dopplerSmoothing", - "Smoothing factor applied to doppler to eliminate jitter or sudden acceleration changes", - }, - { - "snd_draw3D", - "Draw the position and info of world sounds", - }, - { - "snd_drawEqChannels", - "Draw overlay of EQ settings for each channel", - }, - { - "snd_drawEqEnts", - "Show which ents can have EQ turned on/off, which ones are on (green) and off (magenta)", - }, - { - "snd_drawInfo", - "Draw debugging information for sounds", - }, - { - "snd_drawSubmixInfo", - "Displays a list of active sound submixes", - }, - { - "snd_enable2D", - "Enable 2D sounds", - }, - { - "snd_enable3D", - "Enable 3D sounds", - }, - { - "snd_enableEq", - "Enable equalization filter", - }, - { - "snd_enableReverb", - "Enable sound reverberation", - }, - { - "snd_enableStream", - "Enable streamed sounds", - }, - { - "snd_envFollowerBuffScale", - "Amount of buffer to use for envelope follower. Smaller value indicates faster envelope.", - }, - { - "snd_errorOnMissing", - "Cause a Com_Error if a sound file is missing.", - }, - { - "snd_focusGlobalAngleMax", - "", - }, - { - "snd_focusGlobalAngleMin", - "Angle describing the conde where focus attenuation begins (no attenuation).", - }, - { - "snd_focusGlobalAttenuation", - "", - }, - { - "snd_focusGlobalEnabled", - "Enable the global sound focus.", - }, - { - "snd_focusWeaponAngleMax", - "", - }, - { - "snd_focusWeaponAngleMin", - "Angle describing the cone where focus attenuation ends (full attenuation).", - }, - { - "snd_focusWeaponAttenuation", - "", - }, - { - "snd_focusWeaponEnableDVars", - "Enable the weapon sound focus parameter override with DVars.", - }, - { - "snd_focusWeaponFadeTime_ms", - "Time in milliseconds until which the feature is totally in effect after activation.", - }, - { - "snd_hitsoundDisabled", - "Disable the hit indicator sound", - }, - { - "snd_inheritSecondaryPitchVol", - "Set to true for secondary aliases to inherit the pitch of the parent", - }, - { - "snd_levelFadeTime", - "The amout of time in milliseconds for all audio to fade in at the start of a level", - }, - { - "snd_loadFadeTime", - "Fade time for loading from a checkpoint after death.", - }, - { - "snd_logAudioVoices", - "Log to a file, every frame, the info on all voices playing", - }, - { - "snd_logPlayback", - "Logs all alias playback to the console", - }, - { - "snd_loopFadeTime", - "Fade-in time for looping sounds.", - }, - { - "snd_loudVO", - "Doubles the headroom for non-dialogue volmods", - }, - { - "snd_musicDisabledForCustomSoundtrack", - "Disable all in-game music due to user playing a custom soundtrack", - }, - { - "snd_muteAlias", - "Mute every alias that contain those strings", - }, - { - "snd_occlusionDelay", - "Minimum delay in (ms) between occlusion updates", - }, - { - "snd_occlusionEnabled", - "Enable occlusion", - }, - { - "snd_occlusionLerpTime", - "Time to lerp to target occlusion lerp when occluded", - }, - { - "snd_peakLimiterCompression", - "Peak limiter compression factor. The output data is scaled by this and then normalized: F < 1 = disabled; F >= 1 enabled.", - }, - { - "snd_peakLimiterDecay", - "Peak limiter compression decay ratio.", - }, - { - "snd_peakLimiterSustainFrames", - "Number of frames to sustain the limiter peak. 1 frame = 10 msec.", - }, - { - "snd_premixVolume", - "Game sound pre-mix volume", - }, - { - "snd_realtimeAliasUpdate", - "Update a specific parameter for a particular alias", - }, - { - "snd_realtimeCurveUpdate", - "Update a specific curve (LPF, Reverb, Volume fallof)", - }, - { - "snd_realtimeDumpSubmixChanges", - "Activating this dvar will create a debug file containing every tweaks made to submix, done with the snd_realtimeSubmixUpdate dvar", - }, - { - "snd_realtimeSubmixUpdate", - "Update a submix", - }, - { - "snd_reverbZoneOutsideFactor", - "When a 3d sound is played in a different reverb zone than the player, this factor will be applied to its wet level.", - }, - { - "snd_slaveFadeTime", - "The amount of time in milliseconds for a 'slave' sound\nto fade its volumes when a master sound starts or stops", - }, - { - "snd_soloAlias", - "Mute every alias that do not contain those strings", - }, - { - "snd_sortOverlay", - "It will sort the channels shown when using snd_drawinfo", - }, - { - "snd_speakerConfig", - "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround", - }, - { - "snd_sustainPeakVU", - "Display the peak value on the VU for this period of time before resetting.", - }, - { - "snd_useOldPanning", - "Use old and busted panning", - }, - { - "snd_virtualChannelInfo", - "Display virtual voice info.", - }, - { - "snd_virtualForce", - "Forces all sounds to be initially virtual.", - }, - { - "snd_virtualMinDur", - "The minimum duration (in seconds) of a sound if it is to be added to the virtual voice buffer.", - }, - { - "snd_virtualMinPri", - "The minimum priority of an alias if it is to be added to the virtual voice buffer.", - }, - { - "snd_virtualMinTimeLeftToRevive", - "The minimum time (in ms) left in a sample in order to attempt to revive it.", - }, - { - "snd_virtualReviveVoices", - "Whether or not to restore virtual voices.", - }, - { - "snd_virtualWaitToReviveTime", - "The minimum time (in ms) to wait before trying to revive the voice.", - }, - { - "snd_volume", - "Game sound master volume", - }, - { - "so_survival", - "special ops - survival mode", - }, - { - "solo_play", - "User is in solo Spec Ops.", - }, - { - "sp_matchdata_active", - "Are SP match data uploads enabled", - }, - { - "sp_matchdata_maxcompressionbuffer", - "", - }, - { - "specialops", - "special ops", - }, - { - "specops_map_groupnum", - "Level challenge group number", - }, - { - "specops_map_itemnum", - "Level challenge item number", - }, - { - "speech_active", - "Are we allowed to enable Speech or not", - }, - { - "splitscreen", - "Current game is a splitscreen game", - }, - { - "stopspeed", - "The player deceleration", - }, - { - "stringtable_debug", - "spam debug info for stringtable lookups", - }, - { - "sv_cheats", - "Turn on cheats: do not access directly - access through CheatsOk for server demo", - }, - { - "sv_debugTrackServerTime", - "Enable server time track debugging.", - }, - { - "sv_loadingsavegame", - "Is loading up a previous save", - }, - { - "sv_running", - "Server is running", - }, - { - "sv_saveDeviceAvailable", - "True if the save device is currently available", - }, - { - "sv_saveGameAvailable", - "True if the save game is currently available", - }, - { - "sv_saveGameNotReadable", - "True if the save game is not readable", - }, - { - "sv_savegametransients", - "Comma-separated list of transients that should be loaded with this savegame (check sv_loadingsavegame first!)", - }, - { - "sv_saveOnStartMap", - "Save at the start of a level", - }, - { - "sv_trackFrameMsecThreshold", - "server frame time that will trigger script time tracking.", - }, - { - "sv_znear", - "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance.", - }, - { - "svwp", - "playerdata server write protection: 0 = disable, 1 = silent, 2 = kick", - }, - { - "syncTimeTimeout", - "default timeout for sync time task (in seconds)", - }, - { - "sys_language", - "", - }, - { - "theater_active", - "Are we allowed to show theater or not.", - }, - { - "thermalBlurFactorNoScope", - "Amount of blur to use when drawing blur through a weapon's thermal scope.", - }, - { - "thermalBlurFactorScope", - "Amount of blur to use when drawing blur through a weapon's thermal scope.", - }, - { - "timescale", - "", - }, - { - "tokensEnabled", - "Is token economy enabled", - }, - { - "tracer_debugDraw", - "Draw debug lines where the tracers should be visible.", - }, - { - "tracer_disable", - "Disable all weapon tracers.", - }, - { - "tracer_firstPersonMaxWidth", - "The maximum width our OWN tracers can be when looking through our ADS", - }, - { - "tracer_thermalWidthMult", - "The multiplier applied to the base width when viewed in thermal vision", - }, - { - "traceScheduler_debugThrottleTraces", - "Displays debug info for trace throttling.", - }, - { - "traceScheduler_throttleTraces", - "Throttles locational traces on the server.", - }, - { - "transients_load_delay", - "Enables an artificial delay (in seconds) that will be added to SP transient fastfile load times. Useful to figure out if transient syncs are missing.", - }, - { - "transients_verbose", - "Verbose logging information for transient fastfiles.", - }, - { - "trigger_draw", - "Draw trigger geometry", - }, - { - "trigger_drawDepthTest", - "Display trigger geo with depth information", - }, - { - "trigger_drawDistance", - "Trigger draw distance", - }, - { - "triggerDLCEnumerationOnSocialConfigLoad", - "Triggers a new DLC enumeration after social config has loaded.", - }, - { - "turret_adsEnabled", - "Enable/Disable ADS on turrets", - }, - { - "turret_adsTime", - "Time (msec) to transition to ADS", - }, - { - "turretConvergenceHeightDebug", - "When true, turns on debugging for turret converging to enemy head", - }, - { - "turretPlayerAvoidScale", - "Auto turrets will try to avoid the player. They will not choose a target that is within a cone around the player. The diameter of the cone is the player's height, so the cone is smaller, the farther the player is from the turret. Use this dvar to scale the cone size.", - }, - { - "turretSentryRestrictUsageToOwner", - "When true, only players that own the sentry turret are allowed to interact with it.", - }, - { - "turretTargetDebug", - "When true, turns on turret target debugging", - }, - { - "ufoHitsTriggers", - "ufo/noclip will hit triggers when enabled", - }, - { - "ui_allowSkip", - "Overrides unskippable cutscenes", - }, - { - "ui_autoContinue", - "Automatically 'click to continue' after loading a level", - }, - { - "ui_blurAmount", - "Max amount to blur background menu items.", - }, - { - "ui_blurDarkenAmount", - "Amount to darken blurred UI.", - }, - { - "ui_blurTime", - "Time in milliseconds to fade in/out the blur.", - }, - { - "ui_borderLowLightScale", - "Scales the border color for the lowlight color on certain UI borders", - }, - { - "ui_buildLocation", - "Where to draw the build number", - }, - { - "ui_buildSize", - "Font size to use for the build number", - }, - { - "ui_campaign", - "The current campaign", - }, - { - "ui_chyronGameMessages", - "True if game messages should be sent through script to get the chyron treatment", - }, - { - "ui_cinematicsTimestamp", - "Shows cinematics timestamp on subtitle UI elements.", - }, - { - "ui_contextualMenuLocation", - "Contextual menu location from where you entered the store.", - }, - { - "ui_currentLevelIndex", - "The index of the current level in script", - }, - { - "ui_debugMode", - "Shows ui debug information on screen.", - }, - { - "ui_disableInGameStore", - "This will disable the ingame store button on the xbox live menu.", - }, - { - "ui_disableTokenRedemption", - "This will disable the token redemption option in the in-game store menu.", - }, - { - "ui_gametype", - "Current game type", - }, - { - "ui_hideMap", - "Meant to be set by script and referenced by menu files to determine if minimap should be drawn.", - }, - { - "ui_inGameStoreOpen", - "is the InGameStore open", - }, - { - "ui_inSpecOpsLeaderboards", - "User is in Spec Ops Leaderboards.", - }, - { - "ui_is_so_dlc", - "Is the user is attempting to play only spec ops DLC maps", - }, - { - "ui_isSaving", - "True if the game is currently saving", - }, - { - "ui_loadMenuName", - "Frontend menu will start on this level instead of lockout", - }, - { - "ui_mapname", - "Current map name", - }, - { - "ui_mousePitch", - "Invert mouse pitch", - }, - { - "ui_multiplayer", - "True if the game is multiplayer", - }, - { - "ui_myPartyColor", - "Player name font color when in the same party as the local player", - }, - { - "ui_nextMission", - "Next mission", - }, - { - "ui_online_coop", - "Did the user choose to enter an online coop game", - }, - { - "ui_play_credits", - "Should we play the credits", - }, - { - "ui_safearea", - "Show the Screen Safe overlay", - }, - { - "ui_savegame", - "Save game name", - }, - { - "ui_saveMessageMinTime", - "Minumum time for the save message to be on screen in seconds", - }, - { - "ui_selectedFeederMap", - "Current preview game type", - }, - { - "ui_showList", - "Show list of currently visible menus", - }, - { - "ui_showMenuOnly", - "If set, only menus using this name will draw.", - }, - { - "ui_skip_initial_game_mode", - "Forces boot flow to ignore short circuit to default choice", - }, - { - "ui_skipMainLockout", - "True if the page that restricts player control to a single controller is skipped", - }, - { - "ui_sliderSteps", - "The number of steps for a slider itemdef", - }, - { - "ui_startupActiveController", - "default active game pad on start up", - }, - { - "ui_textScrollFadeTime", - "Text scrolling takes this long (seconds) to fade out at the end before restarting", - }, - { - "ui_textScrollPauseEnd", - "Text scrolling waits this long (seconds) before starting", - }, - { - "ui_textScrollPauseStart", - "Text scrolling waits this long (seconds) before starting", - }, - { - "ui_textScrollSpeed", - "Speed at which text scrolls vertically", - }, - { - "uiscript_debug", - "spam debug info for the ui script", - }, - { - "uiscript_verbose", - "Turns on extra ui script debugging console prints", - }, - { - "unattended", - "Allows the game to be run without user input.", - }, - { - "unlockAllAttachments", - "Simulate all attachments being unlocked", - }, - { - "unlockAllEntitlements", - "Development dvar to simulate having entitlements unlocked", - }, - { - "unlockAllItems", - "Simulate all items being unlocked", - }, - { - "unlockAllLootItems", - "Simulate all loot items being locked", - }, - { - "unlockDevAttachments", - "Unlocks all dev-only attachments in the front-end", - }, - { - "unlockDevWeapons", - "Unlocks all dev weapons in the front-end", - }, - { - "uno_current_tos_version", - "Current Uno Terms of Service Version", - }, - { - "use_new_sva_system", - "Temp flag to help depricate the old scripted viewmodel system. This will be removed when all of the old data is gone.", - }, - { - "useCPMarkerForCPOwnership", - "If set, we will check the player inventory to see if he owns the redeemedItem for a contentPack if this contentPack is not available for the player", - }, - { - "useonlinestats", - "Whether to use online stats when in offline modes", - }, - { - "userFileFetchTimeout", - "default timeout for user files FETCH tasks (in seconds)", - }, - { - "userGroup_active", - "Are we allowed to show Usergroups or not", - }, - { - "userGroup_cool_off_time", - "Cool off time between calls to fetch the elite clan", - }, - { - "userGroup_coop_delay", - "Delay between a player joining a coop lobby and the DW user group task starting", - }, - { - "userGroup_max_retry_time", - "Max time that the usergroup read find can retry", - }, - { - "userGroup_refresh_time_secs", - "Time in seconds between re-sending lobby group data to confirmed users.", - }, - { - "userGroup_retry_step", - "Step in m/s for the usegroup read retry", - }, - { - "userGroup_RetryTime", - "Time in ms between sending lobby group data retrys.", - }, - { - "useStatsGroups", - "If true then StatsGroups are in use for all playerdata.ddl accessing.", - }, - { - "useTagFlashSilenced", - "When true, silenced weapons will use \"tag_flash_silenced\" instead of \"tag_flash\".", - }, - { - "using_mlg", - "MLG feature on/off", - }, - { - "veh_aiOverSteerScale", - "Scaler used to cause ai vehicles to over steer", - }, - { - "veh_boneControllerLodDist", - "Distance at which bone controllers are not updated.", - }, - { - "veh_boneControllerUnLodDist", - "Distance at which bone controllers start updating when not moving.", - }, - { - "veh_drawTrack", - "Debug draw the vehicle tracks", - }, - { - "vehAudio_inAirPitchDownLerp", - "Rate at which the pitch lerps down", - }, - { - "vehAudio_inAirPitchUpLerp", - "Rate at which the pitch lerps up", - }, - { - "vehAudio_spawnVolumeTime", - "Seconds it takes for spawned vehicles to reach full volume.", - }, - { - "vehBoatRockingScale", - "Scale of the boat rocking (usually used to turn off rocking during cinematics)", - }, - { - "vehCam_angles", - "Camera angles from vehicle", - }, - { - "vehCam_angles3P", - "Camera angles from vehicle (3rd person)", - }, - { - "vehCam_chaseAngleOffset", - "Angle offset from vehicle angles", - }, - { - "vehCam_chaseDist", - "Camera distance from vehicle", - }, - { - "vehCam_chaseLateralInfluence", - "Vehicle's lateral velocity's influence on the camera's left and right movement. This will be multiplied with the chase distance.", - }, - { - "vehCam_chaseMinRollForLateralMovement", - "The minimum roll required before the camera will begin to move laterally", - }, - { - "vehCam_chaseMinRollTime", - "The minimum time for the plane to be rolling in one direction before the camera reacts to it", - }, - { - "vehCam_chaseOffset", - "", - }, - { - "vehCam_chasePitchLerpRateModifier", - "Multiplied by the frame time to determine the yaw lerp rate", - }, - { - "vehCam_chaseVerticalInfluence", - "Vehicle's vertical velocity's influence on the camera's up and down movement", - }, - { - "vehCam_chaseYawLerpRateModifier", - "Multiplied by the frame time to determine the yaw lerp rate", - }, - { - "vehCam_freeLook", - "Enables free look mode", - }, - { - "vehCam_mode", - "Camera modes: 1st person, 3rd person, or bot", - }, - { - "vehCam_offset", - "", - }, - { - "vehCam_offset3P", - "Focus offset from vehicle origin (3rd person)", - }, - { - "vehCam_pitchClamp", - "Pitch clamp for user adjustment", - }, - { - "vehCam_pitchClamp3P", - "Pitch clamp for user adjustment (3rd person)", - }, - { - "vehCam_pitchTurnRate", - "Pitch turn rate for user adjustment", - }, - { - "vehCam_pitchTurnRate3P", - "Pitch turn rate for user adjustment (3rd person)", - }, - { - "vehCam_radius", - "Camera radius from vehicle", - }, - { - "vehCam_radius3P", - "Camera radius from vehicle (3rd person)", - }, - { - "vehCam_speedInfluence", - "Controls how much the vehicle's speed effects the camera.", - }, - { - "vehCam_speedInfluence3P", - "Controls how much the vehicle's speed effects the camera.", - }, - { - "vehCam_yawClamp", - "Yaw clamp for user adjustment", - }, - { - "vehCam_yawClamp3P", - "Yaw clamp for user adjustment (3rd person)", - }, - { - "vehCam_yawTurnRate", - "Yaw turn rate for user adjustment", - }, - { - "vehCam_yawTurnRate3P", - "Yaw turn rate for user adjustment (3rd person)", - }, - { - "vehCam_zOffsetMode", - "Camera offset mode for Z axis", - }, - { - "vehCam_zOffsetMode3P", - "Camera offset mode for Z axis (3rd person)", - }, - { - "vehDiveboatControlScheme", - "0: like the jetbike. 1: like the pitbull. 2: like the pitbull, but with dive on LTRIG.", - }, - { - "vehHelicopterBoundsRadius", - "The radius of the collision volume to be used when colliding with world geometry.", - }, - { - "vehHelicopterControlsAltitude", - "Determines how to control altitude", - }, - { - "vehHelicopterControlSystem", - "Determines how the helicopter will be controlled", - }, - { - "vehHelicopterDecelerationFwd", - "Set the deceleration of the player helicopter (as a fraction of acceleration) in the direction the chopper is facing. So 1.0 makes it equal to the acceleration.", - }, - { - "vehHelicopterDecelerationSide", - "Set the side-to-side deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration.", - }, - { - "vehHelicopterDecelerationUp", - "Set the vertical deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration.", - }, - { - "vehHelicopterForwardDrag", - "The forward deceleration caused by drag in control system 2", - }, - { - "vehHelicopterFreeLookReleaseSpeed", - "The rate that the player's view moves back to center when freelook is released", - }, - { - "vehHelicopterHeadSwayDontSwayTheTurret", - "If set, the turret will not fire through the crosshairs, but straight ahead of the vehicle, when the player is not freelooking.", - }, - { - "vehHelicopterHoverSpeedThreshold", - "The speed below which the player helicopter begins to jitter the tilt, for hovering", - }, - { - "vehHelicopterInvertUpDown", - "Invert the altitude control on the player helicopter.", - }, - { - "vehHelicopterJitterJerkyness", - "Specifies how jerky the tilt jitter should be", - }, - { - "vehHelicopterLateralDrag", - "The lateral deceleration caused by drag in control system 2", - }, - { - "vehHelicopterLookaheadTime", - "How far ahead (in seconds) the player helicopter looks ahead, to avoid hard collisions. (Like driving down the highway, you should keep 2 seconds distance between you and the vehicle in front of you)", - }, - { - "vehHelicopterMaxAccel", - "Maximum horizontal acceleration of the player helicopter (in MPH per second)", - }, - { - "vehHelicopterMaxAccelVertical", - "Maximum vertical acceleration of the player helicopter (in MPH per second)", - }, - { - "vehHelicopterMaxAltitude", - "Determines the maximum altitude at which a helicopter can fly", - }, - { - "vehHelicopterMaxPitch", - "Maximum pitch of the player helicopter", - }, - { - "vehHelicopterMaxRoll", - "Maximum roll of the player helicopter", - }, - { - "vehHelicopterMaxSpeed", - "Maximum horizontal speed of the player helicopter (in MPH)", - }, - { - "vehHelicopterMaxSpeedVertical", - "Maximum vertical speed of the player helicopter (in MPH)", - }, - { - "vehHelicopterMaxYawAccel", - "Maximum yaw acceleration of the player helicopter", - }, - { - "vehHelicopterMaxYawRate", - "Maximum yaw speed of the player helicopter", - }, - { - "vehHelicopterMinAltitude", - "Determines the minimum altitude at which a helicopter can fly", - }, - { - "vehHelicopterPitchLock", - "True if the view pitches with the body of the helicopter", - }, - { - "vehHelicopterPitchOffset", - "The resting pitch of the helicopter", - }, - { - "vehHelicopterPitchRate", - "The pitch speed of the helicopter in control system 2", - }, - { - "vehHelicopterPitchReturn", - "The rate the pitch returns to the rest pitch of the helicopter in control system 2", - }, - { - "vehHelicopterPitchThrust", - "The forward acceleration produced by pitching forward in control system 2", - }, - { - "vehHelicopterRightStickDeadzone", - "Dead-zone for the axes of the right thumbstick. This helps to better control the two axes separately.", - }, - { - "vehHelicopterRollRate", - "The roll speed of the helicopter in control system 2", - }, - { - "vehHelicopterRollReturn", - "The rate the roll returns to the rest roll of the helicopter in control system 2", - }, - { - "vehHelicopterRollThrust", - "The lateral acceleration produced by rolling to the side in control system 2", - }, - { - "vehHelicopterScaleMovement", - "Scales down the smaller of the left stick axes.", - }, - { - "vehHelicopterSoftCollisions", - "Player helicopters have soft collisions (slow down before they collide).", - }, - { - "vehHelicopterStrafeDeadzone", - "Dead-zone so that you can fly straight forward easily without accidentally strafing (and thus rolling).", - }, - { - "vehHelicopterTiltFromAcceleration", - "The amount of tilt caused by acceleration", - }, - { - "vehHelicopterTiltFromControllerAxes", - "The amount of tilt caused by the desired velocity (i.e., the amount of controller stick deflection)", - }, - { - "vehHelicopterTiltFromDeceleration", - "The amount of tilt caused by deceleration", - }, - { - "vehHelicopterTiltFromFwdAndYaw", - "The amount of roll caused by yawing while moving forward.", - }, - { - "vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt", - "The forward speed (as a fraction of top speed) at which the tilt due to yaw reaches is maximum value.", - }, - { - "vehHelicopterTiltFromLook", - "The contribution in degrees of view pitch to vehicle pitch in control system 1", - }, - { - "vehHelicopterTiltFromLookRate", - "The rate the vehicle pitches due to view pitch in control system 1", - }, - { - "vehHelicopterTiltFromVelocity", - "The amount of tilt caused by the current velocity", - }, - { - "vehHelicopterTiltMomentum", - "The amount of rotational momentum the helicopter has with regards to tilting.", - }, - { - "vehHelicopterTiltSpeed", - "The rate at which the player helicopter's tilt responds", - }, - { - "vehHelicopterVerticalDrag", - "The vertical deceleration caused by drag in control system 2", - }, - { - "vehHelicopterYawOnLeftStick", - "The yaw speed created by the left stick when pushing the stick diagonally (e.g., moving forward and strafing slightly).", - }, - { - "vehHudDrawPipOnStickWhenFreelooking", - "Set to 0 to not draw the pip-on-a-stick reticle when the player is freelooking", - }, - { - "vehHudLineWidth", - "The width of the line used by code to draw elements on the vehicle HUD", - }, - { - "vehHudReticleBouncingDiamondSize", - "The size of the bouncing diamond quad.", - }, - { - "vehHudReticleBouncingRadius", - "The radius of the circle in which the diamond bounces.", - }, - { - "vehHudReticleBouncingSpeed", - "The rate at which the bouncing diamond moves", - }, - { - "vehHudReticlePipOnAStickCenterCircle", - "The diameter of the small, center circle in the pip-on-a-stick reticle", - }, - { - "vehHudReticlePipOnAStickCenterCircleBuffer", - "Tweaks how close the stick is drawn to the center circle. Positive numbers makes the line longer.", - }, - { - "vehHudReticlePipOnAStickMovingCircle", - "The diameter of the large, moving circle in the pip-on-a-stick reticle", - }, - { - "vehHudReticlePipOnAStickMovingCircleBuffer", - "Tweaks how close the stick is drawn to the center circle. Positive numbers makes the line longer.", - }, - { - "vehHudTargetScreenEdgeClampBufferBottom", - "", - }, - { - "vehHudTargetScreenEdgeClampBufferLeft", - "", - }, - { - "vehHudTargetScreenEdgeClampBufferRight", - "", - }, - { - "vehHudTargetScreenEdgeClampBufferTop", - "", - }, - { - "vehHudTargetSize", - "The width of the enemy target indicator on the hud.", - }, - { - "vehicle_debug_render_spline_plane", - "Do we want to render the spline plane data", - }, - { - "vehicle_pathsmooth", - "Smoothed vehicle pathing.", - }, - { - "vehicle_pathsmoothdebug", - "Debug smoothed vehicle pathing.", - }, - { - "vehJetbikeControlScheme", - "Which control scheme to use", - }, - { - "vehPlaneAiLiftModifier", - "ai planes' wing areas are multiplied by this value", - }, - { - "vehPlaneAiNoClip", - "true if planes in AI mode should ignore collision when moving.", - }, - { - "vehPlaneAiPitchResponseRate", - "ai pitch fraction per degree of pitch error", - }, - { - "vehPlaneAiRollResponseRate", - "ai roll fraction per degree of roll error", - }, - { - "vehPlaneAiThrottleModifier", - "ai planes can control throttle up to this multiplier of the plane's actual max thrust", - }, - { - "vehPlaneAiThrottleResponseRate", - "ai throttle fraction per second per knot of speed error", - }, - { - "vehPlaneAiYawResponseRate", - "ai pitch fraction per degree of yaw error", - }, - { - "vehPlaneChordPitchCenter", - "the wing's aoa when the body is level.", - }, - { - "vehPlaneChordPitchMax", - "the max AOA the auto pitch trim will attempt to drive us to", - }, - { - "vehPlaneChordPitchMin", - "the min AOA the auto pitch trim will attempt to drive us to", - }, - { - "vehPlaneCollisionLerpRate", - "Collision lerp rate", - }, - { - "vehPlaneCollisionLookAheadLerpRate", - "Collision look ahead lerp rate", - }, - { - "vehPlaneCollisionLookAheadRollLerpRate", - "Collision look ahead roll lerp rate", - }, - { - "vehPlaneCollisionLookAheadTime", - "Collision look ahead time", - }, - { - "vehPlaneCollisionRollLerpRate", - "Collision roll lerp rate", - }, - { - "vehPlaneControlExponent", - "an exponent on the joystick deflection, higher for sub-linear response", - }, - { - "vehPlaneControlForceReferenceSpeed", - "speed at which control forces will reach their advertised values (knots)", - }, - { - "vehPlaneControlLowpassCoeff", - "how much of the last frame control value to mix in (higher values for more sluggishness)", - }, - { - "vehPlaneControlReduceRoll", - "in control scheme 1, how much to reduce roll by when throttle is up or down", - }, - { - "vehPlaneControlRollYawCoupling", - "how much yaw input affects roll input (doesn't go the other way)", - }, - { - "vehPlaneControlScheme", - "Which control scheme to use", - }, - { - "vehPlaneControlSquaring", - "how much to stretch the circular range of the joystick into a square", - }, - { - "vehPlaneControlYawRollCoupling", - "how much roll input affects yaw input (doesn't go the other way)", - }, - { - "vehPlaneDampingPitch", - "how much pitch rate decays from frame to frame, lower for more momentum", - }, - { - "vehPlaneDampingRoll", - "how much roll rate decays from frame to frame, lower for more momentum", - }, - { - "vehPlaneDampingYaw", - "how much yaw rate decays from frame to frame, lower for more momentum", - }, - { - "vehPlaneDeadZonePercent", - "Percent of stick dead zone", - }, - { - "vehPlaneDihedralCoeff", - "how much sideslip affects roll. higher values for stronger tendency to level out", - }, - { - "vehPlaneFuselageLoading", - "fuselage loading, lower values decrease sideslip (kg / m^2)", - }, - { - "vehPlaneGravity", - "the strength of gravity, (inch/s^2)", - }, - { - "vehPlaneGravityVelocity", - "This velocity will be added to the plane's Z-velocity", - }, - { - "vehPlaneInducedDragCoeffExponent", - "induced drag is modeled as sin(aoa)^e, this is the e", - }, - { - "vehPlaneMass", - "mass (kg)", - }, - { - "vehPlaneMaxControlForcePitch", - "strength of pitch force compared to other forces", - }, - { - "vehPlaneMaxControlForceRoll", - "strength of roll force compared to other forces", - }, - { - "vehPlaneMaxControlForceScale", - "scales all the control forces", - }, - { - "vehPlaneMaxControlForceYaw", - "strength of yaw force compared to other forces", - }, - { - "vehPlaneMaxInducedDragCoeff", - "the maximum induced drag coefficient (reached at 90 degrees aoa)", - }, - { - "vehPlaneMaxLiftCoeff", - "the wing's stalling lift coefficient", - }, - { - "vehPlaneMaxLiftCoeffAoA", - "the wing's stall angle of attack (degrees)", - }, - { - "vehPlaneMaxPitch", - "Maximum pitch", - }, - { - "vehPlaneMaxPitchDiffPerSec", - "Maximum pitch delta per second", - }, - { - "vehPlaneMaxRightingForcePitch", - "strength of pitch righting force compared to other forces", - }, - { - "vehPlaneMaxRightingForceScale", - "scales all the aerodynamic righting forces (which align you with your direction of motion)", - }, - { - "vehPlaneMaxRightingForceYaw", - "strength of yaw righting force compared to other forces", - }, - { - "vehPlaneMaxRoll", - "Maximum roll", - }, - { - "vehPlaneMaxYawRatePerSec", - "Maximum yaw rate per second", - }, - { - "vehPlaneParasiticDragCoeff", - "parasitic drag - higher values will slow you down faster", - }, - { - "vehPlanePathAllowance", - "The angle that the plane is allowed to turn away from the expected path", - }, - { - "vehPlanePathAngle", - "Angle of the current expected path segment in the level that will limit yaw controls", - }, - { - "vehPlanePitchDeadZoneWhileRolling", - "The percent of stick dead zone applied to pitch when rolling", - }, - { - "vehPlanePitchLerpRate", - "Pitch lerp rate", - }, - { - "vehPlanePitchVelocityModifer", - "Modifies the velocity based on the pitch (faster when pitched down, slower when pitched up)", - }, - { - "vehPlaneRightingForceReferenceSpeed", - "speed at which righting forces will reach their advertised values (knots)", - }, - { - "vehPlaneRollLerpRate", - "Roll lerp rate", - }, - { - "vehPlaneRollModifierExponent", - "Applies the exponent to the current roll of the plane", - }, - { - "vehPlaneSecondZeroLiftCoeffAoA", - "the angle of attack, after stalling, at which the lift coefficient goes back to zero", - }, - { - "vehPlaneStickPusherEngageAoA", - "when angle of attack reaches this, you will fully lose pitch-up authority", - }, - { - "vehPlaneStickPusherFullAoA", - "when angle of attack reaches this, you will fully lose pitch-up authority", - }, - { - "vehPlaneSwapSticks", - "Swaps the flight stick from left to right when enabled", - }, - { - "vehPlaneThrustToWeightRatio", - "thrust to weight ratio - higher increases acceleration and max speed", - }, - { - "vehPlaneTurbulenceSpatialFrequency", - "how quickly the wind varies from place to place (1 / inch)", - }, - { - "vehPlaneTurbulenceStrength", - "the strength of the random wind (kts)", - }, - { - "vehPlaneVelocityLerpRate", - "velocity lerp rate", - }, - { - "vehPlaneWingLeveling", - "fraction of control input player's plane will use to automatically roll towards wings-level", - }, - { - "vehPlaneWingLoading", - "wing loading, lower values lower stall speed (kg / m^2)", - }, - { - "vehPlaneYawLerpRate", - "Yaw lerp rate", - }, - { - "vehSubmarineAllowInSolid", - "Allow in solid. Dangerous! Used to push the submarine with a collision brushmodel.", - }, - { - "vehSubmarineBodyRelRotation", - "Submarine Body Relative Rotation (0 == world, 1 == body coupled, 2 == horz is roll only, 3 == horz is world yaw, add 4 for camera relative)", - }, - { - "vehSubmarineControls", - "Submarine controls (0==org, 1=trigger accel, 2=right stick pitch/yaw)", - }, - { - "vehSubmarineForwardDampening", - "The submarine forward dampening fraction", - }, - { - "vehSubmarineFwdCollMaxAccel", - "Submarine forward probe max accel", - }, - { - "vehSubmarineFwdCollMaxAngAccel", - "Submarine forward probe max angular accel", - }, - { - "vehSubmarineFwdProbeTime", - "The time for the submarine forward probe", - }, - { - "vehSubmarineHorizControlGamma", - "Submarine gamma for input on horizontal input", - }, - { - "vehSubmarineInvertUpDown", - "Invert the attitude control on the player submarine.", - }, - { - "vehSubmarineLateralDampening", - "The submarine lateral dampening fraction", - }, - { - "vehSubmarineMaxDownPitch", - "The max pitch down allowed for the submarine", - }, - { - "vehSubmarineMaxForwardAccel", - "The max forward acceleration allowed for the submarine", - }, - { - "vehSubmarineMaxForwardPitchAccel", - "The max pitch acceleration when moving forward for the submarine", - }, - { - "vehSubmarineMaxForwardVel", - "The max forward velocity allowed for the submarine", - }, - { - "vehSubmarineMaxForwardYawAccel", - "The max yaw acceleration when moving forward for the submarine", - }, - { - "vehSubmarineMaxFwdVelRef", - "Submarine max forward velocity reference for coll adjust", - }, - { - "vehSubmarineMaxLateralVel", - "The max lateral velocity allowed for the submarine", - }, - { - "vehSubmarineMaxNegativeBuoyancy", - "The max negative buoyancy allowed for the submarine", - }, - { - "vehSubmarineMaxPositiveBuoyancy", - "The max positive buoyancy allowed for the submarine", - }, - { - "vehSubmarineMaxReverseAccel", - "The max reverse acceleration allowed for the submarine", - }, - { - "vehSubmarineMaxReversePitchAccel", - "The max pitch acceleration when moving forward for the submarine", - }, - { - "vehSubmarineMaxReverseVel", - "The max reverse velocity allowed for the submarine", - }, - { - "vehSubmarineMaxReverseYawAccel", - "The max yaw acceleration when moving backwards for the submarine", - }, - { - "vehSubmarineMaxRoll", - "The max roll allowed for the submarine", - }, - { - "vehSubmarineMaxRollAccel", - "The max roll acceleration for the submarine", - }, - { - "vehSubmarineMaxStoppedPitchAccel", - "The max pitch acceleration when stopped for the submarine", - }, - { - "vehSubmarineMaxStoppedYawAccel", - "The max yaw acceleration when stopped for the submarine", - }, - { - "vehSubmarineMaxUpPitch", - "The max pitch up allowed for the submarine", - }, - { - "vehSubmarineMinForwardVel", - "The min forward velocity allowed for the submarine (only active when non-zero)", - }, - { - "vehSubmarineMinVelNoRestore", - "The minimum velocity the submarine has when restore is enabled", - }, - { - "vehSubmarinePitchDampening", - "The submarine pitch dampening fraction", - }, - { - "vehSubmarinePitchRestore", - "The submarine pitch restore fraction when not moving", - }, - { - "vehSubmarineRollDampening", - "The submarine roll dampening fraction", - }, - { - "vehSubmarineRollDrivenYaw", - "Submarine roll drives applied yaw (0 mean don't scale yaw)", - }, - { - "vehSubmarineRollRestore", - "The submarine roll restore fraction when not moving", - }, - { - "vehSubmarineSideCollMaxAccel", - "Submarine side probe max accel", - }, - { - "vehSubmarineSideCollMaxAngAccel", - "Submarine side probe max angular accel", - }, - { - "vehSubmarineSideProbeMaxDist", - "Max distance for the submarine side probe", - }, - { - "vehSubmarineSideProbeMinDist", - "Min distance for the submarine side probe", - }, - { - "vehSubmarineStoppedVel", - "The threshold velocity to determine the submarine is stopped", - }, - { - "vehSubmarineVertControlGamma", - "Submarine gamma for input on vertical input", - }, - { - "vehSubmarineYawDampening", - "The submarine yaw dampening fraction", - }, - { - "vehUGVPitchTrack", - "UGV body pitch orientation speed", - }, - { - "vehUGVRollTrack", - "UGV body roll orientation speed", - }, - { - "vehUGVWheelInfluence", - "UGV wheel influence on the orientation of the body", - }, - { - "vehWalkerControlMode", - "Walker controls (0==move no turn, 1=move and turn, 2=move relative(tank))", - }, - { - "version", - "Game version", - }, - { - "viewangNow", - "", - }, - { - "viewModelDebugNotetracks", - "Enable display of viewmodel notetrack debug info.", - }, - { - "viewModelHacks", - "Enabled depth hack and remove viewmodel from shadows.", - }, - { - "viewposNow", - "", - }, - { - "virtualLobbyActive", - "Indicates the VL is actively being displayed.", - }, - { - "virtualLobbyAllocated", - "Indicates the first VL zone has been loaded.", - }, - { - "waypointAerialIconMaxSize", - "Max size of aerial targeting waypoints.", - }, - { - "waypointAerialIconMinSize", - "Min size of aerial targeting waypoints.", - }, - { - "waypointAerialIconScale", - "Base scale of aerial targeting waypoints.", - }, - { - "waypointDebugDraw", - "", - }, - { - "waypointDistScaleRangeMax", - "Distance from player that icon distance scaling ends.", - }, - { - "waypointDistScaleRangeMin", - "Distance from player that icon distance scaling ends.", - }, - { - "waypointDistScaleSmallest", - "Smallest scale that the distance effect uses.", - }, - { - "waypointIconHeight", - "", - }, - { - "waypointIconWidth", - "", - }, - { - "waypointOffscreenCircleRadius", - "Radius of circle for circular offscreen waypoints.", - }, - { - "waypointOffscreenCornerRadius", - "Size of the rounded corners.", - }, - { - "waypointOffscreenDistanceThresholdAlpha", - "Distance from the threshold over which offscreen objective icons lerp their alpha.", - }, - { - "waypointOffscreenPadBottom", - "", - }, - { - "waypointOffscreenPadLeft", - "", - }, - { - "waypointOffscreenPadRight", - "", - }, - { - "waypointOffscreenPadTop", - "", - }, - { - "waypointOffscreenPointerDistance", - "Distance from the center of the offscreen objective icon to the center its arrow.", - }, - { - "waypointOffscreenPointerHeight", - "", - }, - { - "waypointOffscreenPointerWidth", - "", - }, - { - "waypointOffscreenRoundedCorners", - "Off-screen icons take rounded corners when true. 90-degree corners when false.", - }, - { - "waypointOffscreenScaleLength", - "How far the offscreen icon scale travels from full to smallest scale.", - }, - { - "waypointOffscreenScaleSmallest", - "Smallest scale that the offscreen effect uses.", - }, - { - "waypointPlayerOffsetCrouch", - "For waypoints pointing to players, how high to offset off of their origin when they are prone.", - }, - { - "waypointPlayerOffsetProne", - "For waypoints pointing to players, how high to offset off of their origin when they are prone.", - }, - { - "waypointPlayerOffsetStand", - "For waypoints pointing to players, how high to offset off of their origin when they are prone.", - }, - { - "waypointScreenCenterFadeAdsMin", - "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads", - }, - { - "waypointScreenCenterFadeHipMin", - "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads", - }, - { - "waypointScreenCenterFadeRadius", - "Radius from screen center that a waypoint will start fading out. Setting to 0 will turn this off", - }, - { - "waypointSplitscreenScale", - "Scale applied to waypoint icons in splitscreen views.", - }, - { - "waypointTweakY", - "", - }, - { - "weap_printSharedAmmo", - "Print out shared ammo between weapons on level load", - }, - { - "weap_printSharedClips", - "Print out shared clip ammo between weapons on level load", - }, - { - "weapon_drop_validate_time", - "Time between checks to see if a weapon position is valid. Will drop the weapon when invalid. Default = 0 which will never test weapon.", - }, - { - "whitelist_fakeNoPingServer", - "Simulate no access to ATVI ping servers", - }, - { - "wideScreen", - "True if the game video is running in 16x9 aspect, false if 4x3.", - }, - { - "xanim_blendshape_raw_anim", - "Toggles uncompressed blendshape animations", - }, - { - "xanim_disableIK", - "Disable inverse kinematics solvers", - }, - { - "xanim_disableLookAt", - "Disable head tracking", - }, - { - "xblive_loggedin", - "User is logged into xbox live", - }, - { - "xenon_maxVoicePacketsPerSec", - "Max voice packets per second a client will send", - }, - { - "xenon_maxVoicePacketsPerSecForServer", - "Max voice packets per second the server will send", - }, - { - "xenon_voiceDebug", - "Debug voice communication", - }, - { - "xenon_voiceDegrade", - "Degrade voice quality", - }, - { - "xphys_enable", - "Turn on dynamic physics joints", - }, - { - "xphys_matchAnimationPose", - "Force position/orientation of physics bones to animation pose", - }, - { - "xphys_teleportAngle", - "If physics body is rotation deviates more than this angle difference from original animation angle, then physics body is teleported", - }, - { - "xphys_teleportDistance", - "If physics body is further than this distance from original animation position, then physics body is manually teleported to be within at least distance from the animation target", + insert_dvar_info(generate_hash(name), name, description); + } + + std::optional get_dvar_info_from_hash(const std::int32_t hash) + { + const auto iter = dvar_map.find(hash); + if (iter != dvar_map.end()) + { + return iter->second; } - }; + + return {}; + } + + std::optional get_dvar_info(const std::string& name) + { + const auto hash = generate_hash(name); + return get_dvar_info_from_hash(hash); + } std::string dvar_get_description(const std::string& name) { - const auto lower = utils::string::to_lower(name); - for (std::uint32_t i = 0; i < dvar_list.size(); i++) + const auto info = get_dvar_info(name); + if (info.has_value()) { - if (utils::string::to_lower(dvar_list[i].name) == lower) - { - return dvar_list[i].description; - } + return info->description; } return {}; } - bool can_add_dvar_to_list(std::string name) - { - const auto lower = utils::string::to_lower(name); - for (std::uint32_t i = 0; i < dvar_list.size(); i++) - { - if (utils::string::to_lower(dvar_list[i].name) == lower) - { - return false; - } - } - - return true; - } - - std::optional get_dvar_info_from_hash(const int hash) - { - for (std::uint32_t i = 0; i < dvar_list.size(); i++) - { - if (dvar_list[i].hash == hash) - { - return {dvar_list[i]}; - } - } - - return {}; - } - - std::string hash_to_string(const int hash) + std::string hash_to_string(const std::int32_t hash) { return utils::string::va("0x%lX", hash); } @@ -11034,78 +187,48 @@ namespace dvars game::dvar_t* register_int(const std::string& name, int value, int min, int max, unsigned int flags, const std::string& description) { - const auto hash = game::generateHashValue(name.data()); - - if (can_add_dvar_to_list(name)) - { - dvar_list.push_back({name, description}); - } - + const auto hash = generate_hash(name); + insert_dvar_info(hash, name, description); return game::Dvar_RegisterInt(hash, "", value, min, max, flags); } game::dvar_t* register_bool(const std::string& name, bool value, unsigned int flags, const std::string& description) { - const auto hash = game::generateHashValue(name.data()); - - if (can_add_dvar_to_list(name)) - { - dvar_list.push_back({name, description}); - } - + const auto hash = generate_hash(name); + insert_dvar_info(hash, name, description); return game::Dvar_RegisterBool(hash, "", value, flags); } game::dvar_t* register_string(const std::string& name, const char* value, unsigned int flags, const std::string& description) { - const auto hash = game::generateHashValue(name.data()); - - if (can_add_dvar_to_list(name)) - { - dvar_list.push_back({name, description}); - } - + const auto hash = generate_hash(name); + insert_dvar_info(hash, name, description); return game::Dvar_RegisterString(hash, "", value, flags); } game::dvar_t* register_float(const std::string& name, float value, float min, float max, unsigned int flags, const std::string& description) { - const auto hash = game::generateHashValue(name.data()); - - if (can_add_dvar_to_list(name)) - { - dvar_list.push_back({name, description}); - } - + const auto hash = generate_hash(name); + insert_dvar_info(hash, name, description); return game::Dvar_RegisterFloat(hash, "", value, min, max, flags); } game::dvar_t* register_vec4(const std::string& name, float x, float y, float z, float w, float min, float max, unsigned int flags, const std::string& description) { - const auto hash = game::generateHashValue(name.data()); - - if (can_add_dvar_to_list(name)) - { - dvar_list.push_back({name, description}); - } - + const auto hash = generate_hash(name); + insert_dvar_info(hash, name, description); return game::Dvar_RegisterVec4(hash, "", x, y, z, w, min, max, flags); } game::dvar_t* register_enum(const std::string& name, const char** value_list, int default_index, unsigned int flags, const std::string& description) { - const auto hash = game::generateHashValue(name.data()); - - if (can_add_dvar_to_list(name)) - { - dvar_list.push_back({name, description}); - } - + const auto hash = generate_hash(name); + insert_dvar_info(hash, name, description); return game::Dvar_RegisterEnum(hash, "", value_list, default_index, flags); } } diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 7ef2bbc2..e9e52251 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -1,19 +1,20 @@ #pragma once #include "structs.hpp" +#include "game.hpp" #include namespace dvars { struct dvar_info { - dvar_info(const std::string& name, const std::string& description); - std::string name; std::string description; - int hash; + std::int32_t hash; }; + extern std::unordered_map dvar_map; + extern game::dvar_t* con_inputBoxColor; extern game::dvar_t* con_inputHintBoxColor; extern game::dvar_t* con_outputBarColor; @@ -36,14 +37,60 @@ namespace dvars extern game::dvar_t* g_enableElevators; - extern game::dvar_t** cg_draw_2d; + WEAK game::symbol com_max_fps{0x14AE2C890}; + WEAK game::symbol cg_draw_2d{0x141E39EC0}; - extern std::vector dvar_list; + constexpr int generate_hash(const char* string) + { + const char* v1; + char v2, v6; + int v4, v5, v7; + char* end_ptr; + + v1 = string; + v2 = *string; + + if (v2 == 48 && v1[1] == 120) + { + return strtoul(v1 + 2, &end_ptr, 16); + } + + v4 = v2; + + if ((v2 - 65) <= 0x19u) + { + v4 = v2 + 32; + } + + v5 = 0xB3CB2E29 * static_cast(v4 ^ 0x319712C3); + + if (v2) + { + do + { + v6 = *++v1; + v7 = v6; + if ((v6 - 65) <= 0x19u) + { + v7 = v6 + 32; + } + + v5 = 0xB3CB2E29 * static_cast(v5 ^ v7); + } while (v6); + } + + return v5; + } + + std::int32_t generate_hash(const std::string& string); + + void insert_dvar_info(const std::int32_t hash, const std::string& name, const std::string& description); + void insert_dvar_info(const std::string& name, const std::string& description); std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain); std::string dvar_get_domain(const game::dvar_type type, const game::dvar_limits& domain); std::string dvar_get_description(const std::string& name); - std::optional get_dvar_info_from_hash(const int hash); + std::optional get_dvar_info_from_hash(const std::int32_t hash); game::dvar_t* register_int(const std::string& name, int value, int min, int max, unsigned int flags, const std::string& description); diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp index 8f11e151..ee8b2135 100644 --- a/src/client/game/scripting/functions.cpp +++ b/src/client/game/scripting/functions.cpp @@ -1,10 +1,8 @@ #include #include "functions.hpp" -#include "../../component/gsc.hpp" - -#include -#include +#include "component/gsc/script_extension.hpp" +#include "component/gsc/script_loading.hpp" #include @@ -15,23 +13,17 @@ namespace scripting int find_function_index(const std::string& name, const bool prefer_global) { const auto target = utils::string::to_lower(name); - auto first = xsk::gsc::h2::resolver::function_id; - auto second = xsk::gsc::h2::resolver::method_id; - if (!prefer_global) + auto const& first = gsc::gsc_ctx->func_map(); + auto const& second = gsc::gsc_ctx->meth_map(); + + if (const auto itr = first.find(name); itr != first.end()) { - std::swap(first, second); + return static_cast(itr->second); } - const auto first_res = first(target); - if (first_res) + if (const auto itr = second.find(name); itr != second.end()) { - return first_res; - } - - const auto second_res = second(target); - if (second_res) - { - return second_res; + return static_cast(itr->second); } return -1; @@ -67,20 +59,20 @@ namespace scripting results.push_back(utils::string::va("_ID%i", id)); results.push_back(utils::string::va("_id_%04X", id)); - results.push_back(xsk::gsc::h2::resolver::token_name(static_cast(id))); + results.push_back(gsc::gsc_ctx->token_name(id)); return results; } std::string find_token_single(unsigned int id) { - return xsk::gsc::h2::resolver::token_name(static_cast(id)); + return gsc::gsc_ctx->token_name(id); } unsigned int find_token_id(const std::string& name) { - const auto id = xsk::gsc::h2::resolver::token_id(name); - if (id != 0) + const auto id = gsc::gsc_ctx->token_id(name); + if (id) { return id; } diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index a9c05780..95de7895 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -12,14 +12,12 @@ #include "component/mods.hpp" #include "component/scheduler.hpp" #include "component/filesystem.hpp" +#include "component/gui/debug.hpp" + +#include "component/gsc/script_loading.hpp" #include "game/ui_scripting/execution.hpp" -#include "lualib.h" - -#include -#include - #include #include #include @@ -103,7 +101,7 @@ namespace scripting::lua a.get_z() + b.get_z() ); }, - [](const vector& a, const int value) + [](const vector& a, const float value) { return vector( a.get_x() + value, @@ -122,7 +120,7 @@ namespace scripting::lua a.get_z() - b.get_z() ); }, - [](const vector& a, const int value) + [](const vector& a, const float value) { return vector( a.get_x() - value, @@ -141,7 +139,7 @@ namespace scripting::lua a.get_z() * b.get_z() ); }, - [](const vector& a, const int value) + [](const vector& a, const float value) { return vector( a.get_x() * value, @@ -160,7 +158,7 @@ namespace scripting::lua a.get_z() / b.get_z() ); }, - [](const vector& a, const int value) + [](const vector& a, const float value) { return vector( a.get_x() / value, @@ -359,7 +357,7 @@ namespace scripting::lua auto entity_type = state.new_usertype("entity"); - for (const auto& func : xsk::gsc::h2::resolver::get_methods()) + for (const auto& func : gsc::gsc_ctx->meth_map()) { const auto name = std::string(func.first); entity_type[name.data()] = [name](const entity& entity, const sol::this_state s, sol::variadic_args va) @@ -481,6 +479,74 @@ namespace scripting::lua return sol::as_returns(returns); }; } + + void setup_debug_funcs(sol::state& state) + { + struct debug + { + }; + auto debug_type = state.new_usertype("debug_"); + state["debug"] = debug(); + + debug_type["reset"] = [](const debug&) + { + gui::debug::reset_debug_items(); + }; + + debug_type["addline"] = [](const debug&, const vector& start, const vector& end, const vector& color) + { + float color_[4]{}; + color_[0] = color[0]; + color_[1] = color[1]; + color_[2] = color[2]; + color_[3] = 1.f; + + return gui::debug::add_debug_line(start, end, color_); + }; + + debug_type["removeline"] = [](const debug&, const size_t line) + { + return gui::debug::remove_debug_line(line); + }; + + debug_type["addsquare"] = [](const debug&, const vector& origin, const vector& color) + { + float color_[4]{}; + color_[0] = color[0]; + color_[1] = color[1]; + color_[2] = color[2]; + color_[3] = 1.f; + + return gui::debug::add_debug_square(origin, color_); + }; + + debug_type["removesquare"] = [](const debug&, const size_t square) + { + return gui::debug::remove_debug_square(square); + }; + + debug_type["setsquarecolor"] = [](const debug&, const size_t& square, const vector& color) + { + float color_[4]{}; + color_[0] = color[0]; + color_[1] = color[1]; + color_[2] = color[2]; + color_[3] = 1.f; + + gui::debug::set_debug_square_color(square, color_); + }; + + debug_type["setlinecolor"] = [](const debug&, const size_t& line, const vector& color) + { + float color_[4]{}; + color_[0] = color[0]; + color_[1] = color[1]; + color_[2] = color[2]; + color_[3] = 1.f; + + gui::debug::set_debug_line_color(line, color_); + }; + } void setup_game_type(sol::state& state, event_handler& handler, scheduler& scheduler) { @@ -490,7 +556,7 @@ namespace scripting::lua auto game_type = state.new_usertype("game_"); state["game"] = game(); - for (const auto& func : xsk::gsc::h2::resolver::get_functions()) + for (const auto& func : gsc::gsc_ctx->func_map()) { const auto name = std::string(func.first); game_type[name] = [name](const game&, const sol::this_state s, sol::variadic_args va) @@ -563,7 +629,7 @@ namespace scripting::lua notifies::clear_hook(pos); }; - detour["enable"] = [&]() + detour["enable"] = [=]() { notifies::set_lua_hook(pos, function); }; @@ -796,14 +862,6 @@ namespace scripting::lua scripting::get_dvar_int_overrides.erase(dvar); }; - game_type["luinotify"] = [](const game&, const std::string& name, const std::string& data) - { - ::scheduler::once([=]() - { - ui_scripting::notify(name, {{"data", data}}); - }, ::scheduler::pipeline::lui); - }; - auto function_ptr_type = state.new_usertype("functionptr", sol::constructors()); @@ -848,6 +906,7 @@ namespace scripting::lua setup_io(this->state_); setup_json(this->state_); setup_vector_type(this->state_); + setup_debug_funcs(this->state_); setup_entity_type(this->state_, this->event_handler_, this->scheduler_); setup_game_type(this->state_, this->event_handler_, this->scheduler_); @@ -880,6 +939,7 @@ namespace scripting::lua setup_io(this->state_); setup_json(this->state_); setup_vector_type(this->state_); + setup_debug_funcs(this->state_); setup_entity_type(this->state_, this->event_handler_, this->scheduler_); setup_game_type(this->state_, this->event_handler_, this->scheduler_); } diff --git a/src/client/game/scripting/lua/value_conversion.cpp b/src/client/game/scripting/lua/value_conversion.cpp index d0cd2312..c8f2822f 100644 --- a/src/client/game/scripting/lua/value_conversion.cpp +++ b/src/client/game/scripting/lua/value_conversion.cpp @@ -41,7 +41,7 @@ namespace scripting::lua { const auto function = value.as(); const auto index = reinterpret_cast(notifies::get_hook_count() + 1); - notifies::set_lua_hook(index, function); + notifies::set_lua_hook(index, function, true); game::VariableValue func{}; func.type = game::SCRIPT_FUNCTION; diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index fdd9c081..3562f751 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1,21 +1,24 @@ #pragma once #include +#include "assets.hpp" namespace game { - typedef float vec_t; - typedef vec_t vec2_t[2]; - typedef vec_t vec3_t[3]; - typedef vec_t vec4_t[4]; - struct gclient_s { - char __pad0[0x8C]; + char __pad0[140]; vec3_t velocity; - char __pad1[0xE870]; + char __pad1[112]; + vec3_t angles; + char __pad2[59380]; char flags; }; + static_assert(sizeof(gclient_s) == 59660); + static_assert(offsetof(gclient_s, flags) == 59656); + static_assert(offsetof(gclient_s, velocity) == 140); + static_assert(offsetof(gclient_s, angles) == 264); + struct client_t { char __pad0[13508]; @@ -62,22 +65,12 @@ namespace game uint16_t entityNum; }; - enum scr_string_t - { - scr_string_t_dummy = 0x0, - }; - - struct Bounds - { - vec3_t midPoint; - vec3_t halfSize; - }; - struct gentity_s { char __pad0[26]; vec3_t origin; - char __pad1[100]; + vec3_t angles; + char __pad1[88]; EntityState s; char __pad2[50]; Bounds box; @@ -103,266 +96,6 @@ namespace game static_assert(offsetof(gentity_s, flags) == 364); static_assert(offsetof(gentity_s, s) == 140); - struct pathnode_yaworient_t - { - float fLocalAngle; - float localForward[2]; - }; - - union $3936EE84564F75EDA6DCBAC77A545FC8 - { - pathnode_yaworient_t yaw_orient; - float angles[3]; - }; - - union PathNodeParentUnion - { - scr_string_t name; - unsigned short index; - }; - - enum nodeType - { - NODE_ERROR = 0x0, - NODE_PATHNODE = 0x1, - NODE_NEGOTIATION_BEGIN = 0x13, - NODE_NEGOTIATION_END = 0x14 - }; - - enum PathNodeErrorCode : std::int32_t - { - PNERR_NONE = 0x0, - PNERR_INSOLID = 0x1, - PNERR_FLOATING = 0x2, - PNERR_NOLINK = 0x3, - PNERR_DUPLICATE = 0x4, - PNERR_NOSTANCE = 0x5, - PNERR_INVALIDDOOR = 0x6, - PNERR_NOANGLES = 0x7, - PNERR_BADPLACEMENT = 0x8, - NUM_PATH_NODE_ERRORS = 0x9, - }; - - union $5F11B9753862CE791E23553F99FA1738 - { - float minUseDistSq; - PathNodeErrorCode error; - }; - - struct pathlink_s - { - float fDist; - unsigned short nodeNum; - unsigned char disconnectCount; - unsigned char negotiationLink; - unsigned char flags; - unsigned char ubBadPlaceCount[3]; - }; - - struct pathnode_constant_t - { - unsigned short type; - unsigned int spawnflags; - scr_string_t targetname; - scr_string_t script_linkName; - scr_string_t script_noteworthy; - scr_string_t target; - scr_string_t animscript; - int animscriptfunc; - float vLocalOrigin[3]; - $3936EE84564F75EDA6DCBAC77A545FC8 ___u9; - PathNodeParentUnion parent; - $5F11B9753862CE791E23553F99FA1738 ___u11; - short wOverlapNode[2]; - char __pad0[4]; - unsigned short totalLinkCount; - pathlink_s* Links; - scr_string_t unk; - char __pad1[4]; - }; - - struct SentientHandle - { - unsigned short number; - unsigned short infoIndex; - }; - - struct pathnode_dynamic_t - { - SentientHandle pOwner; - int iFreeTime; - int iValidTime[3]; - short wLinkCount; - short wOverlapCount; - short turretEntNumber; - unsigned char userCount; - unsigned char hasBadPlaceLink; - int spreadUsedTime[2]; - short flags; - short dangerousCount; - int recentUseProxTime; - }; - - union $73F238679C0419BE2C31C6559E8604FC - { - float nodeCost; - int linkIndex; - }; - - struct pathnode_t; - struct pathnode_transient_t - { - int iSearchFrame; - pathnode_t* pNextOpen; - pathnode_t* pPrevOpen; - pathnode_t* pParent; - float fCost; - float fHeuristic; - $73F238679C0419BE2C31C6559E8604FC ___u6; - }; - - struct pathnode_t - { - pathnode_constant_t constant; - pathnode_dynamic_t dynamic; - pathnode_transient_t transient; - }; - - struct pathnode_tree_nodes_t - { - int nodeCount; - unsigned short* nodes; - }; - - struct pathnode_tree_t; - union pathnode_tree_info_t - { - pathnode_tree_t* child[2]; - pathnode_tree_nodes_t s; - }; - - struct pathnode_tree_t - { - int axis; - float dist; - pathnode_tree_info_t u; - }; - - struct PathDynamicNodeGroup - { - unsigned short parentIndex; - int nodeTreeCount; - pathnode_tree_t* nodeTree; - }; - - struct PathData - { - const char* name; - unsigned int nodeCount; - pathnode_t* nodes; - bool parentIndexResolved; - unsigned short version; - int visBytes; - unsigned char* pathVis; - int nodeTreeCount; - pathnode_tree_t* nodeTree; - int dynamicNodeGroupCount; - PathDynamicNodeGroup* dynamicNodeGroups; - int exposureBytes; - unsigned char* pathExposure; - int noPeekVisBytes; - unsigned char* pathNoPeekVis; - int zoneCount; - int zonesBytes; - unsigned char* pathZones; - int dynStatesBytes; - unsigned char* pathDynStates; - }; - - struct GfxImage; - - union MaterialTextureDefInfo - { - GfxImage* image; - void* water; - }; - - struct MaterialTextureDef - { - unsigned int nameHash; - char nameStart; - char nameEnd; - char samplerState; - char semantic; - MaterialTextureDefInfo u; - }; - - struct MaterialPass - { - void* vertexShader; - void* vertexDecl; - void* hullShader; - void* domainShader; - void* pixelShader; - char pixelOutputMask; - char perPrimArgCount; - char perObjArgCount; - char stableArgCount; - unsigned __int16 perPrimArgSize; - unsigned __int16 perObjArgSize; - unsigned __int16 stableArgSize; - char zone; - char perPrimConstantBuffer; - char perObjConstantBuffer; - char stableConstantBuffer; - unsigned int customBufferFlags; - char customSamplerFlags; - char precompiledIndex; - char stageConfig; - void* args; - }; - - struct MaterialTechnique - { - const char* name; - unsigned __int16 flags; - unsigned __int16 passCount; - MaterialPass passArray[1]; - }; - - struct MaterialTechniqueSet - { - const char* name; - unsigned __int16 flags; - char worldVertFormat; - char preDisplacementOnlyCount; - MaterialTechnique* techniques[309]; - }; - - struct GfxStateBits - { - unsigned int loadBits[3]; - char zone; - char depthStencilState[11]; - char blendState; - char rasterizerState; - }; - - struct Material - { - const char* name; - char __pad0[0x124]; - char textureCount; - char __pad1[0xB]; - MaterialTechniqueSet* techniqueSet; - MaterialTextureDef* textureTable; - void* constantTable; - GfxStateBits* stateBitsTable; - char __pad2[0x118]; - }; - - static_assert(sizeof(Material) == 0x270); - struct point { float x; @@ -582,11 +315,14 @@ namespace game THREAD_CONTEXT_TRACE_COUNT = 0xB, THREAD_CONTEXT_TRACE_LAST = 0xA, THREAD_CONTEXT_CINEMATIC = 0xB, - THREAD_CONTEXT_DATABASE = 0xC, - THREAD_CONTEXT_STREAM = 0xD, - THREAD_CONTEXT_SNDSTREAMPACKETCALLBACK = 0xE, - THREAD_CONTEXT_STATS_WRITE = 0xF, - THREAD_CONTEXT_COUNT = 0x10, + THREAD_CONTEXT_WINDOW = 0xC, + THREAD_CONTEXT_INPUT = 0xD, + THREAD_CONTEXT_DATABASE = 0xE, + THREAD_CONTEXT_STREAM = 0xF, + THREAD_CONTEXT_UNK_16 = 0x10, + THREAD_CONTEXT_UNK_17 = 0x11, + THREAD_CONTEXT_UNK_18 = 0x12, + THREAD_COUNT, }; struct KeyState @@ -677,7 +413,11 @@ namespace game struct dvar_t { - int name; //00 + union + { + int name; + int hash; + }; unsigned int flags; //08 dvar_type type; //0C bool modified; //0D @@ -731,437 +471,15 @@ namespace game const char* name; void(__cdecl* function)(); }; - - enum XAssetType + + struct XZone { - ASSET_TYPE_PHYSPRESET, - ASSET_TYPE_PHYS_COLLMAP, - ASSET_TYPE_PHYSWATERPRESET, - ASSET_TYPE_PHYS_WORLDMAP, - ASSET_TYPE_PHYSCONSTRAINT, - ASSET_TYPE_XANIM, - ASSET_TYPE_XMODELSURFS, - ASSET_TYPE_XMODEL, - ASSET_TYPE_MATERIAL, - ASSET_TYPE_COMPUTESHADER, - ASSET_TYPE_VERTEXSHADER, - ASSET_TYPE_HULLSHADER, - ASSET_TYPE_DOMAINSHADER, - ASSET_TYPE_PIXELSHADER, - ASSET_TYPE_VERTEXDECL, - ASSET_TYPE_TECHSET, - ASSET_TYPE_IMAGE, - ASSET_TYPE_SOUND, - ASSET_TYPE_SOUNDSUBMIX, - ASSET_TYPE_SNDCURVE, - ASSET_TYPE_LPFCURVE, - ASSET_TYPE_REVERBSENDCURVE, - ASSET_TYPE_SNDCONTEXT, - ASSET_TYPE_LOADED_SOUND, - ASSET_TYPE_COL_MAP_SP, - ASSET_TYPE_COM_MAP, - ASSET_TYPE_GLASS_MAP, - ASSET_TYPE_AIPATHS, - ASSET_TYPE_VEHICLE_TRACK, - ASSET_TYPE_MAP_ENTS, - ASSET_TYPE_FX_MAP, - ASSET_TYPE_GFX_MAP, - ASSET_TYPE_LIGHTDEF, - ASSET_TYPE_UI_MAP, - ASSET_TYPE_MENUFILE, - ASSET_TYPE_MENU, - ASSET_TYPE_ANIMCLASS, - ASSET_TYPE_LOCALIZE, - ASSET_TYPE_ATTACHMENT, - ASSET_TYPE_WEAPON, - ASSET_TYPE_SNDDRIVERGLOBALS, - ASSET_TYPE_FX, - ASSET_TYPE_IMPACTFX, - ASSET_TYPE_SURFACEFX, - ASSET_TYPE_AITYPE, - ASSET_TYPE_MPTYPE, - ASSET_TYPE_CHARACTER, - ASSET_TYPE_XMODELALIAS, - ASSET_TYPE_RAWFILE, - ASSET_TYPE_SCRIPTFILE, - ASSET_TYPE_STRINGTABLE, - ASSET_TYPE_LEADERBOARDDEF, - ASSET_TYPE_VIRTUALLEADERBOARDDEF, - ASSET_TYPE_STRUCTUREDDATADEF, - ASSET_TYPE_DDL, - ASSET_TYPE_PROTO, - ASSET_TYPE_TRACER, - ASSET_TYPE_VEHICLE, - ASSET_TYPE_ADDON_MAP_ENTS, - ASSET_TYPE_NETCONSTSTRINGS, - ASSET_TYPE_REVERBPRESET, - ASSET_TYPE_LUAFILE, - ASSET_TYPE_SCRIPTABLE, - ASSET_TYPE_EQUIPSNDTABLE, - ASSET_TYPE_VECTORFIELD, - ASSET_TYPE_DOPPLERPRESET, - ASSET_TYPE_PARTICLESIMANIMATION, - ASSET_TYPE_LASER, - ASSET_TYPE_SKELETONSCRIPT, - ASSET_TYPE_CLUT, - ASSET_TYPE_TTF, - ASSET_TYPE_COUNT, + char __pad0[24]; + char name[64]; + char __pad1[128]; }; - struct StreamFileNameRaw - { - const char* dir; - const char* name; - }; - - struct StreamFileNamePacked - { - unsigned __int64 offset; - unsigned __int64 length; - }; - - union StreamFileInfo - { - StreamFileNameRaw raw; - StreamFileNamePacked packed; - }; - - struct SpeakerLevels - { - char speaker; - char numLevels; - float levels[2]; - }; - - struct ChannelMap - { - int speakerCount; - SpeakerLevels speakers[6]; - }; - - struct SpeakerMap - { - bool isDefault; - const char* name; - int a; - ChannelMap channelMaps[2][2]; - }; //static_assert(sizeof(SpeakerMap) == 0x148); - - struct StreamFileName - { - bool isLocalized; - bool isStreamed; - unsigned __int16 fileIndex; - StreamFileInfo info; - }; - - struct StreamedSound - { - StreamFileName filename; - unsigned int totalMsec; - }; - - struct StreamFile - { - void* handle; - __int64 length; - __int64 startOffset; - bool isPacked; - }; - - struct LoadedSoundInfo - { - char* data; - unsigned int sampleRate; - unsigned int dataByteCount; - unsigned int numSamples; - char channels; - char numBits; - char blockAlign; - short format; - int loadedSize; - }; static_assert(sizeof(LoadedSoundInfo) == 0x20); - - struct LoadedSound - { - const char* name; - StreamFileName filename; - LoadedSoundInfo info; - }; static_assert(sizeof(LoadedSound) == 0x40); - - union SoundFileRef - { - LoadedSound* loadSnd; - StreamedSound streamSnd; - }; - - enum snd_alias_type_t : std::int8_t - { - SAT_UNKNOWN = 0x0, - SAT_LOADED = 0x1, - SAT_STREAMED = 0x2, - SAT_PRIMED = 0x3, - SAT_COUNT = 0x4, - }; - - struct SoundFile - { - snd_alias_type_t type; - char exists; - SoundFileRef u; - }; - - struct SndContext - { - const char* name; - char __pad0[8]; - }; - - struct SndCurve - { - bool isDefault; - union - { - const char* filename; - const char* name; - }; - unsigned short knotCount; - float knots[16][2]; - }; static_assert(sizeof(SndCurve) == 0x98); - - struct DopplerPreset - { - const char* name; - float speedOfSound; - float playerVelocityScale; - float minPitch; - float maxPitch; - float smoothing; - }; static_assert(sizeof(DopplerPreset) == 0x20); - - struct snd_alias_t - { - const char* aliasName; - const char* subtitle; - const char* secondaryAliasName; - const char* chainAliasName; - SoundFile* soundFile; - const char* mixerGroup; - char __pad0[8]; - int sequence; - int u4; - int u5; - float volMin; - float volMax; - int volModIndex; - float pitchMin; - float pitchMax; - float distMin; - float distMax; - float velocityMin; - int flags; - char masterPriority; - float masterPercentage; - float slavePercentage; - char u18; - float probability; - char u20; // value: 0-4 - SndContext* sndContext; - char __pad1[12]; - int startDelay; - SndCurve* sndCurve; - char __pad2[8]; - SndCurve* lpfCurve; - SndCurve* hpfCurve; - SndCurve* reverbSendCurve; - SpeakerMap* speakerMap; - char __pad3[47]; - float u34; - }; - - static_assert(sizeof(snd_alias_t) == 256); - - struct snd_alias_list_t - { - const char* aliasName; - snd_alias_t* head; - short* unk; - unsigned char count; - unsigned char unkCount; - char __pad0[6]; - }; - - struct RawFile - { - const char* name; - int compressedLen; - int len; - const char* buffer; - }; - - struct ScriptFile - { - const char* name; - int compressedLen; - int len; - int bytecodeLen; - char* buffer; - char* bytecode; - }; - - struct StringTableCell - { - const char* string; - int hash; - }; - - struct StringTable - { - const char* name; - int columnCount; - int rowCount; - StringTableCell* values; - }; - - struct LuaFile - { - const char* name; - int len; - char strippingType; - const char* buffer; - }; - - struct TTF - { - const char* name; - int len; - const char* buffer; - int fontFace; - }; - - struct MapEnts - { - const char* name; - char* entityString; - int numEntityChars; - }; - - struct TriggerModel - { - int contents; - unsigned __int16 hullCount; - unsigned __int16 firstHull; - }; - - struct TriggerHull - { - Bounds bounds; - int contents; - unsigned __int16 slabCount; - unsigned __int16 firstSlab; - }; - - struct TriggerSlab - { - float dir[3]; - float midPoint; - float halfSize; - }; - - struct MapTriggers - { - unsigned int modelCount; - TriggerModel* models; - unsigned int hullCount; - TriggerHull* hulls; - unsigned int slabCount; - TriggerSlab* slabs; - }; - - struct AddonMapEnts - { - const char* name; - char* entityString; - int numEntityChars; - MapTriggers trigger; - void* info; - unsigned int numSubModels; - void* cmodels; - void* models; - }; - - struct LocalizeEntry - { - const char* value; - const char* name; - }; - - union XAssetHeader - { - void* data; - Material* material; - Font_s* font; - RawFile* rawfile; - ScriptFile* scriptfile; - StringTable* stringTable; - LuaFile* luaFile; - TTF* ttf; - MapEnts* mapents; - AddonMapEnts* addon_mapents; - LocalizeEntry* localize; - snd_alias_list_t* sound; - DopplerPreset* doppler_preset; - SndContext* snd_context; - SndCurve* snd_curve; - LoadedSound* loaded_sound; - }; - - struct XAsset - { - XAssetType type; - XAssetHeader header; - }; - - struct XAssetEntry - { - XAsset asset; - char zoneIndex; - volatile char inuseMask; - unsigned int nextHash; - unsigned int nextOverride; - unsigned int nextPoolEntry; - }; - - enum DBSyncMode - { - DB_LOAD_ASYNC = 0x0, - DB_LOAD_SYNC = 0x1, - DB_LOAD_ASYNC_WAIT_ALLOC = 0x2, - DB_LOAD_ASYNC_FORCE_FREE = 0x3, - DB_LOAD_ASYNC_NO_SYNC_THREADS = 0x4, - DB_LOAD_SYNC_SKIP_ALWAYS_LOADED = 0x5, - }; - - enum DBAllocFlags : std::int32_t - { - DB_ZONE_NONE = 0x0, - DB_ZONE_COMMON = 0x1, - DB_ZONE_UI = 0x2, - DB_ZONE_GAME = 0x4, - DB_ZONE_LOAD = 0x8, - DB_ZONE_DEV = 0x10, - DB_ZONE_BASEMAP = 0x20, - DB_ZONE_TRANSIENT_POOL = 0x40, - DB_ZONE_TRANSIENT_MASK = 0x40, - DB_ZONE_CUSTOM = 0x1000 // added for custom zone loading - }; - - struct XZoneInfo - { - const char* name; - int allocFlags; - int freeFlags; - }; + static_assert(sizeof(XZone) == 216); struct LevelLoad { @@ -1179,6 +497,44 @@ namespace game unsigned short classnum; }; + typedef void(*BuiltinMethod)(scr_entref_t); + typedef void(*BuiltinFunction)(); + + enum + { + VAR_UNDEFINED = 0x0, + VAR_BEGIN_REF = 0x1, + VAR_POINTER = 0x1, + VAR_STRING = 0x2, + VAR_ISTRING = 0x3, + VAR_VECTOR = 0x4, + VAR_END_REF = 0x5, + VAR_FLOAT = 0x5, + VAR_INTEGER = 0x6, + VAR_CODEPOS = 0x7, + VAR_PRECODEPOS = 0x8, + VAR_FUNCTION = 0x9, + VAR_BUILTIN_FUNCTION = 0xA, + VAR_BUILTIN_METHOD = 0xB, + VAR_STACK = 0xC, + VAR_ANIMATION = 0xD, + VAR_PRE_ANIMATION = 0xE, + VAR_THREAD = 0xF, + VAR_NOTIFY_THREAD = 0x10, + VAR_TIME_THREAD = 0x11, + VAR_CHILD_THREAD = 0x12, + VAR_OBJECT = 0x13, + VAR_DEAD_ENTITY = 0x14, + VAR_ENTITY = 0x15, + VAR_ARRAY = 0x16, + VAR_DEAD_THREAD = 0x17, + VAR_COUNT = 0x18, + VAR_FREE = 0x18, + VAR_THREAD_LIST = 0x19, + VAR_ENDON_LIST = 0x1A, + VAR_TOTAL_COUNT = 0x1B, + }; + enum scriptType_e { SCRIPT_NONE = 0, @@ -1356,11 +712,12 @@ namespace game GFX_DRAW_SCENE_STANDARD = 0x0, }; - enum MaterialTechniqueType + struct GfxVertex { - TECHNIQUE_UNLIT = 8, - TECHNIQUE_EMISSIVE = 9, - TECHNIQUE_LIT = 13, + float xyzw[4]; + GfxColor color; + float texCoord[2]; + PackedUnitVec normal; }; struct GfxDrawMethod_s @@ -1371,67 +728,21 @@ namespace game int forceTechType; }; - struct GfxImageLoadDef + struct materialCommands_t { - char levelCount; - char numElements; - char pad[2]; - int flags; - int format; - int resourceSize; - char data[1]; - }; - - union $3FA29451CE6F1FA138A5ABAB84BE9676 - { - ID3D11Texture1D* linemap; - ID3D11Texture2D* map; - ID3D11Texture3D* volmap; - ID3D11Texture2D* cubemap; - GfxImageLoadDef* loadDef; - }; - - struct GfxTexture - { - $3FA29451CE6F1FA138A5ABAB84BE9676 ___u0; - ID3D11ShaderResourceView* shaderView; - ID3D11ShaderResourceView* shaderViewAlternate; - }; - - struct Picmip - { - char platform[2]; - }; - - struct CardMemory - { - int platform[2]; - }; - - struct GfxImage - { - GfxTexture textures; - int flags; - int imageFormat; - int resourceSize; - char mapType; - char semantic; - char category; - char flags2; - Picmip picmip; - char track; - //CardMemory cardMemory; - unsigned short width; - unsigned short height; - unsigned short depth; - unsigned short numElements; - char pad3[4]; - void* pixelData; - //GfxImageLoadDef *loadDef; - uint64_t streams[4]; - const char* name; + GfxVertex verts[5450]; + unsigned __int16 indices[1048576]; + int vertDeclType; + unsigned int vertexSize; + unsigned int indexCount; + unsigned int vertexCount; + unsigned int firstVertex; + unsigned int lastVertex; }; + static_assert(offsetof(materialCommands_t, indices) == 174400); + static_assert(offsetof(materialCommands_t, indexCount) == 2271560); + static_assert(offsetof(materialCommands_t, vertexCount) == 2271564); struct playerState_s { @@ -1442,9 +753,21 @@ namespace game char __pad2[40]; vec3_t origin; vec3_t velocity; + char __pad3[128]; + float viewHeightCurrent; + char __pad4[12]; + vec3_t delta_angles; }; static_assert(offsetof(playerState_s, origin) == 128); + static_assert(offsetof(playerState_s, viewHeightCurrent) == 280); + static_assert(offsetof(playerState_s, delta_angles) == 296); + + struct cg_s + { + char __pad0[507228]; + float refdefViewAngles[3]; + }; struct SprintState_s { @@ -1459,7 +782,9 @@ namespace game { int serverTime; int buttons; - char __pad0[20]; + int angles[3]; + unsigned int weapon; + unsigned int offHand; char forwardmove; char rightmove; char __pad1[2]; @@ -1616,6 +941,8 @@ namespace game LANGUAGE_KOREAN = 15, LANGUAGE_ENGLISH_SAFE = 16, LANGUAGE_RUSSIAN_PARTIAL = 17, + LANGUAGE_COUNT_ORIGINAL = 18, + LANGUAGE_TURKISH = 18, LANGUAGE_COUNT }; @@ -1629,6 +956,13 @@ namespace game int vertAlign; }; + enum PMem_Direction + { + PHYS_ALLOC_LOW = 0x0, + PHYS_ALLOC_HIGH = 0x1, + PHYS_ALLOC_COUNT = 0x2, + }; + enum PMem_Source { PMEM_SOURCE_EXTERNAL = 0x0, @@ -1637,19 +971,130 @@ namespace game PMEM_SOURCE_DEFAULT_HIGH = 0x3, PMEM_SOURCE_MOVIE = 0x4, PMEM_SOURCE_SCRIPT = 0x5, + PMEM_SOURCE_UNK5 = 0x5, + PMEM_SOURCE_UNK6 = 0x6, + PMEM_SOURCE_UNK7 = 0x7, + PMEM_SOURCE_UNK8 = 0x8, + PMEM_SOURCE_CUSTOMIZATION = 0x9, }; - struct physical_memory + struct PhysicalMemoryAllocation { - char __pad0[0x10]; - char* buf; - char __pad1[0x8]; + const char* name; + char __pad0[16]; + unsigned __int64 pos; + char __pad1[8]; + }; static_assert(sizeof(PhysicalMemoryAllocation) == 40); + + struct PhysicalMemoryPrim + { + const char* name; + unsigned int allocListCount; + char __pad0[4]; + unsigned char* buf; + char __pad1[8]; int unk1; - size_t size; - char __pad2[0x500]; + char __pad2[4]; + unsigned __int64 pos; + PhysicalMemoryAllocation allocList[32]; + }; static_assert(sizeof(PhysicalMemoryPrim) == 1328); + + struct PhysicalMemory + { + PhysicalMemoryPrim prim[2]; + }; static_assert(sizeof(PhysicalMemory) == 0xA60); + + union GamerProfileDataUnion + { + unsigned __int8 byteVal; + bool boolVal; + __int16 shortVal; + int intVal; + float floatVal; + const char* stringVal; }; - static_assert(sizeof(physical_memory) == 0x530); + enum level_number + { + LEVEL_TRAINER, + LEVEL_ROADKILL, + LEVEL_CLIFFHANGER, + LEVEL_AIRPORT, + LEVEL_FAVELA, + + LEVEL_INVASION, + LEVEL_FAVELA_ESCAPE, + LEVEL_ARCADIA, + LEVEL_OILRIG, + LEVEL_GULAG, + LEVEL_DCBURNING, + + LEVEL_CONTINGENCY, + LEVEL_DCEMP, + LEVEL_DC_WHITEHOUSE, + LEVEL_ESTATE, + LEVEL_BONEYARD, + LEVEL_AF_CAVES, + LEVEL_AF_CHASE, + + LEVEL_ENDING, + + LEVEL_COUNT, + }; + + enum GamerProfileDataType : __int32 + { + TYPE_INVALID = 0x0, + TYPE_BYTE = 0x1, + TYPE_BOOL = 0x2, + TYPE_SHORT = 0x3, + TYPE_INT = 0x4, + TYPE_FLOAT = 0x5, + TYPE_STRING = 0x6, + TYPE_BUFFER = 0x7, + TYPE_FLAG = 0x8, + }; + + struct GamerProfileData + { + GamerProfileDataType type; + GamerProfileDataUnion u; + }; + + enum HeFont + { + HE_FONT_DEFAULT = 0x0, + HE_FONT_BIGFIXED = 0x1, + HE_FONT_SMALLFIXED = 0x2, + HE_FONT_OBJECTIVE = 0x3, + HE_FONT_BIG = 0x4, + HE_FONT_SMALL = 0x5, + HE_FONT_HUDBIG = 0x6, + HE_FONT_HUDSMALL = 0x7, + HE_FONT_BUTTONPROMPT = 0x8, + HE_FONT_SUBTITLE = 0x9, + HE_FONT_TIMER = 0xA, + HE_FONT_NAMEPLATE = 0xB, + HE_FONT_BANK = 0xC, + HE_FONT_BANKSHADOW = 0xD, + HE_FONT_BANKSHADOWMORE = 0xE, + HE_FONT_COUNT, + }; + + struct volmod_t + { + char name[64]; + float value; + float headroom; + float mixExclusion; + }; + + struct sound_data_t + { + char __pad0[163720]; + volmod_t volmods[180]; + // ... + }; namespace hks { diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 4849c285..edceaa8d 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -6,6 +6,8 @@ namespace game { // Functions + WEAK symbol AnglesToAxis{0x140613090}; + WEAK symbol AddRefToValue{0x1405C0EB0}; WEAK symbol AddRefToObject{0x1405C0EA0}; WEAK symbol AllocThread{0x1405C1200}; @@ -22,10 +24,16 @@ namespace game WEAK symbol CG_GameMessageBold{0x14037F1B0}; WEAK symbol CG_GetWeaponDisplayName{0x1403B9210}; + WEAK symbol CG_GetGameTime{0x14037F580}; + + WEAK symbol CG_GetPredictedPlayerState{0x14037F720}; WEAK symbol CL_DrawStretchPic{0x1403C9570}; + WEAK symbol CL_GetUserCmd{0x1403C9F10}; + WEAK symbol CL_GetCurrentCmdNumber{0x1403C9D80}; + WEAK symbol Cmd_AddCommandInternal{0x14059A5F0}; WEAK symbol Cmd_ExecuteSingleCommand{0x14059ABA0}; @@ -67,11 +75,11 @@ namespace game WEAK symbol Dvar_DisplayableValue{0x140618EA0}; WEAK symbol Dvar_ValueToString{0x14061B8F0}; WEAK symbol Dvar_SetCommand{0x14061A5C0}; - WEAK symbol Dvar_SetFromStringFromSource{0x14061A910}; + WEAK symbol Dvar_SetFromStringFromSource{0x14061A910}; WEAK symbol Dvar_SetString{0x14061ABF0}; WEAK symbol Dvar_Reset{0x140619FE0}; - WEAK symbol generateHashValue{0x140343D20}; + WEAK symbol generateHashValue{0x140343D20}; WEAK symbol CL_IsCgameInitialized{0x1403CA0C0}; WEAK symbol GetNewArrayVariable{0x1405C2130}; WEAK symbol SetNewVariableValue{0x1405C5EA0}; WEAK symbol RemoveVariableValue{0x1405C2A50}; + WEAK symbol GetObjectType{0x1405C25D0}; + + WEAK symbol GamerProfile_GetDataByName{0x1403DCB70}; WEAK symbol G_GetWeaponForName{0x14051B260}; WEAK symbol @@ -116,7 +128,11 @@ namespace game WEAK symbol LUI_EndEvent{0x140316890}; WEAK symbol LUI_EnterCriticalSection{0x140316980}; WEAK symbol LUI_LeaveCriticalSection{0x14031BC20}; + WEAK symbol Menu_IsMenuOpenAndVisible{0x1405EE1A0}; + WEAK symbol Menus_FindByName{0x140603080}; + WEAK symbol Menus_OpenByName{0x140603770}; + WEAK symbol Menus_Open{0x1406034E0}; WEAK symbol Material_RegisterHandle{0x140759BA0}; @@ -136,10 +152,11 @@ namespace game WEAK symbol Scr_AddInt{0x1405C69A0}; WEAK symbol Scr_AddString{0x1405C6A80}; WEAK symbol Scr_LoadScript{0x1405BCEC0}; - WEAK symbol Scr_GetNumParam{0x1405C7940}; + WEAK symbol Scr_GetNumParam{0x1405C7940}; WEAK symbol Scr_GetFunctionHandle{0x1405BCD50}; WEAK symbol Scr_ExecThread{0x1405C6F40}; WEAK symbol Scr_RegisterFunction{0x1405BC7B0}; + WEAK symbol Scr_CastString{0x1405C33A0}; WEAK symbol PMem_AllocFromSource_NoDebug{0x14061E680}; @@ -173,6 +190,13 @@ namespace game float materialTime, __int64 a7, __int64 a8)> R_AddDObjToScene{0x140775C40}; WEAK symbol R_Cinematic_SysIO_BinkRead{0x1407191B0}; + WEAK symbol RB_SetIdentity{0x1407A0590}; + WEAK symbol RB_SetTessTechnique{0x1407B2B90}; + WEAK symbol RB_TessOverflow{0x1407B2C00}; + WEAK symbol RB_EndTessSurface{0x1407B2B70}; + WEAK symbol R_Set3D{0x14078B5D0}; + WEAK symbol ScrPlace_GetViewPlacement{0x1403E16A0}; WEAK symbol ScrPlace_GetView{0x1403E1660}; WEAK symbol SL_GetCanonicalString{0x1405BC970}; WEAK symbol SV_Loaded{0x1406B3860}; + WEAK symbol SV_SendGameServerCommand{0x1406B2F40}; WEAK symbol Sys_ShowConsole{0x140633080}; WEAK symbol Sys_IsDatabaseReady2{0x1405A9FE0}; @@ -199,6 +224,9 @@ namespace game WEAK symbol UI_DrawWrappedText{0x1406055E0}; + WEAK symbol UI_LoadMenus{0x1406072B0}; + WEAK symbol UI_AddMenuList{0x140604FE0}; + WEAK symbol PM_playerTrace{0x14068F0A0}; WEAK symbol cgs{0x141B96B20}; + WEAK symbol cmd_functions{0x14AD17BB8}; WEAK symbol cmd_args{0x14AD17A60}; WEAK symbol command_whitelist{0x140BF84E0}; WEAK symbol hWnd{0x14CCF81C0}; - WEAK game::symbol g_assetNames{0x140BEF280}; + WEAK symbol g_assetNames{0x140BEF280}; - WEAK game::symbol g_assetPool{0x140BF3620}; + WEAK symbol g_assetPool{0x140BF3620}; - WEAK game::symbol g_zoneCount{0x1422F45F4}; - WEAK game::symbol g_zoneIndex{0x1422F8DC8}; + WEAK symbol g_zoneCount{0x1422F45F4}; + WEAK symbol g_zoneIndex{0x1422F8DC8}; + WEAK symbol g_zones{0x144176040}; WEAK symbol g_compressor{0x142065E80}; WEAK symbol g_poolSize{0x140BF2E40}; + + WEAK symbol gfx_map{0x14EE49000}; + WEAK symbol comWorld{0x14AD26078}; WEAK symbol g_entities{0x1452DDDA0}; WEAK symbol g_clients{0x1455DA980}; @@ -241,6 +275,8 @@ namespace game WEAK symbol gfxDrawMethod{0x14EDF9E00}; WEAK symbol refdef{0x141BC2500}; + WEAK symbol tess{0x151854A30}; + WEAK symbol gfxCmdBufSourceState{0x151B65EA0}; WEAK symbol keyCatchers{0x14203F3C0}; @@ -254,7 +290,15 @@ namespace game WEAK symbol g_script_error{0x14BA9CD40}; WEAK symbol g_classMap{0x140BF95C0}; - WEAK symbol g_scriptmem{0x14CC9FEC0}; + WEAK game::symbol pmem_size{0x14CC9F458}; + WEAK game::symbol pmem_buffer{0x14CC9F450}; + + WEAK game::symbol g_mem{0x14CC9F460}; + WEAK game::symbol g_scriptmem{0x14CC9FEC0}; + WEAK game::symbol g_physmem{0x14CCA0920}; + + WEAK game::symbol stream_size{0x141865C90}; + WEAK game::symbol stream_buffer{0x141865C88}; WEAK symbol scr_VarGlob{0x14B617C00}; WEAK symbol scr_VmPub{0x14BA9EE40}; @@ -264,10 +308,17 @@ namespace game WEAK symbol g_fileSystem{0x1420B27E8}; + WEAK symbol db_hashTable{0x142250000}; + WEAK symbol g_assetEntryPool{0x143CBB140}; + WEAK symbol maps{0x14097EE90}; WEAK symbol languages{0x140BF9740}; + WEAK symbol sound_data{0x151B81A00}; + WEAK symbol volmod_index{0x151BADFD8}; + WEAK symbol music_dsp_bus_index{0x151B9AA40}; + namespace hks { WEAK symbol lua_state{0x1419D83E8}; diff --git a/src/client/launcher/window.cpp b/src/client/launcher/window.cpp index b9390612..59b004b4 100644 --- a/src/client/launcher/window.cpp +++ b/src/client/launcher/window.cpp @@ -3,6 +3,10 @@ #include +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + std::mutex window::mutex_; std::vector window::windows_; @@ -37,6 +41,10 @@ void window::create(const std::string& title, const int width, const int height, this->handle_ = CreateWindowExA(NULL, this->wc_.lpszClassName, title.data(), flags, x, y, width, height, nullptr, nullptr, this->wc_.hInstance, this); + BOOL value = TRUE; + DwmSetWindowAttribute(this->handle_, + DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); + SendMessageA(this->handle_, WM_DPICHANGED, 0, 0); } diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp index cc3437c5..fe702032 100644 --- a/src/client/loader/loader.cpp +++ b/src/client/loader/loader.cpp @@ -180,24 +180,25 @@ void loader::load_tls(const utils::nt::library& target, const utils::nt::library { if (source.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) { - auto* target_tls = tls::allocate_tls_index(); - /* target_tls = reinterpret_cast(library.get_ptr() + library.get_optional_header() - ->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); */ - auto* const source_tls = reinterpret_cast(target.get_ptr() + source.get_optional_header() + const auto target_tls = tls::allocate_tls_index(); + + const auto source_tls = reinterpret_cast(target.get_ptr() + source.get_optional_header() ->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); const auto tls_size = source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData; const auto tls_index = *reinterpret_cast(target_tls->AddressOfIndex); utils::hook::set(source_tls->AddressOfIndex, tls_index); - DWORD old_protect; - VirtualProtect(PVOID(target_tls->StartAddressOfRawData), - source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData, PAGE_READWRITE, - &old_protect); + const auto target_start = PVOID(target_tls->StartAddressOfRawData); + const auto source_start = PVOID(source_tls->StartAddressOfRawData); - auto* const tls_base = *reinterpret_cast(__readgsqword(0x58) + 8ull * tls_index); - std::memmove(tls_base, PVOID(source_tls->StartAddressOfRawData), tls_size); - std::memmove(PVOID(target_tls->StartAddressOfRawData), PVOID(source_tls->StartAddressOfRawData), tls_size); + DWORD old_protect; + VirtualProtect(target_start, tls_size, PAGE_READWRITE, &old_protect); + + const auto tls_base = *reinterpret_cast(__readgsqword(0x58) + 8ull * tls_index); + + std::memmove(tls_base, source_start, tls_size); + std::memmove(target_start, source_start, tls_size); VirtualProtect(target_tls, sizeof(*target_tls), PAGE_READWRITE, &old_protect); *target_tls = *source_tls; diff --git a/src/client/main.cpp b/src/client/main.cpp index 0c15e44b..9cff768c 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -24,7 +24,15 @@ FARPROC WINAPI get_proc_address(const HMODULE hModule, const LPCSTR lpProcName) { if (lpProcName == "InitializeCriticalSectionEx"s) { - component_loader::post_unpack(); + try + { + component_loader::post_unpack(); + } + catch (const std::exception& e) + { + MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR); + std::exit(1); + } } return GetProcAddress(hModule, lpProcName); @@ -125,10 +133,10 @@ FARPROC load_binary(const launcher::mode mode) return loader.load(self, data); #endif } + void remove_crash_file() { utils::io::remove_file("__h2Exe"); - utils::io::remove_file("h2_sp_patched.exe"); // remove this at some point } void verify_version() diff --git a/src/client/resource.hpp b/src/client/resource.hpp index b6a905e4..b6447e3b 100644 --- a/src/client/resource.hpp +++ b/src/client/resource.hpp @@ -12,3 +12,5 @@ #define LUI_UPDATER 304 #define LUA_JSON 305 + +#define DVAR_LIST 306 diff --git a/src/client/resource.rc b/src/client/resource.rc index 26d8709b..a660b369 100644 --- a/src/client/resource.rc +++ b/src/client/resource.rc @@ -102,6 +102,8 @@ LUI_UPDATER RCDATA "resources/ui_scripts/updater.lua" LUA_JSON RCDATA "resources/json.lua" +DVAR_LIST RCDATA "resources/dvar_list.json" + #ifdef _DEBUG TLS_DLL RCDATA "../../build/bin/x64/Debug/tlsdll.dll" #else diff --git a/src/client/resources/dvar_list.json b/src/client/resources/dvar_list.json new file mode 100644 index 00000000..20b58222 --- /dev/null +++ b/src/client/resources/dvar_list.json @@ -0,0 +1,10802 @@ +[ + [ + "ac_test_value", + "Test functionality" + ], + [ + "accessToSubscriberContent", + "Whether to display the subscriber maps." + ], + [ + "actionSlotsHide", + "Hide the actionslots." + ], + [ + "actor_spaceLightingOffset", + "Offset from a Space Actor's origin used to determine what lights effect this actor." + ], + [ + "actor_trace_bound_offset", + "Will offset the actor's hit box in the bullet trace logic." + ], + [ + "actorVisibilityCheckAngleDistMax", + "Distance above which we set angle to actorVisibilityMinCheckAngle." + ], + [ + "actorVisibilityCheckAngleDistMin", + "Distance below which we set angle to 90." + ], + [ + "actorVisibilityMinCheckAngle", + "Angle outside which we don't check for actor visibility." + ], + [ + "ai_accuracy_attackerCountDecrease", + "Accuracy multiplied by this number for each additional attacker upto ai_accuracy_attackerCountMax" + ], + [ + "ai_accuracy_attackerCountMax", + "Accuracy multiplied by ai_accuracy_attackerCountDecrease for each additional attacker upto this" + ], + [ + "ai_accuracyDistScale", + "Distance scale for AI accuracy calculations. Higher = less accurate" + ], + [ + "ai_allowOverTrim", + "Whether to allow trimming beyond the lookahead node, which should not be a safe action" + ], + [ + "ai_backtrackCheckPathDir", + "Whether to abort backtracking unless the offset to the current node aligns with that node's path dir" + ], + [ + "ai_badPathSpam", + "Write debugging information for a bad AI paths of suppressed actors. Non-suppressed actors will still print, but see ai_disableAllPathSpam" + ], + [ + "ai_badPlace_clearSeveredPath", + "If set, AI will have their path cleared if the first link runs through a bad place" + ], + [ + "ai_busyEventDistBullet", + "" + ], + [ + "ai_busyEventDistDeath", + "" + ], + [ + "ai_busyEventDistExplosion", + "" + ], + [ + "ai_busyEventDistFootstep", + "" + ], + [ + "ai_busyEventDistFootstepSprint", + "" + ], + [ + "ai_busyEventDistFootstepWalk", + "" + ], + [ + "ai_busyEventDistGrenadePing", + "" + ], + [ + "ai_busyEventDistGunShot", + "" + ], + [ + "ai_busyEventDistGunShotTeam", + "" + ], + [ + "ai_busyEventDistNewEnemy", + "" + ], + [ + "ai_busyEventDistPain", + "" + ], + [ + "ai_busyEventDistProjImpact", + "" + ], + [ + "ai_busyEventDistProjPing", + "" + ], + [ + "ai_busyEventDistSilencedShot", + "" + ], + [ + "ai_corpseCount", + "Scriptable maximum number of AI corpses" + ], + [ + "ai_corpseLimit", + "Archived maximum number of AI corpses - for PC config files" + ], + [ + "ai_count", + "Maximum number of AI" + ], + [ + "ai_coverScore_coverType", + "Cover node score used when weighting based on distance to node" + ], + [ + "ai_coverScore_dangerousNode", + "Cover node score used for nodes that are dangerous to use (someone died there). This value is subtracted" + ], + [ + "ai_coverScore_distance", + "Cover node score used when weighting based on distance to node" + ], + [ + "ai_coverScore_engagement", + "How much AI prefer cover nodes that are within the engagement distance ranges" + ], + [ + "ai_coverScore_nodeAngle", + "Cover node score used when weighting based on distance to node" + ], + [ + "ai_coverScore_playerLos", + "Cover node score used when weighting based on distance to node" + ], + [ + "ai_coverScore_priority", + "Cover node score used when weighting based on distance to node" + ], + [ + "ai_coverScore_targetDir", + "How strongly an AI will want to move to correct engagement distance" + ], + [ + "ai_coverScore_visibility", + "Cover node score used when weighting based on distance to node" + ], + [ + "ai_coverSearchInterval", + "AI cover search interval when the don't have cover, in milliseconds" + ], + [ + "ai_dangerReactGoalRadius", + "Goal radius to use when reacting to danger" + ], + [ + "ai_debugAccuracy", + "Enable debugging information for accuracy" + ], + [ + "ai_debugAnimDeltas", + "Display animation delta debug information" + ], + [ + "ai_debugCorpsePlant", + "Display debug information for AI corpse planting" + ], + [ + "ai_debugCoverEntityNum", + "Display debug info for cover" + ], + [ + "ai_debugCoverSelection", + "Enable debugging information for cover selection" + ], + [ + "ai_debugEngagementDist", + "Show the engagement distances for currently selected AI" + ], + [ + "ai_debugEntIndex", + "Entity index of an entity to debug" + ], + [ + "ai_debugFindPath", + "Display AI 'find path' debugging information" + ], + [ + "ai_debugFindPathDirect", + "Display AI 'find direct path' debugging information" + ], + [ + "ai_debugFindPathLock", + "Find path lock" + ], + [ + "ai_debugFindPathWidth", + "Display paths with the given width" + ], + [ + "ai_debugGrenadeFailSafe", + "Display grenade fail safe debug information" + ], + [ + "ai_debugGrenadeHintArc", + "Grenade hint arc in degrees" + ], + [ + "ai_debugGunBlocked", + "Show gun blocked by wall traces" + ], + [ + "ai_debugMayMove", + "Display debug information for AI 'may move' calculations" + ], + [ + "ai_debugMeleeAttackSpots", + "Enable debugging information for melee attack spots" + ], + [ + "ai_debugOverlay", + "Display AI debug overlay" + ], + [ + "ai_debugPlayerLOS", + "Debug information for AI staying out of player LOS" + ], + [ + "ai_debugTargetChange", + "Enable debugging information for target changes" + ], + [ + "ai_debugTargets", + "Show primary and secondary targets" + ], + [ + "ai_debugThreatSelection", + "Enable debugging information for threat selection" + ], + [ + "ai_debugVolume", + "Show volume entity" + ], + [ + "ai_disableAllPathSpam", + "Disable any ai path debugging information, even for non-suppressed actors" + ], + [ + "ai_disableSpawn", + "Do not spawn AI" + ], + [ + "ai_dodgeCheckPathDir", + "Whether to abort a dodge attempt if the path segment created between the dodge end node and the next regular path node goes against the path direction" + ], + [ + "ai_dog_sharpTurnAngleRun", + "Dog will always try a sharp-turn when running a turn at this min angle." + ], + [ + "ai_dropAkimboChance", + "Chance that an AI will drop akimbo weapons if available for the weapon" + ], + [ + "ai_eventDistBadPlace", + "" + ], + [ + "ai_eventDistBullet", + "" + ], + [ + "ai_eventDistDeath", + "" + ], + [ + "ai_eventDistExplosion", + "" + ], + [ + "ai_eventDistFootstep", + "" + ], + [ + "ai_eventDistFootstepSprint", + "" + ], + [ + "ai_eventDistFootstepWalk", + "" + ], + [ + "ai_eventDistGrenadePing", + "" + ], + [ + "ai_eventDistGunShot", + "" + ], + [ + "ai_eventDistGunShotTeam", + "" + ], + [ + "ai_eventDistNewEnemy", + "" + ], + [ + "ai_eventDistPain", + "" + ], + [ + "ai_eventDistProjImpact", + "" + ], + [ + "ai_eventDistProjPing", + "" + ], + [ + "ai_eventDistSilencedShot", + "" + ], + [ + "ai_foliageSeeThroughDist", + "Maximum distance AI ignore foliage for sight trace to targets" + ], + [ + "ai_friendlyFireBlockDuration", + "Friendly fire movement block duration" + ], + [ + "ai_friendlySuppression", + "Whether AI fire will suppression teammates or not." + ], + [ + "ai_friendlySuppressionDist", + "Max distance at which AI suppress teammates" + ], + [ + "ai_frontShieldDamageReduction", + "Non bullet damage reduction for AI with front shield getting hit within shield angle. (bullets do 0 damage if blocked by shield)" + ], + [ + "ai_grenadeReturn_approachMinDot", + "Minimal dot product between the approach and throw vectors to perform a grenade return" + ], + [ + "ai_grenadeReturn_debug", + "Turns on debug info for AI grenade returns" + ], + [ + "ai_grenadeReturn_extraFuseTime", + "The amount of time (in ms) to add to a grenade fuse when trying to return grenade that's below minFuseTime" + ], + [ + "ai_grenadeReturn_minDistSqr", + "Minimal distance to a grenade to consider it for a return so that transition anims will play" + ], + [ + "ai_grenadeReturn_minFuseTime", + "If the fuse time drops below this value when an ally is attempting to return a grenade, add extra fuse time" + ], + [ + "ai_grenadeReturn_stationary", + "If set, AI will attempt to return grenades that they are within pickup distance - regardless of min dist" + ], + [ + "ai_grenadeReturn_traceToGrenade", + "If set, AI will only attempt to return grenades when they have a clear sight trace to the grenade" + ], + [ + "ai_hardTurn_traceFromOrigin", + "Whether to trace from the origin or from the lookaheadPos when triggering a hard turn based on a future collision" + ], + [ + "ai_markDangerousNodes", + "If set, AI will mark nodes as dangerous when they're pinned down in cover or have been killed" + ], + [ + "ai_maxGrenadeThrowSpeed", + "Maximum AI grenade throw speed" + ], + [ + "ai_moveOrientMode", + "Debug AI Orient Mode" + ], + [ + "ai_noDodge", + "AI won't dodge to the side" + ], + [ + "ai_pathChokePointCost", + "The distance AI would travel around to randomly avoid going through a choke point." + ], + [ + "ai_pathLookaheadMinDistance", + "Minimum 2D valid distance to continue using the path lookahead position, otherwise it will uses a newly computed lookahead position" + ], + [ + "ai_pathMomentum", + "Momentum factor for continuing motion in previous direction. 0 for no momentum carry over" + ], + [ + "ai_pathNegotiationOverlapCost", + "The distance AI would travel around to randomly avoid going through a choke point." + ], + [ + "ai_pathRandomPercent", + "Amount of random cost percent to add to each path node so AI always take slightly different routes" + ], + [ + "ai_pathSmoothFromNoncodeMove", + "Whether to perform path smoothing when freshly transitioned from animation-driven motion to code movement" + ], + [ + "ai_pathSmoothFromStationary", + "Whether to perform path smoothing based on the actor's facing direction when movement begins for a stationary actor" + ], + [ + "ai_pathsmoothing", + "Toggle pathsmoothing on all AI." + ], + [ + "ai_playerADSTargetTime", + "Duration which the AI will not step in front of the player ADS'ing at a target (millisec)" + ], + [ + "ai_playerFarAccuracy", + "Accuracy for AI far away from the player" + ], + [ + "ai_playerFarRange", + "Minimum range for AI to use 'far' accuracy" + ], + [ + "ai_playerLOSHalfWidth", + "Friendly AI will try not to claim cover nodes in this width of player's line of sight" + ], + [ + "ai_playerLOSMinTime", + "Player line of sight effect will take effect after player is almost stationary for this time (millisec)" + ], + [ + "ai_playerLOSRange", + "Friendly AI will try not to claim cover nodes in this width of player's line of sight" + ], + [ + "ai_playerNearAccuracy", + "Accuracy for an AI near to a player" + ], + [ + "ai_playerNearRange", + "Maximum range for AI to use 'near' accuracy" + ], + [ + "ai_showAmbushNodes", + "Show ambush nodes AI is considering" + ], + [ + "ai_showBadPlaces", + "Display debug information for 'bad places'" + ], + [ + "ai_ShowCanshootChecks", + "Display debugging information for 'can shoot' checks" + ], + [ + "ai_showDodge", + "Display debug information for AI dodging" + ], + [ + "ai_showLastKnownEnemyPos", + "Shows the last known position of enemies" + ], + [ + "ai_showLikelyEnemyPathNode", + "Show likely enemy path node" + ], + [ + "ai_showNearbyNodes", + "Show nearby nodes" + ], + [ + "ai_showNearestNodes", + "Show nearest node of AI" + ], + [ + "ai_showNodes", + "Show AI navigation node debug information" + ], + [ + "ai_showNodesDist", + "Maximum distance from the camera at which AI nodes are shown" + ], + [ + "ai_showPathFindAnomalies", + "0 = off, 1 = show failsafe path anomalies(GREEN), 2 = show backtracking path anomalies(BLUE), 3 = show all anomalies" + ], + [ + "ai_showPathFindNodes", + "Show nodes consider in latest path find" + ], + [ + "ai_showPaths", + "Show AI navigation paths" + ], + [ + "ai_showPotentialThreatDir", + "Display AI potential threat direction" + ], + [ + "ai_showRegion", + "Draw all the cover in a volume for debugging" + ], + [ + "ai_showSuppression", + "Draw the suppression planes for this entity" + ], + [ + "ai_showTeamMove", + "Display debug information for AI team movement" + ], + [ + "ai_showVisData", + "Display debug information for visibility data" + ], + [ + "ai_showVisDataDist", + "Maximum distance for visibility data debugging information to be shown" + ], + [ + "ai_threatUpdateInterval", + "AI target threat update interval in milliseconds" + ], + [ + "ai_turnAnim_checkIntervalMinLookahead", + "Minimum lookaheadDist to check for turn anims on an interval - if the lookahead is shorter, turns will be checked for every frame" + ], + [ + "ai_turnAnim_defaultCheckIntervalDist", + "Base distance covered after a prediction trace failure to try another turn anim" + ], + [ + "ai_turnAnim_defaultCheckIntervalSpeed", + "Base speed used to scale the default check interval distance - faster speeds will check more frequently" + ], + [ + "ai_turnAnim_maxLookaheadDist", + "Maximum lookahead distance where an actor may consider performing a preemptive turn animation (because they're about to round a corner)" + ], + [ + "ai_turnAnim_minAfterTurnLookaheadDist", + "Minimum distance between the turn anim end point and the lookaheadPos" + ], + [ + "ai_turnAnim_newPathTurnMaxLookahead", + "Maximum lookahead where we will turn from the lookahead position to the next node; when the lookahead is above this threshold, just turn to face the lookahead (since the next node beyond it is so far away)" + ], + [ + "aim_accel_turnrate_debug", + "Turn on debugging info for the acceleration" + ], + [ + "aim_accel_turnrate_enabled", + "Enable/disable acceleration of the turnrates" + ], + [ + "aim_accel_turnrate_lerp", + "The acceleration of the turnrates" + ], + [ + "aim_aimAssistRangeScale", + "Scales the weapon's aim assist range" + ], + [ + "aim_autoaim_debug", + "Turn on auto aim debugging" + ], + [ + "aim_autoaim_enabled", + "Turn on auto aim" + ], + [ + "aim_autoaim_lerp", + "The rate in degrees per second that the auto aim will converge to its target" + ], + [ + "aim_autoaim_region_height", + "The height of the auto aim region in virtual screen coordinates(0-480)" + ], + [ + "aim_autoaim_region_width", + "The width of the auto aim region in virtual screen coordinates(0-640)" + ], + [ + "aim_autoAimRangeScale", + "Scales the weapon's auto aim range" + ], + [ + "aim_automelee_debug", + "Turn on auto melee debugging" + ], + [ + "aim_automelee_enabled", + "Turn on auto melee" + ], + [ + "aim_automelee_lerp", + "The rate in degrees per second that the auto aim will converge to its target" + ], + [ + "aim_automelee_range", + "The range of the auto melee" + ], + [ + "aim_automelee_region_height", + "The height of the auto melee region in virtual screen coordinates (0 - 480)" + ], + [ + "aim_automelee_region_width", + "The width of the auto melee region in virtual screen coordinates (0 - 640)" + ], + [ + "aim_input_graph_debug", + "Debug the view input graphs" + ], + [ + "aim_input_graph_enabled", + "Use graph for adjusting view input" + ], + [ + "aim_input_graph_index", + "Which input graph to use" + ], + [ + "aim_lockon_debug", + "Turn on debugging info for aim lock on" + ], + [ + "aim_lockon_deflection", + "The amount of stick deflection for the lockon to activate" + ], + [ + "aim_lockon_enabled", + "Aim lock on helps the player to stay on target" + ], + [ + "aim_lockon_region_height", + "The height of the auto aim region in virtual screen coordinates(0-480)" + ], + [ + "aim_lockon_region_width", + "The width of the auto aim region in virtual screen coordinates(0-640)" + ], + [ + "aim_lockon_strength", + "The amount of aim assistance given by the target lock on" + ], + [ + "aim_resist_pitch_enabled", + "Aim resist pitch applies resistance to the input at the edges of the view cone when the view cone is locked" + ], + [ + "aim_resist_view_threshold", + "The minimum input threshold to apply resistance to (0-1)" + ], + [ + "aim_resist_yaw_enabled", + "Aim resist yaw applies resistance to the input at the edges of the view cone when the view cone is locked" + ], + [ + "aim_scale_view_axis", + "Scale the influence of each input axis so that the major axis has more influence on the control" + ], + [ + "aim_slowdown_debug", + "Turn on debugging info for aim slowdown" + ], + [ + "aim_slowdown_enabled", + "Slowdown the turn rate when the cross hair passes over a target" + ], + [ + "aim_slowdown_pitch_scale", + "The vertical aim assist slowdown ratio from the hip" + ], + [ + "aim_slowdown_pitch_scale_ads", + "The vertical aim assist slowdown ratio from the hip" + ], + [ + "aim_slowdown_prioritization_crosshair_dist_prop", + "Auto aim prioritization - entities considered close if within this proportion of distance" + ], + [ + "aim_slowdown_prioritization_dist_prop", + "Auto aim prioritization - entities considered close if within this proportion of distance" + ], + [ + "aim_slowdown_prioritization_non_character_neg", + "Auto aim prioritization - amount of negation applied to non characters considered close to other entities" + ], + [ + "aim_slowdown_region_height", + "The screen height of the aim assist slowdown region" + ], + [ + "aim_slowdown_region_width", + "The screen width of the aim slowdown region" + ], + [ + "aim_slowdown_yaw_scale", + "The horizontal aim assist slowdown ratio from the hip" + ], + [ + "aim_slowdown_yaw_scale_ads", + "The horizontal aim assist slowdown ratio from the hip" + ], + [ + "aim_target_sentient_radius", + "The radius used to calculate target bounds for a sentient(actor or player)" + ], + [ + "aim_turnrate_pitch", + "The vertical turn rate for aim assist when firing from the hip" + ], + [ + "aim_turnrate_pitch_ads", + "The turn rate up and down for aim assist when aiming down the sight" + ], + [ + "aim_turnrate_yaw", + "The horizontal turn rate for aim assist when firing from the hip" + ], + [ + "aim_turnrate_yaw_ads", + "The horizontal turn rate for aim assist when firing from the hip" + ], + [ + "airburstAdjustDistance", + "Distance to append to airburst locked in distance." + ], + [ + "ammoCounterHide", + "Hide the Ammo Counter" + ], + [ + "arcademode", + "arcade mode" + ], + [ + "arcademode_full", + "arcade mode full" + ], + [ + "arcademode_lives", + "arcade mode lives" + ], + [ + "armory_contentpacks_enabled", + "Allowed armory content packs. 0: none , 1: first armory content pack enabled, 2: first and second armory content pack enabled" + ], + [ + "autobolt_explosions_to_vehicles", + "Turns on system to automatically bolt explosions to vehicles. Used for chase scenes." + ], + [ + "autoexit", + "Time to spend in match before shutting down the exe (in ms)." + ], + [ + "automatedTester", + "Whether we are currently running an automated tester." + ], + [ + "avi_DontUseMemcardStorage", + "Prevent usage of local mem cards for avi rendering and uploading" + ], + [ + "band_12players", + "12 player bandwidth req'd" + ], + [ + "band_18players", + "18 player bandwidth req'd" + ], + [ + "band_2players", + "2 player bandwidth req'd" + ], + [ + "band_4players", + "4 player bandwidth req'd" + ], + [ + "band_8players", + "8 player bandwidth req'd" + ], + [ + "bg_aimSpreadMoveSpeedThreshold", + "When player is moving faster than this speed, the aim spread will increase" + ], + [ + "bg_allowScuffFootsteps", + "If true, scuff sounds will be played when the player rotates in place." + ], + [ + "bg_animUnspeedScaledDuration", + "How long into the start of a speed_scaled_transition anim that speed scaling should be ignored." + ], + [ + "bg_audioHeatLevelHighThreshold", + "Minimum heat level to start playing the high heat start/loop/stop fire sounds." + ], + [ + "bg_audioHeatLevelMedThreshold", + "Minimum heat level to start playing the high heat start/loop/stop fire sounds." + ], + [ + "bg_bulletExplDmgFactor", + "Weapon damage multiplier that will be applied at the center of the slash damage area." + ], + [ + "bg_bulletExplRadius", + "The radius of the bullet splash damage, where the damage gradually falls off to 0." + ], + [ + "bg_checkPlayerOutsideSolid", + "Turn on assert that player is outside collision" + ], + [ + "bg_compassShowEnemies", + "Whether enemies are visible on the compass at all times" + ], + [ + "bg_debugProne", + "Show prone debug information" + ], + [ + "bg_fallDamageMaxHeight", + "The height that a player will take maximum damage when falling" + ], + [ + "bg_fallDamageMinHeight", + "The height that a player will start to take minimum damage if they fall" + ], + [ + "bg_foliagesnd_fastinterval", + "The time between each foliage sound when moving slowly" + ], + [ + "bg_foliagesnd_maxspeed", + "The speed that a player must be going to make minimum noise while moving through foliage" + ], + [ + "bg_foliagesnd_minspeed", + "The speed that a player must be going to make minimum noise while moving through foliage" + ], + [ + "bg_foliagesnd_resetinterval", + "The time interval before foliage sounds are reset after the player has stopped moving" + ], + [ + "bg_foliagesnd_slowinterval", + "The time between each foliage sound when moving slowly" + ], + [ + "bg_forceDualWield", + "Force akimbo for all possible weapons" + ], + [ + "bg_forceExplosiveBullets", + "When set, all bullet weapons will fire explosive rounds (Simulates Perk)" + ], + [ + "bg_ladder_yawcap", + "The maximum angle that a player can look around while on a ladder" + ], + [ + "bg_landFXLightHeight", + "The max height that a player will play light land FX and camera shakes" + ], + [ + "bg_landFXMediumHeight", + "The max height that a player will play light land FX and camera shakes" + ], + [ + "bg_lowGravity", + "Low gravity for slow or floaty objects, in inches per second per second" + ], + [ + "bg_maxGrenadeIndicatorSpeed", + "Maximum speed of grenade that will show up in indicator and can be thrown back." + ], + [ + "bg_prone_yawcap", + "The maximum angle that a player can look around while on a ladder" + ], + [ + "bg_radiusDamageMax", + "The maximum radius damage radius for non-client and non-actor entities" + ], + [ + "bg_shieldHitEncodeHeightVM", + "The decoding range, in height, of a client's viewmodel shield." + ], + [ + "bg_shieldHitEncodeHeightWorld", + "The encoding range, in height, of a client's world shield. A hit in this range is encoded into one of 8 rows." + ], + [ + "bg_shieldHitEncodeWidthVM", + "The decoding range, in width, of a client's viewmodel shield." + ], + [ + "bg_shieldHitEncodeWidthWorld", + "The encoding range, in width, of a client's world shield. A hit in this range is encoded into one of 16 collumns." + ], + [ + "bg_shock_lookControl", + "Alter player control during shellshock" + ], + [ + "bg_shock_lookControl_fadeTime", + "The time for the shellshock player control to fade in seconds" + ], + [ + "bg_shock_lookControl_maxpitchspeed", + "Maximum pitch movement rate while shellshocked in degrees per second" + ], + [ + "bg_shock_lookControl_maxyawspeed", + "Maximum yaw movement rate while shell shocked in degrees per second" + ], + [ + "bg_shock_lookControl_mousesensitivityscale", + "Sensitivity scale to apply to a shellshocked player" + ], + [ + "bg_shock_movement", + "Affect player's movement speed duringi shellshock" + ], + [ + "bg_shock_screenBlurBlendFadeTime", + "The amount of time in seconds for the shellshock effect to fade" + ], + [ + "bg_shock_screenBlurBlendTime", + "The amount of time in seconds for the shellshock effect to fade" + ], + [ + "bg_shock_screenFlashShotFadeTime", + "In seconds, how soon from the end of the effect to start blending out the whiteout layer." + ], + [ + "bg_shock_screenFlashWhiteFadeTime", + "In seconds, how soon from the end of the effect to start blending out the whiteout layer." + ], + [ + "bg_shock_screenType", + "Shell shock screen effect type" + ], + [ + "bg_shock_sound", + "Play shell shock sound" + ], + [ + "bg_shock_soundDryLevel", + "Shell shock sound dry level" + ], + [ + "bg_shock_soundEnd", + "Shellshock end sound alias" + ], + [ + "bg_shock_soundEndAbort", + "Shellshock aborted end sound alias" + ], + [ + "bg_shock_soundFadeInTime", + "Shell shock sound fade in time in seconds" + ], + [ + "bg_shock_soundFadeOutTime", + "Shell shock sound fade out time in seconds" + ], + [ + "bg_shock_soundLoop", + "Shellshock loop alias" + ], + [ + "bg_shock_soundLoopEndDelay", + "Sound loop end offset time from the end of the shellshock in seconds" + ], + [ + "bg_shock_soundLoopFadeTime", + "Shell shock sound loop fade time in seconds" + ], + [ + "bg_shock_soundLoopSilent", + "The sound that gets blended with the shellshock loop alias" + ], + [ + "bg_shock_soundModEndDelay", + "The delay from the end of the shell shock to the end of the sound modification" + ], + [ + "bg_shock_soundRoomType", + "Shell shock sound reverb room type" + ], + [ + "bg_shock_soundSubmix", + "Shell shock submix to apply" + ], + [ + "bg_shock_soundWetLevel", + "Shell shock sound wet level" + ], + [ + "bg_shock_viewKickFadeTime", + "The time for the shellshock kick effect to fade" + ], + [ + "bg_shock_viewKickPeriod", + "The period of the shellshock view kick effect" + ], + [ + "bg_shock_viewKickRadius", + "Shell shock kick radius" + ], + [ + "bg_softLandingMaxDamage", + "The max amount of damage (as % of max health) if soft landing is in effect" + ], + [ + "bg_softLandingMaxHeight", + "The height that a player will start to take minimum damage if they fall" + ], + [ + "bg_softLandingMinHeight", + "The height that a player will start to take minimum damage if they fall" + ], + [ + "bg_viewBobAmplitudeBase", + "The base speed-based view bob amplitude" + ], + [ + "bg_viewBobAmplitudeRoll", + "The amplitude applied to the roll for view bobbing" + ], + [ + "bg_viewBobMax", + "The maximum allowed bob amplitude" + ], + [ + "bg_viewBobMocap", + "Use new mocap motion for viewmodel bob" + ], + [ + "bg_viewKickMax", + "The maximum view kick" + ], + [ + "bg_viewKickMin", + "The minimum view kick" + ], + [ + "bg_viewKickRandom", + "The random direction scale view kick" + ], + [ + "bg_viewKickScale", + "The scale to apply to the damage done to calculate damage view kick" + ], + [ + "bg_weaponBobAmplitudeBase", + "The base speed-based weapon bob amplitude" + ], + [ + "bg_weaponBobAmplitudeRoll", + "The amplitude applied to the roll for weapon bobbing" + ], + [ + "bg_weaponBobLag", + "The lag that will be applied the weapon bob cycle" + ], + [ + "bg_weaponBobMax", + "The maximum allowed weapon/viewmodel bob amplitude" + ], + [ + "bullet_penetration_damage", + "When false, bullets that have penetrated an object will not do damage to AI." + ], + [ + "bullet_penetration_enabled", + "When false, disables bullet penetration completely." + ], + [ + "bullet_penetrationActorHitsActors", + "When false, bullets shot by actors that have penetrated an object will not do damage to other actors." + ], + [ + "bullet_penetrationHitsClients", + "When false, bullets that have penetrated an object will not do damage to AI." + ], + [ + "bullet_penetrationMinFxDist", + "Min distance a penetrated bullet must travel before it'll trigger the effects" + ], + [ + "bullet_ricochetBaseChance", + "The base chance a bullet has of ricocheting off of a riot shield." + ], + [ + "ca_auto_signin", + "CoD Anywhere start sign-in task automatically on startup or first party sign-in" + ], + [ + "ca_do_mlc", + "CoD Anywhere Do Multi Login check" + ], + [ + "ca_intra_only", + "CoD Anywhere Intra Network Only" + ], + [ + "ca_require_signin", + "CoD Anywhere require sign in to enter MP" + ], + [ + "ca_show_signup_request", + "CoD Anywhere should you show new users a popup requesting they create a CoD Account?" + ], + [ + "cameraShakeRemoteHelo_Angles", + "Remote helicopter gunner cam, range to shake the view." + ], + [ + "cameraShakeRemoteHelo_Freqs", + "Remote helicopter gunner cam, how fast to shake." + ], + [ + "cameraShakeRemoteHelo_SpeedRange", + "Remote helicopter gunner cam, range of missile speed to scale the shaking." + ], + [ + "cameraShakeRemoteMissile_Angles", + "Remote missile-cam, range to shake the view." + ], + [ + "cameraShakeRemoteMissile_Freqs", + "Remote missile-cam, how fast to shake." + ], + [ + "cameraShakeRemoteMissile_SpeedRange", + "Remote missile-cam, range of missile speed to scale the shaking." + ], + [ + "capturePlaybackDisableSRE", + "Disable the SRE pop up." + ], + [ + "cg_autosimAllowVariableTime", + "Allow the weapon to do speed up and slow down timing." + ], + [ + "cg_autosimFireSpeedScale", + "1.0: normal speed, 2.0: 200%% speed, 0.5: 50%% speed" + ], + [ + "cg_autosimMinWeaponSpeed", + "Minimum distance between autosimmed weapon shots" + ], + [ + "cg_autosimStopPreviousShot", + "Always try to stop the previous autosim shot" + ], + [ + "cg_blood", + "Show blood effects" + ], + [ + "cg_bloodLimit", + "Limit blood effects (to 'prevent excess blood stacking')" + ], + [ + "cg_bloodLimitMsec", + "When limiting blood effects, number of milliseconds between effects." + ], + [ + "cg_bloodThickColor", + "Color of the blood overlay's thick blood splatter" + ], + [ + "cg_bloodThinColor", + "Color of the blood overlay's thin blood splatter" + ], + [ + "cg_brass", + "Weapons eject brass" + ], + [ + "cg_breathingSoundLvl1Cutoff", + "" + ], + [ + "cg_breathingSoundLvl2Cutoff", + "" + ], + [ + "cg_breathingSoundsEnabled", + "Enable sprint breathing sounds." + ], + [ + "cg_bulletForce", + "Force applied from bullet hit" + ], + [ + "cg_camAngleOffset", + "Pitch, Yaw, and Roll offsets in degrees" + ], + [ + "cg_camAngleOverride", + "If true angle offsets override the actual view angles instead of modifying them." + ], + [ + "cg_camOffset", + "Position offset" + ], + [ + "cg_centertime", + "The time for a center printed message to fade" + ], + [ + "cg_cinematicCanPause", + "Ingame cinematics can be paused" + ], + [ + "cg_cinematicFullscreen", + "Draw ingame cinematics full screen" + ], + [ + "cg_ColorBlind_EnemyTeam", + "Enemy team color for color blind people" + ], + [ + "cg_ColorBlind_MyTeam", + "Player team color for color blind people" + ], + [ + "cg_constantSizeHeadIcons", + "Head icons are the same size regardless of distance from the player" + ], + [ + "cg_crawlBlendOutTimeFiring", + "Milleseconds to blend out of crawl anims to firing weapon" + ], + [ + "cg_crawlBlendTime", + "Milleseconds to blend in and out of crawl anims" + ], + [ + "cg_crawlMaxSpeed", + "At this speed, the crawl anim will play at an anim rate of 1" + ], + [ + "cg_crawlMinSpeed", + "Minimum speed before player will start crawl anim" + ], + [ + "cg_crosshairAlpha", + "The alpha value of the crosshair" + ], + [ + "cg_crosshairAlphaMin", + "The minimum alpha value of the crosshair when it fades in" + ], + [ + "cg_crosshairDynamic", + "Crosshair is Dynamic" + ], + [ + "cg_crosshairEnemyColor", + "The crosshair color when over an enemy" + ], + [ + "cg_crosshairVerticalOffset", + "Amount to vertically offset the crosshair from the center." + ], + [ + "cg_cullBulletAngle", + "Cull bullet trajectories that don't fall within this fov" + ], + [ + "cg_cullBullets", + "Whether to cull bullet fire prediction if trajectory doesn't pass your view or anywhere near you" + ], + [ + "cg_cursorHints", + "Draw cursor hints where:\n 0: no hints" + ], + [ + "cg_damageIndicatorMinAngleDiffMax", + "" + ], + [ + "cg_damageIndicatorMinAngleDiffMin", + "" + ], + [ + "cg_debug_overlay_viewport", + "Remove the sniper overlay so you can check that the scissor window is correct." + ], + [ + "cg_debugDrawHandDragInfo", + "Draw info about hand drag when swimming" + ], + [ + "cg_debugDrawHitBox", + "Display character hit boxes" + ], + [ + "cg_debugevents", + "Output event debug information. EV_NONE turns it off. EV_MAX_EVENTS shows all events. Otherwise, show only specified value." + ], + [ + "cg_debugInfoCornerOffset", + "Offset from top-right corner, for cg_drawFPS, etc" + ], + [ + "cg_debugLookAt", + "Debug look at information" + ], + [ + "cg_disableScreenShake", + "Turns off screen shakes when turned on. Dev-only" + ], + [ + "cg_dobjdump", + "Output dobj info for the given entity id" + ], + [ + "cg_draw2D", + "Draw 2D screen elements" + ], + [ + "cg_drawBreathHint", + "Draw a 'hold breath to steady' hint" + ], + [ + "cg_drawBuildName", + "Draw build name" + ], + [ + "cg_drawCenterLines", + "Draw a horizontal line and a vertical line through the center of the screen" + ], + [ + "cg_drawCrosshair", + "Turn on weapon crosshair" + ], + [ + "cg_drawDamageDirection", + "Draw hit direction arrow." + ], + [ + "cg_drawDamageFlash", + "Draw flash when hit." + ], + [ + "cg_drawDebugAudioClientTriggers", + "Display client side trigger audio debug information" + ], + [ + "cg_drawDebugBones", + "Draw bones for entity number." + ], + [ + "cg_drawDebugBonesBind", + "Draw bind pose when drawing bones with cg_drawDebugBones." + ], + [ + "cg_drawDebugBonesClosest", + "updates cg_drawDebugBones to closest entity to camera." + ], + [ + "cg_drawDebugClientTriggers", + "Display client side trigger debug information" + ], + [ + "cg_drawDebugTags", + "Draw tags for entity number." + ], + [ + "cg_drawDebugVisionClientTriggers", + "Display client side trigger vision debug information" + ], + [ + "cg_drawEffectNum", + "Draw counts of effects and elements" + ], + [ + "cg_drawFPS", + "Draw frames per second" + ], + [ + "cg_drawFPSLabels", + "Draw FPS Info Labels" + ], + [ + "cg_drawFriendlyFireCrosshair", + "draw the friendly fire crosshair (friendly move)" + ], + [ + "cg_drawGun", + "Draw the view model" + ], + [ + "cg_drawHealth", + "Draw health bar" + ], + [ + "cg_drawHUD", + "Draw HUD elements" + ], + [ + "cg_drawImagecache", + "Draw imagecache/streaming state" + ], + [ + "cg_drawMantleHint", + "Draw a 'press key to mantle' hint" + ], + [ + "cg_drawMapBuildInfo", + "Draw timestamps and command line options from the compile process" + ], + [ + "cg_drawMapBuildInfoX", + "X offset for the BSP debug info string" + ], + [ + "cg_drawMapBuildInfoY", + "Y offset for the BSP debug info string" + ], + [ + "cg_drawMaterial", + "Draw debugging information for materials" + ], + [ + "cg_drawpaused", + "Draw paused screen" + ], + [ + "cg_drawPlayerBoundingBox", + "Draw a red bounding box at player's server position" + ], + [ + "cg_drawPlayerPosInFreeMove", + "Draw an orange box at the player's pos in noclip/ufo." + ], + [ + "cg_drawrumbledebug", + "Display rumble debug information" + ], + [ + "cg_drawScriptUsage", + "Draw debugging information for scripts" + ], + [ + "cg_drawShellshock", + "Draw shellshock & flashbang screen effects." + ], + [ + "cg_drawTransients", + "Draw transient fastfile state" + ], + [ + "cg_drawTurretCrosshair", + "Draw a cross hair when using a turret" + ], + [ + "cg_drawVersion", + "Draw the game version" + ], + [ + "cg_drawVersionX", + "X offset for the version string" + ], + [ + "cg_drawVersionY", + "Y offset for the version string" + ], + [ + "cg_drawViewpos", + "Draw viewpos" + ], + [ + "cg_dumpAnims", + "Output animation info for the given entity id" + ], + [ + "cg_dumpAnimsToScreen", + "Output animation info for the given entity id" + ], + [ + "cg_dumpAnimsToScreenAllNodes", + "Show all animations for cg_dumpAnimsToScreen entity, even if the animation has no weight." + ], + [ + "cg_enableWaterSurfaceTransitionFx", + "Turns on water surface transition fx system." + ], + [ + "cg_equipmentSounds", + "Play equipment sounds" + ], + [ + "cg_errordecay", + "Decay for predicted error" + ], + [ + "cg_explodeForce", + "Force applied from explosion hit" + ], + [ + "cg_explodeMinForce", + "Force below which dynents won't even bother waking up" + ], + [ + "cg_explodeSpinScale", + "Scale of the random offset from the center of mass for explosion forces." + ], + [ + "cg_explodeUpbias", + "Upward bias applied to force directions from explosion hits" + ], + [ + "cg_explodingBulletForce", + "Force applied from bullet explosion hit" + ], + [ + "cg_explodingBulletMinForce", + "Force below which dynents won't even bother waking up" + ], + [ + "cg_explodingBulletSpinScale", + "Scale of the random offset from the center of mass for explosion forces." + ], + [ + "cg_explodingBulletUpbias", + "Upward bias applied to force directions from explosion hits" + ], + [ + "cg_foliagesnd_alias", + "The sound that plays when an actor or player enters a foliage clip brush." + ], + [ + "cg_followEnt", + "Entity number to follow when in cg_ufo" + ], + [ + "cg_footsteps", + "Play footstep sounds that are NOT sprint" + ], + [ + "cg_footstepsSprint", + "Play sprint footstep sounds" + ], + [ + "cg_fov", + "The field of view angle in degrees for client 0" + ], + [ + "cg_fov1", + "The field of view angle in degrees for client 0" + ], + [ + "cg_fovMin", + "The minimum possible field of view" + ], + [ + "cg_fovNonVehAdd", + "The field of view angle added in degrees when not in a vehicle" + ], + [ + "cg_fovScale", + "Scale applied to the field of view" + ], + [ + "cg_gameBoldMessageWidth", + "The maximum character width of the bold game messages" + ], + [ + "cg_gameMessageWidth", + "The maximum character width of the game messages" + ], + [ + "cg_gun_x", + "Forward position of the viewmodel" + ], + [ + "cg_gun_y", + "Right position of the viewmodel" + ], + [ + "cg_gun_z", + "Up position of the viewmodel" + ], + [ + "cg_headIconMinScreenRadius", + "The minumum radius of a head icon on the screen" + ], + [ + "cg_hintFadeTime", + "Time in milliseconds for the cursor hint to fade" + ], + [ + "cg_hudDamageIconHeight", + "The height of the damage icon" + ], + [ + "cg_hudDamageIconInScope", + "Draw damage icons when aiming down the sight of a scoped weapon" + ], + [ + "cg_hudDamageIconOffset", + "The offset from the center of the damage icon" + ], + [ + "cg_hudDamageIconOverlayTime", + "The amount of time (in ms) for the overlay portion of the damage icon to stay on screen" + ], + [ + "cg_hudDamageIconStartFadeTime", + "The amount of time (in ms) before the damage icon begins to fade" + ], + [ + "cg_hudDamageIconTime", + "The total amount of time (in ms) for the damage icon to stay on screen after damage is taken" + ], + [ + "cg_hudDamageIconWidth", + "The width of the damage icon" + ], + [ + "cg_hudGrenadeIconEnabledFlash", + "Show the grenade indicator for flash grenades" + ], + [ + "cg_hudGrenadeIconHeight", + "The height of the grenade indicator icon" + ], + [ + "cg_hudGrenadeIconInScope", + "Show the grenade indicator when aiming down the sight of a scoped weapon" + ], + [ + "cg_hudGrenadeIconMaxRangeFlash", + "The maximum distance that a flashbang can be from a player in order to be shown on the grenade indicator" + ], + [ + "cg_hudGrenadeIconMaxRangeFrag", + "The maximum distance that a grenade can be from a player in order to be shown on the grenade indicator" + ], + [ + "cg_hudGrenadeIconOffset", + "The offset from the center of the screen for a grenade icon" + ], + [ + "cg_hudGrenadeIconWidth", + "The width of the grenade indicator icon" + ], + [ + "cg_hudGrenadePointerHeight", + "The height of the grenade indicator pointer" + ], + [ + "cg_hudGrenadePointerPivot", + "The pivot point of th grenade indicator pointer" + ], + [ + "cg_hudGrenadePointerPulseFreq", + "The number of times per second that the grenade indicator flashes in Hertz" + ], + [ + "cg_hudGrenadePointerPulseMax", + "The maximum alpha of the grenade indicator pulse. Values higher than 1 will cause the indicator to remain at full brightness for longer" + ], + [ + "cg_hudGrenadePointerPulseMin", + "The minimum alpha of the grenade indicator pulse. Values lower than 0 will cause the indicator to remain at full transparency for longer" + ], + [ + "cg_hudGrenadePointerWidth", + "The width of the grenade indicator pointer" + ], + [ + "cg_hudLighting_basic_additiveLumOffset", + "[basic] Offset applied to additive light color." + ], + [ + "cg_hudLighting_basic_additiveLumScale", + "[basic] Scale applied to additive light color." + ], + [ + "cg_hudLighting_basic_ambientLumOffset", + "[basic] Offset applied to ambient light color." + ], + [ + "cg_hudLighting_basic_ambientLumScale", + "[basic] Scale applied to ambient light color." + ], + [ + "cg_hudLighting_basic_diffuseLumOffset", + "[basic] Offset applied to diffuse light color." + ], + [ + "cg_hudLighting_basic_diffuseLumScale", + "[basic] Scale applied to diffuse light color." + ], + [ + "cg_hudLighting_basic_specExponent", + "[basic] Specular exponent. Higher values result in sharper highlights." + ], + [ + "cg_hudLighting_basic_specLumOffset", + "[basic] Offset applied to spec light luminance." + ], + [ + "cg_hudLighting_basic_specLumScale", + "[basic] Scale applied to spec light luminance." + ], + [ + "cg_hudLighting_blood_additiveLumOffset", + "[blood] Offset applied to additive light color." + ], + [ + "cg_hudLighting_blood_additiveLumScale", + "[blood] Scale applied to additive light color." + ], + [ + "cg_hudLighting_blood_ambientLumOffset", + "[blood] Offset applied to ambient light color." + ], + [ + "cg_hudLighting_blood_ambientLumScale", + "[blood] Scale applied to ambient light color." + ], + [ + "cg_hudLighting_blood_diffuseLumOffset", + "[blood] Offset applied to diffuse light color." + ], + [ + "cg_hudLighting_blood_diffuseLumScale", + "[blood] Scale applied to diffuse light color." + ], + [ + "cg_hudLighting_blood_specExponent", + "[blood] Specular exponent. Higher values result in sharper highlights." + ], + [ + "cg_hudLighting_blood_specLumOffset", + "[blood] Offset applied to spec light luminance." + ], + [ + "cg_hudLighting_blood_specLumScale", + "[blood] Scale applied to spec light luminance." + ], + [ + "cg_hudLighting_fadeSharpness", + "This controls how sharp the lines are when fading using the mask alpha. Higher values are sharper." + ], + [ + "cg_hudMapBorderWidth", + "The size of the full map's border, filled by the CG_PLAYER_FULLMAP_BORDER ownerdraw" + ], + [ + "cg_hudMapFriendlyHeight", + "" + ], + [ + "cg_hudMapFriendlyWidth", + "" + ], + [ + "cg_hudMapPlayerHeight", + "" + ], + [ + "cg_hudMapPlayerWidth", + "" + ], + [ + "cg_hudMapRadarLineThickness", + "Thickness, relative to the map width, of the radar texture that sweeps across the full screen map" + ], + [ + "cg_hudStanceFlash", + "The background color of the flash when the stance changes" + ], + [ + "cg_hudStanceHintPrints", + "Draw helpful text to say how to change stances" + ], + [ + "cg_invalidCmdHintBlinkInterval", + "Blink rate of an invalid command hint" + ], + [ + "cg_invalidCmdHintDuration", + "Duration of an invalid command hint" + ], + [ + "cg_jumpADSShakeReductionMax", + "Max percentage that ADS can reduce jump/land additive anims" + ], + [ + "cg_landingSounds", + "Play landing on surface sounds" + ], + [ + "cg_mantleSounds", + "Play mantle equipment sounds" + ], + [ + "cg_mapLocationSelectionCursorSpeed", + "Speed of the cursor when selecting a location on the map" + ], + [ + "cg_marks_ents_player_only", + "Marks on entities from player's bullets only." + ], + [ + "cg_minCullBulletDist", + "Don't cull bullet trajectories that are within this distance to you." + ], + [ + "cg_modPrvDrawAxis", + "Draw Axes in the model previewer" + ], + [ + "cg_modPrvMruAnims", + "" + ], + [ + "cg_modPrvMruModels", + "" + ], + [ + "cg_objectiveListWrapCountStandard", + "The amount of on-screen length to wrap an objective in wide-screen mode" + ], + [ + "cg_objectiveListWrapCountWidescreen", + "The amount of on-screen length to wrap an objective in wide-screen mode" + ], + [ + "cg_player_shield_quickraise_override", + "Overrides all weapon quickraise state timers after using exo-shield. 0 disables the override." + ], + [ + "cg_playerCollideWithPhysics", + "Enable player collision with client-side physics objects." + ], + [ + "cg_playerFovScale0", + "Scale applied to player 0 field of view" + ], + [ + "cg_playerFovScale1", + "Scale applied to player 1 field of view" + ], + [ + "cg_rumble_devgui_duration", + "Duration of rumble" + ], + [ + "cg_rumble_devgui_loop", + "Enable a looping rumble" + ], + [ + "cg_scriptIconSize", + "Size of Icons defined by script" + ], + [ + "cg_shoulderFollowEnt", + "When set to true follow the ent set in cg_followEnt in a fixed position, over the shoulder cam." + ], + [ + "cg_shoulderFollowOffsets", + "Set the offsets for the shoulder cam. Usage cg_shoulderFollowOffsets [dist] [height]" + ], + [ + "cg_showmiss", + "Show prediction errors" + ], + [ + "cg_silencedWeaponPingRangeSquared", + "Square of the range at which the firing of a silenced weapon will ping on the compass." + ], + [ + "cg_skipDObjFilterIntoCells", + "Skips CPU logic to push entities into visible set cells. Helps situations where there are large amounts of moving entities that are mostly visible." + ], + [ + "cg_small_dev_string_fontscale", + "Font scale for a small development only display string" + ], + [ + "cg_sprintMeterDisabledColor", + "The color of the sprint meter when the sprint meter is full" + ], + [ + "cg_sprintMeterEmptyColor", + "The color of the sprint meter when the sprint meter is full" + ], + [ + "cg_sprintMeterFullColor", + "The color of the sprint meter when the sprint meter is full" + ], + [ + "cg_subtitleMinTime", + "The minimum time that the subtitles are displayed on screen in seconds" + ], + [ + "cg_subtitleWidthStandard", + "The width of the subtitles on a non wide-screen" + ], + [ + "cg_subtitleWidthWidescreen", + "The width of the subtitle on a wide-screen" + ], + [ + "cg_testVar", + "For random development usage." + ], + [ + "cg_traceProfilingDist", + "If non-negative then length of trace from camera to measure cost of CG_LocationalTrace." + ], + [ + "cg_vectorFieldsDraw", + "Enables debug drawing of vector field instances. (0=off, 1=no depth test, 2=depth test)" + ], + [ + "cg_vectorFieldsForceUniform", + "Forces all vector field assets to represent a single, uniform direction" + ], + [ + "cg_viewmodelAnimatedCrawl", + "Toggle anim play viewmodel crawl anims rather than procedural" + ], + [ + "cg_viewmodelAnimatedJumps", + "Toggle anim play viewmodel jump anims rather than procedural" + ], + [ + "cg_viewmodelAnimBlending", + "Toggle anim blending for viewmodel anims" + ], + [ + "cg_viewVehicleInfluence", + "The influence on the view angles from being in a vehicle" + ], + [ + "cg_viewZSmoothingMax", + "Threshold for the maximum smoothing distance we'll do" + ], + [ + "cg_viewZSmoothingMin", + "Threshold for the minimum smoothing distance it must move to smooth" + ], + [ + "cg_viewZSmoothingTime", + "Amount of time to spread the smoothing over" + ], + [ + "cg_waterSheeting_distortionScaleFactor", + "Distortion uv scales (Default to 1)" + ], + [ + "cg_waterSheeting_magnitude", + "Distortion magnitude" + ], + [ + "cg_waterSheeting_radius", + "Tweak dev var; Glow radius in pixels at 640x480" + ], + [ + "cg_waterSurfaceTransition_BlockingFxMoveRate", + "Rate at which the surface blocking efx moves across the screen." + ], + [ + "cg_waterSurfaceTransition_FastVelocityThreshold", + "Water surface transitions at velocities above this threshold are considered fast." + ], + [ + "cg_waterSurfaceTransition_TransitionDepthTop", + "Upper-bound of the depth over which the surface blocking efx is on screen." + ], + [ + "cg_waterSurfaceTransition_VisionBlendBottom", + "Lower-bound of the depth over which underwater vision set blends in." + ], + [ + "cg_waterSurfaceTransition_VisionBlendTop", + "Upper-bound of the depth over which underwater vision set blends in." + ], + [ + "cg_weapHitCullAngle", + "Angle of cone within which to cull back facing weapon hit effects" + ], + [ + "cg_weapHitCullEnable", + "When true, cull back facing weapon hit fx." + ], + [ + "cg_weaponCycleDelay", + "The delay after cycling to a new weapon to prevent holding down the cycle weapon button from cycling too fast" + ], + [ + "cg_weaponHintsCoD1Style", + "Draw weapon hints in CoD1 style: with the weapon name, and with the icon below" + ], + [ + "chaplinCheat", + "" + ], + [ + "cl_accessibilityAkimboEnabled", + "True if accessibility configurations adjust input for akimbo weapons" + ], + [ + "cl_accessibilityTurboEnabled", + "True if accessibility configurations do continuous fire for akimbo weapons" + ], + [ + "cl_analog_attack_threshold", + "The threshold before firing" + ], + [ + "cl_anglespeedkey", + "Multiplier for max angle speed for gamepad and keyboard" + ], + [ + "cl_cinematicUnpaused", + "Allows cinematics to play while the client is paused" + ], + [ + "cl_dirSelConvergenceTime", + "Time to converge to the new direction when selecting a direction on the map." + ], + [ + "cl_disable_pause", + "Disable Pause" + ], + [ + "cl_force_paused", + "Force the client to be paused. Can't be overridden by LUA scripts, the start button, etc." + ], + [ + "cl_forceFoVEnabled", + "Force a modified FoV calculation for capture" + ], + [ + "cl_forceFoVx", + "Force the X FoV - auto calculate it from aspect ratio and Y FoV if less than 1" + ], + [ + "cl_forceFoVy", + "Force the Y FoV - auto calculate it from aspect ratio and X FoV if less than 1" + ], + [ + "cl_freelook", + "Enable looking with mouse" + ], + [ + "cl_freemove", + "Fly about the level" + ], + [ + "cl_freemoveScale", + "Scale how fast you move in cl_freemove mode" + ], + [ + "cl_lessprint", + "Print less to the console by filtering out certain spammy channels" + ], + [ + "cl_modifiedDebugPlacement", + "Modify the location of debug output (outside of safe area)" + ], + [ + "cl_mouseAccel", + "Mouse acceleration" + ], + [ + "cl_noprint", + "Print nothing to the console" + ], + [ + "cl_paused", + "Pause the game" + ], + [ + "cl_paused_simple", + "Toggling pause won't do any additional special processing if true." + ], + [ + "cl_pitchspeed", + "Max pitch speed in degrees for game pad" + ], + [ + "cl_showmouserate", + "Print mouse rate debugging information to the console" + ], + [ + "cl_shownet", + "Display network debugging information" + ], + [ + "cl_showServerCommands", + "Enable debug prints for server commands" + ], + [ + "cl_spawnDebug", + "Turn on debug lines for spawning traces" + ], + [ + "cl_stanceHoldTime", + "The time to hold the stance button before the player goes prone" + ], + [ + "cl_testAnimWeight", + "test animation weighting" + ], + [ + "cl_waterMarkEnabled", + "" + ], + [ + "cl_waterMarkText", + "" + ], + [ + "cl_yawspeed", + "Max yaw speed in degrees for game pad and keyboard" + ], + [ + "client_trigger_draw", + "Draw client trigger geometry" + ], + [ + "client_trigger_drawDepthTest", + "Display client trigger geo with depth information" + ], + [ + "client_trigger_drawDistance", + "Client trigger draw distance" + ], + [ + "com_animCheck", + "Check anim tree" + ], + [ + "com_attractmode", + "Run attract mode" + ], + [ + "com_attractmodeduration", + "Time when controller is unused before attract mode is enabled" + ], + [ + "com_cinematicEndInWhite", + "Set by script. True if cinematic ends with a white screen." + ], + [ + "com_completionResolveCommand", + "Command to run when the message box successfully closes" + ], + [ + "com_errorMessage", + "Most recent error message" + ], + [ + "com_errorRemoveKeyCatcher", + "True if clearing the error message should also remove the ui focus" + ], + [ + "com_errorResolveCommand", + "Command to run when they close the error box" + ], + [ + "com_errorTitle", + "Title of the most recent error message" + ], + [ + "com_filter_output", + "Use console filters for filtering output." + ], + [ + "com_maxfps", + "Cap frames per second" + ], + [ + "com_maxFrameTime", + "Time slows down if a frame takes longer than this many milliseconds" + ], + [ + "com_playerProfile", + "Set to the name of the profile" + ], + [ + "com_reconDumpFrameStats", + "Dump frame stats for Recon" + ], + [ + "com_reconDumpGpuTimings", + "Dump GPU timings for Recon" + ], + [ + "com_statmon", + "Draw stats monitor" + ], + [ + "com_timescale", + "" + ], + [ + "commerce_dl_retry_step", + "Step in m/s for the commerce download retry" + ], + [ + "commerce_manifest_file_max_retry_time", + "Max time that the commerce manifest can retry" + ], + [ + "commerce_manifest_file_retry_step", + "Step in m/s for the commerce manifest retry" + ], + [ + "commerce_max_dl_retry_time", + "Max time that the commerce download can retry" + ], + [ + "commerce_max_retry_time", + "Max time that the commerce upload can retry" + ], + [ + "commerce_retry_step", + "Step in m/s for the commerce upload retry" + ], + [ + "compass", + "Display Compass" + ], + [ + "compassClampIcons", + "If true, friendlies and enemy pings clamp to the edge of the radar. If false, they disappear off the edge." + ], + [ + "compassCoords", + "x = North-South coord base value, \ny = East-West coord base value, \nz = scale (game units per coord unit)" + ], + [ + "compassDebug", + "Compass Debugging Mode" + ], + [ + "compassECoordCutoff", + "Left cutoff for the scrolling east-west coords" + ], + [ + "compassEnemyFootstepEnabled", + "Enables enemies showing on the compass because of moving rapidly nearby." + ], + [ + "compassEnemyFootstepMaxRange", + "The maximum distance at which an enemy may appear on the compass due to 'footsteps'" + ], + [ + "compassEnemyFootstepMaxZ", + "The maximum vertical distance enemy may be from the player and appear on the compass due to 'footsteps'" + ], + [ + "compassEnemyFootstepMinSpeed", + "The minimum speed an enemy must be moving to appear on the compass due to 'footsteps'" + ], + [ + "compassFastRadarUpdateTime", + "Time between radar updates for the fast radar mode" + ], + [ + "compassFriendlyHeight", + "" + ], + [ + "compassFriendlyWidth", + "" + ], + [ + "compassHideSansObjectivePointer", + "Hide the compass, but leave the obective pointer visible." + ], + [ + "compassHideVehicles", + "When enabled, disables the CG_PLAYER_COMPASS_VEHICLES ownerdraw." + ], + [ + "compassMaxRange", + "The maximum range from the player in world space that objects will be shown on the compass" + ], + [ + "compassMinRadius", + "The minimum radius from the center of the compass that objects will appear." + ], + [ + "compassMinRange", + "The minimum range from the player in world space that objects will appear on the compass" + ], + [ + "compassObjectiveArrowHeight", + "" + ], + [ + "compassObjectiveArrowOffset", + "The offset of the objective arrow inward from the edge of the compass map" + ], + [ + "compassObjectiveArrowRotateDist", + "Distance from the corner of the compass map at which the objective arrow rotates to 45 degrees" + ], + [ + "compassObjectiveArrowWidth", + "" + ], + [ + "compassObjectiveDetailDist", + "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape." + ], + [ + "compassObjectiveDrawLines", + "Draw horizontal and vertical lines to the active target, if it is within the minimap boundries" + ], + [ + "compassObjectiveHeight", + "" + ], + [ + "compassObjectiveIconHeight", + "" + ], + [ + "compassObjectiveIconWidth", + "" + ], + [ + "compassObjectiveMaxHeight", + "The maximum height that an objective is considered to be on this level" + ], + [ + "compassObjectiveMaxRange", + "The maximum range at which an objective is visible on the compass" + ], + [ + "compassObjectiveMinAlpha", + "The minimum alpha for an objective at the edge of the compass" + ], + [ + "compassObjectiveMinDistRange", + "The distance that objective transition effects play over, centered on compassObjectiveNearbyDist." + ], + [ + "compassObjectiveMinHeight", + "The minimum height that an objective is considered to be on this level" + ], + [ + "compassObjectiveNearbyDist", + "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape." + ], + [ + "compassObjectiveNumRings", + "The number of rings when a new objective appears" + ], + [ + "compassObjectiveRingSize", + "The maximum objective ring sige when a new objective appears on the compass" + ], + [ + "compassObjectiveRingTime", + "The amount of time between each ring when an objective appears" + ], + [ + "compassObjectiveTextHeight", + "Objective text height" + ], + [ + "compassObjectiveTextScale", + "Scale to apply to hud objectives" + ], + [ + "compassObjectiveWidth", + "" + ], + [ + "compassObjectiveWraparoundTime", + "How long it takes for the objective to wrap around the compass from one edge to the other" + ], + [ + "compassPlayerHeight", + "" + ], + [ + "compassPlayerWidth", + "" + ], + [ + "compassRadarLineThickness", + "Thickness, relative to the compass size, of the radar texture that sweeps across the map" + ], + [ + "compassRadarPingFadeTime", + "How long an enemy is visible on the compass after it is detected by radar" + ], + [ + "compassRadarUpdateTime", + "Time between radar updates for the normal radar mode" + ], + [ + "compassRotation", + "Style of compass" + ], + [ + "compassSize", + "Scale the compass" + ], + [ + "compassSoundPingFadeTime", + "The time in seconds for the sound overlay on the compass to fade" + ], + [ + "compassTickertapeStretch", + "How far the tickertape should stretch from its center." + ], + [ + "comscore_active", + "Are we allowed to enable ComScore tracking or not" + ], + [ + "con_default_console_filter", + "Default channel filter for the console destination." + ], + [ + "con_errormessagetime", + "Onscreen time for error messages in seconds" + ], + [ + "con_inputBoxColor", + "Color of the console input box" + ], + [ + "con_inputHintBoxColor", + "Color of the console input hint box" + ], + [ + "con_matchPrefixOnly", + "Only match the prefix when listing matching Dvars" + ], + [ + "con_minicon", + "Display the mini console on screen" + ], + [ + "con_miniconlines", + "Number of lines in the minicon message window" + ], + [ + "con_minicontime", + "Onscreen time for minicon messages in seconds" + ], + [ + "con_outputBarColor", + "Color of the console output slider bar" + ], + [ + "con_outputSliderColor", + "Color of the console slider" + ], + [ + "con_outputWindowColor", + "Color of the console output" + ], + [ + "con_subtitleLeading", + "Leading for subtitles, calculated as a percentage of the font height" + ], + [ + "con_typewriterColorGlowCheckpoint", + "" + ], + [ + "con_typewriterColorGlowCompleted", + "" + ], + [ + "con_typewriterColorGlowFailed", + "" + ], + [ + "con_typewriterColorGlowUpdated", + "" + ], + [ + "con_typewriterColorInteriorCheckpoint", + "" + ], + [ + "con_typewriterColorInteriorCompleted", + "" + ], + [ + "con_typewriterColorInteriorFailed", + "" + ], + [ + "con_typewriterColorInteriorUpdated", + "" + ], + [ + "con_typewriterDecayDuration", + "Time (in milliseconds) to spend disolving the line away." + ], + [ + "con_typewriterDecayStartTime", + "Time (in milliseconds) to spend between the build and disolve phases." + ], + [ + "con_typewriterPrintSpeed", + "Time (in milliseconds) to print each letter in the line." + ], + [ + "consoleGame", + "True if running on a console" + ], + [ + "content_download_should_auto_download", + "Checks whether we should auto download PS4 content not already downloaded or not." + ], + [ + "content_download_timer_ms", + "Number of milliseconds between calls to submit met players to the rest system." + ], + [ + "contentEnumerationAuto", + "poll enumeration" + ], + [ + "contentEnumerationTimer", + "time between 2 automatic enumerations" + ], + [ + "coop_matching_type_search", + "Is the matching type set to search" + ], + [ + "coop_showing_game_error_popup", + "Are we showing a game error popup" + ], + [ + "coopNameFontSize", + "" + ], + [ + "coopNameFontSizeSplitscreen", + "" + ], + [ + "counterDownloadInterval", + "Number of minutes before all the global counters are uploaded" + ], + [ + "counterUploadInterval", + "Number of minutes before all the global counters are uploaded" + ], + [ + "cSplineDebugRender", + "Debug Render the csplines." + ], + [ + "cSplineDebugRenderCorridor", + "Debug Render the cspline corridor." + ], + [ + "cSplineDebugRenderData", + "Debug Render the cspline data." + ], + [ + "cSplineDebugRenderSplineId", + "Select a cspline - 0 for all." + ], + [ + "damage_actorRangeFalloff", + "When true, the damage the NPCs deal falls off the further their shot travels. Otherwise it deals basedamage regardless of range." + ], + [ + "damage_rangeLerp", + "When true, lerp damage in between the max/min range by the max/min damage, otherwise just use the mid damage when in between max/min range." + ], + [ + "db_disableImageCacheEvictionQueue", + "Disables image cache streaming queued eviction" + ], + [ + "dc_lobbymerge", + "Allows lobby merging across data centres" + ], + [ + "debug_onlinePlayEvenIfDown", + "Whether to allow people to play even if PSN is down" + ], + [ + "debugOverlay", + "Toggles the display of various debug info." + ], + [ + "debugOverlayOnly", + "Toggles whether debug Overlay hides the rest of the UI." + ], + [ + "dedicated_dhclient", + "True if we're a client playing on a DH server" + ], + [ + "demigod_healthFloor", + "Sets the health floor during demigod mode." + ], + [ + "depthSortViewmodel", + "Enable depth sorting on the viewmodel." + ], + [ + "DEV_PROTOCOL_VERSION", + "Dev only: temporarily override protocol version so as not to join other dev games in progress." + ], + [ + "developer", + "Enable development options" + ], + [ + "developer_looseFiles", + "Enable loose file loading for gsc/lui (PC)" + ], + [ + "developer_script", + "Enable developer script comments: 0 disabled, 1 full developer script, 2 only dev scripts required by art/lighting tweaks." + ], + [ + "devgui_allowMouse", + "Devgui allow mouse input" + ], + [ + "devgui_bevelShade", + "Bevel shade for the devgui" + ], + [ + "devgui_colorBgnd", + "Color background for the devgui" + ], + [ + "devgui_colorBgndFocus", + "Button color while the mouse hovers over it." + ], + [ + "devgui_colorBgndGray", + "Grayed out background color for the devgui" + ], + [ + "devgui_colorBgndGraySel", + "Greyed out, selected background color for the devgui" + ], + [ + "devgui_colorBgndHeld", + "Button color when pressed by the mouse." + ], + [ + "devgui_colorBgndSel", + "Selection background color for the devgui" + ], + [ + "devgui_colorGraphKnotEditing", + "Devgui color graph knot editing color" + ], + [ + "devgui_colorGraphKnotNormal", + "Devgiu Color graph knot normal color" + ], + [ + "devgui_colorGraphKnotSelected", + "Devgui color graph knot selected color" + ], + [ + "devgui_colorSliderBgnd", + "Color slider background for the devgui" + ], + [ + "devgui_colorSliderBgndFocus", + "Focused color slider background for the devgui" + ], + [ + "devgui_colorSliderBgndHeld", + "Held color slider background for the devgui" + ], + [ + "devgui_colorSliderKnob", + "Knob color for the devgui" + ], + [ + "devgui_colorSliderKnobFocus", + "Focused knob color for the devgui" + ], + [ + "devgui_colorSliderKnobHeld", + "Held knob color for the devgui" + ], + [ + "devgui_colorSliderKnobSel", + "Selected knob color for the devgui" + ], + [ + "devgui_colorText", + "Text color for the devgui" + ], + [ + "devgui_colorTextGray", + "Greyed out text color for the devgui" + ], + [ + "devgui_colorTextGraySel", + "Greyed out, selected text color for the devgui" + ], + [ + "devgui_colorTextSel", + "Selection text color for the devgui" + ], + [ + "devgui_mouseScrollDelay", + "Delay before scrolling when holding the slider bar with the left mouse button." + ], + [ + "devgui_mouseScrollSpeed", + "Scroll speed when holding the slider bar with the left mouse button." + ], + [ + "disableDLC", + "" + ], + [ + "disableEliteDLCCheck", + "" + ], + [ + "discard_playerstats_on_suspend", + "Forces stats discard on suspend" + ], + [ + "disconnectOnSignOut", + "If true, the player will be kicked back to the main menu if they sign out of their profile\n" + ], + [ + "dw_addrHandleTimeout", + "Delay before destroying an addrHandle after the connection is lost\n" + ], + [ + "dw_environment_server", + "Choose which Demonware environment to connect to. Use No Preference if you want to keep the default logic." + ], + [ + "dw_ignore_hack", + "Which DemonWare ignore hack fix mode to use" + ], + [ + "dw_leaderboard_write_active", + "Are leaderboard writes enabled" + ], + [ + "dw_memory_display_time", + "Number of seconds between high watermark display." + ], + [ + "dw_neverDisconnect", + "Set to true to avoid getting kick back to main menu when losing connection to dw." + ], + [ + "dw_presence_active", + "Is the demonware presence system enabled" + ], + [ + "dw_presence_coop_join_active", + "Do we allow players to join on presence for private coop matches (post session to demonware" + ], + [ + "dw_presence_get_delay", + "Number of milliseconds to wait after booting the game to fetch demonware presence" + ], + [ + "dw_presence_get_rate", + "Number of milliseconds to wait between sending presence state to demonware" + ], + [ + "dw_presence_put_delay", + "Number of milliseconds to wait in a presence state before sending to demonware" + ], + [ + "dw_presence_put_rate", + "Number of milliseconds to wait between sending presence state to demonware" + ], + [ + "dw_shared_presence_active", + "Is the demonware shared presence system enabled" + ], + [ + "dw_shared_presence_get_delay", + "Number of milliseconds to wait after booting the game to fetch demonware presence" + ], + [ + "dw_shared_presence_get_rate", + "Number of milliseconds to wait between sending presence state to demonware" + ], + [ + "dw_shared_presence_put_delay", + "Number of milliseconds to wait in a shared presence state before sending to demonware" + ], + [ + "dw_shared_presence_put_rate", + "Number of milliseconds to wait between sending presence state to demonware" + ], + [ + "dw_test_disconnect", + "Simulate a demonware disconnect" + ], + [ + "dw_test_retry_disconnect", + "Simulate a demonware disconnect at the end of every connection retry" + ], + [ + "dwBandwidthTestTaskTimeout", + "default timeout for the bandwidth test task (in ms). 0 means no timeout" + ], + [ + "dwInfoLogEnabled", + "Toggle Demonware Info log" + ], + [ + "dwStorageFakeError", + "Fake errors from dwStorage" + ], + [ + "dynEnt_bulletForce", + "Force applied from bullet hit" + ], + [ + "dynEnt_damageScale", + "Scales damage applied to destructible dynents" + ], + [ + "dynEnt_explodeForce", + "Force applied from explosion hit" + ], + [ + "dynEnt_explodeMaxEnts", + "The maximum number of dynents that can be awakened by one explosion" + ], + [ + "dynEnt_explodeMinForce", + "Force below which dynents won't even bother waking up" + ], + [ + "dynEnt_explodeSpinScale", + "Scale of the random offset from the center of mass for explosion forces." + ], + [ + "dynEnt_explodeUpbias", + "Upward bias applied to force directions from explosion hits" + ], + [ + "dynEnt_explodingBulletForce", + "Force applied from bullet explosion hit" + ], + [ + "dynEnt_explodingBulletMaxEnts", + "The maximum number of dynents that can be awakened by one explosion" + ], + [ + "dynEnt_explodingBulletMinForce", + "Force below which dynents won't even bother waking up" + ], + [ + "dynEnt_explodingBulletSpinScale", + "Scale of the random offset from the center of mass for explosion forces." + ], + [ + "dynEnt_explodingBulletUpbias", + "Upward bias applied to force directions from explosion hits" + ], + [ + "dynEnt_playerWakeUpRadius", + "Determines threshold distance from player within which all dynents are woken up." + ], + [ + "dynEnt_playerWakeUpZOffset", + "Determines vertical distance from player's feet from which wake up sphere is centered." + ], + [ + "dynEnt_showWakeUpSphere", + "Shows the wakeup spheres that are trigger by WakeUpPhysicsSphere." + ], + [ + "elite_clan_active", + "Are we allowed to show Elite Clans or not" + ], + [ + "elite_clan_cool_off_time", + "Cool off time between calls to fetch the elite clan" + ], + [ + "elite_clan_delay", + "Delay before the bdTeams calls start to Demonware. -1 means On-Demand and it will wait until the 'starteliteclan' menu call" + ], + [ + "elite_clan_division_icon_active", + "Are we allowed to show Elite Clan division icon or not" + ], + [ + "elite_clan_get_blob_profile_max_retry_time", + "Max time that the Elite Clan get private profile can retry" + ], + [ + "elite_clan_get_blob_profile_retry_step", + "Step in m/s for the Elite Clan get private profile retry" + ], + [ + "elite_clan_get_clan_max_retry_time", + "Max time that the Elite Clan get clan can retry" + ], + [ + "elite_clan_get_clan_retry_step", + "Step in m/s for the Elite Clan get clan retry" + ], + [ + "elite_clan_get_members_max_retry_time", + "Max time that the Elite Clan get members can retry" + ], + [ + "elite_clan_get_members_retry_step", + "Step in m/s for the Elite Clan get members retry" + ], + [ + "elite_clan_get_private_member_profile_max_retry_time", + "Max time that the Elite Clan get private profile can retry" + ], + [ + "elite_clan_get_private_member_profile_retry_step", + "Step in m/s for the Elite Clan get private profile retry" + ], + [ + "elite_clan_get_public_profile_max_retry_time", + "Max time that the Elite Clan get public profile can retry" + ], + [ + "elite_clan_get_public_profile_retry_step", + "Step in m/s for the Elite Clan get public profile retry" + ], + [ + "elite_clan_get_team_stats_max_retry_time", + "Max time that the Elite Clan get team stats can retry" + ], + [ + "elite_clan_get_team_stats_retry_step", + "Step in m/s for the Elite Clan get team stats retry" + ], + [ + "elite_clan_motd_throttle_time", + "Throttle time between motd update calls" + ], + [ + "elite_clan_send_message_to_members_max_retry_time", + "Max time that the Elite Clan send message to members can retry" + ], + [ + "elite_clan_send_message_to_members_retry_step", + "Step in m/s for the Elite Clan send message to members retry" + ], + [ + "elite_clan_set_private_member_profile_max_retry_time", + "Max time that the Elite Clan set private member profile can retry" + ], + [ + "elite_clan_set_private_member_profile_retry_step", + "Step in m/s for the Elite Clan set private member profile retry" + ], + [ + "elite_clan_single_task_popup_text", + "String to be displayed on popup when a single task is being performed" + ], + [ + "elite_clan_using_title", + "Stores whether the Elite Clan title is in use by the user" + ], + [ + "enable_recordRecentActivity", + "records the timestamp of when the player was recently active to the tracker leaderboards" + ], + [ + "energyWeaponDebugDraw", + "Draw energy weapon areas." + ], + [ + "entitlements_active", + "Are we allowed to show Entitlements or not" + ], + [ + "entitlements_config_file_max_retry_time", + "Max time that the Entitlements config file read can retry" + ], + [ + "entitlements_config_file_retry_step", + "Step in m/s for the Entitlements config file read retry" + ], + [ + "entitlements_cool_off_time", + "Cool off time between calls to fetch the elite clan" + ], + [ + "entitlements_delay", + "Delay before the entitlement calls start to Demonware. -1 means On-Demand and it will wait until the 'startentitlements' menu call" + ], + [ + "entitlements_key_archive_max_retry_time", + "Max time that the Entitlements key archive read can retry" + ], + [ + "entitlements_key_archive_retry_step", + "Step in m/s for the Entitlements key archive read retry" + ], + [ + "entitlementSystemOk", + "Set by the game to inform that the entitlement system is initialised" + ], + [ + "facebook_active", + "Are we allowed to show Facebook or not" + ], + [ + "facebook_delay", + "Delay before the Facebook calls start to Demonware. -1 means On-Demand and it will wait until the 'startfacebook' menu call" + ], + [ + "facebook_friends_active", + "Are we allowed to show Facebook Friends or not" + ], + [ + "facebook_friends_max_retry_time", + "Max time that the Facebook friends read can retry" + ], + [ + "facebook_friends_refresh_time", + "Time in seconds between Facebook friend refreshes" + ], + [ + "facebook_friends_retry_step", + "Step in m/s for the Facebook friends read retry" + ], + [ + "facebook_friends_showing_count", + "Contains how many facebook friends are being shown in the UI." + ], + [ + "facebook_friends_throttle_time", + "Throttle time between Facebook friend pages" + ], + [ + "facebook_max_retry_time", + "Max time that the Facebook authentication can retry" + ], + [ + "facebook_password", + "Facebook Password" + ], + [ + "facebook_password_asterisk", + "Facebook Password (Asterisk Version)" + ], + [ + "facebook_popup_text", + "Facebook Popup Text" + ], + [ + "facebook_retry_step", + "Step in m/s for the Facebook authentication retry" + ], + [ + "facebook_upload_photo_active", + "Are we allowed to Upload Photos to Facebook or not" + ], + [ + "facebook_upload_video_active", + "Are we allowed to Upload Videos to Facebook or not" + ], + [ + "facebook_username", + "Facebook Username" + ], + [ + "fastfile_loadDevelopment", + "Enable/Disable loading of the development fast file." + ], + [ + "fixedtime", + "Use a fixed time rate for each frame" + ], + [ + "FoFIconMaxSize", + "Maximum size a Friend-or-Foe icon should ever grow to." + ], + [ + "FoFIconMinSize", + "Minimum size a Friend-or-Foe icon should ever shrink to." + ], + [ + "FoFIconScale", + "Base scale of Friend-or-Foe icons." + ], + [ + "force_ranking", + "Set to true to allow private or system link games to use the ranking system" + ], + [ + "friction", + "Player friction" + ], + [ + "friendlyNameFontColor", + "" + ], + [ + "friendlyNameFontGlowColor", + "" + ], + [ + "friendlyNameFontSize", + "Fontsize of the popup friendly names." + ], + [ + "friendlyNameFontSizeSplitscreen", + "Fontsize of the popup friendly names, in splitscreen." + ], + [ + "fs_basegame", + "Base game name" + ], + [ + "fs_basepath", + "Base game path" + ], + [ + "fs_basepath_output", + "Base game path" + ], + [ + "fs_cdpath", + "CD path" + ], + [ + "fs_copyfiles", + "Copy all used files to another location" + ], + [ + "fs_debug", + "Enable file system debugging information" + ], + [ + "fs_game", + "Game data directory. Must be \"\" or a sub directory of 'mods/'." + ], + [ + "fs_homepath", + "Game home path" + ], + [ + "fs_ignoreLocalized", + "Ignore localized assets" + ], + [ + "fx_alphaThreshold", + "Don't draw billboard sprites, oriented sprites or tails with alpha below this threshold (0-256)." + ], + [ + "fx_cast_shadow", + "Enable transparency shadow mapping from script" + ], + [ + "fx_count", + "Debug effects count" + ], + [ + "fx_cull_elem_draw", + "Culls effect elems for drawing" + ], + [ + "fx_cull_elem_draw_flicker", + "Flicker DPVS culled effect elems" + ], + [ + "fx_cull_elem_spawn", + "Culls effect elems for spawning" + ], + [ + "fx_debug3D", + "Turn on effect system debug information, parameter is culling distance" + ], + [ + "fx_debugAssertQuat", + "Turn on/off debug asserts for quaternions in the fx system" + ], + [ + "fx_debugBolt", + "Debug effects bolt" + ], + [ + "fx_deferelem", + "Toggles deferred processing of elements instead of effects" + ], + [ + "fx_dpvs_cull_elem_draw", + "Culls effect elems for drawing using DPVS(2: ignore per-effect portal culling flag)" + ], + [ + "fx_draw", + "" + ], + [ + "fx_draw_omniLight", + "" + ], + [ + "fx_draw_simd", + "Draw effects using SIMD / Vector code." + ], + [ + "fx_draw_spotLight", + "" + ], + [ + "fx_drawClouds", + "Toggles the drawing of particle clouds" + ], + [ + "fx_dump", + "Sends debug info on PlayFX and PlayFXToTag calls within units of player to the console" + ], + [ + "fx_enable", + "Toggles all effects processing" + ], + [ + "fx_flare", + "Toggles fx flare" + ], + [ + "fx_forceEffectPass", + "Forces effects to render in trans, emissive, or default mode" + ], + [ + "fx_freeze", + "Freeze effects" + ], + [ + "fx_killEffectOnRewind", + "Causes effects that have been marked for a soft kill (fade out) to be killed immediately on a rewind." + ], + [ + "fx_lightGridSampleOffset", + "the length of effect sample's offset along X Axis" + ], + [ + "fx_mark_profile", + "Turn on FX profiling for marks (specify which local client, with '1' being the first.)" + ], + [ + "fx_marks", + "Toggles whether bullet hits leave marks" + ], + [ + "fx_marks_ents", + "Toggles whether bullet hits leave marks" + ], + [ + "fx_marks_nearlimit", + "Sets limit of number of decals that can exist at the same location (0 for unlimited)" + ], + [ + "fx_marks_smodels", + "Toggles whether bullet hits leave marks" + ], + [ + "fx_overrideLightFrac", + "Overrides every lighting-frac value, 0 is all unlit, to 1 that is 100% lit - the default of -1 restores segment lighting-frac values" + ], + [ + "fx_physicsImpactVelocityThreshold", + "Set the min normal velocity threshold in order for model physics fx to generate child impact effects." + ], + [ + "fx_profile", + "Turn on FX profiling (specify which local client, with '1' being the first.)" + ], + [ + "fx_profileFilter", + "Only show effects with this as a substring in FX profile" + ], + [ + "fx_profileFilterElemCountZero", + "Do not include FX that have a zero element count" + ], + [ + "fx_profileSkip", + "Skip the first n lines in FX profile (to see ones off bottom of screen)" + ], + [ + "fx_profileSort", + "Choose sort criteria for FX profiling" + ], + [ + "fx_showLightGridSampleOffset", + "show light grid sample offset in CreateFX mode" + ], + [ + "fx_visMinTraceDist", + "Minimum visibility trace size" + ], + [ + "g_ai", + "Enable AI" + ], + [ + "g_aiAnimscript", + "Enable AI animscript" + ], + [ + "g_aiEventDump", + "Print AI events happening for this entity" + ], + [ + "g_aiEventListenerDump", + "Dump the AI event listeners once. Automatically reset to false after dump" + ], + [ + "g_allowUnusedPak", + "enable loading of texture mips from unused pak" + ], + [ + "g_anim_mp_idle_turn_angle", + "Rotation amount of 3rd-person pivot when player rotates in place while standing." + ], + [ + "g_anim_mp_idle_turn_anim_duration", + "Duration of 3rd-person pivot animation." + ], + [ + "g_anim_mp_idle_turn_rotate_crouch_end", + "Time during 3rd-person crouched pivot at which the player stops rotating in place." + ], + [ + "g_anim_mp_idle_turn_rotate_crouch_start", + "Time during 3rd-person crouched pivot at which the player stops rotating in place." + ], + [ + "g_anim_mp_idle_turn_rotate_prone_end", + "Time during 3rd-person prone pivot at which the player stops rotating in place." + ], + [ + "g_anim_mp_idle_turn_rotate_prone_start", + "Time during 3rd-person prone pivot at which the player stops rotating in place." + ], + [ + "g_anim_mp_idle_turn_rotate_stand_end", + "Time during 3rd-person standing pivot at which the player stops rotating in place." + ], + [ + "g_anim_mp_idle_turn_rotate_stand_start", + "Time during 3rd-person standing pivot at which the player stops rotating in place." + ], + [ + "g_anim_mp_idle_turn_trigger_angle", + "Aim yaw angle at which 3rd-person pivot triggers." + ], + [ + "g_animated_lean_blends", + "Toggles between procedural (0) and blended (1) MP lean animation techniques." + ], + [ + "g_animsCommandsVerbose", + "Dump all animation commands. If false, calls marked as verbose will not be printed" + ], + [ + "g_atmosFogDistanceScaleReadOnly", + "scale applied to scene distance used for atmospheric fog calculation" + ], + [ + "g_atmosFogEnabledReadOnly", + "use atmospheric fog" + ], + [ + "g_atmosFogExtinctionStrengthReadOnly", + "scale out scatter contribution of atmospheric fog" + ], + [ + "g_atmosFogHalfPlaneDistanceReadOnly", + "distance at which atmospheric fog contributes half the pixels color" + ], + [ + "g_atmosFogHazeSpreadReadOnly", + "directionality of haze (1ReadOnly = all forward scatter, 0ReadOnly = all back scatter)" + ], + [ + "g_atmosFogHazeStrengthReadOnly", + "portion of atmospheric fog density that is haze (0ReadOnly = all fog, 1ReadOnly = all haze)" + ], + [ + "g_atmosFogHeightFogBaseHeightReadOnly", + "height fog is full density at this world height and below" + ], + [ + "g_atmosFogHeightFogEnabledReadOnly", + "use height for atmospheric fog" + ], + [ + "g_atmosFogHeightFogHalfPlaneDistanceReadOnly", + "at this distance above g_atmosFogHeightFogBaseHeight, height fog density is half" + ], + [ + "g_atmosFogInScatterStrengthReadOnly", + "scale in scatter contribution of atmospheric fog" + ], + [ + "g_atmosFogSkyAngularFalloffEnabledReadOnly", + "use angular sky falloff for atmospheric fog" + ], + [ + "g_atmosFogSkyDistanceReadOnly", + "distance used for sky box when applying atmospheric fog" + ], + [ + "g_atmosFogSkyFalloffAngleRangeReadOnly", + "sky fog angular falloff angle range sky fog falls off over this range from the start angle" + ], + [ + "g_atmosFogSkyFalloffStartAngleReadOnly", + "sky fog angular falloff start angle (full strength fog at this angle)" + ], + [ + "g_atmosFogStartDistanceReadOnly", + "distance from camera at which fog contribution begins" + ], + [ + "g_atmosFogSunDirectionReadOnly", + "sun direction used when calculating atmospheric fog" + ], + [ + "g_changelevel_time", + "Time for change level fade out" + ], + [ + "g_deathDelay", + "Delay a level restart on death" + ], + [ + "g_debugBullets", + "Show debug information for bullets" + ], + [ + "g_debugDamage", + "Turn on debug information for damage" + ], + [ + "g_debugLocDamage", + "Display locational damage debug information for an entity" + ], + [ + "g_debugLocHit", + "Display locational damage info for an entity when the entity is hit" + ], + [ + "g_debugLocHitTime", + "Time duration of g_debugLocHit lines" + ], + [ + "g_disableAnimTransitions", + "Turns off the animation transition control tables" + ], + [ + "g_disableBulletPenetration", + "Removes all bullet penetration." + ], + [ + "g_dobjdump", + "Write dobj debug info for this entity" + ], + [ + "g_drawDefaultStaticModels", + "Static default xmodels (the big red FX placeholder) are not rendered by default. Enabling this affects transient performance." + ], + [ + "g_drawEntBBoxes", + "Draw entity bounding boxes" + ], + [ + "g_drawGrenadeHints", + "Draw debug information for grenades" + ], + [ + "g_dumpAnims", + "Write animation debug info for this entity" + ], + [ + "g_dumpAnimsCommands", + "Write animation commands debug info for this entity" + ], + [ + "g_dumpAnimTransitions", + "Write animation transition debug info for this entity" + ], + [ + "g_earthquakeEnable", + "Enable camera shake" + ], + [ + "g_enableAccurateTrace", + "Turn on accurate trace, for actors" + ], + [ + "g_entinfo", + "Display entity information" + ], + [ + "g_entinfo_AItext", + "Type of text information for AI entinfo" + ], + [ + "g_entinfo_maxdist", + "Maximum distance of an entity from the camera at which to show entity information" + ], + [ + "g_entinfo_scale", + "Scale of the entity information text" + ], + [ + "g_entinfo_type", + "Type of entities to display information" + ], + [ + "g_fogColorIntensityReadOnly", + "HDR Fog color intensity that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_fogColorReadOnly", + "Fog color that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_fogHalfDistReadOnly", + "" + ], + [ + "g_fogMaxOpacityReadOnly", + "Fog max opacity that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_fogStartDistReadOnly", + "" + ], + [ + "g_friendlyfireDamageScale", + "Scales player damage from other players" + ], + [ + "g_friendlyfireDist", + "Maximum distance at which the player channot shoot while the crosshair is over a friendly" + ], + [ + "g_friendlyNameDist", + "Maximum distance at which a friendly name shows when the crosshairs is over them" + ], + [ + "g_gameskill", + "Game skill level" + ], + [ + "g_giveAll", + "Give all weapons" + ], + [ + "g_gravity", + "Gravity in inches per second per second" + ], + [ + "g_grenadeDamageMaxHeight", + "Maximum vertical distance at which a grenade will do damage when exploding" + ], + [ + "g_heightFogBaseHeightReadOnly", + "height fog is full density at this world height and below" + ], + [ + "g_heightFogEnabledReadOnly", + "use height for normal/sun fog, set in the most recent call to \"setexpfog\"" + ], + [ + "g_heightFogHalfPlaneDistanceReadOnly", + "at this distance above g_heightFogBaseHeight, height fog density is half, set in the most recent call to \"setexpfog\"" + ], + [ + "g_hideMissingXmodels", + "Hide missing xmodels, instead of drawing a big red FX. Must be set on boot command-line, not at runtime." + ], + [ + "g_knockback", + "Maximum player knockback" + ], + [ + "g_listEntity", + "list all of the current entities" + ], + [ + "g_minGrenadeDamageSpeed", + "Minimum speed at which getting hit be a grenade will do damage (not the grenade explosion damage)" + ], + [ + "g_notifydump", + "Write notify debug info for this entity" + ], + [ + "g_onlyPlayerAreaEntities", + "Only checks client entities with movers. SP only." + ], + [ + "g_player_maxhealth", + "Player's maximum health" + ], + [ + "g_recordScriptPlace", + "Records the file and line of the current script command" + ], + [ + "g_reloading", + "True if the game is reloading" + ], + [ + "g_singleplayerAntilag", + "Enable singleplayer/co-op antilag" + ], + [ + "g_spawnai", + "Enable AI spawning" + ], + [ + "g_speed", + "Maximum player speed" + ], + [ + "g_streamingEnable", + "enable loading of textures (priorities will still be calculated)" + ], + [ + "g_sunFogBeginFadeAngleReadOnly", + "Angle from the sun direction to start fade away from the sun fog color that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_sunFogColorIntensityReadOnly", + "HDR Sun fog color intensity that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_sunFogColorReadOnly", + "Sun fog color that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_sunFogDirReadOnly", + "Sun fog direction that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_sunFogEnabledReadOnly", + "Sun fog was enabled in the most recent call to \"setexpfog\"" + ], + [ + "g_sunFogEndFadeAngleReadOnly", + "Angle from the sun direction to end fade away from the sun fog color that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_sunFogScaleReadOnly", + "Distance scale in the sun fog direction that was set in the most recent call to \"setexpfog\"" + ], + [ + "g_useholdtime", + "The time to hold down the 'use' button to activate a 'use' command on a gamepad" + ], + [ + "g_vehicleDebug", + "Turn on debug information for vehicles" + ], + [ + "g_vehicleDrawPath", + "Turn on debug information for vehicle paths" + ], + [ + "gamedate", + "The date compiled" + ], + [ + "gamedvr_active", + "Are we allowed to enable GameDVR or not" + ], + [ + "gamedvr_prohibitrecording", + "Allow user to capture video" + ], + [ + "gamedvr_prohibitscreenshot", + "Allow user to capture screenshots" + ], + [ + "gamedvr_screenshotcomment", + "Comment embedded in user screenshot" + ], + [ + "gamedvr_screenshotgametitle", + "Game name embedded in user screenshot" + ], + [ + "gamedvr_screenshottitle", + "Photo title embedded in user screenshot" + ], + [ + "gamedvr_videocomment", + "" + ], + [ + "gamedvr_videocopyright", + "" + ], + [ + "gamedvr_videodescription", + "" + ], + [ + "gamedvr_videotitle", + "Subtitle for recorded video" + ], + [ + "gameMode", + "Current gameMode" + ], + [ + "glass_angular_vel", + "Sets the range of angular velocities used by new glass pieces" + ], + [ + "glass_beamDamage", + "The amount of damage beam attacks do to glass" + ], + [ + "glass_break", + "Toggle whether or not glass breaks when shot" + ], + [ + "glass_crack_pattern_scale", + "The scale applied to the radius used for the crack pattern" + ], + [ + "glass_damageToDestroy", + "The amount of damage a piece of glass must take to look damaged" + ], + [ + "glass_damageToWeaken", + "The amount of damage a piece of glass must take to look damaged" + ], + [ + "glass_debug", + "Shows debug info for glass" + ], + [ + "glass_edge_angle", + "Sets the range of angle deflections used by new glass pieces on a supported edge" + ], + [ + "glass_fall_delay", + "Sets how long a heavy piece supported by a single edge waits before falling, based on glass_fall_ratio" + ], + [ + "glass_fall_gravity", + "Gravity for falling pieces of glass" + ], + [ + "glass_fall_ratio", + "Ratio of piece area to supporting edge length squared. Below the min, the piece never falls." + ], + [ + "glass_fringe_maxcoverage", + "The maximum portion of the original piece of glass that is allowed to remain after the glass shatters" + ], + [ + "glass_fringe_maxsize", + "The maximum area for an edge piece of glass when shattering. Pieces larger than this will be broken into smaller ones" + ], + [ + "glass_fx_chance", + "Chance to play an effect on a small piece of glass when it hits the ground" + ], + [ + "glass_hinge_friction", + "Friction used by moving glass pieces when joined like a hinge to a frame" + ], + [ + "glass_linear_vel", + "Sets the range of linear velocities used by new glass pieces" + ], + [ + "glass_max_pieces_per_frame", + "Maximum number of pieces to create in one frame. This is a guideline and not a hard limit." + ], + [ + "glass_max_shatter_fx_per_frame", + "Maximum number of shatter effects to play in one frame This is a guideline and not a hard limit." + ], + [ + "glass_meleeDamage", + "The amount of damage melee attacks do to glass" + ], + [ + "glass_physics_chance", + "The chance for a given shard of glass to use physics" + ], + [ + "glass_physics_maxdist", + "The maximum distance of a glass piece from the player to do physics" + ], + [ + "glass_radiusDamageMultiplier", + "The amount to scale damage to glass from grenades and other explosions" + ], + [ + "glass_shard_maxsize", + "The maximum area for a flying piece of glass when shattering. Pieces larger than this will be broken into smaller ones" + ], + [ + "glass_shattered_scale", + "The scale of the shattered glass material" + ], + [ + "glass_simple_duration", + "The time (in ms) that simple (non-physics) glass pieces live for" + ], + [ + "glass_spam", + "Toggle extra spam to help repro glass asserts" + ], + [ + "glass_trace_interval", + "The length of time, in milliseconds, between glass piece traces" + ], + [ + "gpad_button_deadzone", + "Game pad button deadzone threshhold" + ], + [ + "gpad_button_rstick_deflect_max", + "Maximum right stick deflection" + ], + [ + "gpad_dpadDebounceTime", + "" + ], + [ + "gpad_menu_scroll_delay_first", + "Menu scroll key-repeat delay, for the first repeat, in milliseconds" + ], + [ + "gpad_menu_scroll_delay_rest_accel", + "Menu scroll key-repeat delay acceleration from start to end, for repeats after the first, in milliseconds per repeat" + ], + [ + "gpad_menu_scroll_delay_rest_end", + "Menu scroll key-repeat delay end, for repeats after the first, in milliseconds" + ], + [ + "gpad_menu_scroll_delay_rest_start", + "Menu scroll key-repeat delay start, for repeats after the first, in milliseconds" + ], + [ + "gpad_rumbleHighThreshold", + "Game pad activation threshold for the high frequency rumble" + ], + [ + "gpad_stick_deadzone_max", + "Game pad maximum stick deadzone" + ], + [ + "gpad_stick_deadzone_min", + "Game pad minimum stick deadzone" + ], + [ + "gpad_stick_pressed", + "Game pad stick pressed threshhold" + ], + [ + "gpad_stick_pressed_hysteresis", + "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing" + ], + [ + "gpad_touchpad_deadzone_max", + "Touch pad maximum deadzone" + ], + [ + "gpad_touchpad_deadzone_min", + "Touch pad minimum deadzone" + ], + [ + "gpad_vita_sensitivity", + "Vita sensitivity scale" + ], + [ + "grapple_magnet_draw", + "Draw grapple magnet points" + ], + [ + "grapple_magnet_draw_dist", + "Draw grapple magnet point max range" + ], + [ + "grapple_magnet_draw_fov", + "Draw grapple magnet point max fov" + ], + [ + "grapple_surface_dot_limit", + "Surface normal dot limit that can be grappled to [cos(angle limit)]" + ], + [ + "grenadeBounceRestitutionMax", + "Cap to keep code from increasing bounce restitution too high." + ], + [ + "grenadeBumpFreq", + "How likely (per server frame) a bump will occur" + ], + [ + "grenadeBumpMag", + "Size of bumps (as a fraction of the grenade's current speed)" + ], + [ + "grenadeBumpMax", + "Maximum upward speed of a bump (inches/sec)" + ], + [ + "grenadeCurveMax", + "Largest rolling curvature (will be random between +/- this value)" + ], + [ + "grenadeFrictionHigh", + "The amount of friction (0 to 1) for fast-moving grenades" + ], + [ + "grenadeFrictionLow", + "The amount of friction (0 to 1) for slower/rolling grenades" + ], + [ + "grenadeFrictionMaxThresh", + "The speed threshold that determines whether to use grenadeFrictionLow/High" + ], + [ + "grenadeRestThreshold", + "The speed threshold below which grenades will come to rest" + ], + [ + "grenadeRollingEnabled", + "Enables the new \"rolling\" grenade behavior" + ], + [ + "grenadeWobbleFreq", + "Wobble cycles per inch of rolling distance (approx)" + ], + [ + "grenadeWobbleFwdMag", + "The forward rolling speed will oscillate +/- this amount" + ], + [ + "grenadeWobbleSideDamp", + "The rate at which the amount of side-to-side wobbling decreases as overall grenade speed increases" + ], + [ + "grenadeWobbleSideMag", + "The distance to wobble left and right" + ], + [ + "groupDownloadInterval", + "Minimum interval to wait before getting new group counts" + ], + [ + "groupUploadInterval", + "Minimum interval to wait before setting new group counts" + ], + [ + "hiDef", + "True if the game video is running in high-def." + ], + [ + "hostileNameFontColor", + "" + ], + [ + "hostileNameFontGlowColor", + "" + ], + [ + "httpnetfs", + "Stream fastfiles from the specified http server" + ], + [ + "hud_bloodOverlayLerpRate", + "Rate at which blood overlay fades out" + ], + [ + "hud_deathQuoteFadeTime", + "The time for the death quote to fade" + ], + [ + "hud_drawHUD", + "Draw HUD elements. Controlled from non-UI script" + ], + [ + "hud_fade_ammodisplay", + "The time for the ammo display to fade in seconds" + ], + [ + "hud_fade_compass", + "The time for the compass to fade in seconds" + ], + [ + "hud_fade_healthbar", + "The time for the health bar to fade in seconds" + ], + [ + "hud_fade_offhand", + "The time for the offhand weapons to fade in seconds" + ], + [ + "hud_fade_sprint", + "The time for the sprint meter to fade in seconds" + ], + [ + "hud_fade_stance", + "The time for the stance to fade in seconds" + ], + [ + "hud_flash_period_offhand", + "Offhand weapons flash period on changing weapon" + ], + [ + "hud_flash_time_offhand", + "Offhand weapons flash duration on changing weapon" + ], + [ + "hud_forceMantleHint", + "When true, forces the display of the mantle hint. Can still be overridden by, for example, hud drawing being off." + ], + [ + "hud_health_pulserate_critical", + "The pulse rate of the 'critical' pulse effect" + ], + [ + "hud_health_pulserate_injured", + "The pulse rate of the 'injured' pulse effect" + ], + [ + "hud_health_startpulse_critical", + "The health level at which to start the 'injured' pulse effect" + ], + [ + "hud_health_startpulse_injured", + "The health level at which to start the 'injured' pulse effect" + ], + [ + "hud_letterBoxFadeTime", + "The time for the letter box to fade after slam zoom" + ], + [ + "hud_lui_hideshow_debug", + "Debug the hide/show debug info" + ], + [ + "hud_missionFailed", + "Intended to be set by script and referenced by hud.menu elements." + ], + [ + "hud_showStance", + "When true, allow player's stance indicator to draw." + ], + [ + "hudElemPausedBrightness", + "Brightness of the hudelems when the game is paused." + ], + [ + "hudOutlineDuringADS", + "Turn on the HUD outline (green for friendly, red for enemy) when you are pointing at a player while in ADS." + ], + [ + "igs_sosp", + "Show Original Season Pass" + ], + [ + "igs_td", + "Show Trial DLC" + ], + [ + "imageCache_allocationLimit", + "Limit in GB image cache is allowed to allocate" + ], + [ + "imageCache_ShowDebugPrints", + "Enable image cache debug prints to aid in following images through the system." + ], + [ + "intro", + "Intro movie should play" + ], + [ + "inventoryHasAllItems", + "Simulate all items being in the inventory" + ], + [ + "inviteText", + "Text to display for the game invite" + ], + [ + "jump_auto_mantle", + "Auto mantle when jumping" + ], + [ + "jump_auto_mantle_max_z_vel", + "Auto mantle when high jumping" + ], + [ + "jump_height", + "The maximum height of a player's jump" + ], + [ + "jump_ladderPushVel", + "The velocity of a jump off of a ladder" + ], + [ + "jump_slowdownEnable", + "Slow player movement after jumping" + ], + [ + "jump_spreadAdd", + "The amount of spread scale to add as a side effect of jumping" + ], + [ + "jump_stepSize", + "The maximum step up to the top of a jump arc" + ], + [ + "laserDebug", + "Enables the display of various debug info." + ], + [ + "laserForceOn", + "Force laser sights on in all possible places (for debug purposes)." + ], + [ + "lb_file", + "Current Spec Ops leaderboard file" + ], + [ + "lb_filter", + "Filter applied to the leaderboard display: ('none','friends','facebook_friends')" + ], + [ + "lb_filter_duration", + "Current Spec Ops leaderboard filter duration" + ], + [ + "lb_group", + "GroupID applied to the leaderboard display" + ], + [ + "lb_maxrows", + "Maximum number of rows to fetch" + ], + [ + "lb_minrefresh", + "Minimum time (in seconds) between leaderboard fetches" + ], + [ + "lb_readDelay", + "Delay time between reads(in milliseconds) between leaderboard fetches" + ], + [ + "lb_throttle_time", + "Lobby throttling amount" + ], + [ + "lb_times_in_window", + "Lobby throttling window amount" + ], + [ + "lb_window", + "Lobby throttling window" + ], + [ + "le_verbose", + "Light edit system verbosity" + ], + [ + "limited_mode", + "" + ], + [ + "live_qosec_firstupdatems", + "MS to wait before deciding to early out qos" + ], + [ + "live_qosec_lastupdatems", + "MS since last update required to early out qos" + ], + [ + "live_qosec_maxtime", + "Maximum time to allow before qos early out, even if no results" + ], + [ + "live_qosec_minpercent", + "Minimum percentage of probe results required before early outing qos" + ], + [ + "live_qosec_minprobes", + "Minimum probe results required before early outing qos" + ], + [ + "live_test_onlinedataoff", + "Bit flags corresponding enum OnlineDataSyncFlags that indicate we do not have that piece of data" + ], + [ + "liveanticheatunknowndvar", + "Live Anti Cheat Unknown Dvar" + ], + [ + "livestreaming_active", + "Are we allowed to enable LiveStreaming or not" + ], + [ + "livestreaming_bitrate", + "Maximum bitrate of the stream" + ], + [ + "livestreaming_enable", + "Enable streaming video output. Stream displays standin audio/video when disabled." + ], + [ + "livestreaming_enablearchive", + "Allow live stream to be archived by the streaming service." + ], + [ + "livestreaming_metadata", + "Metadata for livestreaming, visible to viewers." + ], + [ + "lmc", + "Load my changes fast file on devmap." + ], + [ + "loading_sre_fatal", + "Loading errors prevent level from loading." + ], + [ + "loc_language", + "Language" + ], + [ + "loc_translate", + "Enable translations" + ], + [ + "loc_warnings", + "Enable localization warnings" + ], + [ + "loc_warningsAsErrors", + "Throw an error for any unlocalized string" + ], + [ + "loc_warningsUI", + "Enable localization warnings for UI" + ], + [ + "lockAllItems", + "Simulate all items being locked" + ], + [ + "log_host_migration_chance", + "The % chance of host migration results telemetry" + ], + [ + "log_ImageLoadTime", + "Toggle the output of images loading time" + ], + [ + "log_mapvote_chance", + "The % chance of sending map vote telemetry" + ], + [ + "log_teambalance_chance", + "The % chance of team balance results telemetry" + ], + [ + "logfile", + "Write to log file - 0 = disabled, 1 = async file write, 2 = Sync every write" + ], + [ + "logScriptTimes", + "Log times for every print called from script" + ], + [ + "lowAmmoWarningColor1", + "Color 1 of 2 to oscilate between" + ], + [ + "lowAmmoWarningColor2", + "Color 2 of 2 to oscilate between" + ], + [ + "lowAmmoWarningNoAmmoColor1", + "Like lowAmmoWarningColor1, but when no ammo." + ], + [ + "lowAmmoWarningNoAmmoColor2", + "lowAmmoWarningColor2, but when no ammo." + ], + [ + "lowAmmoWarningNoReloadColor1", + "Like lowAmmoWarningColor1, but when no ammo." + ], + [ + "lowAmmoWarningNoReloadColor2", + "lowAmmoWarningColor2, but when no ammo." + ], + [ + "lowAmmoWarningPulseFreq", + "Frequency of the pulse (oscilation between the 2 colors)" + ], + [ + "lowAmmoWarningPulseMax", + "Min of oscilation range: 0 is color1 and 1.0 is color2. Can be < 0, and the wave will clip at 0." + ], + [ + "lowAmmoWarningPulseMin", + "Max of oscilation range: 0 is color1 and 1.0 is color2. Can be > 1.0, and the wave will clip at 1.0." + ], + [ + "ls_enableLevelStatTracking", + "if true, level stat tracking can be turned on/off. Set this on the command line before startup." + ], + [ + "lsp_enumertion_max_retry_time", + "Max time that the LSP enumeration can retry" + ], + [ + "lsp_enumertion_retry_step", + "Step in m/s for the LSP enumeration retry" + ], + [ + "lui_demoMode", + "Check if the game is in demo mode." + ], + [ + "lui_disable_blur", + "Disable LUI blur" + ], + [ + "lui_drawdesigngrid", + "Show design grid." + ], + [ + "lui_drawmemreport", + "Show information about memory usage of the LUI system" + ], + [ + "lui_enabled", + "Enables LUI" + ], + [ + "lui_FFotDLocalLoadEnabled", + "Load the ffotd.lua file from the local patch for testing (Dev Only)" + ], + [ + "lui_FFotDSupportEnabled", + "Enables lui to update itself via the ffotd" + ], + [ + "lui_forcelinedraws", + "Force the minimum size of a quad to be at least 1 pixel" + ], + [ + "lui_hud_motion_angle_ease_speed", + "Hud motion ease percentage of degrees per second" + ], + [ + "lui_hud_motion_bob_scale", + "Hud motion bob scale" + ], + [ + "lui_hud_motion_enabled", + "Enable hud motion" + ], + [ + "lui_hud_motion_perspective", + "value for hud motion perspective transform in pixels" + ], + [ + "lui_hud_motion_rotation_max", + "Hud motion rotation max" + ], + [ + "lui_hud_motion_rotation_scale", + "Hud motion rotation scale" + ], + [ + "lui_hud_motion_trans_ease_speed", + "Hud motion ease percentage of pixels per second" + ], + [ + "lui_hud_motion_translation_max", + "Hud motion translation max" + ], + [ + "lui_hud_motion_translation_scale", + "Hud motion translation scale" + ], + [ + "LUI_MemErrorsFatal", + "Out of memory errors cause drops when true, reinits the UI system if false" + ], + [ + "lui_menuFlowEnabled", + "Enables LUI menu flow" + ], + [ + "lui_pausemenu", + "Use the lui version of the pausemenu" + ], + [ + "lui_ReloadMenuRestore", + "Restore the menu state after luiReload" + ], + [ + "lui_splitscreenExtraMemory", + "Increase the memory grab in splitscreen" + ], + [ + "lui_splitscreensignin_menu", + "Enables the LUI splitscreensignin menu" + ], + [ + "lui_splitscreenupscaling", + "Force splitscreen upscaling off/on (-1 off, 1 on) -- requires map change" + ], + [ + "lui_systemlink_menu", + "Enables the LUI systemlink menu" + ], + [ + "lui_timescale", + "Scale time of each frame of LUI animation" + ], + [ + "lui_waitingforgavelmessagesconfirmed", + "" + ], + [ + "lui_waitingfornetworktype", + "value is LuiWaitingForNetworkType enum" + ], + [ + "lui_waitingforonlinedatafetch_controller", + "the controller index that is fetching the online stats data" + ], + [ + "LUI_WorkerCmdGC", + "Dev-only flag to enable/disable LUI workerCmd GC thread" + ], + [ + "lui_xboxlive_menu", + "Enables the LUI xboxlive menu" + ], + [ + "m_filter", + "Allow mouse movement smoothing" + ], + [ + "m_forward", + "Forward speed in units per second" + ], + [ + "m_pitch", + "Default pitch" + ], + [ + "m_side", + "Sideways motion in units per second" + ], + [ + "m_vehMouseSteerSensitivity", + "Vehicle mouse steering sensitivity" + ], + [ + "m_yaw", + "Default yaw" + ], + [ + "mangleDWStats", + "0=do nothing, 1=pretend file doesn't exist--reset, 2=pretend file is corrupted--reset, 3=pretend you're a hacker and we reset your stats" + ], + [ + "manifestfs", + "Use a manifest file to read segmented fastfiles" + ], + [ + "mantle_anim_rate_max", + "Max anim rate when sprinting at mantle" + ], + [ + "mantle_anim_rate_min", + "Min anim rate when mantling." + ], + [ + "mantle_check_angle", + "The minimum angle from the player to a mantle surface to allow a mantle" + ], + [ + "mantle_check_radius", + "The player radius to test against while mantling" + ], + [ + "mantle_check_range", + "" + ], + [ + "mantle_check_range_smooth", + "" + ], + [ + "mantle_debug", + "Show debug information for mantling" + ], + [ + "mantle_debugLineTime", + "How long to show lines when mantle_debug lines" + ], + [ + "mantle_enable", + "Enable player mantling" + ], + [ + "mantle_max_time", + "Max time (ms) to mantle. Can take less time depending on speed when approaching mantle. Must be greater than mantle_min_time" + ], + [ + "mantle_min_over_dist", + "The min mantle over distance a player can traverse horizontally. The over distance can increase depending on speed." + ], + [ + "mantle_on_dist_override", + "If non-zero, overrides the minimum mantle on distance" + ], + [ + "mantle_over_dist_21", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_over_dist_27", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_over_dist_33", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_over_dist_39", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_over_dist_45", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_over_dist_51", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_over_dist_57", + "The max mantle over distance a player can traverse horizontally when sprinting for 57 height" + ], + [ + "mantle_pitch_clamp_enabled", + "Enable pitch clamping code" + ], + [ + "mantle_pitch_default_contact_time", + "When 3p animation doesn't have 'contact' notetrack, use this time to lerp into a fixed pitch" + ], + [ + "mantle_pitch_default_return_time_on", + "When 3p animation doesn't have 'return_pitch' notetrack on a mantle up, use this time to start lerping back to original pitch" + ], + [ + "mantle_pitch_default_return_time_over", + "When 3p animation doesn't have 'return_pitch' notetrack on a mantle up, use this time to start lerping back to original pitch" + ], + [ + "mantle_pitch_return_lerp_time", + "Time for pitch to return to original pitch when mantle started" + ], + [ + "mantle_use_approach_angle", + "Use the approach angle when mantling instead of surface normal" + ], + [ + "mantle_view_yawcap", + "The angle at which to restrict a sideways turn while mantling" + ], + [ + "mapname", + "current map name" + ], + [ + "mapPackMask", + "Mask of map packs that are available for debugging" + ], + [ + "mapPackTwoEnabled", + "" + ], + [ + "marketing_active", + "Are we allowed to enable Marketing Comms or not" + ], + [ + "marketing_autorefresh", + "automatically download new messages after reporting any message read" + ], + [ + "marketing_refresh_time", + "time in seconds to wait before refreshing marketing messages from demonware" + ], + [ + "marketing_simulatefakemotd", + "Simulate a fake Marketing MOTD" + ], + [ + "match_making_telemetry_chance", + "The % chance of sending match making telemetry" + ], + [ + "matchdata_active", + "Are match data uploads enabled" + ], + [ + "matchdata_maxcompressionbuffer", + "" + ], + [ + "max_ping_threshold_good", + "max ping value to be considered as good" + ], + [ + "max_ping_threshold_medium", + "max ping value to be considered as medium" + ], + [ + "maxPrestigeOverride", + "Overrides the maximum prestige level, disabled if 0." + ], + [ + "mdsd", + "enable match data stat delta logging?" + ], + [ + "meetPlayer_ListUpdateInterval", + "Time in milliseconds since uploaded recent met player list." + ], + [ + "meetPlayer_ListUploadInterval", + "This dvar is used to make sure that recent met player list get updates only when it changes." + ], + [ + "melee_debug", + "Turn on debug lines for melee traces" + ], + [ + "mis_cheat", + "Set when level unlock cheat is performed" + ], + [ + "missileCoastingSpeed", + "Speed of missiles when coasting." + ], + [ + "missileDebugAttractors", + "Draw the attractors and repulsors. Attractors are green, and repulsors are yellow. 0 = off, 1 = show origin, 2 = draw sphere, 3 = draw sphere depth checked" + ], + [ + "missileDebugDraw", + "Draw guided missile trajectories." + ], + [ + "missileDebugText", + "Print debug missile info to console." + ], + [ + "missileExplosionLiftDistance", + "Distance to lift the explosion off the surface for \"big explosion\" weapons" + ], + [ + "missileGlassShatterVel", + "Velocity needed by a grenade or missile to shatter glass instead of bouncing off." + ], + [ + "missileHellfireMaxSlope", + "This limits how steeply the hellfire missile can turn upward when climbing" + ], + [ + "missileHellfireUpAccel", + "The rate at which the hellfire missile curves upward" + ], + [ + "missileJavAccelClimb", + "Rocket acceleration when climbing." + ], + [ + "missileJavAccelDescend", + "Rocket acceleration when descending towards target." + ], + [ + "missileJavClimbAngleDirect", + "In direct-fire mode, the minimum angle between the rocket and target until the rocket stops climbing. Smaller angles make for higher climbs." + ], + [ + "missileJavClimbAngleTop", + "In top-fire mode, the minimum angle between the rocket and target until the rocket stops climbing. Smaller angles make for higher climbs." + ], + [ + "missileJavClimbCeilingDirect", + "In direct-fire mode, how high the missile needs to reach before it descends." + ], + [ + "missileJavClimbCeilingTop", + "In top-fire mode, how high the missile needs to reach before it descends." + ], + [ + "missileJavClimbHeightDirect", + "In direct-fire mode, how far above the target the rocket will aim for when climbing." + ], + [ + "missileJavClimbHeightTop", + "In top-fire mode, how far above the target the rocket will aim for when climbing." + ], + [ + "missileJavClimbToOwner", + "" + ], + [ + "missileJavDuds", + "If true, javelins that impact before their booster ignites will not explode, they will play their dud effects instead." + ], + [ + "missileJavSpeedLimitClimb", + "Rocket's speed limit when climbing." + ], + [ + "missileJavSpeedLimitDescend", + "Rocket's speed limit when descending towards target." + ], + [ + "missileJavTurnDecel", + "" + ], + [ + "missileJavTurnRateDirect", + "In direct-fire mode, how sharp the rocket can turn, in angles/sec." + ], + [ + "missileJavTurnRateTop", + "In top-fire mode, how sharp the rocket can turn, in angles/sec." + ], + [ + "missileMacross", + "Swarmy goodness." + ], + [ + "missileRemoteFOV", + "Remote missile-cam, FOV to use." + ], + [ + "missileRemoteSpeedDown", + "Remote-controlled missile slowdown-factor." + ], + [ + "missileRemoteSpeedTargetRange", + "Remote-controlled missile speeds." + ], + [ + "missileRemoteSpeedUp", + "Remote-controlled missile speedup-factor." + ], + [ + "missileRemoteSteerPitchRange", + "Remote-controlled missile allowed up/down range. To keep players from steering missiles above the horizon." + ], + [ + "missileRemoteSteerPitchRate", + "Remote-controlled missile up/down steering speed." + ], + [ + "missileRemoteSteerYawRate", + "Remote-controlled missile left/right steering speed." + ], + [ + "missileWaterMaxDepth", + "If a missile explodes deeper under water than this, they explosion effect/sound will not play." + ], + [ + "modPrvAnimApplyDelta", + "Model previewer animation apply delta" + ], + [ + "modPrvAnimBlendMode", + "Model previewer animation blending mode" + ], + [ + "modPrvAnimBlendWeight", + "Model previewer animation blend weight" + ], + [ + "modPrvAnimCrossBlendDuration", + "Model previewer animation cross blend duration" + ], + [ + "modPrvAnimCrossBlendTime", + "Model previewer animation cross blending time" + ], + [ + "modPrvAnimForceLoop", + "Model Previewer - Force an animation loop" + ], + [ + "modPrvAnimMruName0", + "Model previewer most recently used anim name 0" + ], + [ + "modPrvAnimMruName1", + "Model previewer most recently used anim name 0" + ], + [ + "modPrvAnimMruName2", + "Model previewer most recently used anim name 0" + ], + [ + "modPrvAnimMruName3", + "Model previewer most recently used anim name 0" + ], + [ + "modPrvAnimRate", + "Model previewer - animation rate" + ], + [ + "modPrvCenterOffset", + "Model previewer center offset" + ], + [ + "modPrvDisplayToggle", + "Show model previewer overlay" + ], + [ + "modPrvDrawAxis", + "Draw the model previewer axes" + ], + [ + "modPrvDrawBoneInfo", + "Draw model previewer bone information" + ], + [ + "modPrvDrawDistanceToModel", + "Print viewer's distance to model." + ], + [ + "modPrvForceUpdate", + "Force modPrvLoadModel to be re-evaluated." + ], + [ + "modPrvFromAnimMru", + "Model previewer most recently used 'from' animation" + ], + [ + "modPrvGamepadControlSpeed", + "Model previewer game pad control speed" + ], + [ + "modPrvHideModel", + "Skip drawing the model." + ], + [ + "modPrvLoadFromAnim", + "Model previewer loaded 'from' animation" + ], + [ + "modPrvLoadModel", + "Model previewer loaded model" + ], + [ + "modPrvLoadToAnim", + "Model previewer loaded 'to' animation" + ], + [ + "modPrvLod", + "Model previewer level of detail" + ], + [ + "modPrvMatOverrideFrom", + "This material in the current model will be replaced by modPrvMatOverrideTo" + ], + [ + "modPrvMatOverrideTo", + "This material will replace the material specified by modPrvMatOverrideFrom in the current model" + ], + [ + "modPrvMatReplace", + "Model previewer material replace" + ], + [ + "modPrvMatSelect", + "Model previewer material select" + ], + [ + "modPrvModelMru", + "Model previewer most recently used model" + ], + [ + "modPrvModelMruName0", + "Model previewer most recently used model" + ], + [ + "modPrvModelMruName1", + "Model previewer most recently used model" + ], + [ + "modPrvModelMruName2", + "Model previewer most recently used model" + ], + [ + "modPrvModelMruName3", + "Model previewer most recently used model" + ], + [ + "modPrvOrigin", + "Model previewer origin" + ], + [ + "modPrvRotationAngles", + "Model previwer rotation angles" + ], + [ + "modPrvToAnimMru", + "Model previewer most recently used 'to' animation" + ], + [ + "monkeytoy", + "Restrict console access" + ], + [ + "motd", + "Message of the day" + ], + [ + "motd_store_link", + "Add a link to the in-game store in the MOTD popup" + ], + [ + "motionTrackerBlurDuration", + "The motion blur duration for motion tracker dots" + ], + [ + "motionTrackerCenterX", + "" + ], + [ + "motionTrackerCenterY", + "" + ], + [ + "motionTrackerPingFadeTime", + "How long an enemy is visible on the motion tracker after being detected" + ], + [ + "motionTrackerPingPitchAddPerEnemy", + "The added percentage of pitch for each additional enemy that is detected (final pitch = base pitch * (1 + enemy count * this))" + ], + [ + "motionTrackerPingPitchBase", + "The pitch of the motion tracker sound for a nearby enemy" + ], + [ + "motionTrackerPingPitchNearby", + "The pitch of the motion tracker sound for a nearby enemy" + ], + [ + "motionTrackerPingSize", + "The width and height of the motion tracker's enemy indicators as a percentage of motion tracker scale" + ], + [ + "motionTrackerRange", + "The range, in world units, that the motion tracker displays" + ], + [ + "motionTrackerSweepAngle", + "The maximum angle from straight forward that the motion tracker detects enemies" + ], + [ + "motionTrackerSweepInterval", + "The time between motion tracker sweeps" + ], + [ + "motionTrackerSweepSpeed", + "The speed, in world units per second, of the motion tracker sweep" + ], + [ + "moving_platform_display_antilag", + "Displays mover parent entities that will be included in the antilag calculation for moving platforms. Children are not displayed." + ], + [ + "moving_platform_improved_aim", + "Turns on improved moving platform aim system." + ], + [ + "moving_platform_keep_previous", + "Allows jumping between moving platforms by remembering the player's previous platform while in mid-air." + ], + [ + "moving_platform_rotational_antilag", + "Applies rotational antilag to script movers for moving platform system." + ], + [ + "nextmap", + "The next map name" + ], + [ + "nightVisionDisableEffects", + "" + ], + [ + "nightVisionFadeInOutTime", + "How long the fade to/from black lasts when putting on or removing night vision goggles." + ], + [ + "nightVisionPowerOnTime", + "How long the black-to-nightvision fade lasts when turning on the goggles." + ], + [ + "np_plus_callback_interval_allowed", + "Amount of time we allow before a missed callback means a person no longer has plus access.\n" + ], + [ + "np_status_callback_interval", + "Amount of time between regular calls to sceNpCheckNpAvailability.\n" + ], + [ + "np_status_retry_callback_interval", + "Amount of time to wait after a failure in sceNpCheckNpAvailability before retrying.\n" + ], + [ + "num_available_map_packs", + "Number of map packs available for this platform" + ], + [ + "objectiveAlpha", + "Alpha value for objective waypoints." + ], + [ + "objectiveAlphaEnabled", + "When true, dvar \"objectiveAlpha\" takes effect." + ], + [ + "objectiveArrowHeight", + "Height of the objective pointer." + ], + [ + "objectiveArrowWidth", + "Width of the objective pointer." + ], + [ + "objectiveFadeTimeGoingOff", + "Onscreen Objective Pointer - How long to take to fade out." + ], + [ + "objectiveFadeTimeGoingOn", + "Onscreen Objective Pointer - How long to take to fade out." + ], + [ + "objectiveFadeTimeWaitOff", + "Onscreen Objective Pointer - How long to take to fade out." + ], + [ + "objectiveFadeTimeWaitOn", + "Onscreen Objective Pointer - How long to take to fade out." + ], + [ + "objectiveFadeTooClose", + "Onscreen Objective Pointer - Will not fade out if target ent is farther than this." + ], + [ + "objectiveFadeTooFar", + "Onscreen Objective Pointer - Will not fade out if target ent is farther than this." + ], + [ + "objectiveFontSize", + "Onscreen Objective Pointer - Fontsize of the icon's text." + ], + [ + "objectiveHide", + "When enabled, objectives will not show." + ], + [ + "objectiveHideIcon", + "When true, hides the objective pointer's icon, but will still show the arrow." + ], + [ + "objectiveTextOffsetY", + "Onscreen Objective Pointer - Offset of the icon's text." + ], + [ + "overrideNVGModelWithKnife", + "When true, nightvision animations will attach the weapDef's knife model instead of the night vision goggles." + ], + [ + "painVisionLerpInRate", + "Rate at which pain vision effect lerps in" + ], + [ + "painVisionLerpOutRate", + "Rate at which pain vision effect lerps in" + ], + [ + "partyChatDisallowed", + "Whether to disallow ps4 Live Party Chat" + ], + [ + "partyChatDisconnectTimer", + "Time to wait after user responds to Party Chat dialog before kicking (msec)" + ], + [ + "past_title_data_active", + "Is the past title data system enabled" + ], + [ + "past_title_data_read_failure_interval_hours", + "default interval in which to try and read past title data if kicked off read failed." + ], + [ + "past_title_data_read_success_interval_hours", + "default interval in which to try and read past title data if kicked off read failed." + ], + [ + "path_nodeInfoType", + "Path node information type" + ], + [ + "perk_armorVestDamageMultiplier", + "Multiplier affecting damage while wearing armor vest" + ], + [ + "perk_bulletPenetrationMultiplier", + "Multiplier for extra bullet penetration" + ], + [ + "perk_extendedMagsMGAmmo", + "Number of extra bullets per clip for machine gun weapons with the extended mags perk." + ], + [ + "perk_extendedMagsPistolAmmo", + "Number of extra bullets per clip for pistol weapons with the extended mags perk." + ], + [ + "perk_extendedMagsSMGAmmo", + "Number of extra bullets per clip for sub machine gun weapons with the extended mags perk." + ], + [ + "perk_extendedMagsSpreadAmmo", + "Number of extra bullets per clip for spread weapons with the extended mags perk." + ], + [ + "perk_extendedMeleeRange", + "The range of the auto melee with the extened perk" + ], + [ + "perk_extraBreath", + "Number of extra seconds a player can hold his breath" + ], + [ + "perk_fastOffhandMultiplier", + "Percentage of switching and using offhand weapon time to use" + ], + [ + "perk_fastSnipeScale", + "Scales the recovery speed of the view kick when using a sniper." + ], + [ + "perk_flinchMultiplier", + "Multiplier affecting flinch" + ], + [ + "perk_footstepVolumeAlly", + "" + ], + [ + "perk_footstepVolumeEnemy", + "" + ], + [ + "perk_footstepVolumePlayer", + "" + ], + [ + "perk_footstepVolumeSelectiveHearingMin", + "" + ], + [ + "perk_improvedExtraBreath", + "Number of extra seconds a player can hold his breath" + ], + [ + "perk_lightWeightViewBobScale", + "Scale for first person view movement while lightweight." + ], + [ + "perk_mantleSpeedMultiplier", + "Multiplier affecting mantling speed" + ], + [ + "perk_numExtraLethal", + "Number of extra lethal grenades" + ], + [ + "perk_numExtraTactical", + "Number of extra tactical grenades" + ], + [ + "perk_parabolicAngle", + "Eavesdrop perk's effective FOV angle" + ], + [ + "perk_parabolicIcon", + "Eavesdrop icon to use when displaying eavesdropped voice chats" + ], + [ + "perk_parabolicRadius", + "Eavesdrop perk's effective radius" + ], + [ + "perk_quickDrawSpeedScale", + "Scales the 'Hip to ADS' transition speed." + ], + [ + "perk_recoilMultiplier", + "Multiplier affecting recoil" + ], + [ + "perk_resistExplosionDamageMultiplier", + "Multiplier affecting damage with resist explosion" + ], + [ + "perk_resistShellShockMultiplier", + "Multiplier affecting damage with resist explosion" + ], + [ + "perk_sprintMultiplier", + "Multiplier for player_sprinttime" + ], + [ + "perk_sprintRecoveryMultiplierActual", + "" + ], + [ + "perk_sprintRecoveryMultiplierVisual", + "" + ], + [ + "perk_weapRateMultiplier", + "Percentage of weapon firing rate to use" + ], + [ + "perk_weapReloadMultiplier", + "Percentage of weapon reload time to use" + ], + [ + "perk_weapSpreadMultiplier", + "Percentage of weapon spread to use" + ], + [ + "perk_weapSwapMultiplier", + "Percentage of weapon swap time to use" + ], + [ + "phsyVeh_enableBalanceLoad", + "Force the load at each wheel to share the entire weight of the vehicle equally. (Requires map restart)" + ], + [ + "phys_autoDisableLinear", + "A body must have linear velocity less than this to be considered idle." + ], + [ + "phys_autoDisableTime", + "The amount of time a body must be idle for it to go to sleep." + ], + [ + "phys_bulletSpinScale", + "Scale of the effective offset from the center of mass for the bullet impacts." + ], + [ + "phys_bulletUpBias", + "Up Bias for the direction of the bullet impact." + ], + [ + "phys_dragAngular", + "The amount of angular drag, applied globally" + ], + [ + "phys_dragLinear", + "The amount of linear drag, applied globally" + ], + [ + "phys_drawAwake", + "Debug draw a box indicating which bodies are disabled" + ], + [ + "phys_drawBroadPhase", + "Debug draw broadphase AABBs" + ], + [ + "phys_drawCenterOfMass", + "Debug draw center of masses" + ], + [ + "phys_drawCollision", + "Draw collision for specified world" + ], + [ + "phys_drawContacts", + "Debug draw contact points" + ], + [ + "phys_drawDebugInfo", + "Print info about the physics objects" + ], + [ + "phys_drawDistance", + "Size of region centered around player to draw debug physics information" + ], + [ + "phys_drawJoints", + "Debug draw joints" + ], + [ + "phys_dumpWorld", + "Debug dump out physics world" + ], + [ + "phys_earthquakeStrengthScale", + "The earthquake force overall strength multiplier. Multiplies the scale passed into Earthquake script function." + ], + [ + "phys_earthquakeWaveFrequency", + "The earthquake force wave frequency of oscillation" + ], + [ + "phys_earthquakeWaveLength", + "The earthquake force wave length" + ], + [ + "phys_enableContinuousCollision", + "Enable continuous collision detection" + ], + [ + "phys_enablePicking", + "Enable picking up physics bodies. Hover over dynamic physics body, then press and hold L3 to activate." + ], + [ + "phys_enableSleep", + "Enable rigid body deactivation" + ], + [ + "phys_gravity", + "Physics gravity in units/sec^2." + ], + [ + "phys_gravity_ragdoll", + "Physics gravity used by ragdolls in units/sec^2." + ], + [ + "phys_gravityChangeWakeupRadius", + "The radius around the player within which objects get awakened when gravity changes" + ], + [ + "phys_jitterMaxMass", + "Maximum mass to jitter - jitter will fall off up to this mass" + ], + [ + "phys_maxTimeStep", + "Max physics time step in seconds" + ], + [ + "phys_rollingResistance", + "The amount of rolling resistance, applied globally" + ], + [ + "phys_solverPositionIterations", + "Number of solver position iterations used for constraint solving." + ], + [ + "phys_solverVelocityIterations", + "Number of solver velocity iterations used for constraint solving." + ], + [ + "phys_solverWarmStarting", + "Enable solver warm starting for better stability" + ], + [ + "physVeh_antiRollScale", + "Amount to scale antiroll force (Requires map restart)" + ], + [ + "physVeh_dampingCoefficientScale", + "Scale applied to the suspension damping strength. (Requires map restart)" + ], + [ + "physVeh_downForceScale", + "Max amount of downforce proportional to gravity that is applied. (Requires map restart)" + ], + [ + "physVeh_explodeForce", + "The force applied to physics vehicles due to explosions" + ], + [ + "physVeh_explodeSpinScale", + "The max (random) offset from the center of mass at which splash damage applies its force" + ], + [ + "physVeh_jump", + "Set to 1 to make a vehicle jump." + ], + [ + "physVeh_lateralFrictionScale", + "Scale applied to lateral/side friction. (Requires map restart)" + ], + [ + "physVeh_minContactImpulse", + "The minimum impulse needed to register a contact notification" + ], + [ + "physVeh_minImpactMomentum", + "The minimum collision momentum needed to register an impact" + ], + [ + "physVeh_sideToFrontFrictionScale", + "Ratio between longitudinal friction and lateral friction. (Requires map restart)" + ], + [ + "physVeh_speedIntegralMaxError", + "The absolute accumulated error between desired - current speed over time is clamped by this value over time. Lower this value to limit overshoot of target speed due to integral windup." + ], + [ + "physVeh_springCoefficientScale", + "Scale applied to the suspension spring strength. (Requires map restart)" + ], + [ + "physVeh_StepsPerFrame", + "The number of physics timesteps that the server frame will be divided into." + ], + [ + "pickupPrints", + "Print a message to the game window when picking up ammo, etc." + ], + [ + "player_adsExitDelayGamepad", + "Delay before exiting aim down sight with mouse" + ], + [ + "player_adsExitDelayMouse", + "Delay before exiting aim down sight with mouse" + ], + [ + "player_backSpeedScale", + "The scale applied to the player speed when strafing" + ], + [ + "player_breath_fire_delay", + "The amount of time subtracted from the player remaining breath time when a weapon is fired" + ], + [ + "player_breath_gasp_lerp", + "The interpolation rate for the target waver amplitude when gasping" + ], + [ + "player_breath_gasp_scale", + "Scale value to apply to the target waver during a gasp" + ], + [ + "player_breath_gasp_time", + "The amount of time a player will gasp once they can breath again" + ], + [ + "player_breath_hold_lerp", + "The interpolation rate for the target waver amplitude when gasping" + ], + [ + "player_breath_hold_time", + "The maximum time a player can hold his breath" + ], + [ + "player_breath_snd_delay", + "The delay before playing the breathe in sound" + ], + [ + "player_breath_snd_lerp", + "The interpolation rate for the player hold breath sound" + ], + [ + "player_damageMultiplier", + "Player damage is scaled by this amount; used by script for setting difficulty level" + ], + [ + "player_deathInvulnerableToMelee", + "The player is invulnerable to melee attacks during death invulnerability" + ], + [ + "player_deathInvulnerableToProjectile", + "The player is invulnerable to projectile attacks during death invulnerability" + ], + [ + "player_debugHealth", + "Turn on debugging info for player health" + ], + [ + "player_debugTrace", + "Show player trace debug planes" + ], + [ + "player_dmgtimer_flinchTime", + "Maximum time to play flinch animations" + ], + [ + "player_dmgtimer_maxTime", + "The maximum time that the player is slowed due to damage" + ], + [ + "player_dmgtimer_minScale", + "The minimum scale value to slow the player by when damaged" + ], + [ + "player_dmgtimer_stumbleTime", + "Maximum time to play stumble animations" + ], + [ + "player_dmgtimer_timePerPoint", + "The time in milliseconds that the player is slowed down per point of damage" + ], + [ + "player_footstepsThreshhold", + "The minimum speed at which the player makes loud footstep noises" + ], + [ + "player_footstepsThreshholdCrouch", + "The minimum speed at which the player makes loud footstep noises" + ], + [ + "player_footstepsThreshholdProne", + "The minimum speed at which the player makes loud footstep noises" + ], + [ + "player_lastStandCrawlSpeedScale", + "The scale applied to the player speed when strafing" + ], + [ + "player_lastStandDebug", + "Forces players into last stand for debugging purposes." + ], + [ + "player_lateralPlane", + "The plane used for the player's lateral movement." + ], + [ + "player_meleeChargeFriction", + "Friction used during melee charge" + ], + [ + "player_meleeChargeHeightTolerance", + "Height tolerance to allow charging to a victim. If victim and attacker heights are greater than this value, attack will always do swipe" + ], + [ + "player_meleeChargeMaxSpeed", + "Max speed to clamp when doing a charge melee" + ], + [ + "player_meleeChargeMaxSpeedUp", + "Max vertical (up) speed to clamp when doing a charge melee" + ], + [ + "player_meleeChargePlayerLockTime", + "The amount of time, in milliseconds, to lock the player's movement when performing a melee charge" + ], + [ + "player_meleeDamageMultiplier", + "Melee damage to the player is scaled by this amount; used by script for setting difficulty level" + ], + [ + "player_meleeForceAlternate", + "Forces the player to use alternate melee even if the PWF is not set." + ], + [ + "player_meleeForceServerMiss", + "Force the server to always miss melee" + ], + [ + "player_meleeHeight", + "The height of the player's melee attack" + ], + [ + "player_meleeIdealEndDistance", + "Ideal distance that the melee attacker and victim should be apart from each other when melee ends. -1 means off" + ], + [ + "player_meleeMaxQuickRaiseTime", + "After melee is done, max quickraise time. Allows raising weapon quicker to give more responsive feel after melee." + ], + [ + "player_meleeMinimumResponseGraceTime", + "Melee Combo: max input roundtrip time (ms) before considering player to have skipped combo input" + ], + [ + "player_meleeRange", + "The maximum range of the player's melee attack" + ], + [ + "player_meleeRangeCharge", + "The maximum range of the player's melee attack" + ], + [ + "player_meleeSwipePlayerLockTime", + "When swiping, lock player view and movement for this number of milliseconds" + ], + [ + "player_meleeSwipeViewLockReleaseTime", + "When swiping, lock player view until this much weapon time left." + ], + [ + "player_meleeWidth", + "The width of the player's melee attack" + ], + [ + "player_MGUseRadius", + "The radius within which a player can mount a machine gun" + ], + [ + "player_moveThreshhold", + "The speed at which the player is considered to be moving for the purposes of \nview model bob and multiplayer model movement" + ], + [ + "player_on_vehicle_aim_fix", + "Turns on/off aim fix while player is on a vehicle or platform. Defaults to on." + ], + [ + "player_prone_view_pitch_down", + "Maximum angle that the player can look up" + ], + [ + "player_prone_view_pitch_up", + "Maximum angle that the player can look up" + ], + [ + "player_radiusDamageMultiplier", + "Radius damage to the player is scaled by this amount; used by script for setting difficulty level" + ], + [ + "player_runThreshhold", + "The speed threshold before a player is considered to be running forwards" + ], + [ + "player_scope_prototype", + "Enables the 'scope drift' system that takes the place of the current 'hold breath' system" + ], + [ + "player_scopeExitOnDamage", + "Exit the scope if the player takes damage" + ], + [ + "player_shield_postUseWeaponDelay", + "The delay between putting down the exo-shield and being able to fire your weapon again." + ], + [ + "player_spaceCapsuleHeight", + "Player capsule height. 70 = standing, 50 = crouch, 30 = prone" + ], + [ + "player_spaceEnabled", + "True if player space logic is enabled. (Player must also be swim enabled)" + ], + [ + "player_spaceViewHeight", + "Camera view height. 60 = standing, 40 = crouch, 11 = prone" + ], + [ + "player_spectateSpeedScale", + "The scale applied to the player speed when strafing" + ], + [ + "player_sprintCameraBob", + "The speed the camera bobs while you sprint" + ], + [ + "player_sprintForwardMinimum", + "The minimum forward deflection required to maintain a sprint" + ], + [ + "player_sprintJumpAnimRate", + "If > 0, allow sprint to persist through jumps. The value also determins anim rate to play sprint loop at while jumping." + ], + [ + "player_sprintJumpDropWeaponScaler", + "If 'player_sprintJumpAnimRate' is set, this dvar scales down the time sprint drop timer when player is in the air and wants to fire." + ], + [ + "player_sprintMinTime", + "The minimum sprint time needed in order to start sprinting" + ], + [ + "player_sprintRechargePause", + "The length of time the meter will pause before starting to recharge after a player sprints" + ], + [ + "player_sprintSpeedScale", + "The scale applied to the player speed when strafing" + ], + [ + "player_sprintStrafeSpeedScale", + "The speed at which you can strafe while sprinting" + ], + [ + "player_sprintTime", + "The base length of time a player can sprint" + ], + [ + "player_sprintUnlimited", + "Whether players can sprint forever or not" + ], + [ + "player_strafeAnimCosAngle", + "Cosine of the angle which player starts using strafe animations" + ], + [ + "player_strafeSpeedScale", + "The scale applied to the player speed when strafing" + ], + [ + "player_sustainAmmo", + "Firing weapon will not decrease clip ammo." + ], + [ + "player_swimAcceleration", + "Forward/lateral swim acceleration" + ], + [ + "player_swimCombatTimer", + "Time (ms) at which viewmodel switches from combat to relaxed animation state when not firing" + ], + [ + "player_swimDragHandEnabled", + "Enable/disable left hand drag during swimming" + ], + [ + "player_swimDragHandFrictionMax", + "Max friction value to bring the dragging hand back to default idle position" + ], + [ + "player_swimDragHandFrictionMin", + "Min friction value to bring the dragging hand back to default idle position" + ], + [ + "player_swimDragHandLookAtOffset", + "Forward axis offset to compare against last look at position for hand drag anims" + ], + [ + "player_swimForwardAnimCatchupMax", + "Lerped max speed to extend or retract arms if player is moving forward or back" + ], + [ + "player_swimForwardAnimCatchupMin", + "Lerped min speed to extend or retract arms if player is moving forward or back" + ], + [ + "player_swimForwardMinAngle", + "Min angle (relative to forward axis) for player to be in swim forward state" + ], + [ + "player_swimForwardMinSpeed", + "Min speed (relative to forward axis) for player to be in swim forward state" + ], + [ + "player_swimForwardSettleTime", + "Time (ms) that player will stay in swim forward state even if outside parameters when already in forward state" + ], + [ + "player_swimForwardWarmupTime", + "Time (ms) that player has to wait before moving into swim forward state once speed and angle are met" + ], + [ + "player_swimFriction", + "Friction value applied to velocity when swimming and no input is given" + ], + [ + "player_swimSpeed", + "Max forward/lateral swim speed" + ], + [ + "player_swimVerticalAcceleration", + "Vertical swim acceleration" + ], + [ + "player_swimVerticalFriction", + "Vertical friction value applied to velocity when swimming and no input is given" + ], + [ + "player_swimVerticalSpeed", + "Max vertical swim speed" + ], + [ + "player_swimWaterSurface", + "Water surface Z value" + ], + [ + "player_swimWaterSurfaceEnabled", + "Water surface Z value movement restriction enabled" + ], + [ + "player_throwbackInnerRadius", + "The radius to a live grenade player must be within initially to do a throwback" + ], + [ + "player_throwbackOuterRadius", + "The radius player is allow to throwback a grenade once the player has been in the inner radius" + ], + [ + "player_useRadius", + "The radius within which a player can use things" + ], + [ + "player_view_pitch_down", + "Maximum angle that the player can look up" + ], + [ + "player_view_pitch_up", + "Maximum angle that the player can look up" + ], + [ + "player_walkCameraBob", + "The speed the camera bobs while you walk." + ], + [ + "playercard_cache_download_max_retry_time", + "Max time that the player cache download can retry" + ], + [ + "playercard_cache_download_retry_step", + "Step in m/s for the player cache download retry" + ], + [ + "playercard_cache_show_cached", + "Shows whether a playercard is in the cache or not" + ], + [ + "playercard_cache_upload_max_retry_time", + "Max time that the player cache upload can retry" + ], + [ + "playercard_cache_upload_retry_step", + "Step in m/s for the player cache upload retry" + ], + [ + "playercard_cache_validity_life", + "The life of a cached gamercard (it can be re-downloaded after this)" + ], + [ + "playerPositionRecordSampleTime", + "How often to sample player positions and save them into match data." + ], + [ + "prestige_shop_active", + "Are we allowed to show the Prestige Shop or not" + ], + [ + "prestige30EasterEggEnabled", + "Enables the easter egg for prestige 30 if 1, disabled if 0." + ], + [ + "printSnapshotDetails", + "Log snapshot details (can slow down the game a lot)" + ], + [ + "prof_probe0", + "" + ], + [ + "prof_probe1", + "" + ], + [ + "prof_probe2", + "" + ], + [ + "prof_probe3", + "" + ], + [ + "prof_probe4", + "" + ], + [ + "prof_probeMaxMsec", + "Height of each profile probe graph, in milliseconds" + ], + [ + "prof_sortTime", + "Time in seconds between resort profiles" + ], + [ + "profile", + "" + ], + [ + "profile_rowcount", + "Profile row count" + ], + [ + "profile_script", + "Enable profile scripts" + ], + [ + "profile_script_by_file", + "Enable profile scripts by source file" + ], + [ + "profile_script_hierarchical", + "Toggle hierarchical drawing of script profiling" + ], + [ + "profile_show_loading", + "Show map load profiler" + ], + [ + "profile_thread", + "Thread being profiled" + ], + [ + "profile2", + "" + ], + [ + "profile2_frames", + "Profile frame count" + ], + [ + "profile2_mode", + "Reporting mode" + ], + [ + "profileMenuOption_blacklevel", + "" + ], + [ + "profileMenuOption_offensiveContentMode", + "Mode of the offensive content warning at startup - 0, skip and turn on; 1, skip and turn off; 2, ask user" + ], + [ + "profileMenuOption_safeAreaHorz", + "" + ], + [ + "profileMenuOption_safeAreaVert", + "" + ], + [ + "profileMenuOption_sensitivity", + "" + ], + [ + "profileMenuOption_volume", + "" + ], + [ + "prologue_select", + "Toggles intro.map between the prologue and the persona non grata setup." + ], + [ + "ps4_dw_disconnect_test", + "Turns on automatic random disconnects from demonware to test connectivity code.\n" + ], + [ + "ps4_how_long_to_wait_on_join_ms", + "Delay in milliseconds we're willing to wait before shutting down a join in progress due to lack of friend." + ], + [ + "ps4_meetplayer_rest_submit_delay", + "Number of milliseconds between calls to submit met players to the rest system." + ], + [ + "ps4_num_session_slots_override", + "Override the max number of player slots in a ps4 session. 0 will use the proper number." + ], + [ + "ps4_presence_put_delay", + "Delay in milliseconds after presence changes before sending updated presence through np" + ], + [ + "ps4_presence_put_rate", + "Minimum delay in milliseconds before sending updated presence through np" + ], + [ + "ps4_signin_notify_delay", + "Delay in milliseconds after a sign in status change before we change our sign-in status (in-game)" + ], + [ + "ps4Game", + "True if running on PS4" + ], + [ + "publisherFileFetchTimeout", + "default timeout for publisher files FETCH tasks (in seconds)" + ], + [ + "r_adaptiveSubdiv", + "Enables screen space Catmull Clark adaptive tessellation. If disabled, models tessellate to their designed subdivision level." + ], + [ + "r_adaptiveSubdivBaseFactor", + "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation." + ], + [ + "r_adaptiveSubdivPatchFactor", + "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation." + ], + [ + "r_allCells", + "Draw all cells. Most useful for seeing if portals or cells are hiding things they should not.." + ], + [ + "r_animBoundsScale", + "Scale animated xmodel bounds by the given factor" + ], + [ + "r_animBoundsWarn", + "Warn when model bounds are estimated far off from their actual animated values." + ], + [ + "r_animEstimatedBoundsScale", + "Scale animated xmodel estimated bounds by the given factor" + ], + [ + "r_aoBlurSharpness", + "Controls the tolerance for depth discontinuities during the bilateral blur step. Larger values reduce the depth tolerance and effectively sharpen more edges." + ], + [ + "r_aoBlurStep", + "Step scale applied to sample offsets during the bilateral blur. A value of 1 results in a normal gaussian blur. Increasing it to 2 or 3 makes the filter larger but causes fine dithering patterns." + ], + [ + "r_aoDiminish", + "Decrease the effect of occlusion on brighter colors" + ], + [ + "r_aoPower", + "Power curve applied to AO factor" + ], + [ + "r_aoStrength", + "Strength of Ambient Occlusion effect" + ], + [ + "r_aoUseTweaks", + "Use r_ao* dvars instead of the current light set values for AO common params" + ], + [ + "r_artTweaksLastVisionSet", + "Tells the script which vision set was last set in code" + ], + [ + "r_artUseTweaks", + "Tells the game that art tweaks is enabled and script is in control (as opposed to ColorEd)." + ], + [ + "r_asyncCompute", + "Enables scheduling GPU compute shader work prior to the graphics frame, improving overlap." + ], + [ + "r_atlasAnimFPS", + "Speed to animate atlased 2d materials" + ], + [ + "r_balanceLightmapOpaqueLists", + "Split lightmap opaque into multiple draw lists." + ], + [ + "r_balanceOpaqueLists", + "Split opaque into multiple draw lists." + ], + [ + "r_blacklevel", + "Black level (negative brightens output)" + ], + [ + "r_blendshape_debug", + "Entity number to debug blendshape weights" + ], + [ + "r_blendshape_debug_index", + "Blendshape weight index to debug/force; all others will be 0" + ], + [ + "r_blendshape_debug_value", + "Blendshape weight value to use for debug/force" + ], + [ + "r_blendshape_emulation", + "Enables blendshape emulation" + ], + [ + "r_blendshape_enable", + "Toggles blendshapes" + ], + [ + "r_blur", + "Dev tweak to blur the screen" + ], + [ + "r_blurdstGaussianBlurLevel", + "MIP level to start gaussian blur at" + ], + [ + "r_blurdstGaussianBlurRadius", + "Amount to gaussian blur blur distortion render target" + ], + [ + "r_blurdstShowOverlay", + "Toggles blur distortion overlay" + ], + [ + "r_brightness", + "Brightness adjustment" + ], + [ + "r_cacheModelLighting", + "Speed up model lighting by caching previous results" + ], + [ + "r_cacheSModelLighting", + "Speed up static model lighting by caching previous results" + ], + [ + "r_clampLodScale", + "Clamps the amount that the engine can adjust the LOD distance. 0 the engine can fully adjust. 1 the engine cannot adjust it at all. 0.5 the maximum the engine can adjust the LOD distance is 50% or the default." + ], + [ + "r_clear", + "Controls how the color buffer is cleared" + ], + [ + "r_clearColor", + "Color to clear the screen to when clearing the frame buffer" + ], + [ + "r_clearColor2", + "Color to clear every second frame to (for use during development)" + ], + [ + "r_clutCompositeVisionSet", + "Composite clut with vision set." + ], + [ + "r_clutDebugOverlay", + "Enable Clut Debug Overlay" + ], + [ + "r_clutDumpAssets", + "Dump Assets" + ], + [ + "r_clutEnable", + "Enable/Disable Clut" + ], + [ + "r_cmdbuf_handoff", + "Allow the backend thread to take over partially executed command buffer jobs." + ], + [ + "r_cmdbuf_worker", + "Process command buffer in a separate thread" + ], + [ + "r_colorblindMode", + "Selects the Colorblind simulation mode" + ], + [ + "r_colorGradingEnable", + "Enable color grading." + ], + [ + "r_colorGradingFilmTweaks", + "Enable/Disable Vision Set Film Tweaks" + ], + [ + "r_colorGradingForceReinhard", + "Enable/Disable Force Reinhard" + ], + [ + "r_colorMap", + "Replace all color maps with pure black or pure white" + ], + [ + "r_colorScaleUseTweaks", + "Override color scale LightSet settings with tweak dvar values. (MP)" + ], + [ + "r_combinePostOpaqueFx", + "" + ], + [ + "r_contrast", + "Contrast adjustment" + ], + [ + "r_daltonizeIntensity", + "Daltonize correction strength." + ], + [ + "r_daltonizeMode", + "Selects the Daltonize mode" + ], + [ + "r_darkBlur", + "Apply blur (decrease of visual acuity) when dark" + ], + [ + "r_darkBlurPower", + "Power curve of blurring (decrease of visual acuity) when dark" + ], + [ + "r_darkBlurRadius", + "Radius of blurring (decrease of visual acuity) when dark" + ], + [ + "r_darkColor", + "Reduce color sensitivity when dark" + ], + [ + "r_darkColorPower", + "Power curve of color sensitivity when dark" + ], + [ + "r_debugDrawLights", + "Draw light debug info" + ], + [ + "r_debugDrawLightsDrawRadius", + "Max distance from camera to draw debug light info" + ], + [ + "r_debugDrawLightsIndex", + "Draw light index" + ], + [ + "r_debugLineWidth", + "Width of server side debug lines" + ], + [ + "r_debugRefHeight", + "Reference Image's Height" + ], + [ + "r_debugRefImageLeft", + "Reference Image's Left Screen Pos." + ], + [ + "r_debugRefImagePrePostFx", + "Draw Debug Reference before postFx." + ], + [ + "r_debugRefImageTop", + "Reference Image's Top Screen Pos." + ], + [ + "r_debugRefWidth", + "Reference Image's Width " + ], + [ + "r_debugShader", + "Enable shader debugging information" + ], + [ + "r_defaultPatchCount", + "Patches per thread group for all other surfaces." + ], + [ + "r_delayAddSceneModels", + "Add DObjs and brushes to GfxScene in a separate worker command" + ], + [ + "r_depthPrepass", + "Enable depth prepass for various geometries" + ], + [ + "r_depthSortDebug", + "Enable depth sort debug visualization." + ], + [ + "r_depthSortEnable", + "Enable sorting of transparent surfaces." + ], + [ + "r_depthSortRange", + "Range to consider depth sort," + ], + [ + "r_desaturation", + "Desaturation adjustment" + ], + [ + "r_detailMap", + "Replace all detail maps with an image that effectively disables them" + ], + [ + "r_diffuseColorScale", + "Globally scale the diffuse color of all point lights" + ], + [ + "r_disableLightSets", + "Disable LightSets" + ], + [ + "r_displacementMap", + "Replace all displacement maps with an image that effectively disables them" + ], + [ + "r_displacementPatchCount", + "Patches per thread group for displacement surfaces." + ], + [ + "r_distortion", + "Enable distortion" + ], + [ + "r_distortion_script_force_off", + "Force distortion off in script" + ], + [ + "r_dlightLimit", + "Maximum number of dynamic lights drawn simultaneously" + ], + [ + "r_dof_bias", + "Depth of field bias as a power function (like gamma); less than 1 is sharper" + ], + [ + "r_dof_enable", + "Enable the depth of field effect" + ], + [ + "r_dof_farBlur", + "" + ], + [ + "r_dof_farEnd", + "Depth of field far end distance, in inches" + ], + [ + "r_dof_farStart", + "Depth of field far start distance, in inches" + ], + [ + "r_dof_nearBlur", + "" + ], + [ + "r_dof_nearEnd", + "Depth of field near end distance, in inches" + ], + [ + "r_dof_nearStart", + "Depth of field near start distance, in inches" + ], + [ + "r_dof_physical_accurateFov", + "Enable physical fov (but still based on cg_fov). This will make the fov to subtlety change depending on the focus distance" + ], + [ + "r_dof_physical_adsFocusSpeed", + "ADS focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)" + ], + [ + "r_dof_physical_adsMaxFstop", + "ADS maximum f-stop (optimal aperture and focus distance are automatically calculated for this mode)" + ], + [ + "r_dof_physical_adsMinFstop", + "ADS minimum f-stop (optimal aperture and focus distance are automatically calculated for this mode)" + ], + [ + "r_dof_physical_bokehEnable", + "Enable the bokeh depth of field effect" + ], + [ + "r_dof_physical_bokehPreset", + "Changes dof sampling quality" + ], + [ + "r_dof_physical_bokehRotation", + "Bokeh shape rotation in degrees (hexagonal and octogonal only)" + ], + [ + "r_dof_physical_bokehShape", + "Changes the bokeh shape" + ], + [ + "r_dof_physical_bokehSharpness", + "Bokeh shape sharpness, trades sharpness for stability (circular only)" + ], + [ + "r_dof_physical_distanceMeter", + "Enable physical depth of field debug information" + ], + [ + "r_dof_physical_enable", + "enable physical camera controls (using aperture priority)" + ], + [ + "r_dof_physical_filmDiagonal", + "Diagonal size of the film/sensor (mm). The bigger the sensor size, the bigger the circle of confusion (which means stronger blurring at all distances). Defaults to full-frame 35mm" + ], + [ + "r_dof_physical_focusDistance", + "Distance to the plane in focus for the scene" + ], + [ + "r_dof_physical_fstop", + "Aperture of the camera for the scene. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32" + ], + [ + "r_dof_physical_hipEnable", + "Enable hyperfocal mode" + ], + [ + "r_dof_physical_hipFocusSpeed", + "Hyperfocal mode focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)" + ], + [ + "r_dof_physical_hipFstop", + "Aperture of the camera for the scene in the hyperfocal mode" + ], + [ + "r_dof_physical_hipSharpCocDiameter", + "Defines what circle of confusion can be considered sharp (mm). Defaults to 0.03mm, generally accepted value for 35mm" + ], + [ + "r_dof_physical_maxCocDiameter", + "Maximum circle of confusion diameter (virtual units, might be clamped for bokeh dof)" + ], + [ + "r_dof_physical_minFocusDistance", + "Minimum focus distance (inches)" + ], + [ + "r_dof_physical_viewModelFocusDistance", + "Distance to the plane in focus for the scene" + ], + [ + "r_dof_physical_viewModelFstop", + "Aperture of the camera for the view model. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32" + ], + [ + "r_dof_tweak", + "Use dvars to set the depth of field effect; overrides r_dof_enable" + ], + [ + "r_dof_viewModelEnd", + "Depth of field viewmodel end distance, in inches" + ], + [ + "r_dof_viewModelStart", + "Depth of field viewmodel start distance, in inches" + ], + [ + "r_dpvsFilterDebug", + "Filter all entities to all cells (debug)" + ], + [ + "r_draw_frustum", + "Draw the frustum using debug lines" + ], + [ + "r_drawBModels", + "Enable brush model rendering" + ], + [ + "r_drawDebugRefImage", + "Draw Debug Reference Image." + ], + [ + "r_drawDynEnts", + "Enable dynamic entity rendering" + ], + [ + "r_drawEntities", + "Enable entity rendering" + ], + [ + "r_drawPoly", + "Enable poly rendering" + ], + [ + "r_drawPrimHistogram", + "Draws a histogram of the sizes of each primitive batch" + ], + [ + "r_drawRigidModels", + "Enable rigid model rendering" + ], + [ + "r_drawSkinnedModels", + "Enable skinned model rendering" + ], + [ + "r_drawSModels", + "Fraction of static models to render" + ], + [ + "r_drawStreaming", + "Makes materials with textures that are not yet loaded draw in pink" + ], + [ + "r_drawSun", + "Enable sun effects" + ], + [ + "r_drawTessellatedWorld", + "Draw tessellated world surfaces" + ], + [ + "r_drawWater", + "Enable water animation" + ], + [ + "r_drawWorld", + "Enable world rendering" + ], + [ + "r_drawXModels", + "Enable xmodel rendering" + ], + [ + "r_dumpViewInfo", + "Dump all the info in the GfxViewInfo structure" + ], + [ + "r_dynamicLight", + "Toggle VFX ( omni & spot ) light, debug only" + ], + [ + "r_dynamicOPL", + "Enable drawing vfx lights as overlapping primary light for saving gpu performance." + ], + [ + "r_dynamicSpotLightShadows", + "Enable shadows for dynamic/VFX spot lights, you should set this dvar then spawn the new light." + ], + [ + "r_emblemBrightnessScale", + "Modifier that scales the brightness of the emblem on model materials" + ], + [ + "r_emissiveMap", + "Replace all emissive maps with pure black or pure white" + ], + [ + "r_enableNoTessBuckets", + "Enables placing triangles that don't need tessellation into additional draw calls using non-tessellated shaders." + ], + [ + "r_envBrdfLutMap", + "Replace environment BRDF lookup table with pure black (no secondary specular) or pure white (maximum secondary specular)" + ], + [ + "r_envMapExponent", + "Reflection exponent." + ], + [ + "r_envMapMaxIntensity", + "Max reflection intensity based on glancing angle." + ], + [ + "r_envMapMinIntensity", + "" + ], + [ + "r_envMapOverride", + "" + ], + [ + "r_envMapSunIntensity", + "Max sun specular intensity intensity with env map materials." + ], + [ + "r_eyePupil", + " Change eye's pupil Size." + ], + [ + "r_eyeRedness", + " Change eye's redness." + ], + [ + "r_eyeWetness", + " Change eye's wetness." + ], + [ + "r_fastModelPrimaryLightCheck", + "Reduce R_GetNonSunPrimaryLightForSphere/R_GetNonSunPrimaryLightForBox function calls" + ], + [ + "r_fastModelPrimaryLightLink", + "Speed up R_LinkSphereEntityToPrimaryLights and R_LinkBoxEntityToPrimaryLights." + ], + [ + "r_filmAltShader", + "Use alternate shader (with middle tint and dark desat) for film color." + ], + [ + "r_filmTweakBrightness", + "Tweak dev var; film color brightness" + ], + [ + "r_filmTweakContrast", + "Tweak dev var; film color contrast" + ], + [ + "r_filmTweakDesaturation", + "Tweak dev var; Desaturation applied after all 3D drawing to light areas" + ], + [ + "r_filmTweakDesaturationDark", + "Tweak dev var; Additional desaturation applied after all 3D drawing to dark areas" + ], + [ + "r_filmTweakEnable", + "Tweak dev var; enable film color effects" + ], + [ + "r_filmTweakInvert", + "Tweak dev var; enable inverted video" + ], + [ + "r_filmUseTweaks", + "Overide film effects with tweak dvar values." + ], + [ + "r_floatzCopyCompressed", + "Use a compute shader to copy compressed depth data to $floatz" + ], + [ + "r_fog", + "Set to 0 to disable fog" + ], + [ + "r_fog_depthhack_scale", + "Fog scale for depth hack surfaces" + ], + [ + "r_fog_ev_adjust", + "Fog color ev adjustment (+2 means fog color is 2 stops brighter)" + ], + [ + "r_fogDebugOverlay", + "Fog Debug Overlay" + ], + [ + "r_font_cache_debug_display", + "Display the current fontcache texture on the HUD for debug purposes" + ], + [ + "r_forceLetterbox4x3", + "Force 16:9 -> 4:3 letterbox mode on, regardless of aspect ratio." + ], + [ + "r_forceLod", + "Force all level of detail to this level" + ], + [ + "r_fullbright", + "Toggles rendering without lighting" + ], + [ + "r_fxaaSubpixel", + "FXAA sub-pixel amount, lower values have more aliasing and less blur" + ], + [ + "r_FXAverageColorFunc", + "How to compute FX system average color? 0 = use IWrad equation, 1 = legacy equation, 2 = spherical harmonics 1 coefficient." + ], + [ + "r_globalGenericMaterialScale", + "Hack global generic material constants" + ], + [ + "r_glow", + "Enable glow." + ], + [ + "r_glow_allowed", + "Allow glow." + ], + [ + "r_glow_allowed_script_forced", + "Force 'allow glow' to be treated as true, by script." + ], + [ + "r_glowTweakAltColorScaleB", + "Tweak dev var; Alt cutoff intensity B" + ], + [ + "r_glowTweakAltColorScaleG", + "Tweak dev var; Alt cutoff intensity G" + ], + [ + "r_glowTweakAltColorScaleR", + "Tweak dev var; Alt cutoff intensity R" + ], + [ + "r_glowTweakAltCutoff", + "Tweak dev var; Alt cutoff" + ], + [ + "r_glowTweakBloomCutoff", + "Tweak dev var; Glow bloom cut off fraction" + ], + [ + "r_glowTweakBloomDesaturation", + "Tweak dev var; Glow bloom desaturation" + ], + [ + "r_glowTweakBloomIntensity0", + "Tweak dev var; Glow bloom intensity" + ], + [ + "r_glowTweakBloomPinch", + "Tweak dev var; Pinch the bloom horizontally ( positive ) or vertically ( negative )" + ], + [ + "r_glowTweakEnable", + "Tweak dev var; Enable glow" + ], + [ + "r_glowTweakRadius0", + "Tweak dev var; Glow radius in pixels at 640x480" + ], + [ + "r_glowTweakUseAltCutoff", + "Tweak dev var; Enable glow alt cutoff" + ], + [ + "r_glowUseTweaks", + "Overide glow with tweak dvar values." + ], + [ + "r_gpuFrameHistogram", + "Enables a visual histogram of time between page flips." + ], + [ + "r_gpuTimers", + "GPU Timers to display" + ], + [ + "r_gpuTimersShowPrepass", + "Show prepass in GPU Timers" + ], + [ + "r_gradientAdjust", + "Enable mipmap gradient adjust (required by checkerboard upsample)" + ], + [ + "r_gunSightColorEntityScale", + "Scale the gun sight color when over an entity." + ], + [ + "r_gunSightColorNoneScale", + "Scale the gun sight color when not over an entity." + ], + [ + "r_hdrSkyIntensity", + "Vision set intensity for HDR sky." + ], + [ + "r_hdrSkyIntensityUseTweaks", + "Enables HDR sky intensity tweaks" + ], + [ + "r_hdrSpotmeter", + "Perform HDR spot meter measurement of luminance and color in center of screen" + ], + [ + "r_hemiAoBlurTolerance", + "Hemi SSAO Blur Tolerance (log10)" + ], + [ + "r_hemiAoCombineResolutionsBeforeBlur", + "The higher quality modes blend wide and narrow sampling patterns. The wide pattern is due to deinterleaving and requires blurring. The narrow pattern is not on a deinterleaved buffer, but it only samples every other pixel. The blur on it is optional. If you combine the two before blurring, the narrow will get blurred as well. This creates a softer effect but can remove any visible noise from having 50% sample coverage." + ], + [ + "r_hemiAoCombineResolutionsWithMul", + "When combining the wide and narrow patterns, a mul() operation can be used or a min() operation. Multiplication exaggerates the result creating even darker creases. This is an artistic choice. I think it looks less natural, but often art teams prefer more exaggerated contrast. For me, it's more about having the right AO falloff so that it's a smooth gradient rather than falling off precipitously and forming overly dark recesses." + ], + [ + "r_hemiAoDepthSquash", + "Hemi SSAO depth squash. Value is rcp." + ], + [ + "r_hemiAoEnable", + "Enable Hemi SSAO" + ], + [ + "r_hemiAoHierarchyDepth", + "Hemi SSAO recursion depth (filter width)" + ], + [ + "r_hemiAoMaxDepthDownsample", + "Use max depth value when downsampling, instead of pseudo-randomly picking a depth sample? Leaving this at the default false may produce more stable results." + ], + [ + "r_hemiAoNoiseFilterTolerance", + "This is necessary to filter out pixel shimmer due to bilateral upsampling with too much lost resolution. High frequency detail can sometimes not be reconstructed, and the noise filter fills in the missing pixels with the result of the higher resolution SSAO. Value is log10." + ], + [ + "r_hemiAoPower", + "Power curve applied to Hemi SSAO factor, not applied in game yet" + ], + [ + "r_hemiAoQualityLevel", + "Hemi SSAO quality setting" + ], + [ + "r_hemiAoRejectionFalloff", + "Controls how aggressive to fade off samples that occlude spheres but by so much as to be unreliable. This is what gives objects a dark halo around them when placed in front of a wall. If you want to fade off the halo, boost your rejection falloff. The tradeoff is that it reduces overall AO. Value is rcp." + ], + [ + "r_hemiAoStrength", + "Strength of Hemi Screen Space Ambient Occlusion effect" + ], + [ + "r_hemiAoUpsampleTolerance", + "Hemi SSAO Upsample Tolerance (log10)" + ], + [ + "r_heroLighting", + "Enable hero-only lighting" + ], + [ + "r_hideAmbientSModels", + "Hide ambient static models." + ], + [ + "r_hideDepthHack", + "Hide depth hackS to make it easier to find floating decals." + ], + [ + "r_hideLitTSplit0", + "Hide lit transparent prior to split" + ], + [ + "r_hideLitTSplit1", + "Hide lit transparent post split" + ], + [ + "r_hideModelLMapSModels", + "Hide model lightmap static models." + ], + [ + "r_hideOpaque", + "Hide opaque to make it easier to find floating decals." + ], + [ + "r_hideReactiveMotionSModels", + "Hide reactive motion static models." + ], + [ + "r_hideVertexLitSModels", + "Hide vertex lit static models." + ], + [ + "r_highLodDist", + "Distance for high level of detail" + ], + [ + "r_hudFx", + "Draw HUD Effects" + ], + [ + "r_ignore", + "" + ], + [ + "r_ignoreDoplFlags", + "Debug only dvar: Enable it then all vfx spot light becomes dopls depend on r_dynamicOPL." + ], + [ + "r_ignoref", + "" + ], + [ + "r_inGameVideo", + "Allow in game cinematics" + ], + [ + "r_lateAllocParamCacheAllowed", + "Enable late allocation of parameter cache for VS stage." + ], + [ + "r_lateAllocParamCacheDefault", + "Late allocation of parameter cache value for sub-div materials." + ], + [ + "r_lateAllocParamCacheDisplacement", + "Late allocation of parameter cache value for sub-div materials." + ], + [ + "r_lateAllocParamCacheSubdiv", + "Late allocation of parameter cache value for sub-div materials." + ], + [ + "r_letterbox4x3", + "Use 16:9 aspect ratio always, with conversion to letterbox 4:3 if necessary." + ], + [ + "r_lightCacheLessFrequentMaxDistance", + "Adjust the distance fx models (and models tagged as less-frequently-lit by script) move before immediately being relit" + ], + [ + "r_lightCacheLessFrequentPeriod", + "Adjust how frequently fx models (and models tagged as less-frequently-lit by script) get relit on average (1 is every frame, 8 is every 8th frame)" + ], + [ + "r_lightGridAvgApplyPrimaryLight", + "apply primary light color onto r_showLightGridAvgProbes boxes" + ], + [ + "r_lightGridAvgFollowCamera", + "allow the r_showLightGridAvgProbes boxes following current camera position" + ], + [ + "r_lightGridAvgProbeCount", + "how many light grid avg color probes will show up)" + ], + [ + "r_lightGridAvgTraceGround", + " lock boxes to ground " + ], + [ + "r_lightGridContrast", + "Adjust the contrast of light color from the light grid" + ], + [ + "r_lightGridDefaultFXLightingLookup", + "Default FX lighting lookup location\n" + ], + [ + "r_lightGridDefaultModelLightingLookup", + "Default model lighting lookup location" + ], + [ + "r_lightGridEnableTweaks", + "Enable tweaks of the light color from the light grid" + ], + [ + "r_lightGridIntensity", + "Adjust the intensity of light color from the light grid" + ], + [ + "r_lightGridSHBands", + "Spherical harmonics bands being used for evaluating current-gen light grids colors. 0 = default, 1 = 1 band, 2 = 2 bands, 3 = 3 bands.\n" + ], + [ + "r_lightGridUseTweakedValues", + "Use tweaked values instead of default" + ], + [ + "r_lightMap", + "Replace all lightmaps with pure black or pure white" + ], + [ + "r_lightSetDebugOverlay", + "Enable LightSets Debug Overlay" + ], + [ + "r_lightTweakBoneSpaceIndex", + "Tweak origin and angles appear in the space of this entity" + ], + [ + "r_lightTweakColor", + "Light color" + ], + [ + "r_lightTweakEnable", + "Apply light tweaks to the active primary light" + ], + [ + "r_lightTweakEntSpaceIndex", + "Tweak origin and angles appear in the space of this entity" + ], + [ + "r_lightTweakHeading", + "Light heading in degrees" + ], + [ + "r_lightTweakIndex", + "Light index to tweak. Works with r_lightTweakEnable." + ], + [ + "r_lightTweakInnerCone", + "Light tweak inner cone angle" + ], + [ + "r_lightTweakIntensity", + "Light strength" + ], + [ + "r_lightTweakOuterCone", + "Light tweak outer cone angle" + ], + [ + "r_lightTweakPitch", + "Light pitch in degrees" + ], + [ + "r_lightTweakRadius", + "Light radius" + ], + [ + "r_limitCUCount", + "1 limits the PS4 CU count to 12 matching Xbox One, 0 restores default CU limit." + ], + [ + "r_litSurfaceHDRScalar", + "Vision set based scalar applied to lit surfaces" + ], + [ + "r_lockPvs", + "Lock the viewpoint used for determining what is visible to the current position and direction" + ], + [ + "r_lod4Dist", + "Distance for lowest level of detail 4" + ], + [ + "r_lod5Dist", + "Distance for lowest level of detail 5" + ], + [ + "r_lowestLodDist", + "Distance for lowest level of detail" + ], + [ + "r_lowLodDist", + "Distance for low level of detail" + ], + [ + "r_mbEnable", + "Set of objects which will be enabled for motion blur" + ], + [ + "r_mbFastEnable", + "Toggle on/off fast high quality motion blur" + ], + [ + "r_mbFastPreset", + "Changes motion blur quality" + ], + [ + "r_mdao", + "Enable the medium distance ambient occlusion feature" + ], + [ + "r_mdaoAsyncOccluderGen", + "The occluder generation step is performed via async compute" + ], + [ + "r_mdaoBoneInfluenceRadiusScale", + "Scale for the bone influence radius for mdao" + ], + [ + "r_mdaoCapsuleStrength", + "MDAO strength for capsule occluders" + ], + [ + "r_mdaoDrawOccluders", + "Draws the entity occluder ellipsoids used as MDAO casters" + ], + [ + "r_mdaoMinBoneBoundsToOcclude", + "Minimum volume of the bone collider to create occluders for" + ], + [ + "r_mdaoOccluderCullDistance", + "Culling distance for mdao occluders" + ], + [ + "r_mdaoOccluderFadeOutStartDistance", + "Fade out distance for mdao occluders" + ], + [ + "r_mdaoUseTweaks", + "Use r_mdao* dvars instead of the current light set values for MDAO" + ], + [ + "r_mdaoVolumeStrength", + "MDAO strength for volume occluders" + ], + [ + "r_mediumLodDist", + "Distance for medium level of detail" + ], + [ + "r_mode", + "Display mode" + ], + [ + "r_modelLightingMap", + "Replace all model lighting maps (light grid) with pure black" + ], + [ + "r_mpRimColor", + "Change character's rim color for multiplayer" + ], + [ + "r_mpRimDiffuseTint", + "Change character's rim diffuse tint for multiplayer." + ], + [ + "r_mpRimStrength", + "Change character's rim color for multiplayer" + ], + [ + "r_mrtEnable", + "Enable setting of multiple render targets." + ], + [ + "r_normalMap", + "Replace all normal maps with a flat normal map" + ], + [ + "r_occlusionQueryDebugOverlay", + "Enable OcclusionQuery Debug Overlay" + ], + [ + "r_offchipTessellationAllowed", + "Enable off-chip tessellation support." + ], + [ + "r_offchipTessellationTfThreshold", + "Tessellation factor threshold for off-chip." + ], + [ + "r_offchipTessellationWaveThreshold", + "Domain shader wave threshold for off-chip." + ], + [ + "r_opaqueUnlit", + "Toggles opaque rendering without lighting" + ], + [ + "r_outdoor", + "Prevents snow from going indoors" + ], + [ + "r_outdoorDebugOverlay", + "Enable Outdoor Debug Overlay" + ], + [ + "r_outdoorFeather", + "Outdoor z-feathering value" + ], + [ + "r_overrideDrawList", + "Replace textures for this draw list" + ], + [ + "r_p4xCapture", + "P4X capture" + ], + [ + "r_particleHdr", + "Enable Hdr Particle Features" + ], + [ + "r_patchCountAllowed", + "Enable run-time setting of patch count per draw call." + ], + [ + "r_pix_material", + "Enable profile material names. Set to 1 to see material and technique names as markers. Set to 2 to also see shader names." + ], + [ + "r_polygonOffsetBias", + "Offset bias for decal polygons; bigger values z-fight less but poke through walls more" + ], + [ + "r_polygonOffsetClamp", + "Offset clamp for decal polygons; bigger values z-fight less but poke through walls more" + ], + [ + "r_polygonOffsetScale", + "Offset scale for decal polygons; bigger values z-fight less but poke through walls more" + ], + [ + "r_portalBevels", + "Helps cull geometry by angles of portals that are acute when projected onto the screen, value is the cosine of the angle" + ], + [ + "r_portalBevelsOnly", + "Use screen-space bounding box of portals rather than the actual shape of the portal projected onto the screen" + ], + [ + "r_portalMinClipArea", + "Don't clip child portals by a parent portal smaller than this fraction of the screen area." + ], + [ + "r_portalMinRecurseDepth", + "Ignore r_portalMinClipArea for portals with fewer than this many parent portals." + ], + [ + "r_portalWalkLimit", + "Stop portal recursion after this many iterations. Useful for debugging portal errors." + ], + [ + "r_postAA", + "Post process antialiasing mode" + ], + [ + "r_postfx_enable", + "Enable post-processing effects such as color correction, bloom, depth-of-field, etc." + ], + [ + "r_primaryLightTweakDiffuseStrength", + "Tweak the diffuse intensity for primary lights" + ], + [ + "r_primaryLightTweakSpecularStrength", + "Tweak the specular intensity for primary lights" + ], + [ + "r_primaryLightUseTweaks", + "" + ], + [ + "r_primBegin", + "Beginning of the range of drawn primitives, inclusive." + ], + [ + "r_primBisect", + "Enables limiting the range of drawn primitives, for debugging." + ], + [ + "r_primEnd", + "End of the range range of drawn primitives, inclusive." + ], + [ + "r_PS4HardwareGamma", + "Controls the hardware gamma curve used (higher is darker)" + ], + [ + "r_randomFailCommandBuffer", + "Command buffer failure rate" + ], + [ + "r_randomFailConstantBuffer", + "Constant buffer failure rate" + ], + [ + "r_reactiveMotionActorRadius", + "Radial distance from the ai characters that influences reactive motion models (inches)" + ], + [ + "r_reactiveMotionActorVelocityMax", + "AI velocity considered the maximum when determining the length of motion tails (inches/sec)" + ], + [ + "r_reactiveMotionActorZOffset", + "Distance from the actor origin along Z direction where the actor's reactive motion effector sphere is centered at." + ], + [ + "r_reactiveMotionEffectorDebugDraw", + "Enable debug drawing of effector spheres" + ], + [ + "r_reactiveMotionEffectorStrengthScale", + "Additional scale for the effector influence, as a factor of the model part distance from the effector center and model part extents" + ], + [ + "r_reactiveMotionHelicopterLimit", + "Maximum number of helicopter entities that actively influence reactive motion. Can increase CPU cost of the scene." + ], + [ + "r_reactiveMotionHelicopterRadius", + "Radial distance from the helicopter that influences reactive motion models (inches)" + ], + [ + "r_reactiveMotionHelicopterStrength", + "Scales the influence of helicopter wind tunnel motion" + ], + [ + "r_reactiveMotionPlayerHeightAdjust", + "Amount to adjust the vertical distance of the effector from the player position (inches)" + ], + [ + "r_reactiveMotionPlayerRadius", + "Radial distance from the player that influences reactive motion models (inches)" + ], + [ + "r_reactiveMotionPlayerZOffset", + "Distance from the player origin along Z direction where the player's reactive motion effector sphere is centered at." + ], + [ + "r_reactiveMotionVelocityTailScale", + "Additional scale for the velocity-based motion tails, as a factor of the effector radius" + ], + [ + "r_reactiveMotionWindAmplitudeScale", + "Scales amplitude of wind wave motion" + ], + [ + "r_reactiveMotionWindAreaScale", + "Scales distribution of wind motion" + ], + [ + "r_reactiveMotionWindDir", + "Controls the global wind direction" + ], + [ + "r_reactiveMotionWindFrequencyScale", + "Scales frequency of wind wave motion" + ], + [ + "r_reactiveMotionWindStrength", + "Scale of the global wind direction (inches/sec)" + ], + [ + "r_reflectionProbeMap", + "Replace all reflection probes with pure black" + ], + [ + "r_reflectionProbeNmlLuminance", + "Enable/disable shader code for computing luminance during reflection probe denormalization. This is just an experiment.\n" + ], + [ + "r_rimLight0Heading", + "Rim Light 0 heading in degrees" + ], + [ + "r_rimLight0Pitch", + "Rim Light 0 pitch in degrees -90 is noon." + ], + [ + "r_rimLightBias", + "How much to bias the n.l calculation" + ], + [ + "r_rimLightDiffuseIntensity", + "Strength of the diffuse component of the rim light." + ], + [ + "r_rimLightFalloffMaxDistance", + "Distance at which the rim light hits intensity of 100%." + ], + [ + "r_rimLightFalloffMinDistance", + "Distance at which the rim light hits intensity of 100%." + ], + [ + "r_rimLightFalloffMinIntensity", + "Intensity of the effect at and before minDistance." + ], + [ + "r_rimLightPower", + "Power to raise the n.l calculation" + ], + [ + "r_rimLightSpecIntensity", + "Strength of the spec ( additive) component of the rim light" + ], + [ + "r_rimLightUseTweaks", + "Turn on rim lighting tweaks" + ], + [ + "r_scaleViewport", + "Scale 3D viewports by this fraction. Use this to see if framerate is pixel shader bound." + ], + [ + "r_sceneMipShowOverlay", + "Toggles scene mip rendertarget overlay" + ], + [ + "r_showAabbTrees", + "Show axis-aligned bounding box trees used in potentially visibile set determination. 1 shows hierarchy, 2 shows world surfaces, 3 shows both." + ], + [ + "r_showCollision", + "Show the collision surfaces for the selected mask types" + ], + [ + "r_showCollisionDepthTest", + "Select whether to use depth test in collision surfaces display" + ], + [ + "r_showCollisionDist", + "Maximum distance to show collision surfaces" + ], + [ + "r_showCollisionGroups", + "Select whether to show the terrain, brush or all collision surface groups" + ], + [ + "r_showCollisionPolyType", + "Select whether to display the collision surfaces as wireframe, poly interiors, or both" + ], + [ + "r_showCullBModels", + "Show culled brush models" + ], + [ + "r_showCullSModels", + "Show culled static models" + ], + [ + "r_showCullXModels", + "Show culled xmodels" + ], + [ + "r_showFbColorDebug", + "Show front buffer color debugging information" + ], + [ + "r_showFloatZDebug", + "Show float z buffer used to eliminate hard edges on particles near geometry" + ], + [ + "r_showLightGrid", + "Show light grid debugging information (2: detailed, 3: detailed for this box only)" + ], + [ + "r_showLightGridAvgProbes", + "show an array of boxes which are using the light grid average color at its location" + ], + [ + "r_showLightGridDetailInfo", + "Show more details for light grid debugging." + ], + [ + "r_showLightProbes", + "Show the light probes at the light grid sample locations in world space centered around the camera." + ], + [ + "r_showMissingLightGrid", + "Use rainbow colors for entities that are outside the light grid" + ], + [ + "r_showModelLightingLowWaterMark", + "" + ], + [ + "r_showModelList", + "Display models that are in the ShowModelList.txt" + ], + [ + "r_showModelLods", + "Currently drawn LOD displayed with each model" + ], + [ + "r_showModelNames", + "Model names displayed with each model" + ], + [ + "r_showPortals", + "Show portals for debugging" + ], + [ + "r_showPortalsOverview", + "Render 2d XY portal overlay scaled to fit to this distance. Useful for debugging portal errors." + ], + [ + "r_showPrimCounts", + "Prim count for each rendered entity" + ], + [ + "r_showReflectionProbeSelection", + "Show reflection probe selection" + ], + [ + "r_showSModelNames", + "Show static model names" + ], + [ + "r_showSurfCounts", + "Surface count for each rendered entity" + ], + [ + "r_showTess", + "Show details for each surface" + ], + [ + "r_showTexelDensity", + "Enable shader overrides for texel density." + ], + [ + "r_showTriCountMin", + "Minimum triangle count to show when showing tri counts" + ], + [ + "r_showTriCounts", + "Triangle count for each rendered entity" + ], + [ + "r_showTris", + "Show triangle outlines" + ], + [ + "r_showVertCountMin", + "Minimum vertex count to show when showing vert counts" + ], + [ + "r_showVertCounts", + "" + ], + [ + "r_singleCell", + "Only draw things in the same cell as the camera. Most useful for seeing how big the current cell is." + ], + [ + "r_skipPvs", + "Skipt the determination of what is in the potentially visible set (disables most drawing)" + ], + [ + "r_sky_fog_intensity", + "Amount of sky fog fading" + ], + [ + "r_sky_fog_max_angle", + "End of angular sky fog fading" + ], + [ + "r_sky_fog_min_angle", + "Start of angular sky fog fading" + ], + [ + "r_skyFogUseTweaks", + "Enable dvar control of sky fog" + ], + [ + "r_smodelInstancedRenderer", + "Render static models with instanced renderer" + ], + [ + "r_smodelInstancedThreshold", + "Minimum number of static model instances before instanced rendering is used" + ], + [ + "r_smp_backend", + "Process renderer back end in a separate thread" + ], + [ + "r_smp_worker", + "Process renderer front end in a separate thread" + ], + [ + "r_smp_worker_thread0", + "" + ], + [ + "r_smp_worker_thread1", + "" + ], + [ + "r_smp_worker_thread2", + "" + ], + [ + "r_specOccMap", + "Replace all specular occlusion maps with pure black (fully occluded) or pure white (not occluded)" + ], + [ + "r_specularColorScale", + "Set greater than 1 to brighten specular highlights" + ], + [ + "r_specularMap", + "Replace all specular maps with pure black (off) or pure white (super shiny)" + ], + [ + "r_spotLightEntityShadows", + "Enable entity shadows for spot lights." + ], + [ + "r_spotLightShadows", + "Enable shadows for spot lights." + ], + [ + "r_ssao", + "Screen Space Ambient Occlusion mode" + ], + [ + "r_ssaoDebug", + "Render calculated or blurred Screen Space Ambient Occlusion values" + ], + [ + "r_ssaoDebugMip", + "Selects which mip level to render when r_ssaoDebug is enabled. If 0 and r_ssaoDownsample is enabled, will render mip 1." + ], + [ + "r_ssaoDepthScale", + "Scale applied to depth values used for occlusion tests." + ], + [ + "r_ssaoDepthScaleViewModel", + "Scale applied to depth values used for occlusion tests." + ], + [ + "r_ssaoDownsample", + "Screen Space Ambient Occlusion calculation occurs at half linear resolution" + ], + [ + "r_ssaoFadeDepth", + "Depth at which the SSAO begins to fade out. It fades at even increments of this distance (e.g. it's at 1 for depth r_ssaoFadeDepth, 1/2 for depth 2*r_ssaoFadeDepth, etc.)" + ], + [ + "r_ssaoGapFalloff", + "Falloff used to blend between creases (that should darken) and silhouettes (that should not darken). Lower values falloff more quickly." + ], + [ + "r_ssaoGradientFalloff", + "Falloff used to fade out the effect for steep depth gradients (i.e. surfaces nearly parallel to the camera direction). This fixes sampling artifacts that appear for surfaces nearly parallel to the camera direction (commonly occuring for flat ground planes)." + ], + [ + "r_ssaoMaxStrengthDepth", + "Depth at which SSAO strength is at its maximum" + ], + [ + "r_ssaoMethod", + "Screen Space Ambient Occlusion method (original or IW6, both are volumetric obscurance)" + ], + [ + "r_ssaoMinPixelWidth", + "Minimum pixel width of the effect. When the effect is smaller than this, it is culled entirely." + ], + [ + "r_ssaoMinStrengthDepth", + "Depth at which SSAO strength is zero, effectively disabled" + ], + [ + "r_ssaoMultiRes", + "Screen Space Ambient Occlusion calculation occurs at half linear resolution" + ], + [ + "r_ssaoPower", + "Power curve applied to SSAO factor" + ], + [ + "r_ssaoRejectDepth", + "Depth at which the SSAO is disabled. Smaller values result in more rejected pixels which is faster, but limits the distance at which the effect is visible." + ], + [ + "r_ssaoSampleCount", + "Selects the number of samples used for SSAO" + ], + [ + "r_ssaoScriptScale", + "Allows script to lerp to disable or enable the SSAO. This applies a scalar value to the SSAO strength. When set to 0, this effectively disables SSAO." + ], + [ + "r_ssaoStrength", + "Strength of Screen Space Ambient Occlusion effect" + ], + [ + "r_ssaoUseTweaks", + "Use r_ssao* dvars instead of the current light set values for SSAO" + ], + [ + "r_ssaoWidth", + "The width of the SSAO effect, in pixels at 720p. Larger values increase area but lower effective quality." + ], + [ + "r_ssrBlendScale", + "Add extra scale to ssr weight versus reflection probe weight, >1 value will make ssr more obvious." + ], + [ + "r_ssrDepthTraceFakeOff", + "toggle on/off to see ssr depth trace material performance impact." + ], + [ + "r_ssrFadeInDuration", + "Duration of the screen-space reflection fade-in, which occurs whenever the reflection source buffer is invalidated due to view changes (in particular, dual-view scope transitions)." + ], + [ + "r_ssrRoughnessMipParameters", + "X: mirror mip; Y: roughest mip; Z: roughness middle point, may need different value for different screen resolution on PC." + ], + [ + "r_ssrShowOverlay", + "Toggles overlay drawing of screen space reflection occlusion buffers." + ], + [ + "r_sssBlendWeight", + "Controls the blend between the wide (zero) and narrow (one) gaussians" + ], + [ + "r_sssDebugMaterial", + "Debug Feature: toggle materials with SSS" + ], + [ + "r_sssEnable", + "Enables the subsurface scattering effect (note that disabling SSS will not prevent the filter from running)" + ], + [ + "r_sssGlobalRadius", + "Controls the global radius (in inches)" + ], + [ + "r_sssJitterRadius", + "Percentage of the kernel to be jittered" + ], + [ + "r_sssNarrowRadius", + "Controls the narrow Gaussian radius" + ], + [ + "r_sssPreset", + "Changes subsurface scattering quality" + ], + [ + "r_sssWideRadius", + "Controls the wide Gaussian radius" + ], + [ + "r_staticModelDumpLodInfo", + "Dump static model info for the next frame." + ], + [ + "r_subdiv", + "Enables Catmull Clark surface subdivision." + ], + [ + "r_subdivLimit", + "Set the maximum Catmull Clark subdivision level." + ], + [ + "r_subdivPatchCount", + "Patches per thread group for sub-division surfaces." + ], + [ + "r_subdomainLimit", + "Maximum number of extra tessellation subdivisions using instancing (max tess amts are 0:64, 1:128, 2:192, 3:256, max instances used are 0:1, 1:4, 2:9, 3:12)" + ], + [ + "r_subdomainScale", + "Debug only: Scales the extra subdivision amount (for values < 1, not all instanced sub triangles will draw)." + ], + [ + "r_subwindow", + "subwindow to draw: left, right, top, bottom" + ], + [ + "r_sun_from_dvars", + "Set sun flare values from dvars rather than the level" + ], + [ + "r_sun_fx_position", + "Position in degrees of the sun effect" + ], + [ + "r_sunblind_fadein", + "time in seconds to fade blind from 0% to 100%" + ], + [ + "r_sunblind_fadeout", + "time in seconds to fade blind from 100% to 0%" + ], + [ + "r_sunblind_max_angle", + "angle from sun in degrees inside which effect is max" + ], + [ + "r_sunblind_max_darken", + "0-1 fraction for how black the world is at max blind" + ], + [ + "r_sunblind_min_angle", + "angle from sun in degrees outside which effect is 0" + ], + [ + "r_sunflare_fadein", + "time in seconds to fade alpha from 0% to 100%" + ], + [ + "r_sunflare_fadeout", + "time in seconds to fade alpha from 100% to 0%" + ], + [ + "r_sunflare_max_alpha", + "0-1 vertex color and alpha of sun at max effect" + ], + [ + "r_sunflare_max_angle", + "angle from sun in degrees inside which effect is max" + ], + [ + "r_sunflare_max_size", + "largest size of flare effect in pixels at 640x480" + ], + [ + "r_sunflare_min_angle", + "angle from sun in degrees outside which effect is 0" + ], + [ + "r_sunflare_min_size", + "smallest size of flare effect in pixels at 640x480" + ], + [ + "r_sunflare_shader", + "name for flare effect; can be any material" + ], + [ + "r_sunglare_fadein", + "time in seconds to fade glare from 0% to 100%" + ], + [ + "r_sunglare_fadeout", + "time in seconds to fade glare from 100% to 0%" + ], + [ + "r_sunglare_max_angle", + "angle from sun in degrees inside which effect is max" + ], + [ + "r_sunglare_max_lighten", + "0-1 fraction for how white the world is at max glare" + ], + [ + "r_sunglare_min_angle", + "angle from sun in degrees inside which effect is max" + ], + [ + "r_sunInfDist", + "Sun infinite distance used to place sun fx" + ], + [ + "r_sunshadowmap_cmdbuf_worker", + "Process shadowmap command buffer in a separate thread" + ], + [ + "r_sunsprite_shader", + "name for static sprite; can be any material" + ], + [ + "r_sunsprite_size", + "diameter in pixels at 640x480 and 80 fov" + ], + [ + "r_sunsprite_size_override", + "override the .sun file for the sunsprite size; diameter in pixels at 640x480 and 80 fov, -1 means off" + ], + [ + "r_surfaceHDRScalarUseTweaks", + "Enables lit and unlit surface scalar tweaks" + ], + [ + "r_tension_enable", + "Toggles tension" + ], + [ + "r_tessellation", + "Enables tessellation of world geometry, with an optional cutoff distance." + ], + [ + "r_tessellationCutoffDistance", + "Distance at which world geometry ceases to tessellate." + ], + [ + "r_tessellationCutoffFalloff", + "Range over which tessellation is faded out, up to the cutoff." + ], + [ + "r_tessellationEyeScale", + "Scale applied due to eye * object normal for less tessellation on facing polygons." + ], + [ + "r_tessellationFactor", + "Target edge length, based on dividing full window height by this factor, for dynamic tessellation. Use zero to disable tessellation." + ], + [ + "r_tessellationGPUSync", + "Sync GPU between tessellated world surfaces (temporary hack for GPU hang)" + ], + [ + "r_tessellationHeightAuto", + "Correctly auto scale displacement heights for layers to grow as texture is stretched over larger surface areas to preserve feature proportions." + ], + [ + "r_tessellationHeightScale", + "Displacement height scale factor." + ], + [ + "r_tessellationHybrid", + "Hybrid per pixel displacement scale." + ], + [ + "r_tessellationLodBias", + "Displacement map lod bias." + ], + [ + "r_texFilterAnisoBias", + "Bias used when computing anisotropy ratio. Lower values are more efficient at the expense of filtering quality." + ], + [ + "r_texFilterAnisoMax", + "Maximum anisotropy to use for texture filtering" + ], + [ + "r_texFilterAnisoMin", + "Minimum anisotropy to use for texture filtering (overridden by max)" + ], + [ + "r_texFilterDisable", + "Disables all texture filtering (uses nearest only.)" + ], + [ + "r_texFilterMipBias", + "Change the mipmap bias" + ], + [ + "r_texFilterMipMode", + "Forces all mipmaps to use a particular blend between levels (or disables mipping.)" + ], + [ + "r_texFilterProbeBilinear", + "Force reflection probe to use bilinear filter" + ], + [ + "r_texFilterTrilinearWindow", + "Window over which trilinear filtering blends between mips. A value of 1.0 is a linear blend, and a value of 0 is the minimal blend. Smaller values are more efficient but result in a sharper transition between mip levels." + ], + [ + "r_texShowMipMode", + "Forces textures with the specified mip filtering to draw black." + ], + [ + "r_thermal", + "Select thermal effect mode" + ], + [ + "r_thermalColorOffset", + "Offset of the thermal colors (offset + scale*color)" + ], + [ + "r_thermalColorScale", + "Scale of the thermal colors (offset + scale*color)" + ], + [ + "r_thermalDetailScale", + "Scale of the detail that is added to the thermal map from the normal map (multiplies the detail amount from AssetManager)" + ], + [ + "r_thermalFadeColor", + "Color the thermal fades to at distance." + ], + [ + "r_thermalFadeControl", + "Select thermal fade mode" + ], + [ + "r_thermalFadeMax", + "Distance at which thermal stops fading" + ], + [ + "r_thermalFadeMin", + "Distance at which thermal starts fading" + ], + [ + "r_tonemap", + "HDR Tonemapping mode" + ], + [ + "r_tonemapAdaptSpeed", + "HDR Tonemap exposure adaptation speed" + ], + [ + "r_tonemapAuto", + "HDR Tonemapping performs auto-exposure" + ], + [ + "r_tonemapAutoExposureAdjust", + "HDR Tonemap Auto Exposure Adjust value (set to 0.0 for automatic adjustment)" + ], + [ + "r_tonemapBlack", + "HDR Filmic Tonemap black point" + ], + [ + "r_tonemapBlend", + "HDR Tonemapping blends between exposures" + ], + [ + "r_tonemapCaptureExposurePoint", + "Capture the specified exposure point (Negative value means no capture)." + ], + [ + "r_tonemapCaptureMode", + "Tonemap Exposure Capture Mode." + ], + [ + "r_tonemapCaptureTweakExposureAdjust", + "HDR Tonemap Exposure Adjust Tweak" + ], + [ + "r_tonemapCrossover", + "HDR Filmic Tonemap crossover point" + ], + [ + "r_tonemapDarkEv", + "HDR Tonemap Dark EV" + ], + [ + "r_tonemapDarkExposureAdjust", + "HDR Tonemap Dark Exposure Adjust" + ], + [ + "r_tonemapDebug", + "Tonemap curve debug" + ], + [ + "r_tonemapExposure", + "HDR Tonemap exposure (in EV) override (only works in non-auto mode)" + ], + [ + "r_tonemapExposureAdjust", + "HDR Tonemap exposure adjustment (in EV, 0 is no adjustment, works like a camera where +1 reduces EV by 1)" + ], + [ + "r_tonemapGamma", + "HDR Tonemap gamma curve power" + ], + [ + "r_tonemapHighlightRange", + "HDR Tonemap dynamic range, which determines white point luminance" + ], + [ + "r_tonemapLightEv", + "HDR Tonemap Light EV" + ], + [ + "r_tonemapLightExposureAdjust", + "HDR Tonemap Light Exposure Adjust" + ], + [ + "r_tonemapLockAutoExposureAdjust", + "HDR Tonemapping lock auto exposure adjust" + ], + [ + "r_tonemapMaxExposure", + "HDR Tonemap maximum exposure (in EV)" + ], + [ + "r_tonemapMaxExposureAdjust", + "HDR Tonemap Max Exposure Adjust" + ], + [ + "r_tonemapMidEv", + "HDR Tonemap Mid EV" + ], + [ + "r_tonemapMidExposureAdjust", + "HDR Tonemap Mid Exposure Adjust" + ], + [ + "r_tonemapMinExposureAdjust", + "HDR Tonemap Min Exposure Adjust" + ], + [ + "r_tonemapShoulder", + "HDR Filmic Tonemap shoulder control (0 is linear)" + ], + [ + "r_tonemapToe", + "HDR Filmic Tonemap toe control (0 is linear)" + ], + [ + "r_tonemapUseCS", + "HDR Tonemapping uses compute shader." + ], + [ + "r_tonemapUseTweaks", + "Override tone map LightSet settings with tweak dvar values." + ], + [ + "r_tonemapWhite", + "HDR Filmic Tonemap white point" + ], + [ + "r_trace", + "Razor GPU trace capture" + ], + [ + "r_uhdMode", + "UHD up-scale mode" + ], + [ + "r_ui3d_debug_display", + "Show UI3D debug overlay" + ], + [ + "r_ui3d_h", + "ui3d texture window height" + ], + [ + "r_ui3d_use_debug_values", + "Use UI debug values" + ], + [ + "r_ui3d_w", + "ui3d texture window width" + ], + [ + "r_ui3d_x", + "ui3d texture window x" + ], + [ + "r_ui3d_y", + "ui3d texture window y" + ], + [ + "r_uiBlurDstMode", + "UI blur distortion mode. Fast uses the scene mip map render target, PostSun uses a downsampled post sun resolve buffer, PostSun HQ uses a gaussian blurred post sun resolve buffer." + ], + [ + "r_umbra", + "Enables Umbra-based portal culling." + ], + [ + "r_umbraAccurateOcclusionThreshold", + "The distance (in inches) to which accurate occlusion information is gathered. -1.0 = deduced automatically." + ], + [ + "r_umbraExclusive", + "Toggle Umbra for exclusive static culling (disables static portal dpvs)" + ], + [ + "r_umbraQueryParts", + "The number of parts the Umbra query frustum is broken into for async query processing as an M x N grid (0, 0 = all queries are synchronous)." + ], + [ + "r_umbraUseDpvsCullDist", + "Use cull distance from the DPVS instead of the far plane distance." + ], + [ + "r_unlitSurfaceHDRScalar", + "Vision set based scalar applied to unlit surfaces to balance those surfaces with the luminance of the scene" + ], + [ + "r_upsampleMode", + "Checkerboard upsample mode" + ], + [ + "r_useComputeSkinning", + "Enables compute shader (GPU) skinning." + ], + [ + "r_useLightGridDefaultFXLightingLookup", + "Enable/disable default fx lighting lookup\n" + ], + [ + "r_useLightGridDefaultModelLightingLookup", + "Enable/disable default model lighting lookup\n" + ], + [ + "r_useShadowGeomOpt", + "Enable iwRad shadow geometry optimization. It only works when we have the data generated in iwRad." + ], + [ + "r_useSunShadowPortals", + "Enable sun shadow portals when dir light change and not using cached shadow." + ], + [ + "r_useXAnimIK", + "Enables IK animation." + ], + [ + "r_validateCmdBuf", + "Enable validation of command buffer during kick." + ], + [ + "r_vc_makelog", + "Enable logging of light grid points for the vis cache. 1 starts from scratch, 2 appends." + ], + [ + "r_vc_showlog", + "Show this many rows of light grid points for the vis cache" + ], + [ + "r_veil", + "Apply veiling luminance (HDR glow)" + ], + [ + "r_veilAntialiasing", + "Veil antialiasing mode (downsample technique used for first mip)." + ], + [ + "r_veilBackgroundStrength", + "Strength of background when applying veiling luminance (HDR glow)" + ], + [ + "r_veilFalloffScale1", + "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)" + ], + [ + "r_veilFalloffScale2", + "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)" + ], + [ + "r_veilFalloffWeight1", + "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)" + ], + [ + "r_veilFalloffWeight2", + "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)" + ], + [ + "r_veilFilter", + "Changes the veil filtering mode" + ], + [ + "r_veilPreset", + "Changes veil sampling quality" + ], + [ + "r_veilRadius", + "Controls the radius of the first Gaussian in virtual pixels (remaining Gaussians follow proportionally)." + ], + [ + "r_veilStrength", + "Strength of veiling luminance (HDR glow)" + ], + [ + "r_veilUseTweaks", + "Override veil LightSet settings with tweak dvar values." + ], + [ + "r_velocityPrepass", + "Perform velocity rendering during the depth prepass" + ], + [ + "r_viewModelPrimaryLightTweakDiffuseStrength", + "Tweak the diffuse intensity for view model primary lights" + ], + [ + "r_viewModelPrimaryLightTweakSpecularStrength", + "Tweak the specular intensity for view model primary lights" + ], + [ + "r_viewModelPrimaryLightUseTweaks", + "" + ], + [ + "r_volumeLightScatter", + "Enables volumetric light scattering" + ], + [ + "r_volumeLightScatterAngularAtten", + "Distance of sun from center of screen before angular attenuation starts for god rays" + ], + [ + "r_volumeLightScatterBackgroundDistance", + "Distance at which pixels are considered background for volume light scatter effect" + ], + [ + "r_volumeLightScatterDebug", + "Enables volumetric light scattering debug rendering" + ], + [ + "r_volumeLightScatterDepthAttenFar", + "Pixels >= than this depth recieve full volume light scatter." + ], + [ + "r_volumeLightScatterDepthAttenNear", + "Pixels <= than this depth recieve no volume light scatter." + ], + [ + "r_volumeLightScatterEv", + "Light intensity (in EV) for volumetric light scattering" + ], + [ + "r_volumeLightScatterLinearAtten", + "Coefficient of linear attenuation of god rays" + ], + [ + "r_volumeLightScatterQuadraticAtten", + "Coefficient of quadratic attenuation of god rays)" + ], + [ + "r_volumeLightScatterUseTweaks", + "Enables volumetric light scattering tweaks" + ], + [ + "r_vsync", + "Enable v-sync before drawing the next frame to avoid 'tearing' artifacts." + ], + [ + "r_warningRepeatDelay", + "Number of seconds after displaying a \"per-frame\" warning before it will display again" + ], + [ + "r_wideTessFactorsThreshold", + "If a surface has more than this many triangles, process triangles in parallel instead of surfaces." + ], + [ + "r_xdebug", + "xmodel/xanim debug rendering" + ], + [ + "r_zfar", + "Change the distance at which culling fog reaches 100% opacity; 0 is off" + ], + [ + "r_znear", + "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance." + ], + [ + "r_znear_depthhack", + "Viewmodel near clip plane" + ], + [ + "radarjamDistMax", + "" + ], + [ + "radarjamDistMin", + "" + ], + [ + "radarjamSinCurve", + "" + ], + [ + "radius_damage_debug", + "Turn on debug lines for radius damage traces" + ], + [ + "ragdoll_baselerp_time", + "Default time ragdoll baselerp bones take to reach the base pose" + ], + [ + "ragdoll_bullet_force", + "Bullet force applied to ragdolls" + ], + [ + "ragdoll_bullet_upbias", + "Upward bias applied to ragdoll bullet effects" + ], + [ + "ragdoll_debug_trace", + "Draw traces from penetration test" + ], + [ + "ragdoll_dump_anims", + "Dump animation data when ragdoll fails" + ], + [ + "ragdoll_enable", + "Turn on ragdoll death animations" + ], + [ + "ragdoll_explode_force", + "Explosive force applied to ragdolls" + ], + [ + "ragdoll_explode_upbias", + "Upwards bias applied to ragdoll explosion effects" + ], + [ + "ragdoll_exploding_bullet_force", + "Force applied to ragdolls from explosive bullets" + ], + [ + "ragdoll_exploding_bullet_upbias", + "Upwards bias applied to ragdoll from explosive bullets" + ], + [ + "ragdoll_idle_min_velsq", + "Minimum squared speed a ragdoll body needs to be moving before it will shut down due to time" + ], + [ + "ragdoll_jitter_scale", + "Scale up or down the effect of physics jitter on ragdolls" + ], + [ + "ragdoll_jointlerp_time", + "Default time taken to lerp down ragdoll joint friction" + ], + [ + "ragdoll_max_life", + "Max lifetime of a ragdoll system in msec" + ], + [ + "ragdoll_max_simulating", + "Max number of simultaneous active ragdolls - archived" + ], + [ + "ragdoll_max_stretch_pct", + "Force ragdoll limbs to not stretch more than this percentage in one frame" + ], + [ + "ragdoll_resolve_penetration_bias", + "Bias value on force to push ragdolls out of environment." + ], + [ + "ragdoll_rotvel_scale", + "Ragdoll rotational velocity estimate scale" + ], + [ + "ragdoll_self_collision_scale", + "Scale the size of the collision capsules used to prevent ragdoll limbs from interpenetrating" + ], + [ + "ragdoll_stretch_iters", + "Iterations to run the alternate limb solver" + ], + [ + "rankedPlayEndMatchKeepLobby", + "keep the lobby if the lobby host is in our private party." + ], + [ + "recon_serverPort", + "Recon Server Port (IP:Port)" + ], + [ + "RemoteCameraSounds_DryLevel", + "" + ], + [ + "RemoteCameraSounds_RoomType", + "" + ], + [ + "RemoteCameraSounds_WetLevel", + "" + ], + [ + "replay_asserts", + "Enable/Disable replay aborts due to inconsistency" + ], + [ + "replay_autosave", + "Use autosaves as part of demos - will make demo access faster but will cause hitches" + ], + [ + "replay_autosaveOnError", + "Auto save replay on error" + ], + [ + "replay_time", + "Draw replay time" + ], + [ + "reportUserVoteInterval", + "The interval in minutes you wait before getting another vote on this console as long as the console is turned on." + ], + [ + "requirestats", + "Whether stats are currently required" + ], + [ + "reset_mm_data", + "reset data with dlc popup" + ], + [ + "riotshield_bullet_damage_scale", + "Value to scale bullet damage to deployed riotshield." + ], + [ + "riotshield_debug", + "Riotshield debug." + ], + [ + "riotshield_deploy_extents", + "Trace extents of the riotshield when planting" + ], + [ + "riotshield_deploy_forward_offset", + "Forward offset from the player when planting" + ], + [ + "riotshield_deploy_limit_radius", + "Min distance deployed riotshields must be from each other." + ], + [ + "riotshield_deploy_pitch_max", + "Max surface pitch angle to allow riotshield deployment" + ], + [ + "riotshield_deploy_roll_max", + "Max surface roll angle to allow riotshield deployment" + ], + [ + "riotshield_deploy_trace_parallel", + "Report collisions when riotshield traces are parallel to plane of triangle. If disabled traces parallel to triangle planes do not report collisions at all." + ], + [ + "riotshield_deploy_trigger_yoffset", + "Y offset from the shield to place the trigger" + ], + [ + "riotshield_deploy_trigger_zoffset", + "Z offset from the shield to place the trigger" + ], + [ + "riotshield_deploy_zdiff_max", + "Max height difference allowed between plant surface and player origin" + ], + [ + "riotshield_deployed_health", + "Deployed riotshield health." + ], + [ + "riotshield_destroyed_cleanup_time", + "Time (in seconds) destroyed riotshield model persists before disappearing" + ], + [ + "riotshield_explosive_damage_scale", + "Value to scale explosive damage to deployed riotshield.." + ], + [ + "riotshield_melee_damage_scale", + "Value to scale melee damage to deployed riotshield." + ], + [ + "riotshield_projectile_damage_scale", + "Value to scale projectile damage to deployed riotshield." + ], + [ + "riotshield_use_mindot", + "The minimum angle dot in order to pick up a deployed riot shield" + ], + [ + "riotshield_use_radius", + "The radius within which the player can pick up a deployed riot shield" + ], + [ + "RunForTime", + "Time for the server to run" + ], + [ + "s_scriptable_physBaseExplosionScale", + "Base multiplier applied to the explosion force calculations (consider this a 'range scaler')." + ], + [ + "safeArea_adjusted_horizontal", + "User-adjustable horizontal safe area as a fraction of the screen width" + ], + [ + "safeArea_adjusted_vertical", + "User-adjustable vertical safe area as a fraction of the screen height" + ], + [ + "safeArea_horizontal", + "Horizontal safe area as a fraction of the screen width" + ], + [ + "safeArea_vertical", + "Vertical safe area as a fraction of the screen height" + ], + [ + "savegame_profile", + "Profile the size of savegames. Prints results to console after every save." + ], + [ + "scr_dof_enable", + "enable dof" + ], + [ + "screenshots_active", + "Are we allowed to enable Screenshots or not" + ], + [ + "scriptable_debug", + "Debug mode for scriptables" + ], + [ + "scriptable_enable", + "Debug option to enable/disable spawning scriptable instances at run time." + ], + [ + "scriptable_explCamShakeDuration", + "Duration, in MS, that a camera shake should last for during an explosion" + ], + [ + "scriptable_explCamShakeRadiusMultiplier", + "Multiplier applied to the outer radius of an explosion event to trigger the shake within." + ], + [ + "scriptable_explCamShakeScale", + "Scale applied to the camera shake. Higher means more shaking." + ], + [ + "scriptIgnoreInfiniteLoops", + "Allows script to loop infinitely without any script errors or warnings." + ], + [ + "sensitivity", + "Mouse sensitivity" + ], + [ + "sentry_placement_debug", + "Enables sentry placement debug lines" + ], + [ + "sentry_placement_feet_offset", + "Position of the feet from the center axis." + ], + [ + "sentry_placement_feet_trace_dist_z", + "Max distance for a foot to be considered touching the ground" + ], + [ + "sentry_placement_trace_dist", + "Distance along the trace axis where the sentry will attempt to position itself" + ], + [ + "sentry_placement_trace_min_normal", + "Minimum normal to accept a sentry position" + ], + [ + "sentry_placement_trace_parallel", + "Enable turret traces that are parallel to plane of triangle. If 0, traces parallel to triangle planes do not report collisions at all. If 2 (debug-only), then trace code ping pongs between new and old." + ], + [ + "sentry_placement_trace_pitch", + "Pitch used for the trace axis" + ], + [ + "sentry_placement_trace_radius", + "Radius of the bound used for the placement trace" + ], + [ + "sentry_placement_trace_radius_canon_safety", + "Extra radius used in the forward direction to compensate for the canon length" + ], + [ + "serverCulledSounds", + "Enable culling of sounds on the server thread" + ], + [ + "session_join_min_time", + "Minimum number of milliseconds between join attempts" + ], + [ + "session_nonblocking", + "Non-blocking Session code" + ], + [ + "shieldBlastDamageProtection_120", + "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield." + ], + [ + "shieldBlastDamageProtection_180", + "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield." + ], + [ + "shieldBlastDamageProtection_30", + "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield." + ], + [ + "shieldBlastDamageProtection_60", + "How much protection a shield has against an explosion. 0.0 is none, 1.0 is full. For explosions within a 30-degree arc of the shield." + ], + [ + "shieldDeployShakeDuration", + "Viewmodel shake duration for riotshield deploy." + ], + [ + "shieldDeployShakeScale", + "Viewmodel shake scale for riotshield deploy." + ], + [ + "shieldImpactBulletShakeDuration", + "Viewmodel shake duration for bullet impacts." + ], + [ + "shieldImpactBulletShakeScale", + "Viewmodel shake scale for bullet impacts." + ], + [ + "shieldImpactExplosionHighShakeDuration", + "Viewmodel shake duration for strong splash damage." + ], + [ + "shieldImpactExplosionHighShakeScale", + "Viewmodel shake scale for strong splash damage." + ], + [ + "shieldImpactExplosionLowShakeDuration", + "Viewmodel shake duration for weak splash damage." + ], + [ + "shieldImpactExplosionLowShakeScale", + "Viewmodel shake scale for weak splash damage." + ], + [ + "shieldImpactExplosionThreshold", + "Pre-shield splash damage that is above this will be 'strong'." + ], + [ + "shieldImpactMissileShakeDuration", + "Viewmodel shake duration for direct missile impacts." + ], + [ + "shieldImpactMissileShakeScale", + "Viewmodel shake scale for direct missile impacts." + ], + [ + "shieldPlayerBulletProtectionDegrees", + "Bullets fired at a riotshield-bearing player will be blocked if they are within this many degrees of the player's forward direction. Higher value means wider protection." + ], + [ + "showDebugAmmoCounter", + "Show the debug ammo counter when unable to show ar ammo counter" + ], + [ + "showPlaylistTotalPlayers", + "Toggle the display of the total number of players in a playlist and online" + ], + [ + "si_validateFileAccess", + "Validate accessed files against install file list." + ], + [ + "sm_cacheSpotShadows", + "Cache spot shadow maps, improves shadow map performance at the cost of memory (requires vid_restart)" + ], + [ + "sm_cacheSpotShadowsEnabled", + "Enables caching of spot shadows." + ], + [ + "sm_cacheSunShadow", + "Cache sun shadow map, improves shadow map performance at the cost of memory (requires vid_restart)" + ], + [ + "sm_cacheSunShadowEnabled", + "Enables caching of sun-based shadows." + ], + [ + "sm_cameraOffset", + "" + ], + [ + "sm_debugFastSunShadow", + "Debug fast sun shadow" + ], + [ + "sm_dynlightAllSModels", + "Enable, from script, rendering all static models in dynamic light volume when shadow mapping" + ], + [ + "sm_enable", + "Enable shadow mapping" + ], + [ + "sm_fastSunShadow", + "Fast sun shadow" + ], + [ + "sm_forceLinear", + "Force shadow sampling to be linear" + ], + [ + "sm_lightScore_eyeProjectDist", + "When picking shadows for primary lights, measure distance from a point this far in front of the camera." + ], + [ + "sm_lightScore_spotProjectFrac", + "When picking shadows for primary lights, measure distance from a point this far in front of the camera." + ], + [ + "sm_maxLightsWithShadows", + "Limits how many primary lights can have shadow maps" + ], + [ + "sm_minSpotLightScore", + "Minimum score (based on intensity, radius, and position relative to the camera) for a spot light to have shadow maps." + ], + [ + "sm_polygonOffsetBias", + "Shadow map offset bias" + ], + [ + "sm_polygonOffsetClamp", + "Shadow map offset clamp" + ], + [ + "sm_polygonOffsetPreset", + "Shadow map polygon offset preset." + ], + [ + "sm_polygonOffsetScale", + "Shadow map offset scale" + ], + [ + "sm_projStepSize", + "" + ], + [ + "sm_qualitySpotShadow", + "Fast spot shadow" + ], + [ + "sm_shadowUseTweaks", + "Override shadow LightSet settings with tweak dvar values." + ], + [ + "sm_showCachedSunOverlay", + "Show cached sun shadow map overlay; dvar value picks the partition." + ], + [ + "sm_showOverlay", + "Show shadow map overlay" + ], + [ + "sm_showOverlayDepthBounds", + "Near and far depth values for the shadow map overlay" + ], + [ + "sm_showOverlayTrans", + "Show transparency shadow map overlay" + ], + [ + "sm_spotDistCull", + "Distance cull spot shadows" + ], + [ + "sm_spotEnable", + "Enable spot shadow mapping from script" + ], + [ + "sm_spotFilterRadius", + "Spot soft shadows filter radius" + ], + [ + "sm_spotLightScoreModelScale", + "Scale the calculated spot light score by this value if the light currently only affects static or script brush models." + ], + [ + "sm_spotLightScoreRadiusPower", + "Power to apply to light radius when determining spot light shadowing score (1.0 means radius scales up score a lot, 0.0 means don't scale score using radius)" + ], + [ + "sm_spotLimit", + "Limit number of spot shadows from script" + ], + [ + "sm_spotShadowFadeTime", + "How many seconds it takes for a primary light shadow map to fade in or out" + ], + [ + "sm_strictCull", + "Strict shadow map cull" + ], + [ + "sm_sunEnable", + "Enable sun shadow mapping from script" + ], + [ + "sm_sunFilterRadius", + "Sun soft shadows filter radius" + ], + [ + "sm_sunSampleSizeNear", + "Shadow sample size" + ], + [ + "sm_sunShadowBoundsMax", + "Max Shadow Bounds" + ], + [ + "sm_sunShadowBoundsMin", + "Min Shadow Bounds" + ], + [ + "sm_sunShadowBoundsOverride", + "Override Shadow Bounds" + ], + [ + "sm_sunShadowCenter", + "Sun shadow center, 0 0 0 means don't override" + ], + [ + "sm_sunShadowCenterMode", + "When false center value only used for far map, when true sets both maps" + ], + [ + "sm_sunShadowScale", + "Sun shadow scale optimization" + ], + [ + "sm_usedSunCascadeCount", + "How many shadow cascade we are using" + ], + [ + "snd_allowHeadphoneHRTF", + "Enable HRTF over headphones" + ], + [ + "snd_announcerVoicePrefix", + "Local mp announcer voice to use" + ], + [ + "snd_autoSim", + "turn on client side simulation of automatic gun sounds" + ], + [ + "snd_cinematicVolumeScale", + "Scales the volume of Bink videos." + ], + [ + "snd_debugAlias", + "Print out tracking information about a particular alias" + ], + [ + "snd_debugReplace", + "Print out information about when we stop a playing sound to play another" + ], + [ + "snd_detectedSpeakerConfig", + "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround" + ], + [ + "snd_dolbyPanning", + "Enables experimental Dolby-standard -3dB pan laws and speaker angles" + ], + [ + "snd_dopplerAuditionEnable", + "Enables doppler calculation preview mode" + ], + [ + "snd_dopplerBaseSpeedOfSound", + "The base speed of sound used in doppler calculation" + ], + [ + "snd_dopplerEnable", + "Enables doppler calculation" + ], + [ + "snd_dopplerPitchMax", + "Maximum pitch that can be legally applied by doppler" + ], + [ + "snd_dopplerPitchMin", + "Minimum pitch that can be legally applied by doppler" + ], + [ + "snd_dopplerPlayerVelocityScale", + "The scale of the player velocity, relative the the sound source velocity, when applied to the doppler calculation" + ], + [ + "snd_dopplerSmoothing", + "Smoothing factor applied to doppler to eliminate jitter or sudden acceleration changes" + ], + [ + "snd_draw3D", + "Draw the position and info of world sounds" + ], + [ + "snd_drawEqChannels", + "Draw overlay of EQ settings for each channel" + ], + [ + "snd_drawEqEnts", + "Show which ents can have EQ turned on/off, which ones are on (green) and off (magenta)" + ], + [ + "snd_drawInfo", + "Draw debugging information for sounds" + ], + [ + "snd_drawSubmixInfo", + "Displays a list of active sound submixes" + ], + [ + "snd_enable2D", + "Enable 2D sounds" + ], + [ + "snd_enable3D", + "Enable 3D sounds" + ], + [ + "snd_enableEq", + "Enable equalization filter" + ], + [ + "snd_enableReverb", + "Enable sound reverberation" + ], + [ + "snd_enableStream", + "Enable streamed sounds" + ], + [ + "snd_envFollowerBuffScale", + "Amount of buffer to use for envelope follower. Smaller value indicates faster envelope." + ], + [ + "snd_errorOnMissing", + "Cause a Com_Error if a sound file is missing." + ], + [ + "snd_focusGlobalAngleMax", + "" + ], + [ + "snd_focusGlobalAngleMin", + "Angle describing the conde where focus attenuation begins (no attenuation)." + ], + [ + "snd_focusGlobalAttenuation", + "" + ], + [ + "snd_focusGlobalEnabled", + "Enable the global sound focus." + ], + [ + "snd_focusWeaponAngleMax", + "" + ], + [ + "snd_focusWeaponAngleMin", + "Angle describing the cone where focus attenuation ends (full attenuation)." + ], + [ + "snd_focusWeaponAttenuation", + "" + ], + [ + "snd_focusWeaponEnableDVars", + "Enable the weapon sound focus parameter override with DVars." + ], + [ + "snd_focusWeaponFadeTime_ms", + "Time in milliseconds until which the feature is totally in effect after activation." + ], + [ + "snd_hitsoundDisabled", + "Disable the hit indicator sound" + ], + [ + "snd_inheritSecondaryPitchVol", + "Set to true for secondary aliases to inherit the pitch of the parent" + ], + [ + "snd_levelFadeTime", + "The amout of time in milliseconds for all audio to fade in at the start of a level" + ], + [ + "snd_loadFadeTime", + "Fade time for loading from a checkpoint after death." + ], + [ + "snd_logAudioVoices", + "Log to a file, every frame, the info on all voices playing" + ], + [ + "snd_logPlayback", + "Logs all alias playback to the console" + ], + [ + "snd_loopFadeTime", + "Fade-in time for looping sounds." + ], + [ + "snd_loudVO", + "Doubles the headroom for non-dialogue volmods" + ], + [ + "snd_musicDisabledForCustomSoundtrack", + "Disable all in-game music due to user playing a custom soundtrack" + ], + [ + "snd_muteAlias", + "Mute every alias that contain those strings" + ], + [ + "snd_occlusionDelay", + "Minimum delay in (ms) between occlusion updates" + ], + [ + "snd_occlusionEnabled", + "Enable occlusion" + ], + [ + "snd_occlusionLerpTime", + "Time to lerp to target occlusion lerp when occluded" + ], + [ + "snd_peakLimiterCompression", + "Peak limiter compression factor. The output data is scaled by this and then normalized: F < 1 = disabled; F >= 1 enabled." + ], + [ + "snd_peakLimiterDecay", + "Peak limiter compression decay ratio." + ], + [ + "snd_peakLimiterSustainFrames", + "Number of frames to sustain the limiter peak. 1 frame = 10 msec." + ], + [ + "snd_premixVolume", + "Game sound pre-mix volume" + ], + [ + "snd_realtimeAliasUpdate", + "Update a specific parameter for a particular alias" + ], + [ + "snd_realtimeCurveUpdate", + "Update a specific curve (LPF, Reverb, Volume fallof)" + ], + [ + "snd_realtimeDumpSubmixChanges", + "Activating this dvar will create a debug file containing every tweaks made to submix, done with the snd_realtimeSubmixUpdate dvar" + ], + [ + "snd_realtimeSubmixUpdate", + "Update a submix" + ], + [ + "snd_reverbZoneOutsideFactor", + "When a 3d sound is played in a different reverb zone than the player, this factor will be applied to its wet level." + ], + [ + "snd_slaveFadeTime", + "The amount of time in milliseconds for a 'slave' sound\nto fade its volumes when a master sound starts or stops" + ], + [ + "snd_soloAlias", + "Mute every alias that do not contain those strings" + ], + [ + "snd_sortOverlay", + "It will sort the channels shown when using snd_drawinfo" + ], + [ + "snd_speakerConfig", + "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround" + ], + [ + "snd_sustainPeakVU", + "Display the peak value on the VU for this period of time before resetting." + ], + [ + "snd_useOldPanning", + "Use old and busted panning" + ], + [ + "snd_virtualChannelInfo", + "Display virtual voice info." + ], + [ + "snd_virtualForce", + "Forces all sounds to be initially virtual." + ], + [ + "snd_virtualMinDur", + "The minimum duration (in seconds) of a sound if it is to be added to the virtual voice buffer." + ], + [ + "snd_virtualMinPri", + "The minimum priority of an alias if it is to be added to the virtual voice buffer." + ], + [ + "snd_virtualMinTimeLeftToRevive", + "The minimum time (in ms) left in a sample in order to attempt to revive it." + ], + [ + "snd_virtualReviveVoices", + "Whether or not to restore virtual voices." + ], + [ + "snd_virtualWaitToReviveTime", + "The minimum time (in ms) to wait before trying to revive the voice." + ], + [ + "snd_volume", + "Game sound master volume" + ], + [ + "so_survival", + "special ops - survival mode" + ], + [ + "solo_play", + "User is in solo Spec Ops." + ], + [ + "sp_matchdata_active", + "Are SP match data uploads enabled" + ], + [ + "sp_matchdata_maxcompressionbuffer", + "" + ], + [ + "specialops", + "special ops" + ], + [ + "specops_map_groupnum", + "Level challenge group number" + ], + [ + "specops_map_itemnum", + "Level challenge item number" + ], + [ + "speech_active", + "Are we allowed to enable Speech or not" + ], + [ + "splitscreen", + "Current game is a splitscreen game" + ], + [ + "stopspeed", + "The player deceleration" + ], + [ + "stringtable_debug", + "spam debug info for stringtable lookups" + ], + [ + "sv_cheats", + "Turn on cheats: do not access directly - access through CheatsOk for server demo" + ], + [ + "sv_debugTrackServerTime", + "Enable server time track debugging." + ], + [ + "sv_loadingsavegame", + "Is loading up a previous save" + ], + [ + "sv_running", + "Server is running" + ], + [ + "sv_saveDeviceAvailable", + "True if the save device is currently available" + ], + [ + "sv_saveGameAvailable", + "True if the save game is currently available" + ], + [ + "sv_saveGameNotReadable", + "True if the save game is not readable" + ], + [ + "sv_savegametransients", + "Comma-separated list of transients that should be loaded with this savegame (check sv_loadingsavegame first!)" + ], + [ + "sv_saveOnStartMap", + "Save at the start of a level" + ], + [ + "sv_trackFrameMsecThreshold", + "server frame time that will trigger script time tracking." + ], + [ + "sv_znear", + "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance." + ], + [ + "svwp", + "playerdata server write protection: 0 = disable, 1 = silent, 2 = kick" + ], + [ + "syncTimeTimeout", + "default timeout for sync time task (in seconds)" + ], + [ + "sys_language", + "" + ], + [ + "theater_active", + "Are we allowed to show theater or not." + ], + [ + "thermalBlurFactorNoScope", + "Amount of blur to use when drawing blur through a weapon's thermal scope." + ], + [ + "thermalBlurFactorScope", + "Amount of blur to use when drawing blur through a weapon's thermal scope." + ], + [ + "timescale", + "" + ], + [ + "tokensEnabled", + "Is token economy enabled" + ], + [ + "tracer_debugDraw", + "Draw debug lines where the tracers should be visible." + ], + [ + "tracer_disable", + "Disable all weapon tracers." + ], + [ + "tracer_firstPersonMaxWidth", + "The maximum width our OWN tracers can be when looking through our ADS" + ], + [ + "tracer_thermalWidthMult", + "The multiplier applied to the base width when viewed in thermal vision" + ], + [ + "traceScheduler_debugThrottleTraces", + "Displays debug info for trace throttling." + ], + [ + "traceScheduler_throttleTraces", + "Throttles locational traces on the server." + ], + [ + "transients_load_delay", + "Enables an artificial delay (in seconds) that will be added to SP transient fastfile load times. Useful to figure out if transient syncs are missing." + ], + [ + "transients_verbose", + "Verbose logging information for transient fastfiles." + ], + [ + "trigger_draw", + "Draw trigger geometry" + ], + [ + "trigger_drawDepthTest", + "Display trigger geo with depth information" + ], + [ + "trigger_drawDistance", + "Trigger draw distance" + ], + [ + "triggerDLCEnumerationOnSocialConfigLoad", + "Triggers a new DLC enumeration after social config has loaded." + ], + [ + "turret_adsEnabled", + "Enable/Disable ADS on turrets" + ], + [ + "turret_adsTime", + "Time (msec) to transition to ADS" + ], + [ + "turretConvergenceHeightDebug", + "When true, turns on debugging for turret converging to enemy head" + ], + [ + "turretPlayerAvoidScale", + "Auto turrets will try to avoid the player. They will not choose a target that is within a cone around the player. The diameter of the cone is the player's height, so the cone is smaller, the farther the player is from the turret. Use this dvar to scale the cone size." + ], + [ + "turretSentryRestrictUsageToOwner", + "When true, only players that own the sentry turret are allowed to interact with it." + ], + [ + "turretTargetDebug", + "When true, turns on turret target debugging" + ], + [ + "ufoHitsTriggers", + "ufo/noclip will hit triggers when enabled" + ], + [ + "ui_allowSkip", + "Overrides unskippable cutscenes" + ], + [ + "ui_autoContinue", + "Automatically 'click to continue' after loading a level" + ], + [ + "ui_blurAmount", + "Max amount to blur background menu items." + ], + [ + "ui_blurDarkenAmount", + "Amount to darken blurred UI." + ], + [ + "ui_blurTime", + "Time in milliseconds to fade in/out the blur." + ], + [ + "ui_borderLowLightScale", + "Scales the border color for the lowlight color on certain UI borders" + ], + [ + "ui_buildLocation", + "Where to draw the build number" + ], + [ + "ui_buildSize", + "Font size to use for the build number" + ], + [ + "ui_campaign", + "The current campaign" + ], + [ + "ui_chyronGameMessages", + "True if game messages should be sent through script to get the chyron treatment" + ], + [ + "ui_cinematicsTimestamp", + "Shows cinematics timestamp on subtitle UI elements." + ], + [ + "ui_contextualMenuLocation", + "Contextual menu location from where you entered the store." + ], + [ + "ui_currentLevelIndex", + "The index of the current level in script" + ], + [ + "ui_debugMode", + "Shows ui debug information on screen." + ], + [ + "ui_disableInGameStore", + "This will disable the ingame store button on the xbox live menu." + ], + [ + "ui_disableTokenRedemption", + "This will disable the token redemption option in the in-game store menu." + ], + [ + "ui_gametype", + "Current game type" + ], + [ + "ui_hideMap", + "Meant to be set by script and referenced by menu files to determine if minimap should be drawn." + ], + [ + "ui_inGameStoreOpen", + "is the InGameStore open" + ], + [ + "ui_inSpecOpsLeaderboards", + "User is in Spec Ops Leaderboards." + ], + [ + "ui_is_so_dlc", + "Is the user is attempting to play only spec ops DLC maps" + ], + [ + "ui_isSaving", + "True if the game is currently saving" + ], + [ + "ui_loadMenuName", + "Frontend menu will start on this level instead of lockout" + ], + [ + "ui_mapname", + "Current map name" + ], + [ + "ui_mousePitch", + "Invert mouse pitch" + ], + [ + "ui_multiplayer", + "True if the game is multiplayer" + ], + [ + "ui_myPartyColor", + "Player name font color when in the same party as the local player" + ], + [ + "ui_nextMission", + "Next mission" + ], + [ + "ui_online_coop", + "Did the user choose to enter an online coop game" + ], + [ + "ui_play_credits", + "Should we play the credits" + ], + [ + "ui_safearea", + "Show the Screen Safe overlay" + ], + [ + "ui_savegame", + "Save game name" + ], + [ + "ui_saveMessageMinTime", + "Minumum time for the save message to be on screen in seconds" + ], + [ + "ui_selectedFeederMap", + "Current preview game type" + ], + [ + "ui_showList", + "Show list of currently visible menus" + ], + [ + "ui_showMenuOnly", + "If set, only menus using this name will draw." + ], + [ + "ui_skip_initial_game_mode", + "Forces boot flow to ignore short circuit to default choice" + ], + [ + "ui_skipMainLockout", + "True if the page that restricts player control to a single controller is skipped" + ], + [ + "ui_sliderSteps", + "The number of steps for a slider itemdef" + ], + [ + "ui_startupActiveController", + "default active game pad on start up" + ], + [ + "ui_textScrollFadeTime", + "Text scrolling takes this long (seconds) to fade out at the end before restarting" + ], + [ + "ui_textScrollPauseEnd", + "Text scrolling waits this long (seconds) before starting" + ], + [ + "ui_textScrollPauseStart", + "Text scrolling waits this long (seconds) before starting" + ], + [ + "ui_textScrollSpeed", + "Speed at which text scrolls vertically" + ], + [ + "uiscript_debug", + "spam debug info for the ui script" + ], + [ + "uiscript_verbose", + "Turns on extra ui script debugging console prints" + ], + [ + "unattended", + "Allows the game to be run without user input." + ], + [ + "unlockAllAttachments", + "Simulate all attachments being unlocked" + ], + [ + "unlockAllEntitlements", + "Development dvar to simulate having entitlements unlocked" + ], + [ + "unlockAllItems", + "Simulate all items being unlocked" + ], + [ + "unlockAllLootItems", + "Simulate all loot items being locked" + ], + [ + "unlockDevAttachments", + "Unlocks all dev-only attachments in the front-end" + ], + [ + "unlockDevWeapons", + "Unlocks all dev weapons in the front-end" + ], + [ + "uno_current_tos_version", + "Current Uno Terms of Service Version" + ], + [ + "use_new_sva_system", + "Temp flag to help depricate the old scripted viewmodel system. This will be removed when all of the old data is gone." + ], + [ + "useCPMarkerForCPOwnership", + "If set, we will check the player inventory to see if he owns the redeemedItem for a contentPack if this contentPack is not available for the player" + ], + [ + "useonlinestats", + "Whether to use online stats when in offline modes" + ], + [ + "userFileFetchTimeout", + "default timeout for user files FETCH tasks (in seconds)" + ], + [ + "userGroup_active", + "Are we allowed to show Usergroups or not" + ], + [ + "userGroup_cool_off_time", + "Cool off time between calls to fetch the elite clan" + ], + [ + "userGroup_coop_delay", + "Delay between a player joining a coop lobby and the DW user group task starting" + ], + [ + "userGroup_max_retry_time", + "Max time that the usergroup read find can retry" + ], + [ + "userGroup_refresh_time_secs", + "Time in seconds between re-sending lobby group data to confirmed users." + ], + [ + "userGroup_retry_step", + "Step in m/s for the usegroup read retry" + ], + [ + "userGroup_RetryTime", + "Time in ms between sending lobby group data retrys." + ], + [ + "useStatsGroups", + "If true then StatsGroups are in use for all playerdata.ddl accessing." + ], + [ + "useTagFlashSilenced", + "When true, silenced weapons will use \"tag_flash_silenced\" instead of \"tag_flash\"." + ], + [ + "using_mlg", + "MLG feature on/off" + ], + [ + "veh_aiOverSteerScale", + "Scaler used to cause ai vehicles to over steer" + ], + [ + "veh_boneControllerLodDist", + "Distance at which bone controllers are not updated." + ], + [ + "veh_boneControllerUnLodDist", + "Distance at which bone controllers start updating when not moving." + ], + [ + "veh_drawTrack", + "Debug draw the vehicle tracks" + ], + [ + "vehAudio_inAirPitchDownLerp", + "Rate at which the pitch lerps down" + ], + [ + "vehAudio_inAirPitchUpLerp", + "Rate at which the pitch lerps up" + ], + [ + "vehAudio_spawnVolumeTime", + "Seconds it takes for spawned vehicles to reach full volume." + ], + [ + "vehBoatRockingScale", + "Scale of the boat rocking (usually used to turn off rocking during cinematics)" + ], + [ + "vehCam_angles", + "Camera angles from vehicle" + ], + [ + "vehCam_angles3P", + "Camera angles from vehicle (3rd person)" + ], + [ + "vehCam_chaseAngleOffset", + "Angle offset from vehicle angles" + ], + [ + "vehCam_chaseDist", + "Camera distance from vehicle" + ], + [ + "vehCam_chaseLateralInfluence", + "Vehicle's lateral velocity's influence on the camera's left and right movement. This will be multiplied with the chase distance." + ], + [ + "vehCam_chaseMinRollForLateralMovement", + "The minimum roll required before the camera will begin to move laterally" + ], + [ + "vehCam_chaseMinRollTime", + "The minimum time for the plane to be rolling in one direction before the camera reacts to it" + ], + [ + "vehCam_chaseOffset", + "" + ], + [ + "vehCam_chasePitchLerpRateModifier", + "Multiplied by the frame time to determine the yaw lerp rate" + ], + [ + "vehCam_chaseVerticalInfluence", + "Vehicle's vertical velocity's influence on the camera's up and down movement" + ], + [ + "vehCam_chaseYawLerpRateModifier", + "Multiplied by the frame time to determine the yaw lerp rate" + ], + [ + "vehCam_freeLook", + "Enables free look mode" + ], + [ + "vehCam_mode", + "Camera modes: 1st person, 3rd person, or bot" + ], + [ + "vehCam_offset", + "" + ], + [ + "vehCam_offset3P", + "Focus offset from vehicle origin (3rd person)" + ], + [ + "vehCam_pitchClamp", + "Pitch clamp for user adjustment" + ], + [ + "vehCam_pitchClamp3P", + "Pitch clamp for user adjustment (3rd person)" + ], + [ + "vehCam_pitchTurnRate", + "Pitch turn rate for user adjustment" + ], + [ + "vehCam_pitchTurnRate3P", + "Pitch turn rate for user adjustment (3rd person)" + ], + [ + "vehCam_radius", + "Camera radius from vehicle" + ], + [ + "vehCam_radius3P", + "Camera radius from vehicle (3rd person)" + ], + [ + "vehCam_speedInfluence", + "Controls how much the vehicle's speed effects the camera." + ], + [ + "vehCam_speedInfluence3P", + "Controls how much the vehicle's speed effects the camera." + ], + [ + "vehCam_yawClamp", + "Yaw clamp for user adjustment" + ], + [ + "vehCam_yawClamp3P", + "Yaw clamp for user adjustment (3rd person)" + ], + [ + "vehCam_yawTurnRate", + "Yaw turn rate for user adjustment" + ], + [ + "vehCam_yawTurnRate3P", + "Yaw turn rate for user adjustment (3rd person)" + ], + [ + "vehCam_zOffsetMode", + "Camera offset mode for Z axis" + ], + [ + "vehCam_zOffsetMode3P", + "Camera offset mode for Z axis (3rd person)" + ], + [ + "vehDiveboatControlScheme", + "0: like the jetbike. 1: like the pitbull. 2: like the pitbull, but with dive on LTRIG." + ], + [ + "vehHelicopterBoundsRadius", + "The radius of the collision volume to be used when colliding with world geometry." + ], + [ + "vehHelicopterControlsAltitude", + "Determines how to control altitude" + ], + [ + "vehHelicopterControlSystem", + "Determines how the helicopter will be controlled" + ], + [ + "vehHelicopterDecelerationFwd", + "Set the deceleration of the player helicopter (as a fraction of acceleration) in the direction the chopper is facing. So 1.0 makes it equal to the acceleration." + ], + [ + "vehHelicopterDecelerationSide", + "Set the side-to-side deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration." + ], + [ + "vehHelicopterDecelerationUp", + "Set the vertical deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration." + ], + [ + "vehHelicopterForwardDrag", + "The forward deceleration caused by drag in control system 2" + ], + [ + "vehHelicopterFreeLookReleaseSpeed", + "The rate that the player's view moves back to center when freelook is released" + ], + [ + "vehHelicopterHeadSwayDontSwayTheTurret", + "If set, the turret will not fire through the crosshairs, but straight ahead of the vehicle, when the player is not freelooking." + ], + [ + "vehHelicopterHoverSpeedThreshold", + "The speed below which the player helicopter begins to jitter the tilt, for hovering" + ], + [ + "vehHelicopterInvertUpDown", + "Invert the altitude control on the player helicopter." + ], + [ + "vehHelicopterJitterJerkyness", + "Specifies how jerky the tilt jitter should be" + ], + [ + "vehHelicopterLateralDrag", + "The lateral deceleration caused by drag in control system 2" + ], + [ + "vehHelicopterLookaheadTime", + "How far ahead (in seconds) the player helicopter looks ahead, to avoid hard collisions. (Like driving down the highway, you should keep 2 seconds distance between you and the vehicle in front of you)" + ], + [ + "vehHelicopterMaxAccel", + "Maximum horizontal acceleration of the player helicopter (in MPH per second)" + ], + [ + "vehHelicopterMaxAccelVertical", + "Maximum vertical acceleration of the player helicopter (in MPH per second)" + ], + [ + "vehHelicopterMaxAltitude", + "Determines the maximum altitude at which a helicopter can fly" + ], + [ + "vehHelicopterMaxPitch", + "Maximum pitch of the player helicopter" + ], + [ + "vehHelicopterMaxRoll", + "Maximum roll of the player helicopter" + ], + [ + "vehHelicopterMaxSpeed", + "Maximum horizontal speed of the player helicopter (in MPH)" + ], + [ + "vehHelicopterMaxSpeedVertical", + "Maximum vertical speed of the player helicopter (in MPH)" + ], + [ + "vehHelicopterMaxYawAccel", + "Maximum yaw acceleration of the player helicopter" + ], + [ + "vehHelicopterMaxYawRate", + "Maximum yaw speed of the player helicopter" + ], + [ + "vehHelicopterMinAltitude", + "Determines the minimum altitude at which a helicopter can fly" + ], + [ + "vehHelicopterPitchLock", + "True if the view pitches with the body of the helicopter" + ], + [ + "vehHelicopterPitchOffset", + "The resting pitch of the helicopter" + ], + [ + "vehHelicopterPitchRate", + "The pitch speed of the helicopter in control system 2" + ], + [ + "vehHelicopterPitchReturn", + "The rate the pitch returns to the rest pitch of the helicopter in control system 2" + ], + [ + "vehHelicopterPitchThrust", + "The forward acceleration produced by pitching forward in control system 2" + ], + [ + "vehHelicopterRightStickDeadzone", + "Dead-zone for the axes of the right thumbstick. This helps to better control the two axes separately." + ], + [ + "vehHelicopterRollRate", + "The roll speed of the helicopter in control system 2" + ], + [ + "vehHelicopterRollReturn", + "The rate the roll returns to the rest roll of the helicopter in control system 2" + ], + [ + "vehHelicopterRollThrust", + "The lateral acceleration produced by rolling to the side in control system 2" + ], + [ + "vehHelicopterScaleMovement", + "Scales down the smaller of the left stick axes." + ], + [ + "vehHelicopterSoftCollisions", + "Player helicopters have soft collisions (slow down before they collide)." + ], + [ + "vehHelicopterStrafeDeadzone", + "Dead-zone so that you can fly straight forward easily without accidentally strafing (and thus rolling)." + ], + [ + "vehHelicopterTiltFromAcceleration", + "The amount of tilt caused by acceleration" + ], + [ + "vehHelicopterTiltFromControllerAxes", + "The amount of tilt caused by the desired velocity (i.e., the amount of controller stick deflection)" + ], + [ + "vehHelicopterTiltFromDeceleration", + "The amount of tilt caused by deceleration" + ], + [ + "vehHelicopterTiltFromFwdAndYaw", + "The amount of roll caused by yawing while moving forward." + ], + [ + "vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt", + "The forward speed (as a fraction of top speed) at which the tilt due to yaw reaches is maximum value." + ], + [ + "vehHelicopterTiltFromLook", + "The contribution in degrees of view pitch to vehicle pitch in control system 1" + ], + [ + "vehHelicopterTiltFromLookRate", + "The rate the vehicle pitches due to view pitch in control system 1" + ], + [ + "vehHelicopterTiltFromVelocity", + "The amount of tilt caused by the current velocity" + ], + [ + "vehHelicopterTiltMomentum", + "The amount of rotational momentum the helicopter has with regards to tilting." + ], + [ + "vehHelicopterTiltSpeed", + "The rate at which the player helicopter's tilt responds" + ], + [ + "vehHelicopterVerticalDrag", + "The vertical deceleration caused by drag in control system 2" + ], + [ + "vehHelicopterYawOnLeftStick", + "The yaw speed created by the left stick when pushing the stick diagonally (e.g., moving forward and strafing slightly)." + ], + [ + "vehHudDrawPipOnStickWhenFreelooking", + "Set to 0 to not draw the pip-on-a-stick reticle when the player is freelooking" + ], + [ + "vehHudLineWidth", + "The width of the line used by code to draw elements on the vehicle HUD" + ], + [ + "vehHudReticleBouncingDiamondSize", + "The size of the bouncing diamond quad." + ], + [ + "vehHudReticleBouncingRadius", + "The radius of the circle in which the diamond bounces." + ], + [ + "vehHudReticleBouncingSpeed", + "The rate at which the bouncing diamond moves" + ], + [ + "vehHudReticlePipOnAStickCenterCircle", + "The diameter of the small, center circle in the pip-on-a-stick reticle" + ], + [ + "vehHudReticlePipOnAStickCenterCircleBuffer", + "Tweaks how close the stick is drawn to the center circle. Positive numbers makes the line longer." + ], + [ + "vehHudReticlePipOnAStickMovingCircle", + "The diameter of the large, moving circle in the pip-on-a-stick reticle" + ], + [ + "vehHudReticlePipOnAStickMovingCircleBuffer", + "Tweaks how close the stick is drawn to the center circle. Positive numbers makes the line longer." + ], + [ + "vehHudTargetScreenEdgeClampBufferBottom", + "" + ], + [ + "vehHudTargetScreenEdgeClampBufferLeft", + "" + ], + [ + "vehHudTargetScreenEdgeClampBufferRight", + "" + ], + [ + "vehHudTargetScreenEdgeClampBufferTop", + "" + ], + [ + "vehHudTargetSize", + "The width of the enemy target indicator on the hud." + ], + [ + "vehicle_debug_render_spline_plane", + "Do we want to render the spline plane data" + ], + [ + "vehicle_pathsmooth", + "Smoothed vehicle pathing." + ], + [ + "vehicle_pathsmoothdebug", + "Debug smoothed vehicle pathing." + ], + [ + "vehJetbikeControlScheme", + "Which control scheme to use" + ], + [ + "vehPlaneAiLiftModifier", + "ai planes' wing areas are multiplied by this value" + ], + [ + "vehPlaneAiNoClip", + "true if planes in AI mode should ignore collision when moving." + ], + [ + "vehPlaneAiPitchResponseRate", + "ai pitch fraction per degree of pitch error" + ], + [ + "vehPlaneAiRollResponseRate", + "ai roll fraction per degree of roll error" + ], + [ + "vehPlaneAiThrottleModifier", + "ai planes can control throttle up to this multiplier of the plane's actual max thrust" + ], + [ + "vehPlaneAiThrottleResponseRate", + "ai throttle fraction per second per knot of speed error" + ], + [ + "vehPlaneAiYawResponseRate", + "ai pitch fraction per degree of yaw error" + ], + [ + "vehPlaneChordPitchCenter", + "the wing's aoa when the body is level." + ], + [ + "vehPlaneChordPitchMax", + "the max AOA the auto pitch trim will attempt to drive us to" + ], + [ + "vehPlaneChordPitchMin", + "the min AOA the auto pitch trim will attempt to drive us to" + ], + [ + "vehPlaneCollisionLerpRate", + "Collision lerp rate" + ], + [ + "vehPlaneCollisionLookAheadLerpRate", + "Collision look ahead lerp rate" + ], + [ + "vehPlaneCollisionLookAheadRollLerpRate", + "Collision look ahead roll lerp rate" + ], + [ + "vehPlaneCollisionLookAheadTime", + "Collision look ahead time" + ], + [ + "vehPlaneCollisionRollLerpRate", + "Collision roll lerp rate" + ], + [ + "vehPlaneControlExponent", + "an exponent on the joystick deflection, higher for sub-linear response" + ], + [ + "vehPlaneControlForceReferenceSpeed", + "speed at which control forces will reach their advertised values (knots)" + ], + [ + "vehPlaneControlLowpassCoeff", + "how much of the last frame control value to mix in (higher values for more sluggishness)" + ], + [ + "vehPlaneControlReduceRoll", + "in control scheme 1, how much to reduce roll by when throttle is up or down" + ], + [ + "vehPlaneControlRollYawCoupling", + "how much yaw input affects roll input (doesn't go the other way)" + ], + [ + "vehPlaneControlScheme", + "Which control scheme to use" + ], + [ + "vehPlaneControlSquaring", + "how much to stretch the circular range of the joystick into a square" + ], + [ + "vehPlaneControlYawRollCoupling", + "how much roll input affects yaw input (doesn't go the other way)" + ], + [ + "vehPlaneDampingPitch", + "how much pitch rate decays from frame to frame, lower for more momentum" + ], + [ + "vehPlaneDampingRoll", + "how much roll rate decays from frame to frame, lower for more momentum" + ], + [ + "vehPlaneDampingYaw", + "how much yaw rate decays from frame to frame, lower for more momentum" + ], + [ + "vehPlaneDeadZonePercent", + "Percent of stick dead zone" + ], + [ + "vehPlaneDihedralCoeff", + "how much sideslip affects roll. higher values for stronger tendency to level out" + ], + [ + "vehPlaneFuselageLoading", + "fuselage loading, lower values decrease sideslip (kg / m^2)" + ], + [ + "vehPlaneGravity", + "the strength of gravity, (inch/s^2)" + ], + [ + "vehPlaneGravityVelocity", + "This velocity will be added to the plane's Z-velocity" + ], + [ + "vehPlaneInducedDragCoeffExponent", + "induced drag is modeled as sin(aoa)^e, this is the e" + ], + [ + "vehPlaneMass", + "mass (kg)" + ], + [ + "vehPlaneMaxControlForcePitch", + "strength of pitch force compared to other forces" + ], + [ + "vehPlaneMaxControlForceRoll", + "strength of roll force compared to other forces" + ], + [ + "vehPlaneMaxControlForceScale", + "scales all the control forces" + ], + [ + "vehPlaneMaxControlForceYaw", + "strength of yaw force compared to other forces" + ], + [ + "vehPlaneMaxInducedDragCoeff", + "the maximum induced drag coefficient (reached at 90 degrees aoa)" + ], + [ + "vehPlaneMaxLiftCoeff", + "the wing's stalling lift coefficient" + ], + [ + "vehPlaneMaxLiftCoeffAoA", + "the wing's stall angle of attack (degrees)" + ], + [ + "vehPlaneMaxPitch", + "Maximum pitch" + ], + [ + "vehPlaneMaxPitchDiffPerSec", + "Maximum pitch delta per second" + ], + [ + "vehPlaneMaxRightingForcePitch", + "strength of pitch righting force compared to other forces" + ], + [ + "vehPlaneMaxRightingForceScale", + "scales all the aerodynamic righting forces (which align you with your direction of motion)" + ], + [ + "vehPlaneMaxRightingForceYaw", + "strength of yaw righting force compared to other forces" + ], + [ + "vehPlaneMaxRoll", + "Maximum roll" + ], + [ + "vehPlaneMaxYawRatePerSec", + "Maximum yaw rate per second" + ], + [ + "vehPlaneParasiticDragCoeff", + "parasitic drag - higher values will slow you down faster" + ], + [ + "vehPlanePathAllowance", + "The angle that the plane is allowed to turn away from the expected path" + ], + [ + "vehPlanePathAngle", + "Angle of the current expected path segment in the level that will limit yaw controls" + ], + [ + "vehPlanePitchDeadZoneWhileRolling", + "The percent of stick dead zone applied to pitch when rolling" + ], + [ + "vehPlanePitchLerpRate", + "Pitch lerp rate" + ], + [ + "vehPlanePitchVelocityModifer", + "Modifies the velocity based on the pitch (faster when pitched down, slower when pitched up)" + ], + [ + "vehPlaneRightingForceReferenceSpeed", + "speed at which righting forces will reach their advertised values (knots)" + ], + [ + "vehPlaneRollLerpRate", + "Roll lerp rate" + ], + [ + "vehPlaneRollModifierExponent", + "Applies the exponent to the current roll of the plane" + ], + [ + "vehPlaneSecondZeroLiftCoeffAoA", + "the angle of attack, after stalling, at which the lift coefficient goes back to zero" + ], + [ + "vehPlaneStickPusherEngageAoA", + "when angle of attack reaches this, you will fully lose pitch-up authority" + ], + [ + "vehPlaneStickPusherFullAoA", + "when angle of attack reaches this, you will fully lose pitch-up authority" + ], + [ + "vehPlaneSwapSticks", + "Swaps the flight stick from left to right when enabled" + ], + [ + "vehPlaneThrustToWeightRatio", + "thrust to weight ratio - higher increases acceleration and max speed" + ], + [ + "vehPlaneTurbulenceSpatialFrequency", + "how quickly the wind varies from place to place (1 / inch)" + ], + [ + "vehPlaneTurbulenceStrength", + "the strength of the random wind (kts)" + ], + [ + "vehPlaneVelocityLerpRate", + "velocity lerp rate" + ], + [ + "vehPlaneWingLeveling", + "fraction of control input player's plane will use to automatically roll towards wings-level" + ], + [ + "vehPlaneWingLoading", + "wing loading, lower values lower stall speed (kg / m^2)" + ], + [ + "vehPlaneYawLerpRate", + "Yaw lerp rate" + ], + [ + "vehSubmarineAllowInSolid", + "Allow in solid. Dangerous! Used to push the submarine with a collision brushmodel." + ], + [ + "vehSubmarineBodyRelRotation", + "Submarine Body Relative Rotation (0 == world, 1 == body coupled, 2 == horz is roll only, 3 == horz is world yaw, add 4 for camera relative)" + ], + [ + "vehSubmarineControls", + "Submarine controls (0==org, 1=trigger accel, 2=right stick pitch/yaw)" + ], + [ + "vehSubmarineForwardDampening", + "The submarine forward dampening fraction" + ], + [ + "vehSubmarineFwdCollMaxAccel", + "Submarine forward probe max accel" + ], + [ + "vehSubmarineFwdCollMaxAngAccel", + "Submarine forward probe max angular accel" + ], + [ + "vehSubmarineFwdProbeTime", + "The time for the submarine forward probe" + ], + [ + "vehSubmarineHorizControlGamma", + "Submarine gamma for input on horizontal input" + ], + [ + "vehSubmarineInvertUpDown", + "Invert the attitude control on the player submarine." + ], + [ + "vehSubmarineLateralDampening", + "The submarine lateral dampening fraction" + ], + [ + "vehSubmarineMaxDownPitch", + "The max pitch down allowed for the submarine" + ], + [ + "vehSubmarineMaxForwardAccel", + "The max forward acceleration allowed for the submarine" + ], + [ + "vehSubmarineMaxForwardPitchAccel", + "The max pitch acceleration when moving forward for the submarine" + ], + [ + "vehSubmarineMaxForwardVel", + "The max forward velocity allowed for the submarine" + ], + [ + "vehSubmarineMaxForwardYawAccel", + "The max yaw acceleration when moving forward for the submarine" + ], + [ + "vehSubmarineMaxFwdVelRef", + "Submarine max forward velocity reference for coll adjust" + ], + [ + "vehSubmarineMaxLateralVel", + "The max lateral velocity allowed for the submarine" + ], + [ + "vehSubmarineMaxNegativeBuoyancy", + "The max negative buoyancy allowed for the submarine" + ], + [ + "vehSubmarineMaxPositiveBuoyancy", + "The max positive buoyancy allowed for the submarine" + ], + [ + "vehSubmarineMaxReverseAccel", + "The max reverse acceleration allowed for the submarine" + ], + [ + "vehSubmarineMaxReversePitchAccel", + "The max pitch acceleration when moving forward for the submarine" + ], + [ + "vehSubmarineMaxReverseVel", + "The max reverse velocity allowed for the submarine" + ], + [ + "vehSubmarineMaxReverseYawAccel", + "The max yaw acceleration when moving backwards for the submarine" + ], + [ + "vehSubmarineMaxRoll", + "The max roll allowed for the submarine" + ], + [ + "vehSubmarineMaxRollAccel", + "The max roll acceleration for the submarine" + ], + [ + "vehSubmarineMaxStoppedPitchAccel", + "The max pitch acceleration when stopped for the submarine" + ], + [ + "vehSubmarineMaxStoppedYawAccel", + "The max yaw acceleration when stopped for the submarine" + ], + [ + "vehSubmarineMaxUpPitch", + "The max pitch up allowed for the submarine" + ], + [ + "vehSubmarineMinForwardVel", + "The min forward velocity allowed for the submarine (only active when non-zero)" + ], + [ + "vehSubmarineMinVelNoRestore", + "The minimum velocity the submarine has when restore is enabled" + ], + [ + "vehSubmarinePitchDampening", + "The submarine pitch dampening fraction" + ], + [ + "vehSubmarinePitchRestore", + "The submarine pitch restore fraction when not moving" + ], + [ + "vehSubmarineRollDampening", + "The submarine roll dampening fraction" + ], + [ + "vehSubmarineRollDrivenYaw", + "Submarine roll drives applied yaw (0 mean don't scale yaw)" + ], + [ + "vehSubmarineRollRestore", + "The submarine roll restore fraction when not moving" + ], + [ + "vehSubmarineSideCollMaxAccel", + "Submarine side probe max accel" + ], + [ + "vehSubmarineSideCollMaxAngAccel", + "Submarine side probe max angular accel" + ], + [ + "vehSubmarineSideProbeMaxDist", + "Max distance for the submarine side probe" + ], + [ + "vehSubmarineSideProbeMinDist", + "Min distance for the submarine side probe" + ], + [ + "vehSubmarineStoppedVel", + "The threshold velocity to determine the submarine is stopped" + ], + [ + "vehSubmarineVertControlGamma", + "Submarine gamma for input on vertical input" + ], + [ + "vehSubmarineYawDampening", + "The submarine yaw dampening fraction" + ], + [ + "vehUGVPitchTrack", + "UGV body pitch orientation speed" + ], + [ + "vehUGVRollTrack", + "UGV body roll orientation speed" + ], + [ + "vehUGVWheelInfluence", + "UGV wheel influence on the orientation of the body" + ], + [ + "vehWalkerControlMode", + "Walker controls (0==move no turn, 1=move and turn, 2=move relative(tank))" + ], + [ + "version", + "Game version" + ], + [ + "viewangNow", + "" + ], + [ + "viewModelDebugNotetracks", + "Enable display of viewmodel notetrack debug info." + ], + [ + "viewModelHacks", + "Enabled depth hack and remove viewmodel from shadows." + ], + [ + "viewposNow", + "" + ], + [ + "virtualLobbyActive", + "Indicates the VL is actively being displayed." + ], + [ + "virtualLobbyAllocated", + "Indicates the first VL zone has been loaded." + ], + [ + "waypointAerialIconMaxSize", + "Max size of aerial targeting waypoints." + ], + [ + "waypointAerialIconMinSize", + "Min size of aerial targeting waypoints." + ], + [ + "waypointAerialIconScale", + "Base scale of aerial targeting waypoints." + ], + [ + "waypointDebugDraw", + "" + ], + [ + "waypointDistScaleRangeMax", + "Distance from player that icon distance scaling ends." + ], + [ + "waypointDistScaleRangeMin", + "Distance from player that icon distance scaling ends." + ], + [ + "waypointDistScaleSmallest", + "Smallest scale that the distance effect uses." + ], + [ + "waypointIconHeight", + "" + ], + [ + "waypointIconWidth", + "" + ], + [ + "waypointOffscreenCircleRadius", + "Radius of circle for circular offscreen waypoints." + ], + [ + "waypointOffscreenCornerRadius", + "Size of the rounded corners." + ], + [ + "waypointOffscreenDistanceThresholdAlpha", + "Distance from the threshold over which offscreen objective icons lerp their alpha." + ], + [ + "waypointOffscreenPadBottom", + "" + ], + [ + "waypointOffscreenPadLeft", + "" + ], + [ + "waypointOffscreenPadRight", + "" + ], + [ + "waypointOffscreenPadTop", + "" + ], + [ + "waypointOffscreenPointerDistance", + "Distance from the center of the offscreen objective icon to the center its arrow." + ], + [ + "waypointOffscreenPointerHeight", + "" + ], + [ + "waypointOffscreenPointerWidth", + "" + ], + [ + "waypointOffscreenRoundedCorners", + "Off-screen icons take rounded corners when true. 90-degree corners when false." + ], + [ + "waypointOffscreenScaleLength", + "How far the offscreen icon scale travels from full to smallest scale." + ], + [ + "waypointOffscreenScaleSmallest", + "Smallest scale that the offscreen effect uses." + ], + [ + "waypointPlayerOffsetCrouch", + "For waypoints pointing to players, how high to offset off of their origin when they are prone." + ], + [ + "waypointPlayerOffsetProne", + "For waypoints pointing to players, how high to offset off of their origin when they are prone." + ], + [ + "waypointPlayerOffsetStand", + "For waypoints pointing to players, how high to offset off of their origin when they are prone." + ], + [ + "waypointScreenCenterFadeAdsMin", + "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads" + ], + [ + "waypointScreenCenterFadeHipMin", + "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads" + ], + [ + "waypointScreenCenterFadeRadius", + "Radius from screen center that a waypoint will start fading out. Setting to 0 will turn this off" + ], + [ + "waypointSplitscreenScale", + "Scale applied to waypoint icons in splitscreen views." + ], + [ + "waypointTweakY", + "" + ], + [ + "weap_printSharedAmmo", + "Print out shared ammo between weapons on level load" + ], + [ + "weap_printSharedClips", + "Print out shared clip ammo between weapons on level load" + ], + [ + "weapon_drop_validate_time", + "Time between checks to see if a weapon position is valid. Will drop the weapon when invalid. Default = 0 which will never test weapon." + ], + [ + "whitelist_fakeNoPingServer", + "Simulate no access to ATVI ping servers" + ], + [ + "wideScreen", + "True if the game video is running in 16x9 aspect, false if 4x3." + ], + [ + "xanim_blendshape_raw_anim", + "Toggles uncompressed blendshape animations" + ], + [ + "xanim_disableIK", + "Disable inverse kinematics solvers" + ], + [ + "xanim_disableLookAt", + "Disable head tracking" + ], + [ + "xblive_loggedin", + "User is logged into xbox live" + ], + [ + "xenon_maxVoicePacketsPerSec", + "Max voice packets per second a client will send" + ], + [ + "xenon_maxVoicePacketsPerSecForServer", + "Max voice packets per second the server will send" + ], + [ + "xenon_voiceDebug", + "Debug voice communication" + ], + [ + "xenon_voiceDegrade", + "Degrade voice quality" + ], + [ + "xphys_enable", + "Turn on dynamic physics joints" + ], + [ + "xphys_matchAnimationPose", + "Force position/orientation of physics bones to animation pose" + ], + [ + "xphys_teleportAngle", + "If physics body is rotation deviates more than this angle difference from original animation angle, then physics body is teleported" + ], + [ + "xphys_teleportDistance", + "If physics body is further than this distance from original animation position, then physics body is manually teleported to be within at least distance from the animation target" + ] +] diff --git a/src/client/resources/icon.ico b/src/client/resources/icon.ico index 255503b1..a6f49456 100644 Binary files a/src/client/resources/icon.ico and b/src/client/resources/icon.ico differ diff --git a/src/client/resources/icon.png b/src/client/resources/icon.png index 100578dc..674b6524 100644 Binary files a/src/client/resources/icon.png and b/src/client/resources/icon.png differ diff --git a/src/client/resources/main.html b/src/client/resources/main.html index 8869773f..39eb02bf 100644 --- a/src/client/resources/main.html +++ b/src/client/resources/main.html @@ -12,6 +12,17 @@ -ms-user-select: none; cursor: default; box-sizing: border-box; + line-height: 130%; + } + + .row { + display: inline-flex; + text-align: center; + width: 70% + } + + .column { + flex: 25%; } html, @@ -22,10 +33,9 @@ background-size: cover; background-position: center; background-repeat: no-repeat; - color: #FFF; - font-family: "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial, sans-serif; - font-style: normal; - font-weight: lighter; + background-color: #202020; + color: white; + font-family: "HModMix-Medium", "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial, sans-serif; display: flex; min-height: 100vh; flex-direction: column; @@ -34,34 +44,39 @@ padding: 0; overflow-y: hidden; } - + main { flex: 1 0 auto; display: flex; } - + p { - font-weight: 200; - font-size: 1.2em; + font-size: 3.1vw; + color: white; + text-shadow: 1px 1px 3px black, 0px 0 20px black; + margin: 2%; } - + a { color: inherit; text-decoration: none; } - + a:visited { color: inherit; } - + p a { - text-decoration: underline; + text-decoration: none; + color: #edfdf1; + text-shadow: 2px 1px 1px black, 1px 1px 3px black, 0 0 13px black; } - + p a:hover { - color: #ffc320; + color: #66e391; + cursor: pointer; } - + nav { padding: 0px; margin-left: 15px; @@ -69,11 +84,11 @@ border-bottom: 1px solid; border-color: rgba(34, 34, 34, 0.25); } - + #brand { display: none; } - + #brand i { font-size: 40px; width: 64px; @@ -81,58 +96,68 @@ text-align: center; cursor: pointer; } - + #brand span { font-size: 27px; margin-left: 10px; } - + nav ul { list-style: none; padding: 0; margin: 0; } - + nav ul li { display: inline-block; } - + nav .nav-link { display: inline-block; - font-size: 1.3em; - color: #FFF; + font-size: 2.8vw; + color: white; text-transform: uppercase; padding: 0 10px; letter-spacing: 1px; padding: 10px 0px; margin-right: 15px; margin-bottom: -1px; + text-shadow: none; } - + nav .nav-link.active { - border-bottom: 1px solid #FFF; + border-bottom: 1px solid white; } - + + nav .nav-link:hover { + cursor: pointer; + } + nav .nav-link:hover, nav .nav-link.active { - text-shadow: 0px 0px 8px rgba(34, 34, 34, 0.5); + text-shadow: 0px 0px 10px rgba(255, 255, 255, 0.5); } - + + nav .nav-link.active { + border-bottom: 1px solid white; + cursor: default; + } + nav .nav-link:first-child { padding-left: 0; } - + nav .nav-link.not-active { color: rgba(34, 34, 34, 0.25); pointer-events: none; } - + .side-nav-container { min-width: 64px; border-right: 1px solid; border-color: rgba(34, 34, 34, 0.25); } - + .side-nav { color: rgba(34, 34, 34, 0.7); display: flex; @@ -145,27 +170,27 @@ position: fixed; left: 0; } - + .side-nav i { padding: 10px 0; transition: all .1s ease; cursor: pointer; } - + .side-nav i:hover { color: rgba(34, 34, 34, 1); } - + .side-nav-bottom { position: absolute; bottom: 0; } - + .main-container { padding: 10px; width: 100%; } - + .container { width: 80%; padding: 0 15px; @@ -174,59 +199,67 @@ justify-content: flex-start; flex-wrap: wrap; } - + .container.full { width: 100%; /*padding: 0px;*/ } - + .container h1, .container h2, .container h3 { width: 100%; - margin-bottom: 10px; - margin-left: 5px; + margin-bottom: 0; margin-top: 0; - letter-spacing: 1px; - font-weight: 200; + letter-spacing: 0.15vw; + text-shadow: 1px 1px 3px black, 0px 0 20px black; + line-height: 100%; + font-weight: normal; } - + + .container h1 { + font-family: "HModMixGothic-Regular", "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial, sans-serif; + font-size: 8vw; + color: #faffef; + text-shadow: 1px 1px 3px #1e3119, -1px 4px 6px #747474, 0px 0 20px #63a252; + } + .container h3 { margin-bottom: 0px; - font-weight: 500; } - + .full-row .card { flex: 2; } - + .full-row .card.small { flex: 1; } - + .card { display: flex; width: 25%; box-sizing: border-box; } - + .card.small { width: 12.5%; } - + .card.full { width: 100%; } - + @media(max-width: 1341px) { .card { width: 50%; } + .card.small { width: 25%; } } - + .card .card-container { width: 100%; /*margin: 5px; @@ -235,18 +268,20 @@ display: flex; flex-direction: column; overflow: hidden; + border-radius: 8px; box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.5); transition: all 0.5s ease; } + /*.card:hover .card-container { box-shadow: 0px 0px 5px 0px rgba(0,0,0,0); }*/ - + .card .card-img { overflow: hidden; - height: 265px; + height: 57.5vh; } - + .card img { display: block; width: 100%; @@ -254,8 +289,9 @@ object-position: center bottom; z-index: 1; transition: all 0.5s ease; + cursor: pointer; } - + .card .card-content { flex: 1; position: relative; @@ -263,37 +299,51 @@ padding: 10px 20px; padding-bottom: 42px; background-color: rgba(34, 34, 34, 0.1); - color: #FFF; + color: white; z-index: 5; transition: all 0.5s ease; - text-align: center; + text-align: center; } - + + .card:hover .card-content span { + text-shadow: none; + } + .card:hover .card-content { background-color: white; color: black; + cursor: pointer; } + /*.card:hover img { transform: scale(1.1); }*/ - + .card .card-content span { - font-size: 1.7em; - font-weight: 500; + font-family: "HModMixGothic-Regular", "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial, sans-serif; + font-size: 4.4vw; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 0.2vw; + line-height: 106%; + text-shadow: 2px 2px 4px #0a320a, 0px 0px 12px #317e37, 0px 1px 2px #003a02; + cursor: pointer; } - + + .card .card-content span#conp { + margin-left: -0.5vw; + } + .card .card-content p { margin-top: 10px; + cursor: pointer; } - + .card:hover .card-action { opacity: 1; bottom: 0; border-color: rgba(0, 0, 0, 0.25); } - + .card .card-action { /*opacity: 0;*/ position: absolute; @@ -306,60 +356,60 @@ text-transform: uppercase; padding: 7px; box-sizing: border-box; - font-weight: 500; transition: opacity bottom 0.5s; + font-size: 2.2vw; } - + .card .card-action.hidden-action { bottom: -43px; transition: bottom 0.5s ease; border-color: rgba(0, 0, 0, 0.0); + text-shadow: none; } - + .card:hover .card-action.hidden-action { bottom: 0; border-color: rgba(0, 0, 0, 0.25); } - + a.btn { display: inline-block; background-color: rgba(0, 0, 0, 0.2); border: 1px solid rgba(34, 34, 34, 0.42); - color: #FFF; - font-weight: 600; + color: white; padding: 10px 100px; border-radius: 1px; transition: all 0.5s ease; cursor: pointer; } - + a.btn i { vertical-align: middle; } - + a.btn.highlight { background: white; color: black; } - + a.btn:hover { background: white; color: black; box-shadow: 0px 0px 10px rgba(34, 34, 34, 0.42); } - + a.btn.small { padding: 10px 50px; } - + div.menus>div { display: none; } - + div.menus>div.active { display: block !important; } - + .progress { width: 100%; height: 40px; @@ -369,7 +419,7 @@ border: 1px solid rgba(34, 34, 34, 0.25); background: rgba(0, 0, 0, 0.25); } - + .progress>.bar { width: 50%; height: 100%; @@ -378,6 +428,22 @@ background: linear-gradient(145deg, rgba(121, 121, 121, 1) 0%, rgba(0, 212, 255, 1) 100%); transition: all 0.2s linear; } + + @font-face { + font-family: 'HModMix-Medium'; + src: url('data:font/woff;charset=utf-8;base64,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') format('woff'); + font-weight: normal; + font-style: normal; + font-display: swap; + } + + @font-face { + font-family: 'HModMixGothic-Regular'; + src: url('data:font/woff;charset=utf-8;base64,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') format('woff'); + font-weight: normal; + font-style: normal; + font-display: swap; + } @@ -406,10 +472,11 @@
- +
- Singleplayer + Singleplayer
Launch @@ -430,9 +497,52 @@
-

FED

-

Developed by fed

+

H2-Mod

+

GitHub + Page

+

Developers +

+
+

fed

+
+
+

Vlad +

+
+
+

Future +

+
+
+

netadr

+
+
+

+

Special Thanks +

+
+

momo5502 +

+
+
+

quaK +

+
+
+

xensik +

+
+
+

JariKCoding +

+
+
+

+
@@ -478,10 +588,10 @@ activateElement(menu, buttons); } - window.onload = function() { + window.onload = function () { showMenu("play"); }; - + \ No newline at end of file diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua index 95f4e27e..ee4a79f8 100644 --- a/src/client/resources/ui_scripts/updater.lua +++ b/src/client/resources/ui_scripts/updater.lua @@ -31,17 +31,21 @@ function startupdatecheck(popup, autoclose) return end - LUI.yesnopopup({ - title = Engine.Localize("@MENU_NOTICE"), - text = Engine.Localize("@MENU_CCS_NEW_PATCH_NOTICE") .. " " .. Engine.Localize("@MENU_DOWNLOAD_AUTOUPDATE_PATCH"), - callback = function(result) - if (result) then - startupdatedownload(popup, autoclose) - else - LUI.FlowManager.RequestLeaveMenu(popup) + if (updater.shouldforceupdate()) then + startupdatedownload(popup, autoclose) + else + LUI.yesnopopup({ + title = Engine.Localize("@MENU_NOTICE"), + text = Engine.Localize("@MENU_CCS_NEW_PATCH_NOTICE") .. " " .. Engine.Localize("@MENU_DOWNLOAD_AUTOUPDATE_PATCH"), + callback = function(result) + if (result) then + startupdatedownload(popup, autoclose) + else + LUI.FlowManager.RequestLeaveMenu(popup) + end end - end - }) + }) + end end) updater.startupdatecheck() diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 6fe72a49..5f68ac6d 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -1,8 +1,11 @@ #pragma once #define BINARY_PAYLOAD_SIZE 0x12000000 +#define BASE_ADDRESS 0x140000000 #define INJECT_HOST_AS_LIB +#define RVA(ptr) static_cast(reinterpret_cast(ptr) - BASE_ADDRESS) + #pragma warning(push) #pragma warning(disable: 4100) #pragma warning(disable: 4127) @@ -47,6 +50,7 @@ #include #include #include +#include // min and max is required by gdi, therefore NOMINMAX won't work #ifdef max diff --git a/src/client/utils/mapents.cpp b/src/client/utils/mapents.cpp new file mode 100644 index 00000000..549b088a --- /dev/null +++ b/src/client/utils/mapents.cpp @@ -0,0 +1,163 @@ +#include + +#include "mapents.hpp" + +#include + +namespace mapents +{ + void mapents_entity::add_var(const spawn_var& var) + { + this->vars.push_back(var); + } + + std::string mapents_entity::get(const std::string& key) const + { + for (const auto& var : this->vars) + { + if (var.key == key) + { + return var.value; + } + } + + return ""; + } + + std::vector mapents_entity::get_var_list() const + { + return this->vars; + } + + void mapents_entity::clear() + { + this->vars.clear(); + } + + mapents_list parse(const std::string& data, const token_name_callback& get_token_name) + { + mapents_list list; + mapents_entity current_entity; + + const auto lines = utils::string::split(data, '\n'); + auto in_map_ent = false; + auto in_comment = false; + + for (auto i = 0; i < lines.size(); i++) + { + auto line = lines[i]; + if (line.ends_with('\r')) + { + line.pop_back(); + } + + if (line.starts_with("/*") || line.ends_with("/*")) + { + in_comment = true; + continue; + } + + if (line.starts_with("*/") || line.ends_with("*/")) + { + in_comment = false; + continue; + } + + if (in_comment || line.starts_with("//") || line.empty()) + { + continue; + } + + if (line[0] == '{' && !in_map_ent) + { + current_entity.clear(); + in_map_ent = true; + continue; + } + + if (line[0] == '{' && in_map_ent) + { + throw std::runtime_error(utils::string::va("Unexpected '{' on line %i", i)); + } + + if (line[0] == '}' && in_map_ent) + { + list.entities.push_back(current_entity); + in_map_ent = false; + continue; + } + + if (line[0] == '}' && !in_map_ent) + { + throw std::runtime_error(utils::string::va("Unexpected '}' on line %i", i)); + } + + if (line[0] == '\n' || line[0] == '\0' || line[0] == '\n') + { + continue; + } + + spawn_var var{}; + + if (line.starts_with("0 \"")) + { + std::regex expr(R"~(0 "(.+)" "(.*)")~"); + std::smatch match{}; + if (!std::regex_search(line, match, expr)) + { + throw std::runtime_error(utils::string::va("Failed to parse line %i (%s)", i, line.data())); + continue; + } + + var.key = utils::string::to_lower(match[1].str()); + var.value = match[2].str(); + var.sl_string = true; + } + else + { + std::regex expr(R"~((.+) "(.*)")~"); + std::smatch match{}; + if (!std::regex_search(line, match, expr)) + { + throw std::runtime_error( + utils::string::va("Failed to parse line %i (%s)", i, line.data())); + continue; + } + + var.key = utils::string::to_lower(match[1].str()); + var.value = match[2].str(); + + if (utils::string::is_numeric(var.key) && !var.key.starts_with("\"") && !var.key.ends_with("\"")) + { + var.key = get_token_name(static_cast(std::atoi(var.key.data()))); + } + else if (var.key.starts_with("\"") && var.key.ends_with("\"") && var.key.size() >= 3) + { + var.key = var.key.substr(1, var.key.size() - 2); + } + else + { + throw std::runtime_error( + utils::string::va("Invalid key ('%s') on line %i (%s)", var.key.data(), i, line.data())); + continue; + } + } + + if (var.key.size() <= 0) + { + throw std::runtime_error( + utils::string::va("Invalid key ('%s') on line %i (%s)", var.key.data(), i, line.data())); + continue; + } + + if (var.value.size() <= 0) + { + continue; + } + + current_entity.add_var(var); + } + + return list; + } +} diff --git a/src/client/utils/mapents.hpp b/src/client/utils/mapents.hpp new file mode 100644 index 00000000..55e62dc3 --- /dev/null +++ b/src/client/utils/mapents.hpp @@ -0,0 +1,34 @@ +#pragma once + +namespace mapents +{ + using token_name_callback = std::function; + using token_id_callback = std::function; + + struct spawn_var + { + std::string key; + std::string value; + bool sl_string; + }; + + class mapents_entity + { + public: + void clear(); + void add_var(const spawn_var& var); + + std::string get(const std::string& key) const; + std::vector get_var_list() const; + + private: + std::vector vars; + }; + + struct mapents_list + { + std::vector entities; + }; + + mapents_list parse(const std::string& data, const token_name_callback& token_name); +} diff --git a/src/common/utils/hook.cpp b/src/common/utils/hook.cpp index be05cb96..9af1ee7c 100644 --- a/src/common/utils/hook.cpp +++ b/src/common/utils/hook.cpp @@ -3,6 +3,13 @@ #include +Mem seg_ptr(const SReg& segment, const uint64_t off) +{ + auto mem = ptr_abs(off); + mem.setSegment(segment); + return mem; +} + namespace utils::hook { namespace @@ -220,6 +227,11 @@ namespace utils::hook set(patch_pointer + 1, int32_t(size_t(data) - (size_t(pointer) + 5))); } + void call(void* pointer, const size_t data) + { + return call(pointer, reinterpret_cast(data)); + } + void call(const size_t pointer, void* data) { return call(reinterpret_cast(pointer), data); @@ -255,6 +267,11 @@ namespace utils::hook } } + void jump(void* pointer, const size_t data, const bool use_far) + { + return jump(pointer, reinterpret_cast(data), use_far); + } + void jump(const size_t pointer, void* data, const bool use_far) { return jump(reinterpret_cast(pointer), data, use_far); diff --git a/src/common/utils/hook.hpp b/src/common/utils/hook.hpp index bb24f8ce..3a1480ad 100644 --- a/src/common/utils/hook.hpp +++ b/src/common/utils/hook.hpp @@ -1,11 +1,14 @@ #pragma once #include "signature.hpp" +#include "memory.hpp" #include #include using namespace asmjit::x86; +Mem seg_ptr(const SReg& segment, const uint64_t off); + namespace utils::hook { namespace detail @@ -151,10 +154,12 @@ namespace utils::hook bool is_relatively_far(const void* pointer, const void* data, int offset = 5); void call(void* pointer, void* data); + void call(void* pointer, size_t data); void call(size_t pointer, void* data); void call(size_t pointer, size_t data); void jump(void* pointer, void* data, bool use_far = false); + void jump(void* pointer, size_t data, bool use_far = false); void jump(size_t pointer, void* data, bool use_far = false); void jump(size_t pointer, size_t data, bool use_far = false); @@ -202,4 +207,59 @@ namespace utils::hook { return static_cast(func)(args...); } + + template + void* allocate_far_jump() + { + constexpr auto alloc_size = 0x1000; + constexpr auto far_jmp_size = 0xC; + + const auto alloc_jump_table = [] + { + return reinterpret_cast( + memory::allocate_near(Base, alloc_size, PAGE_EXECUTE_READWRITE)); + }; + + static auto jump_table = alloc_jump_table(); + static auto current_pos = jump_table; + + if (current_pos + far_jmp_size >= jump_table + alloc_size) + { + jump_table = alloc_jump_table(); + current_pos = jump_table; + } + + const auto ptr = current_pos; + current_pos += far_jmp_size; + return ptr; + } + + template + void* create_far_jump(const T dest) + { + static std::unordered_map allocated_jumps; + if (const auto iter = allocated_jumps.find(reinterpret_cast(dest)); iter != allocated_jumps.end()) + { + return iter->second; + } + + const auto pos = allocate_far_jump(); + jump(pos, dest, true); + allocated_jumps.insert(std::make_pair(dest, pos)); + return pos; + } + + template + void far_jump(const size_t address, const T dest) + { + const auto pos = create_far_jump(dest); + jump(address, pos, false); + } + + template + void far_call(const size_t address, const T dest) + { + const auto pos = create_far_jump(dest); + call(address, pos); + } } diff --git a/src/common/utils/memory.cpp b/src/common/utils/memory.cpp index 52d46771..68395019 100644 --- a/src/common/utils/memory.cpp +++ b/src/common/utils/memory.cpp @@ -158,6 +158,33 @@ namespace utils return false; } + void* memory::allocate_near(const size_t address, const size_t size, const std::uint32_t protect) + { + SYSTEM_INFO system_info{}; + GetSystemInfo(&system_info); + + const auto page_size = system_info.dwPageSize; + const auto aligned_size = size + (~size & (page_size - 1)); + auto current_address = address; + + while (true) + { + current_address -= page_size; + + if (current_address <= reinterpret_cast(system_info.lpMinimumApplicationAddress)) + { + return nullptr; + } + + const auto result = VirtualAlloc(reinterpret_cast(current_address), aligned_size, MEM_RESERVE | MEM_COMMIT, protect); + if (result != nullptr) + { + std::memset(result, 0, aligned_size); + return result; + } + } + } + memory::allocator* memory::get_allocator() { return &memory::mem_allocator_; diff --git a/src/common/utils/memory.hpp b/src/common/utils/memory.hpp index 5af5645e..f72aa081 100644 --- a/src/common/utils/memory.hpp +++ b/src/common/utils/memory.hpp @@ -67,6 +67,8 @@ namespace utils static bool is_bad_code_ptr(const void* ptr); static bool is_rdata_ptr(void* ptr); + static void* allocate_near(const size_t address, const size_t size, const std::uint32_t protect); + static allocator* get_allocator(); private: diff --git a/src/common/utils/string.cpp b/src/common/utils/string.cpp index 401ff88f..eca34948 100644 --- a/src/common/utils/string.cpp +++ b/src/common/utils/string.cpp @@ -216,9 +216,29 @@ namespace utils::string std::string truncate(const std::string& text, const size_t length, const std::string& end) { - return text.size() <= length - ? text - : text.substr(0, length - end.size()) + end; + const auto new_line = text.find_first_of('\n'); + if (text.size() <= length) + { + if (new_line == std::string::npos) + { + return text; + } + else + { + return text.substr(0, new_line + 1); + } + } + else + { + if (new_line == std::string::npos) + { + return text.substr(0, length - end.size()) + end; + } + else + { + return text.substr(0, std::min(new_line + 1, length) - end.size()) + end; + } + } } bool strstr_lower(const char* a, const char* b) @@ -228,7 +248,7 @@ namespace utils::string while (*a_ != '\0' && *b_ != '\0') { - if (std::tolower(*a_) == std::tolower(*b_)) + if (*b_ == '*' || std::tolower(*a_) == std::tolower(*b_)) { b_++; } @@ -242,4 +262,9 @@ namespace utils::string return *b_ == '\0'; } + + bool is_numeric(const std::string& text) + { + return std::to_string(atoi(text.data())) == text; + } } diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 447a6960..7033e161 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -105,4 +105,6 @@ namespace utils::string std::string truncate(const std::string& text, const size_t length, const std::string& end); bool strstr_lower(const char* a, const char* b); + + bool is_numeric(const std::string& text); }