diff --git a/.gitignore b/.gitignore index 6cd2bf7..5660df0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ *.suo *.user The Long Dark Save Editor 2/bin/ -The Long Dark Save Editor 2/obj/ \ No newline at end of file +The Long Dark Save Editor 2/obj/ +# Build output for all projects (Core/Server live under src/) +[Bb]in/ +[Oo]bj/ diff --git a/README.md b/README.md index 148f343..f57552a 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,24 @@ Edit The Long Dark save files Downloads from ModDB: http://www.moddb.com/mods/the-long-dark-save-editor-2/downloads + +## Cross-platform web editor (Linux / macOS / Windows) + +The original editor is a Windows-only WPF app. This repository also includes a +cross-platform port under `src/`: a portable core library (`TldSaveEditor.Core`) +and a small local web app (`TldSaveEditor.Server`) that runs in your browser. + +**Requirements:** the [.NET 10 SDK](https://dotnet.microsoft.com/download). + +**Run it:** + +- Linux / macOS: `./run.sh` +- Windows: `run.cmd` (double-click) — or any platform: `dotnet run --project src/TldSaveEditor.Server -c Release` + +It builds on first run, serves `http://127.0.0.1:5173` (loopback only) and opens +your browser. Your save folder is detected automatically (Windows `%LOCALAPPDATA%`, +Linux Steam/Proton prefix, macOS Application Support); you can also point it elsewhere +in the UI. Every save writes a timestamped backup to a `backups/` folder next to the +save, and the UI can restore any backup. + +The editor covers the Player, Skills, Inventory, Afflictions, Map and Profile tabs. diff --git a/The Long Dark Save Editor 2/Game data/GlobalData.cs b/The Long Dark Save Editor 2/Game data/GlobalData.cs index 1e15d4d..3892bea 100644 --- a/The Long Dark Save Editor 2/Game data/GlobalData.cs +++ b/The Long Dark Save Editor 2/Game data/GlobalData.cs @@ -349,10 +349,25 @@ public class FoodItemSaveDataProxy public bool m_Packaged { get; set; } } + // The game stores liquid volume / fuel as a fixed-point Int64 where 1 litre == 1_000_000_000. + // Reading those values into a float overflows the UI (e.g. 2L is shown as 2E+09) and corrupts + // the save on write. See issues #85, #87 and the Storm Lantern part of #74. + public static class FixedPoint + { + public const long LitersScale = 1_000_000_000; + } + public class LiquidItemSaveDataProxy { - public float m_LiquidLitersProxy { get; set; } + public long m_LiquidLitersProxy { get; set; } public EnumWrapper m_LiquidQuality { get; set; } + + [JsonIgnore] + public double Liters + { + get => m_LiquidLitersProxy / (double)FixedPoint.LitersScale; + set => m_LiquidLitersProxy = (long)Math.Round(value * FixedPoint.LitersScale); + } } public class FlareItemSaveDataProxy @@ -372,8 +387,15 @@ public class FlashlightItemSaveDataProxy public class KeroseneLampItemSaveDataProxy { public float m_HoursPlayed { get; set; } - public float m_CurrentFuelLitersProxy { get; set; } + public long m_CurrentFuelLitersProxy { get; set; } public bool m_OnProxy { get; set; } + + [JsonIgnore] + public double Liters + { + get => m_CurrentFuelLitersProxy / (double)FixedPoint.LitersScale; + set => m_CurrentFuelLitersProxy = (long)Math.Round(value * FixedPoint.LitersScale); + } } public class ClothingItemSaveDataProxy @@ -396,7 +418,14 @@ public class GunItemSaveDataProxy public class WaterSupplySaveDataProxy { - public float m_VolumeProxy { get; set; } + public long m_VolumeProxy { get; set; } + + [JsonIgnore] + public double Liters + { + get => m_VolumeProxy / (double)FixedPoint.LitersScale; + set => m_VolumeProxy = (long)Math.Round(value * FixedPoint.LitersScale); + } } public class BedSaveDataProxy diff --git a/The Long Dark Save Editor 2/Helpers/ItemDictionary.cs b/The Long Dark Save Editor 2/Helpers/ItemDictionary.cs index ac01c1d..39431cc 100644 --- a/The Long Dark Save Editor 2/Helpers/ItemDictionary.cs +++ b/The Long Dark Save Editor 2/Helpers/ItemDictionary.cs @@ -38,7 +38,7 @@ static ItemDictionary() { // First aid AddItemInfo("GEAR_BottleAntibiotics", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); - AddItemInfo("GEAR_BottleHydrogenPeroxide", ItemCategory.FirstAid, @"{""LiquidItem"": {""m_LiquidLitersProxy"": 0.5,""m_LiquidQuality"": { ""Value"":""NonPotable""}}}"); + AddItemInfo("GEAR_BottleHydrogenPeroxide", ItemCategory.FirstAid, @"{""LiquidItem"": {""m_LiquidLitersProxy"": 500000000,""m_LiquidQuality"": { ""Value"":""NonPotable""}}}"); AddItemInfo("GEAR_BottlePainKillers", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); AddItemInfo("GEAR_HeavyBandage", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); AddItemInfo("GEAR_OldMansBeardDressing", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); @@ -181,8 +181,8 @@ static ItemDictionary() AddItemInfo("GEAR_SodaGrape", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 250}}"); AddItemInfo("GEAR_SodaOrange", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 250}}"); AddItemInfo("GEAR_TomatoSoupCan", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 300}, ""SmashableItem"": {}}"); - AddItemInfo("GEAR_WaterSupplyNotPotable", ItemCategory.Food, @"{""WaterSupply"":{""m_VolumeProxy"": 1}}", true); - AddItemInfo("GEAR_WaterSupplyPotable", ItemCategory.Food, @"{""WaterSupply"":{""m_VolumeProxy"": 1}}", true); + AddItemInfo("GEAR_WaterSupplyNotPotable", ItemCategory.Food, @"{""WaterSupply"":{""m_VolumeProxy"": 1000000000}}", true); + AddItemInfo("GEAR_WaterSupplyPotable", ItemCategory.Food, @"{""WaterSupply"":{""m_VolumeProxy"": 1000000000}}", true); AddItemInfo("GEAR_WolfQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); AddItemInfo("GEAR_BearQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); AddItemInfo("GEAR_StagQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); @@ -218,12 +218,12 @@ static ItemDictionary() AddItemInfo("GEAR_HighQualityTools", ItemCategory.Tools, @"{}"); AddItemInfo("GEAR_Hook", ItemCategory.Tools, @"{}"); AddItemInfo("GEAR_HookAndLine", ItemCategory.Tools, @"{}"); - AddItemInfo("GEAR_JerrycanRusty", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 2,m_LiquidQuality:{Value:""NonPotable""}}}"); - AddItemInfo("GEAR_KeroseneLampB", ItemCategory.Tools, @"{""KeroseneLampItem"": {""m_CurrentFuelLitersProxy"": 1}}"); + AddItemInfo("GEAR_JerrycanRusty", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 2000000000,m_LiquidQuality:{Value:""NonPotable""}}}"); + AddItemInfo("GEAR_KeroseneLampB", ItemCategory.Tools, @"{""KeroseneLampItem"": {""m_CurrentFuelLitersProxy"": 1000000000}}"); AddItemInfo("GEAR_Knife", ItemCategory.Tools, @"{}"); AddItemInfo("GEAR_KnifeImprovised", ItemCategory.Tools, @"{}"); - AddItemInfo("GEAR_LampFuel", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 0.5,m_LiquidQuality:{Value:""NonPotable""}}}"); - AddItemInfo("GEAR_LampFuelFull", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 0.5,m_LiquidQuality:{Value:""NonPotable""}}}"); + AddItemInfo("GEAR_LampFuel", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 500000000,m_LiquidQuality:{Value:""NonPotable""}}}"); + AddItemInfo("GEAR_LampFuelFull", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 500000000,m_LiquidQuality:{Value:""NonPotable""}}}"); AddItemInfo("GEAR_Line", ItemCategory.Tools, @"{}"); AddItemInfo("GEAR_MagnifyingLens", ItemCategory.Tools, @"{}"); AddItemInfo("GEAR_NewsprintRoll", ItemCategory.Tools, @"{}"); diff --git a/The Long Dark Save Editor 2/MainWindow.xaml.cs b/The Long Dark Save Editor 2/MainWindow.xaml.cs index 8b12cbf..c97dc38 100644 --- a/The Long Dark Save Editor 2/MainWindow.xaml.cs +++ b/The Long Dark Save Editor 2/MainWindow.xaml.cs @@ -62,13 +62,9 @@ public ObservableCollection Saves public MainWindow() { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings - { - //MissingMemberHandling = MissingMemberHandling.Error, - FloatFormatHandling = FloatFormatHandling.Symbol, - // Serialize byte arrays as arrays of numbers instead of base64 - Converters = new List { new ByteArrayConverter() }, - }; + // JsonConvert.DefaultSettings (FloatFormatHandling.Symbol + ByteArrayConverter) is + // configured once in GameSave's static constructor so the WPF app and the web server + // share a single definition. #if DEBUG IsDebug = true; diff --git a/The Long Dark Save Editor 2/Tabs/InventoryTab.xaml b/The Long Dark Save Editor 2/Tabs/InventoryTab.xaml index b50e6ae..6ddf040 100644 --- a/The Long Dark Save Editor 2/Tabs/InventoryTab.xaml +++ b/The Long Dark Save Editor 2/Tabs/InventoryTab.xaml @@ -60,13 +60,13 @@ @@ -78,7 +78,7 @@ diff --git a/TldSaveEditor.slnx b/TldSaveEditor.slnx new file mode 100644 index 0000000..13d2e3f --- /dev/null +++ b/TldSaveEditor.slnx @@ -0,0 +1,6 @@ + + + + + + diff --git a/run.cmd b/run.cmd new file mode 100644 index 0000000..051df9c --- /dev/null +++ b/run.cmd @@ -0,0 +1,10 @@ +@echo off +REM Launch the TLD Save Editor (local web app) on Windows. +REM Builds on first run, then serves http://127.0.0.1:5173 and opens your browser. +REM Requires the .NET 10 SDK (https://dotnet.microsoft.com/download). +REM +REM Usage: +REM run.cmd (double-click, or run from a terminal) +REM run.cmd --no-browser run without opening a browser +cd /d "%~dp0" +dotnet run --project "src\TldSaveEditor.Server" -c Release %* diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..43642cc --- /dev/null +++ b/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# Launch the TLD Save Editor (local web app). Builds on first run, then starts the +# server bound to 127.0.0.1:5173 and opens your browser. +# +# Usage: +# ./run.sh # build (Release) + run + open browser +# ./run.sh --no-browser # run without opening a browser +set -euo pipefail + +cd "$(dirname "$0")" + +exec dotnet run --project src/TldSaveEditor.Server -c Release "$@" diff --git a/src/TldSaveEditor.Core/GameData/Afflictions.cs b/src/TldSaveEditor.Core/GameData/Afflictions.cs new file mode 100644 index 0000000..aec8614 --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/Afflictions.cs @@ -0,0 +1,176 @@ +using System.Collections.ObjectModel; +using System.Windows.Input; +using The_Long_Dark_Save_Editor_2.Helpers.Helpers; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + + public class Affliction + { + + public AfflictionType AfflictionType { get; set; } + public int Location { get; set; } + public ICommand RemoveCommand { get; set; } + + public Affliction(ObservableCollection collection) + { + RemoveCommand = new CommandHandler(() => + { + collection.Remove(this); + }); + } + } + + public class Hypothermia : Affliction + { + public Hypothermia(ObservableCollection collection) : base(collection) { } + + private static int hoursSpentFreezingRequired = 10; + public float ElapsedHours { get; set; } + public float ElapsedWarmHours { get; set; } + public float RiskChance + { + get { return ElapsedHours / hoursSpentFreezingRequired; } + } + public string Cause { get; set; } + } + + public class Frostbite : Affliction + { + public Frostbite(ObservableCollection collection) : base(collection) { } + + private static int[] bodyAreaHP = new int[] { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 }; + + public float DamagePercentage + { + get { return Damage / bodyAreaHP[Location]; } + set { Damage = bodyAreaHP[Location] * value; } + } + public float Damage { get; set; } + } + + public class FoodPoisoning : Affliction + { + public FoodPoisoning(ObservableCollection collection) : base(collection) { } + + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + public bool AntibioticsTaken { get; set; } + public float ElapsedRest { get; set; } + public string Cause { get; set; } + } + + public class Dysentery : Affliction + { + public Dysentery(ObservableCollection collection) : base(collection) { } + + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + public bool AntibioticsTaken { get; set; } + public float ElapsedRest { get; set; } + public float CleanWaterConsumed { get; set; } + } + + public class SprainAffliction : Affliction + { + public SprainAffliction(ObservableCollection collection) : base(collection) { } + + public string CauseLocID { get; set; } + public float Duration { get; set; } + public float ElapsedHours { get; set; } + public float ElapsedRest { get; set; } + } + + public class Burns : Affliction + { + public Burns(ObservableCollection collection) : base(collection) { } + + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + public bool PainKillersTaken { get; set; } + public bool BandageApplied { get; set; } + public string CauseLocID { get; set; } + } + + public class BurnsElectric : Affliction + { + public BurnsElectric(ObservableCollection collection) : base(collection) { } + + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + public bool PainKillersTaken { get; set; } + public bool BandageApplied { get; set; } + } + + public class BloodLoss : Affliction + { + public BloodLoss(ObservableCollection collection) : base(collection) { } + + public string CauseLocID { get; set; } + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + } + + public class Infection : Affliction + { + public Infection(ObservableCollection collection) : base(collection) { } + + public string CauseLocID { get; set; } + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + public bool AntibioticsTaken { get; set; } + public float ElapsedRest { get; set; } + } + + public class InfectionRisk : Affliction + { + public InfectionRisk(ObservableCollection collection) : base(collection) { } + + public string CauseLocID { get; set; } + public float ElapsedHours { get; set; } + public float DurationHours { get; set; } + public bool AntisepticTaken { get; set; } + public float CurrentInfectionChance { get; set; } + public bool Constant { get; set; } + } + + public class CabinFever : Affliction + { + public CabinFever(ObservableCollection collection) : base(collection) { } + + public float ElapsedHours { get; set; } + } + + public class IntestinalParasites : Affliction + { + public IntestinalParasites(ObservableCollection collection) : base(collection) { } + + public float CurrentInfectionChance { get; set; } + public float ParasitesElapsedHours { get; set; } + public float RiskElapsedHours { get; set; } + public float RiskDurationHours { get; set; } + public int DosesTaken { get; set; } + public bool HasTakenDoseToday { get; set; } + public int DayToAllowNextDose { get; set; } + public int PiecesEatenThisRiskCycle { get; set; } + + } + + public class BrokenRib : Affliction + { + public BrokenRib(ObservableCollection collection) : base(collection) { } + + public string CauseLocID { get; set; } + public int PainKillersTaken { get; set; } + public int BandagesApplied { get; set; } + public float ElapsedRest { get; set; } + public float NumHoursRestForCure { get; set; } + } + + public class WellFed : Affliction + { + public WellFed(ObservableCollection collection) : base(collection) { } + + public float ElapsedHoursNotStarving { get; set; } + } +} diff --git a/src/TldSaveEditor.Core/GameData/AfflictionsContainer.cs b/src/TldSaveEditor.Core/GameData/AfflictionsContainer.cs new file mode 100644 index 0000000..c0489a1 --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/AfflictionsContainer.cs @@ -0,0 +1,710 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using The_Long_Dark_Save_Editor_2.Helpers; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + public class AfflictionsContainer + { + + private ObservableCollection negative = new ObservableCollection(); + public ObservableCollection Negative { get { return negative; } set { SetPropertyField(ref negative, value); } } + private ObservableCollection positive = new ObservableCollection(); + public ObservableCollection Positive { get { return positive; } set { SetPropertyField(ref positive, value); } } + public Dictionary proxies = new Dictionary(); + + public AfflictionsContainer(GlobalSaveGameFormat global) + { + negative.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Negative")); }; + positive.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Positive")); }; + + ConvertHypothermia(global.Hypothermia); + ConvertFrostbite(global.FrostBite); + ConvertFoodPoisoning(global.FoodPoisoning); + ConvertDysentery(global.Dysentery); + ConvertSprainedAnkle(global.SprainedAnkle); + ConvertSprainedWrist(global.SprainedWrist); + ConvertBurns(global.Burns); + ConvertBurnsElectric(global.BurnsElectric); + ConvertBloodLoss(global.BloodLoss); + ConvertInfection(global.Infection); + ConvertInfectionRisk(global.InfectionRisk); + ConvertCabinFever(global.CabinFever); + ConvertIntestinalParasites(global.IntestinalParasites); + ConvertBrokenRib(global.BrokenRibs); + ConvertWellFed(global.WellFed); + + } + + private void ConvertHypothermia(HypothermiaSaveDataProxy proxy) + { + if (proxy == null) + return; + if (proxy.m_Active) + { + Negative.Add(new Hypothermia(negative) + { + AfflictionType = AfflictionType.Hypothermia, + Location = 6, + ElapsedHours = proxy.m_ElapsedHours, + ElapsedWarmHours = proxy.m_ElapsedHours, + Cause = proxy.m_CauseLocID, + }); + } + else if (proxy.m_ElapsedHours > 0) + { + Negative.Add(new Hypothermia(negative) + { + AfflictionType = AfflictionType.HypothermiaRisk, + Location = 6, + ElapsedHours = proxy.m_ElapsedHours, + ElapsedWarmHours = proxy.m_ElapsedHours, + Cause = proxy.m_CauseLocID, + }); + } + } + + private void ConvertFrostbite(FrostbiteSaveDataProxy proxy) + { + if (proxy == null) + return; + + var frostbiteDamage = new List(proxy.m_LocationsCurrentFrostbiteDamage); + + foreach (int bodyArea in proxy.m_LocationsWithActiveFrostbite) + { + Negative.Add(new Frostbite(negative) + { + AfflictionType = AfflictionType.Frostbite, + Location = bodyArea, + Damage = proxy.m_LocationsCurrentFrostbiteDamage[bodyArea], + }); + frostbiteDamage[bodyArea] = 0; + } + foreach (int bodyArea in proxy.m_LocationsWithFrostbiteRisk) + { + Negative.Add(new Frostbite(negative) + { + AfflictionType = AfflictionType.FrostbiteRisk, + Location = bodyArea, + Damage = proxy.m_LocationsCurrentFrostbiteDamage[bodyArea], + }); + frostbiteDamage[bodyArea] = 0; + } + for (int i = 0; i < frostbiteDamage.Count; i++) + { + if (frostbiteDamage[i] > 0) + { + Negative.Add(new Frostbite(negative) + { + AfflictionType = AfflictionType.FrostbiteDamage, + Location = i, + Damage = frostbiteDamage[i], + }); + } + } + } + + private void ConvertFoodPoisoning(FoodPoisoningSaveDataProxy proxy) + { + if (proxy == null || !proxy.m_Active) + return; + Negative.Add(new FoodPoisoning(negative) + { + AfflictionType = AfflictionType.FoodPoisioning, + Location = 6, + AntibioticsTaken = proxy.m_AntibioticsTaken, + Cause = proxy.m_CauseLocID, + DurationHours = proxy.m_DurationHours, + ElapsedHours = proxy.m_ElapsedHours, + ElapsedRest = proxy.m_ElapsedHours, + }); + } + + private void ConvertDysentery(DysenterySaveDataProxy proxy) + { + if (proxy == null || !proxy.m_Active) + return; + Negative.Add(new Dysentery(negative) + { + AfflictionType = AfflictionType.Dysentery, + Location = 7, + AntibioticsTaken = proxy.m_AntibioticsTaken, + CleanWaterConsumed = proxy.m_CleanWaterConsumedLiters, + DurationHours = proxy.m_DurationHours, + ElapsedHours = proxy.m_ElapsedHours, + ElapsedRest = proxy.m_ElapsedRest, + }); + } + + private void ConvertSprainedAnkle(SprainedAnkleSaveDataProxy proxy) + { + if (proxy == null || proxy.m_ElapsedHoursList == null) + return; + for (int i = 0; i < proxy.m_ElapsedHoursList.Count; i++) + { + Negative.Add(new SprainAffliction(negative) + { + AfflictionType = AfflictionType.SprainedAnkle, + Location = proxy.m_Locations[i], + CauseLocID = proxy.m_CausesLocIDs[i], + Duration = proxy.m_DurationHoursList[i], + ElapsedHours = proxy.m_ElapsedHoursList[i], + ElapsedRest = proxy.m_ElapsedRestList[i], + }); + } + } + + private void ConvertSprainedWrist(SprainedWristSaveDataProxy proxy) + { + if (proxy == null || proxy.m_CausesLocIDs == null) + return; + for (int i = 0; i < proxy.m_ElapsedHoursList.Count; i++) + { + Negative.Add(new SprainAffliction(negative) + { + AfflictionType = AfflictionType.SprainedWrist, + Location = proxy.m_Locations[i], + CauseLocID = proxy.m_CausesLocIDs[i], + Duration = proxy.m_DurationHoursList[i], + ElapsedHours = proxy.m_ElapsedHoursList[i], + ElapsedRest = proxy.m_ElapsedRestList[i], + }); + } + } + + private void ConvertBurns(BurnsSaveDataProxy proxy) + { + if (proxy == null || !proxy.m_Active) + return; + Negative.Add(new Burns(negative) + { + AfflictionType = AfflictionType.Burns, + Location = 5, + BandageApplied = proxy.m_BandageApplied, + CauseLocID = proxy.m_CauseLocID, + DurationHours = proxy.m_DurationHours, + ElapsedHours = proxy.m_ElapsedHours, + PainKillersTaken = proxy.m_PainKillersTaken, + }); + } + + private void ConvertBurnsElectric(BurnsElectricSaveDataProxy proxy) + { + if (proxy == null || !proxy.m_Active) + return; + Negative.Add(new BurnsElectric(negative) + { + AfflictionType = AfflictionType.BurnsElectric, + Location = 3, + BandageApplied = proxy.m_BandageApplied, + DurationHours = proxy.m_DurationHours, + ElapsedHours = proxy.m_ElapsedHours, + PainKillersTaken = proxy.m_PainKillersTaken, + }); + } + + private void ConvertBloodLoss(BloodLossSaveDataProxy proxy) + { + if (proxy == null || proxy.m_CausesLocIDs == null) + return; + for (int i = 0; i < proxy.m_DurationHoursList.Count; i++) + { + Negative.Add(new BloodLoss(negative) + { + AfflictionType = AfflictionType.BloodLoss, + Location = proxy.m_Locations[i], + CauseLocID = proxy.m_CausesLocIDs[i], + DurationHours = proxy.m_DurationHoursList[i], + ElapsedHours = proxy.m_ElapsedHoursList[i], + }); + } + } + + private void ConvertInfection(InfectionSaveDataProxy proxy) + { + if (proxy == null || proxy.m_DurationHoursList == null) + return; + for (int i = 0; i < proxy.m_DurationHoursList.Count; i++) + { + Negative.Add(new Infection(negative) + { + AfflictionType = AfflictionType.Infection, + Location = proxy.m_Locations[i], + AntibioticsTaken = proxy.m_AntibioticsTakenList[i], + CauseLocID = proxy.m_CausesLocIDs[i], + DurationHours = proxy.m_DurationHoursList[i], + ElapsedHours = proxy.m_ElapsedHoursList[i], + ElapsedRest = proxy.m_ElapsedRestList[i], + }); + } + } + + private void ConvertInfectionRisk(InfectionRiskSaveDataProxy proxy) + { + if (proxy == null || proxy.m_CausesLocIDs == null) + return; + for (int i = 0; i < proxy.m_DurationHoursList.Count; i++) + { + Negative.Add(new InfectionRisk(negative) + { + AfflictionType = AfflictionType.InfectionRisk, + Location = proxy.m_Locations[i], + AntisepticTaken = proxy.m_AntisepticTakenList[i], + CauseLocID = proxy.m_CausesLocIDs[i], + CurrentInfectionChance = proxy.m_CurrentInfectionChanceList[i], + DurationHours = proxy.m_DurationHoursList[i], + ElapsedHours = proxy.m_ElapsedHoursList[i], + }); + } + } + + private void ConvertCabinFever(CabinFeverSaveDataProxy proxy) + { + if (proxy == null) + return; + if (proxy.m_Active) + { + Negative.Add(new CabinFever(negative) + { + AfflictionType = AfflictionType.CabinFever, + Location = 0, + ElapsedHours = proxy.m_ElapsedHours, + }); + } + else if (proxy.m_RiskActive) + { + Negative.Add(new CabinFever(negative) + { + AfflictionType = AfflictionType.CabinFeverRisk, + Location = 0, + ElapsedHours = proxy.m_ElapsedHours, + }); + } + } + + private void ConvertIntestinalParasites(IntestinalParasitesSaveDataProxy proxy) + { + if (proxy == null) + return; + if (proxy.m_HasParasites || proxy.m_HasParasiteRisk) + { + var affliction = proxy.m_HasParasites ? AfflictionType.IntestinalParasites : AfflictionType.IntestinalParasitesRisk; + Negative.Add(new IntestinalParasites(negative) + { + AfflictionType = affliction, + Location = 7, + CurrentInfectionChance = proxy.m_CurrentInfectionChance, + DayToAllowNextDose = proxy.m_DayToAllowNextDose, + DosesTaken = proxy.m_NumDosesTaken, + HasTakenDoseToday = proxy.m_HasTakenDoseToday, + ParasitesElapsedHours = proxy.m_ParasitesElapsedHours, + PiecesEatenThisRiskCycle = proxy.m_NumPiecesEatenThisRiskCycle, + RiskDurationHours = proxy.m_RiskDurationHours, + RiskElapsedHours = proxy.m_RiskElapsedHours, + }); + } + } + + private void ConvertBrokenRib(BrokenRibSaveDataProxy proxy) + { + if (proxy == null || proxy.m_CausesLocIDs == null) + return; + for (int i = 0; i < proxy.m_Locations.Count; i++) + { + Negative.Add(new BrokenRib(negative) + { + AfflictionType = AfflictionType.BrokenRib, + Location = proxy.m_Locations[i], + BandagesApplied = proxy.m_BandagesApplied[i], + ElapsedRest = proxy.m_ElapsedRestList[i], + NumHoursRestForCure = proxy.m_NumHoursRestForCureList[i], + PainKillersTaken = proxy.m_PainKillersTaken[i], + }); + } + } + + private void ConvertWellFed(WellFedSaveDataProxy proxy) + { + if (proxy == null || !proxy.m_Active) + return; + Positive.Add(new WellFed(positive) + { + AfflictionType = AfflictionType.WellFed, + Location = 6, + ElapsedHoursNotStarving = proxy.m_ElapsedHoursNotStarving, + }); + } + + public void SerializeTo(GlobalSaveGameFormat global) + { + var afflictionDict = new Dictionary>(); + foreach (var affliction in Negative.Concat(Positive)) + { + if (!afflictionDict.ContainsKey(affliction.AfflictionType)) + afflictionDict.Add(affliction.AfflictionType, new List()); + afflictionDict[affliction.AfflictionType].Add(affliction); + } + + global.Hypothermia = ConvertBackHypothermia(global.Hypothermia, afflictionDict); + global.FrostBite = ConvertBackFrostBite(global.FrostBite, afflictionDict); + global.FoodPoisoning = ConvertBackFoodPoisoning(global.FoodPoisoning, afflictionDict); + global.Dysentery = ConvertBackDysentery(global.Dysentery, afflictionDict); + global.SprainedAnkle = ConvertBackSprainedAnkle(global.SprainedAnkle, afflictionDict); + global.SprainedWrist = ConvertBackSprainedWrist(global.SprainedWrist, afflictionDict); + global.Burns = ConvertBackBurns(global.Burns, afflictionDict); + global.BurnsElectric = ConvertBackBurnsElectric(global.BurnsElectric, afflictionDict); + global.BloodLoss = ConvertBackBloodLoss(global.BloodLoss, afflictionDict); + global.Infection = ConvertBackInfection(global.Infection, afflictionDict); + global.InfectionRisk = ConvertBackInfectionRisk(global.InfectionRisk, afflictionDict); + global.CabinFever = ConvertBackCabinFever(global.CabinFever, afflictionDict); + global.IntestinalParasites = ConvertBackIntestinalParasites(global.IntestinalParasites, afflictionDict); + global.BrokenRibs = ConvertBackBrokenRib(global.BrokenRibs, afflictionDict); + global.WellFed = ConvertBackWellFed(global.WellFed, afflictionDict); + } + + private HypothermiaSaveDataProxy ConvertBackHypothermia(HypothermiaSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new HypothermiaSaveDataProxy(); + if (!afflictionDict.ContainsKey(AfflictionType.Hypothermia) && !afflictionDict.ContainsKey(AfflictionType.HypothermiaRisk)) + { + return (proxy?.m_ElapsedHours > 0) ? new HypothermiaSaveDataProxy() : proxy; + } + proxy.m_Active = afflictionDict.ContainsKey(AfflictionType.Hypothermia); + var hypothermia = (Hypothermia)(proxy.m_Active ? afflictionDict[AfflictionType.Hypothermia][0] : afflictionDict[AfflictionType.HypothermiaRisk][0]); + proxy.m_ElapsedHours = hypothermia.ElapsedHours; + proxy.m_ElapsedWarmTime = hypothermia.ElapsedWarmHours; + proxy.m_CauseLocID = hypothermia.Cause; + return proxy; + } + + private FrostbiteSaveDataProxy ConvertBackFrostBite(FrostbiteSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new FrostbiteSaveDataProxy(); + var frostbites = afflictionDict.GetOrDefault(AfflictionType.Frostbite, new List()).Cast().ToList(); + var frostbiteRisks = afflictionDict.GetOrDefault(AfflictionType.FrostbiteRisk, new List()).Cast().ToList(); + var frostbiteDamage = afflictionDict.GetOrDefault(AfflictionType.FrostbiteDamage, new List()).Cast().ToList(); + proxy.m_LocationsCurrentFrostbiteDamage = new List() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + proxy.m_LocationsWithActiveFrostbite = new List(); + foreach (var frostbite in frostbites) + { + proxy.m_LocationsWithActiveFrostbite.Add(frostbite.Location); + proxy.m_LocationsCurrentFrostbiteDamage[frostbite.Location] = frostbite.Damage; + } + foreach (var frostbite in frostbiteRisks) + { + proxy.m_LocationsWithFrostbiteRisk.Add(frostbite.Location); + proxy.m_LocationsCurrentFrostbiteDamage[frostbite.Location] = frostbite.Damage; + } + foreach (var frostbite in frostbiteDamage) + { + proxy.m_LocationsCurrentFrostbiteDamage[frostbite.Location] = frostbite.Damage; + } + return proxy; + } + + private FoodPoisoningSaveDataProxy ConvertBackFoodPoisoning(FoodPoisoningSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new FoodPoisoningSaveDataProxy(); + var foodpoisoning = (FoodPoisoning)afflictionDict.Get(AfflictionType.FoodPoisioning)?[0]; + if (foodpoisoning == null) + { + return proxy.m_Active ? new FoodPoisoningSaveDataProxy() : proxy; + } + proxy.m_Active = true; + proxy.m_AntibioticsTaken = foodpoisoning.AntibioticsTaken; + proxy.m_CauseLocID = foodpoisoning.Cause; + proxy.m_DurationHours = foodpoisoning.DurationHours; + proxy.m_ElapsedHours = foodpoisoning.ElapsedHours; + proxy.m_ElapsedRest = foodpoisoning.ElapsedRest; + return proxy; + } + + private DysenterySaveDataProxy ConvertBackDysentery(DysenterySaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new DysenterySaveDataProxy(); + var dysentery = (Dysentery)afflictionDict.Get(AfflictionType.Dysentery)?[0]; + if (dysentery == null) + { + return proxy.m_Active ? new DysenterySaveDataProxy() : proxy; + } + + proxy.m_Active = true; + proxy.m_AntibioticsTaken = dysentery.AntibioticsTaken; + proxy.m_CleanWaterConsumedLiters = dysentery.CleanWaterConsumed; + proxy.m_DurationHours = dysentery.DurationHours; + proxy.m_ElapsedHours = dysentery.ElapsedHours; + proxy.m_ElapsedRest = dysentery.ElapsedRest; + return proxy; + } + + private SprainedAnkleSaveDataProxy ConvertBackSprainedAnkle(SprainedAnkleSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new SprainedAnkleSaveDataProxy(); + var sprainedAnkles = afflictionDict.Get(AfflictionType.SprainedAnkle)?.Cast().ToList(); + if (sprainedAnkles == null) + { + return (proxy.m_CausesLocIDs?.Count > 0) ? new SprainedAnkleSaveDataProxy() : proxy; + } + proxy.m_CausesLocIDs = new List(); + proxy.m_DurationHoursList = new List(); + proxy.m_ElapsedHoursList = new List(); + proxy.m_ElapsedRestList = new List(); + proxy.m_Locations = new List(); + foreach (var sprain in sprainedAnkles) + { + proxy.m_CausesLocIDs.Add(sprain.CauseLocID); + proxy.m_DurationHoursList.Add(sprain.Duration); + proxy.m_ElapsedHoursList.Add(sprain.ElapsedHours); + proxy.m_ElapsedRestList.Add(sprain.ElapsedRest); + proxy.m_Locations.Add(sprain.Location); + } + return proxy; + } + + private SprainedWristSaveDataProxy ConvertBackSprainedWrist(SprainedWristSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new SprainedWristSaveDataProxy(); + var sprainedWrists = afflictionDict.Get(AfflictionType.SprainedWrist)?.Cast().ToList(); + if (sprainedWrists == null) + { + return (proxy.m_CausesLocIDs?.Count > 0) ? new SprainedWristSaveDataProxy() : proxy; + } + proxy.m_CausesLocIDs = new List(); + proxy.m_DurationHoursList = new List(); + proxy.m_ElapsedHoursList = new List(); + proxy.m_ElapsedRestList = new List(); + proxy.m_Locations = new List(); + foreach (var sprain in sprainedWrists) + { + proxy.m_CausesLocIDs.Add(sprain.CauseLocID); + proxy.m_DurationHoursList.Add(sprain.Duration); + proxy.m_ElapsedHoursList.Add(sprain.ElapsedHours); + proxy.m_ElapsedRestList.Add(sprain.ElapsedRest); + proxy.m_Locations.Add(sprain.Location); + } + return proxy; + } + + private BurnsSaveDataProxy ConvertBackBurns(BurnsSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new BurnsSaveDataProxy(); + var burns = afflictionDict.Get(AfflictionType.Burns)?.Cast().ToList()[0]; + if (burns == null) + { + return proxy.m_Active ? new BurnsSaveDataProxy() : proxy; + } + proxy.m_Active = true; + proxy.m_BandageApplied = burns.BandageApplied; + proxy.m_DurationHours = burns.DurationHours; + proxy.m_ElapsedHours = burns.ElapsedHours; + proxy.m_PainKillersTaken = burns.PainKillersTaken; + proxy.m_CauseLocID = burns.CauseLocID; + return proxy; + } + + private BurnsElectricSaveDataProxy ConvertBackBurnsElectric(BurnsElectricSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new BurnsElectricSaveDataProxy(); + var burns = afflictionDict.Get(AfflictionType.BurnsElectric)?.Cast().ToList()[0]; + if (burns == null) + { + return proxy.m_Active ? new BurnsElectricSaveDataProxy() : proxy; + } + proxy.m_Active = true; + proxy.m_BandageApplied = burns.BandageApplied; + proxy.m_DurationHours = burns.DurationHours; + proxy.m_ElapsedHours = burns.ElapsedHours; + proxy.m_PainKillersTaken = burns.PainKillersTaken; + return proxy; + } + + private BloodLossSaveDataProxy ConvertBackBloodLoss(BloodLossSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new BloodLossSaveDataProxy(); + var bloodLosses = afflictionDict.Get(AfflictionType.BloodLoss)?.Cast().ToList(); + if (bloodLosses == null) + { + return (proxy.m_CausesLocIDs?.Count > 0) ? new BloodLossSaveDataProxy() : proxy; + } + proxy.m_CausesLocIDs = new List(); + proxy.m_DurationHoursList = new List(); + proxy.m_ElapsedHoursList = new List(); + proxy.m_Locations = new List(); + foreach (var bloodLoss in bloodLosses) + { + proxy.m_CausesLocIDs.Add(bloodLoss.CauseLocID); + proxy.m_DurationHoursList.Add(bloodLoss.DurationHours); + proxy.m_ElapsedHoursList.Add(bloodLoss.ElapsedHours); + proxy.m_Locations.Add(bloodLoss.Location); + } + return proxy; + } + + private InfectionSaveDataProxy ConvertBackInfection(InfectionSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new InfectionSaveDataProxy(); + var infections = afflictionDict.Get(AfflictionType.Infection)?.Cast().ToList(); + if (infections == null) + { + return (proxy.m_CausesLocIDs?.Count > 0) ? new InfectionSaveDataProxy() : proxy; + } + proxy.m_CausesLocIDs = new List(); + proxy.m_DurationHoursList = new List(); + proxy.m_ElapsedHoursList = new List(); + proxy.m_Locations = new List(); + proxy.m_AntibioticsTakenList = new List(); + proxy.m_ElapsedRestList = new List(); + foreach (var infection in infections) + { + proxy.m_CausesLocIDs.Add(infection.CauseLocID); + proxy.m_DurationHoursList.Add(infection.DurationHours); + proxy.m_ElapsedHoursList.Add(infection.ElapsedHours); + proxy.m_Locations.Add(infection.Location); + proxy.m_AntibioticsTakenList.Add(infection.AntibioticsTaken); + proxy.m_ElapsedRestList.Add(infection.ElapsedRest); + } + return proxy; + } + + private InfectionRiskSaveDataProxy ConvertBackInfectionRisk(InfectionRiskSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new InfectionRiskSaveDataProxy(); + var infectionRisks = afflictionDict.Get(AfflictionType.InfectionRisk)?.Cast().ToList(); + if (infectionRisks == null) + { + return (proxy.m_CausesLocIDs?.Count > 0) ? new InfectionRiskSaveDataProxy() : proxy; + } + proxy.m_CausesLocIDs = new List(); + proxy.m_DurationHoursList = new List(); + proxy.m_ElapsedHoursList = new List(); + proxy.m_Locations = new List(); + proxy.m_AntisepticTakenList = new List(); + proxy.m_ConstantAfflictionIndices = new List(); + proxy.m_CurrentInfectionChanceList = new List(); + foreach (var infectionRisk in infectionRisks) + { + proxy.m_CausesLocIDs.Add(infectionRisk.CauseLocID); + proxy.m_DurationHoursList.Add(infectionRisk.DurationHours); + proxy.m_ElapsedHoursList.Add(infectionRisk.ElapsedHours); + proxy.m_Locations.Add(infectionRisk.Location); + proxy.m_AntisepticTakenList.Add(infectionRisk.AntisepticTaken); + if (infectionRisk.Constant) + { + proxy.m_ConstantAfflictionIndices.Add(infectionRisk.Location); + } + proxy.m_CurrentInfectionChanceList.Add(infectionRisk.CurrentInfectionChance); + } + return proxy; + } + + private CabinFeverSaveDataProxy ConvertBackCabinFever(CabinFeverSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new CabinFeverSaveDataProxy(); + var cabinFever = (CabinFever)afflictionDict.Get(AfflictionType.CabinFever)?[0]; + var cabinFeverRisk = (CabinFever)afflictionDict.Get(AfflictionType.CabinFeverRisk)?[0]; + if (cabinFever == null && cabinFeverRisk == null) + { + return (proxy.m_Active || proxy.m_RiskActive) ? new CabinFeverSaveDataProxy() : proxy; + } + proxy.m_Active = cabinFever != null; + proxy.m_RiskActive = cabinFeverRisk != null; + proxy.m_ElapsedHours = cabinFever != null ? cabinFever.ElapsedHours : cabinFeverRisk.ElapsedHours; + return proxy; + } + + private IntestinalParasitesSaveDataProxy ConvertBackIntestinalParasites(IntestinalParasitesSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new IntestinalParasitesSaveDataProxy(); + var parasites = (IntestinalParasites)afflictionDict.Get(AfflictionType.IntestinalParasites)?[0]; + var parasitesRisk = (IntestinalParasites)afflictionDict.Get(AfflictionType.IntestinalParasitesRisk)?[0]; + if (parasites == null && parasitesRisk == null) + { + return (proxy.m_HasParasites || proxy.m_HasParasiteRisk) ? new IntestinalParasitesSaveDataProxy() : proxy; + } + if (parasites != null) + { + proxy.m_CurrentInfectionChance = 80; + proxy.m_DayToAllowNextDose = 0; + proxy.m_HasParasiteRisk = false; + proxy.m_HasParasites = true; + proxy.m_HasTakenDoseToday = false; + proxy.m_NumDosesTaken = 0; + proxy.m_NumPiecesEatenThisRiskCycle = 0; + proxy.m_ParasitesElapsedHours = 0; + proxy.m_RiskDurationHours = 0; + proxy.m_RiskElapsedHours = 0; + } + else + { + proxy.m_CurrentInfectionChance = 40; + proxy.m_DayToAllowNextDose = 0; + proxy.m_HasParasiteRisk = true; + proxy.m_HasParasites = false; + proxy.m_HasTakenDoseToday = false; + proxy.m_NumDosesTaken = 0; + proxy.m_NumPiecesEatenThisRiskCycle = 0; + proxy.m_ParasitesElapsedHours = 0; + proxy.m_RiskDurationHours = 0; + proxy.m_RiskElapsedHours = 0; + } + return proxy; + } + + private BrokenRibSaveDataProxy ConvertBackBrokenRib(BrokenRibSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new BrokenRibSaveDataProxy(); + var brokenRibs = afflictionDict.Get(AfflictionType.BrokenRib)?.Cast().ToList(); + if (brokenRibs == null) + { + return (proxy.m_CausesLocIDs?.Count > 0) ? new BrokenRibSaveDataProxy() : proxy; + } + proxy.m_BandagesApplied = new List(); + proxy.m_CausesLocIDs = new List(); + proxy.m_ElapsedRestList = new List(); + proxy.m_Locations = new List(); + proxy.m_NumHoursRestForCureList = new List(); + proxy.m_PainKillersTaken = new List(); + foreach (var brokenRib in brokenRibs) + { + proxy.m_BandagesApplied.Add(brokenRib.BandagesApplied); + proxy.m_CausesLocIDs.Add(brokenRib.CauseLocID); + proxy.m_ElapsedRestList.Add(brokenRib.ElapsedRest); + proxy.m_Locations.Add(brokenRib.Location); + proxy.m_NumHoursRestForCureList.Add(brokenRib.NumHoursRestForCure); + proxy.m_PainKillersTaken.Add(brokenRib.PainKillersTaken); + } + return proxy; + } + + private WellFedSaveDataProxy ConvertBackWellFed(WellFedSaveDataProxy proxy, Dictionary> afflictionDict) + { + proxy = proxy ?? new WellFedSaveDataProxy(); + var wellFed = (WellFed)afflictionDict.Get(AfflictionType.WellFed)?[0]; + if (wellFed == null) + { + return proxy.m_Active ? new WellFedSaveDataProxy() : proxy; + } + proxy.m_Active = true; + proxy.m_ElapsedHoursNotStarving = wellFed.ElapsedHoursNotStarving; + return proxy; + } + + protected void SetPropertyField(ref T field, T newValue, [CallerMemberName] string propertyName = null) + { + if (!EqualityComparer.Default.Equals(field, newValue)) + { + field = newValue; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/src/TldSaveEditor.Core/GameData/BootSaveGameData.cs b/src/TldSaveEditor.Core/GameData/BootSaveGameData.cs new file mode 100644 index 0000000..d0e11e3 --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/BootSaveGameData.cs @@ -0,0 +1,10 @@ +using The_Long_Dark_Save_Editor_2.Serialization; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + public class BootSaveGameFormat + { + public EnumWrapper m_SceneName { get; set; } + public int m_Version { get; set; } + } +} diff --git a/src/TldSaveEditor.Core/GameData/Enums.cs b/src/TldSaveEditor.Core/GameData/Enums.cs new file mode 100644 index 0000000..3a06e58 --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/Enums.cs @@ -0,0 +1,510 @@ +using System.ComponentModel; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + + // ----- My enums + + public enum ItemCategory + { + FirstAid, + Clothing, + Food, + Tools, + Materials, + Collectible, + Books, + Hidden, + Unknown + } + + public enum RegionsWithMap + { + CoastalRegion, + LakeRegion, + WhalingStationRegion, + RuralRegion, + CrashMountainRegion, + MarshRegion, + RavineTransitionZone, + HighwayTransitionZone, + TracksRegion, + RiverValleyRegion, + MountainTownRegion, + CanneryRegion, + AshCanyonRegion + } + + // ----- + + + public enum WindDirection + { + North, + South, + West, + East, + NorthWest, + NorthEast, + SouthWest, + SouthEast, + } + + public enum WindStrength + { + Calm, + SlightlyWindy, + Windy, + VeryWindy, + Blizzard, + } + + public enum WeatherStage + { + DenseFog = 0, + LightSnow = 1, + HeavySnow = 2, + PartlyCloudy = 3, + Clear = 4, + Cloudy = 5, + LightFog = 6, + Blizzard = 7, + ClearAurora = 8, + Num = 9, + Undefined = 9, + } + + public enum ConditionLevel + { + NoInjuries, + SlightlyInjured, + Injured, + VeryInjured, + NearDeath, + } + + public enum EncumberLevel + { + None, + Low, + Medium, + High, + } + + public enum HungerLevel + { + Full, + SlightlyHungry, + Hungry, + VeryHungry, + Starving, + } + + public enum ThirstLevel + { + Hydrated, + SlightlyThirsty, + Thirsty, + VeryThirsty, + Dehydrated, + } + + public enum FatigueLevel + { + Rested, + SlightlyTired, + Tired, + VeryTired, + Exhausted, + } + + public enum FreezingLevel + { + Warm, + SlightlyCold, + Cold, + VeryCold, + Freezing, + } + + public enum LiquidQuality + { + Potable, + NonPotable, + } + + public enum FlareState + { + Fresh, + Burning, + BurnedOut, + Wet + } + + public enum BedRollState + { + Rolled, + Placed, + } + + public enum SnareState + { + Default, + Set, + Broken, + WithRabbit, + } + + public enum TorchState + { + Fresh, + Burning, + BlownOut, + BurnedOut, + Extinguished, + Wet + } + + public enum MissionObjectClass + { + General, + Trigger, + Player, + InteractiveNPC, + InteractiveObject, + Invalid, + } + + public enum VoicePersona + { + Male, + Female, + } + + public enum SprayColor + { + Orange + } + + public enum AfflictionType + { + BloodLoss, + Burns, + Dysentery, + Infection, + FoodPoisioning, + SprainedAnkle, + InfectionRisk, + SprainedWrist, + Frostbite, + FrostbiteDamage, + Hypothermia, + ReducedFatigue, + ImprovedRest, + WarmingUp, + HypothermiaRisk, + CabinFever, + IntestinalParasitesRisk, + IntestinalParasites, + SprainedWristMajor, + CabinFeverRisk, + FrostbiteRisk, + BurnsElectric, + BrokenRib, + WellFed + } + + public enum ExperienceModeType + { + Pilgrim, + Voyageur, + Stalker, + Story, + ChallengeRescue, + ChallengeHunted, + ChallengeWhiteout, + ChallengeNomad, + ChallengeHuntedPart2, + Interloper, + Custom, + StoryFresh, + StoryHardened, + FourDaysOfNight, + ChallengeArchivist, + ChallengeDeadManWalk, + } + + public enum StatID + { + HoursSurvived, + LocationsExplored, + WorldExploredPercentage, + TotalCaloriesExpended, + AverageCaloriesPerDay, + DistanceTravelled, + HoursAwake, + HoursAsleep, + HoursIndoors, + HoursOutdoors, + TimeRestedOutdoors, + HoursInMysteryLake, + HoursInPleasantValley, + HoursInCoastalHighway, + HoursInDesolationPoint, + HoursInCrashMountainRegion, + SuccessfulRepairs, + BowShot, + SuccessfulHits_Bow, + RifleShot, + SuccessfulHits_Rifle, + DistressPistolShot, + SuccessfulHits_DistressPistol, + WolfCloseEncounters, + WolfStruggles, + WolfStrugglesWon, + WolvesKilled, + WolvesDistactedByDecoys, + BearEncountersSurvived, + BearsKilled, + StagsKilled, + RabbitsKilled, + RabbitsSnared, + MeatConsumed, + FishConsumed, + FishCaught, + MeatHarvested, + GutsHarvested, + HidesHarvested, + ItemsLooted, + ItemsCrafted, + ItemsBrokenDown, + PlantsHarvested, + CansOpened, + CanOpenersFound, + FiresStarted, + LongestBurningFire, + Sprains_Wrist, + Sprains_Ankle, + FoodPoisoning, + Dysentry, + Infection, + Hypothermia, + BloodLoss, + FallCount, + Blizzards, + NumRopeSlips, + NumRopeFalls, + DistanceTravelledOnRope, + CabinFever, + IntestinalParasites, + Frostbite, + HoursInMarshRegion, + HoursInTracksRegion, + BrokenRib, + EpisodeProgress, + HoursInMountainTownRegion, + MooseEncountersSurvived, + MooseKilled, + HoursInRiverValleyRegion, + NumStats, + } + + public enum CustomManagedObjectState + { + InitialActive = 1, + ManagedActive = 2, + InitialUnknown = 4, + } + + public enum GameRegion + { + LakeRegion, + CoastalRegion, + WhalingStationRegion, + RuralRegion, + CrashMountainRegion, + MarshRegion, + RandomRegion, + FutureRegion, + MountainTownRegion, + TracksRegion, + RiverValleyRegion, + CanneryRegion, + AshCanyonRegion + } + + public enum UpSell + { + MainMenu_Challenges, + MainMenu_Logs, + MainMenu_Badges, + } + + public enum GraphicsMode + { + Fullscreen, + Window, + } + + public enum MeasurementUnits + { + Metric, + Imperial, + } + + public enum HudPref + { + DebugInfo, + Normal, + Disabled, + } + + public enum SubtitlesState + { + Off, + On, + ClosedCaptioning, + } + + public enum LanguageState + { + English, + German, + Russian, + } + + public enum FeatType + { + BookSmarts, + ColdFusion, + EfficientMachine, + FireMaster, + FreeRunner, + SnowWalker, + } + + public enum ForcedMovement + { + None, + ForceCrouch, + ForceWalk, + ForceLimp, + ForceLimpSlow, + } + + public enum KnowledgeCateogry + { + Unknown, + People, + Places, + Things, + Actions, + } + + public enum MissionObjectiveCountType + { + NoUnits, + Weight, + Volume, + } + + public enum SaveSlotType + { + UNKNOWN, + CHALLENGE, + CHECKPOINT, + SANDBOX, + STORY, + AUTOSAVE, + } + + public enum Episode + { + One, + Two, + Three, + Four, + Five, + } + + public enum Achievement + { + Survival_10_Days = 1, + Survival_50_Days = 6, + LakeCoastalInteriors = 7, + Harvest_10_Deer = 8, + Survival_1_Night = 9, + Survival_3_Nights = 10, + NoGun_50_Days = 11, + NoKill_25_Days = 12, + Wrapped_Fur = 13, + Big_Fish = 14, + Living_Off_Land = 15, + Natural_Healer = 16, + Happy_Harvester = 17, + Survival_1_Days = 18, + Survival_100_Days = 20, + Survival_500_Days = 22, + StoneAgeSniper = 23, + SkilledSurvivor = 24, + TasteTheImpossible = 25, + WellNourished = 26, + FaithfulCartographer = 27, + ResoluteOutfitter = 28, + PenitentScholar = 29, + TimberwolfMountain = 30, + DesolationPoint = 31, + DeepForest = 32, + EP1_YourJourneyBegins = 33, + EP1_ParadiseLost = 34, + EP1_TheLongWinter = 35, + EP1_LosingAChildIsLike = 36, + EP1_LeavingTheOldWorldBehind = 37, + EP2_TheOldTrapper = 38, + EP2_LightsInTheSky = 39, + EP2_GraduationDay = 40, + EP2_FreightTrainOfHateAndHunger = 41, + EP2_YouWillBeWithHerSoon = 42, + SM_UnlockAllMiltonDepositBoxes = 43, + SM_FoundAllForestTalkerCaches = 44, + SM_FoundAllHiddenCaches = 45, + ChallengeMastery = 46, + } + + public enum DamageSide + { + DamageSideNone = -1, + DamageSideLeft = 0, + DamageSideRight = 1, + } + + public enum HudSize + { + Small, + Regular, + Large, + } + + public enum HudType + { + Off, + Contextual, + AlwaysOn, + } + + public enum AfflictionBodyArea + { + Head, + Neck, + ArmLeft, + HandLeft, + ArmRight, + HandRight, + Chest, + Stomach, + LegLeft, + FootLeft, + LegRight, + FootRight, + } +} diff --git a/src/TldSaveEditor.Core/GameData/GlobalData.cs b/src/TldSaveEditor.Core/GameData/GlobalData.cs new file mode 100644 index 0000000..06f9437 --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/GlobalData.cs @@ -0,0 +1,1025 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using The_Long_Dark_Save_Editor_2.Helpers; +using System.Linq; +using The_Long_Dark_Save_Editor_2.Serialization; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + public class SlotData + { + public string m_Name { get; set; } + public string m_BaseName { get; set; } + public string m_DisplayName { get; set; } + public string m_Timestamp { get; set; } + public EnumWrapper m_GameMode { get; set; } + public uint m_GameId { get; set; } + public Dictionary m_Dict { get; set; } + } + + public class GameManagerData + { + public bool m_BlockAbilityToRest { get; set; } + public string m_BlockedRestLocID { get; set; } + [Deserialize("m_SceneTransitionDataSerialized", true)] + public SceneTransitionData SceneTransition { get; set; } + } + + public class SceneTransitionData + { + public bool m_TeleportPlayerSaveGamePosition { get; set; } + public string m_SpawnPointName { get; set; } + public string m_ForceSceneOnNextNavMapLoad { get; set; } + public string m_ForceNextSceneLoadTriggerScene { get; set; } + public float[] m_PosBeforeInteriorLoad { get; set; } + public string m_SceneSaveFilenameCurrent { get; set; } + public string m_SceneSaveFilenameNextLoad { get; set; } + public string m_SceneLocationLocIDToShow { get; set; } + public int m_GameRandomSeed { get; set; } + public string m_Location { get; set; } + public string m_LastOutdoorScene { get; set; } + } + + public class HudManagerSaveDataProxy + { + public bool m_ShowDebugInfo { get; set; } + } + + public class TimeOfDaySaveDataProxy + { + public float m_TimeProxy { get; set; } + public float m_HoursPlayedNotPausedProxy { get; set; } + public int m_UniStormDayCounterProxy { get; set; } + public int m_UniStormMoonPhaseIndexProxy { get; set; } + public int m_UniStormDayNumberProxy { get; set; } + public int m_DayLastDawnStingerAudioPlayed { get; set; } + public int m_DayLastNightStingerAudioPlayed { get; set; } + public int m_DayLastDawnVoiceOverPlayed { get; set; } + public int m_DayLastNightVoiceOverPlayed { get; set; } + public int m_4DONCurrentDay { get; set; } + public bool m_LockedTOD { get; set; } + } + + public class WindSaveDataProxy + { + // Has Container class + public int m_Version { get; set; } + public EnumWrapper m_windDirectionProxy { get; set; } + public EnumWrapper m_windStrengthProxy { get; set; } + public float m_windMPHProxy { get; set; } + public bool m_FirstPhaseSetProxy { get; set; } + public float m_PhaseElapsedTODSecondsProxy { get; set; } + public float m_PhaseDurationHoursProxy { get; set; } + public float m_TransitionTimeTODSecondsProxy { get; set; } + public string m_ActiveSettingsSerialized { get; set; } + public string m_SourceSettingsSerialized { get; set; } + public string m_TargetSettingsSerialized { get; set; } + } + + public class ActiveWindSettings + { + public float m_Angle { get; set; } + public float m_Velocity { get; set; } + public float m_Gustiness { get; set; } + public float m_LateralBluster { get; set; } + public float m_VerticalBluster { get; set; } + } + + public class WeatherSaveDataProxy + { + public float m_PrevBodyTempProxy { get; set; } + public float m_TempHighProxy { get; set; } + public float m_TempLowProxy { get; set; } + public EnumWrapper m_WeatherStageProxy { get; set; } + public float m_UniStormElapsedHoursProxy { get; set; } + public float m_UniStormNextWeatherChangeElapsedHoursProxy { get; set; } + public bool m_UseMinAirTemperature { get; set; } + public int m_MinAirTemperature { get; set; } + } + + public class WeatherTransitionSaveDataProxy + { + public bool m_UseUnmanagedWeatherStage; + public EnumWrapper m_UnmanagedWeatherStage; + public string m_CurrentWeatherSetName { get; set; } + public float m_CurrentWeatherSetProgressFrac { get; set; } + public string m_CurrentWeatherSetSerialized { get; set; } + public int m_CurrentWeatherSetType { get; set; } + public int m_PreviousWeatherSetType { get; set; } + } + + public class WeatherSetInstanceSaveData + { + public int m_CurrentIndex { get; set; } + public float m_CurrentStageElapsedTime { get; set; } + public float[] m_StageDurations { get; set; } + public float[] m_StageTransitionTimes { get; set; } + } + + public class ConditionSaveDataProxy + { + public float m_CurrentHPProxy { get; set; } + public float m_NumSecondsSinceLastVoiceOver { get; set; } + public bool m_NeverDieProxy { get; set; } + public bool m_Invulnerable { get; set; } + public bool m_HideDamageEvents { get; set; } + public bool m_FoceUncrouched { get; set; } + public bool m_CanPlayNearDeathMusic { get; set; } + public EnumWrapper m_ConditionLevelForPreviousVoiceOver { get; set; } + public bool m_SuppressVoiceOver { get; set; } + } + + public class EncumberSaveDataProxy + { + public bool m_EncumberedInLog { get; set; } + public float m_NumSecondsSinceLastVoiceOver { get; set; } + public EnumWrapper m_EcumberLevelForPreviousVoiceOver { get; set; } + } + + public class HungerSaveDataProxy + { + public float m_CurrentReserveCaloriesProxy { get; set; } + public float m_NumSecondsSinceLastVoiceOver { get; set; } + public bool m_StarvingInLog { get; set; } + public float m_NumHoursStarving { get; set; } + public float m_FatiguePenalty { get; set; } + public EnumWrapper m_HungerLevelForPreviousVoiceOver { get; set; } + public float m_CaloriesEatenToday { get; set; } + public bool m_SuppressVoiceOver { get; set; } + } + + public class ThirstSaveDataProxy + { + public float m_CurrentThirstProxy { get; set; } + public float m_NumSecondsSinceLastVoiceOver { get; set; } + public bool m_DehydratedInLog { get; set; } + public EnumWrapper m_ThirstLevelForPreviousVoiceOver { get; set; } + public bool m_SuppressVoiceOver { get; set; } + } + + public class FatigueSaveDataProxy + { + public float m_CurrentFatigueProxy { get; set; } + public float m_NumSecondsSinceLastVoiceOver { get; set; } + public bool m_ExhaustedInLog { get; set; } + public EnumWrapper m_FatigueLevelForPreviousVoiceOver { get; set; } + public bool m_SuppressVoiceOver { get; set; } + } + + public class FreezingSaveDataProxy + { + public float m_CurrentFreezingProxy { get; set; } + public float m_NumSecondsSinceLastVoiceOver { get; set; } + public bool m_FreezingInLog { get; set; } + public EnumWrapper m_FreezingLevelForPreviousVoiceOver { get; set; } + public float m_TemperatureBonusFromRunning { get; set; } + public bool m_SuppressVoiceOver { get; set; } + } + + public class WillpowerSaveDataProxy + { + public float m_TimeRemainingSecondsProxy { get; set; } + } + + public class KnowledgeManagerSaveData + { + public string m_TrustDictSerialized { get; set; } + public string m_KnowledgeDictSerialized { get; set; } + public string m_NameRefDictSerialized { get; set; } + public bool m_SnowSheltersUnlockedInStory { get; set; } + } + + public class CollectionManagerSaveData + { + public string m_UnlockedCairnsDictSerialized { get; set; } + public string m_UnlockedAuroraSetSerialized { get; set; } + } + + #region Inventory + + public class InventorySaveDataProxy + { + [Deserialize("m_SerializedItems")] + public ObservableCollection Items { get; set; } + public int[] m_QuickSelectInstanceIDs { get; set; } + public bool m_ForceOverrideWeight { get; set; } + public float m_OverridedWeight { get; set; } + public bool m_ConsumedCoffee { get; set; } + public bool m_ConsumedRosehipTea { get; set; } + public bool m_ConsumedReishiTea { get; set; } + public bool m_ConsumedOldMansBeardDressing { get; set; } + public bool m_SuppressScentIndicator { get; set; } + } + + public class InventoryItemSaveData + { + public string m_PrefabName { get; set; } + [Deserialize("m_SerializedGear", true)] + public GearItemSaveDataProxy Gear { get; set; } + + [JsonIgnore] + public ItemCategory Category { get { return ItemDictionary.GetCategory(m_PrefabName); } } + [JsonIgnore] + public string InGameName { get { return ItemDictionary.GetInGameName(m_PrefabName); } } + } + + + public class GearItemSaveDataProxy : BindableBase + { + public float m_HoursPlayed { get; set; } + public float[] m_Position { get; set; } + public float[] m_Rotation { get; set; } + public int m_InstanceIDProxy { get; set; } + public float m_CurrentHPProxy { get; set; } + public float m_NormalizedCondition; + [JsonIgnore] + public float NormalizedCondition + { + get { return m_NormalizedCondition; } + set + { + SetProperty(ref m_NormalizedCondition, value); + } + } + public bool m_BeenInPlayerInventoryProxy { get; set; } + public bool m_BeenInContainerProxy { get; set; } + public bool m_BeenInspectedProxy { get; set; } + public bool m_ItemLootedProxy { get; set; } + public bool m_HasBeenOwnedByPlayer { get; set; } + public bool m_RolledSpawnChanceProxy { get; set; } + public bool m_WornOut { get; set; } + [Deserialize("m_StackableItemSerialized", true)] + public StackableItemSaveDataProxy StackableItem { get; set; } + [Deserialize("m_FoodItemSerialized", true)] + public FoodItemSaveDataProxy FoodItem { get; set; } + [Deserialize("m_LiquidItemSerialized", true)] + public LiquidItemSaveDataProxy LiquidItem { get; set; } + [Deserialize("m_FlareItemSerialized", true)] + public FlareItemSaveDataProxy FlareItem { get; set; } + [Deserialize("m_FlashlightItemSerialized", true)] + public FlashlightItemSaveDataProxy FlashLightItem { get; set; } + [Deserialize("m_KeroseneLampItemSerialized", true)] + public KeroseneLampItemSaveDataProxy KeroseneLampItem { get; set; } + [Deserialize("m_ClothingItemSerialized", true)] + public ClothingItemSaveDataProxy ClothingItem { get; set; } + [Deserialize("m_WeaponItemSerialized", true)] + public GunItemSaveDataProxy WeaponItem { get; set; } + [Deserialize("m_WaterSupplySerialized", true)] + public WaterSupplySaveDataProxy WaterSupply { get; set; } + [Deserialize("m_BedSerialized", true)] + public BedSaveDataProxy Bed { get; set; } + [Deserialize("m_SmashableItemSerialized", true)] + public SmashableItemSaveDataProxy SmashableItem { get; set; } + [Deserialize("m_MatchesItemSerialized", true)] + public MatchesItemSaveDataProxy MatchesItem { get; set; } + [Deserialize("m_SnareItemSerialized", true)] + public SnareItemSaveDataProxy SnareItem { get; set; } + [Deserialize("m_SprayPaintCanSerialized", true)] + public SprayPaintSaveDataProxy SprayItem { get; set; } + [Deserialize("m_RigidBodySerialized", true)] + public RigidBodySaveDataProxy RigidBody { get; set; } + [Deserialize("m_PowderItemSerialized", true)] + public PowderItemSaveDataProxy PowderItem { get; set; } + [Deserialize("m_MillableSerialized", true)] + public MillableSaveDataProxy Millable { get; set; } + [Deserialize("m_InProgressItemSerialized", true)] + public InProgressCraftItemSaveDataProxy InProgressItem { get; set; } + [Deserialize("m_TorchItemSerialized", true)] + public TorchItemSaveDataProxy TorchItem { get; set; } + public string m_CollectibleNoteSerialized { get; set; } + [Deserialize("m_EvolveItemSerialized", true)] + public EvolveItemSaveData EvolveItem { get; set; } + public string m_ObjectGuidSerialized { get; set; } + public string m_MissionObjectSerialized { get; set; } + [Deserialize("m_ResearchItemSerialized", true)] + public ResearchItemSaveData ResearchItem { get; set; } + public float m_WeightKG { get; set; } + public bool m_HarvestedByPlayer { get; set; } + public bool m_IsInSatchel { get; set; } + public int m_SatchelIndex { get; set; } + public string m_OwnershipOverrideSerialized { get; set; } + [Deserialize("m_BodyHarvestSerialized", true)] + public BodyHarvestSaveDataProxy BodyHarvest { get; set; } + public bool m_LockedInContainer { get; set; } + public int m_GearItemSaveVersion { get; set; } + public string m_CookingPotItemSerialized { get; set; } + public string m_PlacePointGuidSerialized { get; set; } + public string m_PlacePointNameSerialized { get; set; } + public bool m_NonInteractive { get; set; } + public bool m_HasBeenEquippedAndUsed { get; set; } + public string m_InspectSerialized { get; set; } + public bool m_StoneItemThrown { get; set; } + + public static GearItemSaveDataProxy Create(GlobalSaveGameFormat global) + { + var item = new GearItemSaveDataProxy(); + item.m_Rotation = new float[4]; + item.m_Position = new float[3]; + item.m_BeenInPlayerInventoryProxy = true; + item.NormalizedCondition = 1; + item.m_WornOut = false; + item.m_HoursPlayed = global.TimeOfDay.m_HoursPlayedNotPausedProxy; + var r = new Random(); + var id = r.Next(); + while (global.Inventory.Items.Any(i => i.Gear.m_InstanceIDProxy == id)) + id = r.Next(); + item.m_InstanceIDProxy = id; + item.m_NonInteractive = false; + item.m_HasBeenEquippedAndUsed = false; + return item; + } + } + + public class StackableItemSaveDataProxy + { + public int m_UnitsProxy { get; set; } + } + + public class FoodItemSaveDataProxy + { + public float m_CaloriesRemainingProxy { get; set; } + public float m_CaloriesTotal { get; set; } + public bool m_Opened { get; set; } + public float m_HeatPercent { get; set; } + public float m_HoursPlayed { get; set; } + public bool m_HarvestedByPlayer { get; set; } + public int m_NumTimesHeatedUp { get; set; } + public bool m_Packaged { get; set; } + } + + // The game stores liquid volume / fuel as a fixed-point Int64 where 1 litre == 1_000_000_000. + // Reading those values into a float overflows the UI (e.g. 2L is shown as 2E+09) and corrupts + // the save on write. See issues #85, #87 and the Storm Lantern part of #74. + public static class FixedPoint + { + public const long LitersScale = 1_000_000_000; + } + + public class LiquidItemSaveDataProxy + { + public long m_LiquidLitersProxy { get; set; } + public EnumWrapper m_LiquidQuality { get; set; } + + [JsonIgnore] + public double Liters + { + get => m_LiquidLitersProxy / (double)FixedPoint.LitersScale; + set => m_LiquidLitersProxy = (long)Math.Round(value * FixedPoint.LitersScale); + } + } + + public class FlareItemSaveDataProxy + { + public float m_HoursPlayed { get; set; } + public EnumWrapper m_StateProxy { get; set; } + public float m_ElapsedBurnMinutesProxy { get; set; } + } + + public class FlashlightItemSaveDataProxy + { + public bool m_IsOn { get; set; } + public bool m_IsHigh { get; set; } + public float m_CurrentBatteryCharge { get; set; } + } + + public class KeroseneLampItemSaveDataProxy + { + public float m_HoursPlayed { get; set; } + public long m_CurrentFuelLitersProxy { get; set; } + public bool m_OnProxy { get; set; } + + [JsonIgnore] + public double Liters + { + get => m_CurrentFuelLitersProxy / (double)FixedPoint.LitersScale; + set => m_CurrentFuelLitersProxy = (long)Math.Round(value * FixedPoint.LitersScale); + } + } + + public class ClothingItemSaveDataProxy + { + public bool m_WearingProxy { get; set; } + public float m_PercentWet { get; set; } + public float m_PercentFrozen { get; set; } + public float m_HoursPlayed { get; set; } + public float m_HoursRemainingOnCloseFire { get; set; } + public bool m_DroppedIndoors { get; set; } + public bool m_HasEquippedData { get; set; } + public int m_EquippedLayerIndex { get; set; } + } + + public class GunItemSaveDataProxy + { + public int m_RoundsInClipProxy { get; set; } + public bool m_IsJammed { get; set; } + } + + public class WaterSupplySaveDataProxy + { + public long m_VolumeProxy { get; set; } + + [JsonIgnore] + public double Liters + { + get => m_VolumeProxy / (double)FixedPoint.LitersScale; + set => m_VolumeProxy = (long)Math.Round(value * FixedPoint.LitersScale); + } + } + + public class BedSaveDataProxy + { + public EnumWrapper m_BedRollState { get; set; } + } + + public class SmashableItemSaveDataProxy + { + public bool m_HasBeenSmashed { get; set; } + } + + public class MatchesItemSaveDataProxy + { + public float m_BurnTimeGametimeSeconds { get; set; } + public float m_ElapsedBurnGametimeSeconds { get; set; } + public bool m_Ignited { get; set; } + public bool m_IsFresh { get; set; } + } + + public class SnareItemSaveDataProxy + { + public float m_HoursPlayed { get; set; } + public float m_HoursAtLastRoll { get; set; } + public EnumWrapper m_State { get; set; } + } + + public class SprayPaintSaveDataProxy + { + public EnumWrapper m_Colour { get; set; } + } + + public class RigidBodySaveDataProxy + { + } + + public class PowderItemSaveDataProxy + { + } + + public class MillableSaveDataProxy + { + } + + public class InProgressCraftItemSaveDataProxy + { + public float m_PercentComplete { get; set; } + public float m_Weight { get; set; } + } + + public class TorchItemSaveDataProxy + { + public float m_HoursPlayed { get; set; } + public EnumWrapper m_StateProxy { get; set; } + public float m_ElapsedBurnMinutesProxy { get; set; } + } + + public class EvolveItemSaveData + { + public float m_HoursPlayed { get; set; } + public float m_TimeSpentEvolvingGameHours { get; set; } + public bool m_ForceNoAutoEvolve; + } + + public class MissionObjectIdentifierSaveProxy + { + public string m_Id { get; set; } + public EnumWrapper m_ObjectClass { get; set; } + public string m_ActivityTags { get; set; } + public bool m_DestroyAfterMission { get; set; } + } + + public class ResearchItemSaveData + { + public float m_ElapsedHours { get; set; } + } + + public class BodyHarvestSaveDataProxy + { + public float m_MeatAvailableKG { get; set; } + public int m_HideAvailableUnits { get; set; } + public int m_GutAvailableUnits { get; set; } + public bool m_Frozen { get; set; } + public bool m_Ravaged { get; set; } + public float m_Condition { get; set; } + public bool m_RolledSpawnChance { get; set; } + public bool m_AllowDecay { get; set; } + public float m_HoursPlayed { get; set; } + public float m_PercentFrozen { get; set; } + public float m_HoursRemainingOnCloseFire { get; set; } + public float m_DecimationKGPerHour { get; set; } + public float m_DecimationHoursRemaining { get; set; } + public float m_QuarterDurationMinutes { get; set; } + public bool m_HasHarvested { get; set; } + public float m_LastHarvestTimeHours { get; set; } + public float m_QuarterBagWasteMultiplier { get; set; } + public string m_MissionIdSerialized { get; set; } + public string m_BearHuntAiSerialized { get; set; } + public string m_BearHuntAiReduxSerialized { get; set; } + public EnumWrapper m_DamageSide { get; set; } + } + + public class CookingPotItemSaveDataProxy + { + public string m_FireBeingUsedGUID { get; set; } + public string m_GearItemBeingCookedGUID { get; set; } + public float m_CookingElapsedHours { get; set; } + public float m_GracePeriodElapsedHours { get; set; } + public float m_FireBurningTimeTODHours { get; set; } + public float m_HoursPlayedWhenSerialized { get; set; } + public float m_LitersSnowBeingMelted { get; set; } + public float m_LitersWaterBeingBoiled { get; set; } + public bool m_CanOnlyWarmUpFood { get; set; } + } + + #endregion + + public class PlayerManagerSaveDataProxy + { + public List m_KnownCodes { get; set; } + public ObservableCollection m_SaveGamePosition { get; set; } + public float[] m_SaveGameRotation { get; set; } + public bool m_StartGearAppliedProxy { get; set; } + public int m_ItemInHandsInstanceID { get; set; } + public int m_LastUnequippedItemInstanceID { get; set; } + public bool m_InRunMode { get; set; } + public bool m_Ghost { get; set; } + public bool m_God { get; set; } + public bool m_CheatsUsed { get; set; } + public EnumWrapper m_VoicePersona { get; set; } + public float m_CaloriesHarvestedToday { get; set; } + public float m_FreezingRateScale { get; set; } + public float m_FatigueRateScale { get; set; } + public float m_ConditonPercentBonus { get; set; } + public float m_FatigueBuffHoursRemaining { get; set; } + public float m_FreezingBuffHoursRemaining { get; set; } + public float m_ConditionRestBuffHoursRemaining { get; set; } + public string m_StartingRegionName { get; set; } + public int m_SelectedBlueprintItemIndexWorkbench { get; set; } + public int m_SelectedBlueprintItemIndexForge { get; set; } + public bool m_PlayerInVehicle { get; set; } + public float[] m_PlayerInVehicleCameraPos { get; set; } + public bool m_PlayerInSnowShelter { get; set; } + public float m_PumpkinPieBuffHoursRemaining { get; set; } + public float m_PumpkinPieFreezingRateScale { get; set; } + public SerializableBounds m_LimitCampfiresToBounds { get; set; } + public bool m_StatusBarsLocked { get; set; } + } + + public class PlayerClimbRopeProxy + { + public string m_RopeGuid { get; set; } + public float m_SplineT { get; set; } + public float m_NoStaminaTimerSeconds { get; set; } + public float m_NextSlipRollSeconds { get; set; } + public float m_NextSlipChance { get; set; } + public float m_NextFallChance { get; set; } + } + + public class PlayerSkillsSaveData + { + [Obsolete] + public float m_FireStartingSkill { get; set; } + [Obsolete] + public float m_RepairSkill { get; set; } + public float m_CleanSkill { get; set; } + public float m_SharpenSkill { get; set; } + [Obsolete] + public float m_CraftingSkill { get; set; } + } + + public class PlayerGameStatsProxy + { + public float m_CaloriesBurned { get; set; } + public float m_CaloriesEaten { get; set; } + public float m_BodyTempHigh { get; set; } + public float m_BodyTempLow { get; set; } + public float m_DistanceTravelledDay { get; set; } + public float m_DistanceTravelledNight { get; set; } + public float m_ConditionGained { get; set; } + public float m_ConditionLost { get; set; } + public float m_CaloriesExpendedToday { get; set; } + } + + public class HypothermiaSaveDataProxy + { + public bool m_Active { get; set; } + public float m_ElapsedHours { get; set; } + public float m_ElapsedWarmTime { get; set; } + public string m_CauseLocID { get; set; } + } + + public class FrostbiteSaveDataProxy + { + public List m_LocationsWithActiveFrostbite { get; set; } + public List m_LocationsWithFrostbiteRisk { get; set; } + public List m_LocationsCurrentFrostbiteDamage { get; set; } + } + + public class FoodPoisoningSaveDataProxy + { + public bool m_Active { get; set; } + public float m_ElapsedHours { get; set; } + public float m_DurationHours { get; set; } + public bool m_AntibioticsTaken { get; set; } + public float m_ElapsedRest { get; set; } + public string m_CauseLocID { get; set; } + } + + public class DysenterySaveDataProxy + { + public bool m_Active { get; set; } + public float m_ElapsedHours { get; set; } + public float m_DurationHours { get; set; } + public bool m_AntibioticsTaken { get; set; } + public float m_ElapsedRest { get; set; } + public float m_CleanWaterConsumedLiters { get; set; } + } + + public class SprainedAnkleSaveDataProxy + { + public float m_SecondsSinceLastPainAudio { get; set; } + public float m_SecondsUntilNextPainAudio { get; set; } + public List m_CausesLocIDs { get; set; } + public List m_Locations { get; set; } + public List m_ElapsedHoursList { get; set; } + public List m_DurationHoursList { get; set; } + public List m_ElapsedRestList { get; set; } + } + + public class SprainedWristSaveDataProxy + { + public List m_CausesLocIDs { get; set; } + public List m_Locations { get; set; } + public List m_ElapsedHoursList { get; set; } + public List m_DurationHoursList { get; set; } + public List m_ElapsedRestList { get; set; } + public bool m_IsNoSprainWristForced { get; set; } + } + + public class BurnsSaveDataProxy + { + public bool m_Active { get; set; } + public float m_ElapsedHours { get; set; } + public float m_DurationHours { get; set; } + public bool m_PainKillersTaken { get; set; } + public bool m_BandageApplied { get; set; } + public int m_NumBurnRemindersPlayed { get; set; } + public float m_SecondsUntilNextBurnReminder { get; set; } + public string m_CauseLocID; + } + + public class BurnsElectricSaveDataProxy + { + public bool m_Active { get; set; } + public float m_ElapsedHours { get; set; } + public float m_DurationHours { get; set; } + public bool m_PainKillersTaken { get; set; } + public bool m_BandageApplied { get; set; } + public int m_NumBurnRemindersPlayed { get; set; } + public float m_SecondsUntilNextBurnReminder { get; set; } + } + + public class BloodLossSaveDataProxy + { + public List m_CausesLocIDs { get; set; } + public List m_Locations { get; set; } + public List m_ElapsedHoursList { get; set; } + public List m_DurationHoursList { get; set; } + } + + public class BrokenRibSaveDataProxy + { + public List m_CausesLocIDs { get; set; } + public List m_Locations { get; set; } + public List m_PainKillersTaken { get; set; } + public List m_BandagesApplied { get; set; } + public List m_ElapsedRestList { get; set; } + public List m_NumHoursRestForCureList { get; set; } + } + + public class InfectionSaveDataProxy + { + public List m_CausesLocIDs { get; set; } + public List m_Locations { get; set; } + public List m_ElapsedHoursList { get; set; } + public List m_DurationHoursList { get; set; } + public List m_AntibioticsTakenList { get; set; } + public List m_ElapsedRestList { get; set; } + } + + public class InfectionRiskSaveDataProxy + { + public float m_CommentTime; + public List m_CausesLocIDs { get; set; } + public List m_Locations { get; set; } + public List m_ElapsedHoursList { get; set; } + public List m_DurationHoursList { get; set; } + public List m_AntisepticTakenList { get; set; } + public List m_CurrentInfectionChanceList { get; set; } + public List m_ConstantAfflictionIndices { get; set; } + } + + public class CabinFeverSaveDataProxy + { + public bool m_Active { get; set; } + public bool m_RiskActive { get; set; } + public float m_ElapsedHours { get; set; } + public List m_IndoorTimeTracked { get; set; } + public int m_HourLastFrame { get; set; } + public bool m_DoneHalloweenEventFix { get; set; } = true; + } + + public class IntestinalParasitesSaveDataProxy + { + public bool m_HasParasites { get; set; } + public bool m_HasParasiteRisk { get; set; } + public float m_CurrentInfectionChance { get; set; } + public float m_ParasitesElapsedHours { get; set; } + public float m_RiskElapsedHours { get; set; } + public float m_RiskDurationHours { get; set; } + public int m_NumDosesTaken { get; set; } + public bool m_HasTakenDoseToday { get; set; } + public int m_DayToAllowNextDose { get; set; } + public int m_NumPiecesEatenThisRiskCycle { get; set; } + } + + #region Log + public class LogSaveDataProxy + { + public string m_GeneralNotes { get; set; } + public List m_LogDayInfoList { get; set; } + public LogDayInfo m_TodayLogDayInfo { get; set; } + public int m_DayToLogEndOfDayInfo { get; set; } + } + + public class LogDayInfo + { + public int m_DayNumber { get; set; } + public string m_Notes { get; set; } + public int m_WorldExplored { get; set; } + public int m_HoursRested { get; set; } + public int m_ConditionLow { get; set; } + public int m_ConditionHigh { get; set; } + public int m_CaloriesBurned { get; set; } + public List> m_Afflictions { get; set; } + public List m_LocationLocIDs { get; set; } + public List m_RegionLocIDs { get; set; } + public List m_RegionSceneNames { get; set; } + } + + #endregion + + public class RestSaveDataProxy + { + public int m_LastDisplayedDayNumberOnAwake { get; set; } + public int[] m_LastTwentyFourHoursOfSleep { get; set; } + public bool m_PassTimeIsLocked { get; set; } + } + + public class FlyoverDataProxy + { + public float m_SecondsSinceLastFlyover { get; set; } + public float m_SecondsBetweenFlyovers { get; set; } + } + + public class AchievementSaveData + { + public int m_Version { get; set; } + public int m_NumDaysSurvived { get; set; } + public int m_ConsecutiveNightsSurvived { get; set; } + public int m_FullyHarvestedDeer { get; set; } + public bool m_StartedNightOutside { get; set; } + public bool m_WentInsideThisNight { get; set; } + public bool m_HasFiredGun { get; set; } + public bool m_HasKilledSomething { get; set; } + public bool m_LakeRegionAllInteriors { get; set; } + public bool m_CoastalRegionAllInteriors { get; set; } + public int m_NumDaysLivingOffLand { get; set; } + public bool m_UsedRosehipTea { get; set; } + public bool m_UsedReishiTea { get; set; } + public bool m_UsedOldMansBeardDressing { get; set; } + public int m_NumRosehipPlantsHarvested { get; set; } + public int m_NumReishiPlantsHarvested { get; set; } + public int m_NumOldMansPlantsHarvested { get; set; } + public int m_NumCatTailPlantsHarvested { get; set; } + public int m_NumDaysCalorieStoreAboveZero { get; set; } + public int m_NumArcheryBooksRead { get; set; } + public int m_NumCarcassHarvestingBooksRead { get; set; } + public int m_NumCookingBooksRead { get; set; } + public int m_NumFireStartingBooksRead { get; set; } + public int m_NumIceFishingBooksRead { get; set; } + public int m_NumMendingBooksRead { get; set; } + public int m_NumRifleFirearmAdvancedBooksRead { get; set; } + public int m_NumRifleFirearmBooksRead { get; set; } + public int m_NumImprovisedKnivesCrafted { get; set; } + public int m_NumImprovisedHatchetsCrafted { get; set; } + public int m_LongestBurningCampFire { get; set; } + public bool m_FoundAllCachesEpisodeOne { get; set; } + public bool m_FoundAllCachesEpisodeTwo { get; set; } + public Dictionary m_MappedRegions { get; set; } + } + + public class ExperienceModeManagerSaveDataProxy + { + public EnumWrapper m_CurrentModeType { get; set; } + public string m_CustomModeString { get; set; } + } + + public class PlayerMovementSaveDataProxy + { + public float m_SprintStamina { get; set; } + public EnumWrapper m_ForcedMovement { get; set; } + public bool m_ForceNoSprain { get; set; } + public bool m_IsCrouching { get; set; } + } + + public class MusicEventSaveData + { + public float m_HappySuccessLastPlayTime { get; set; } + public float m_SorrowLastPlayTime { get; set; } + public float m_RopeClimbStressLastPlayTime { get; set; } + public float m_BeingStalkedLastPlayTime { get; set; } + public float m_NumHoursWithAffliction { get; set; } + } + + public class EmergencyStimParams + { + public float m_LastUsageTimeInGameHours { get; set; } + public float m_PlayCatchBreathSecondsAfterBegin { get; set; } + public float m_HoursStimulatedWhenInjected { get; set; } + public float m_MinHoursBetweenUsage { get; set; } + public float m_StimPulseFrequencyStart { get; set; } + public float m_StimPulseFrequencyEnd { get; set; } + public float m_FatigueIncreaseWhenComplete { get; set; } + public float m_StaminaDecreaseWhenComplete { get; set; } + public uint m_AudioIDEmergencyStim { get; set; } + } + + public class SnowfallManagerSaveDataProxy + { + public List m_SceneNames { get; set; } + public List m_Records { get; set; } + } + + public class SnowfallRecordSaveDataProxy + { + public float m_CurrentSnowDepth; + } + + public class MissionServicesManagerSaveProxy + { + public List m_SerializedMissions { get; set; } + public List m_SerializedConcurrentGraphs { get; set; } + public List m_SerializedTimers { get; set; } + public List m_MissionObjectFilterTags { get; set; } + public List m_CustomManagedObjects { get; set; } + public List> m_CustomManagedObjectStates { get; set; } + public string m_SerializedGlobalBlackboard; + public string m_VisibleMissionTimer { get; set; } + } + + public class TrustManagerSaveData + { + public Dictionary m_TrustDictionary { get; set; } + public Dictionary m_StrikesDictionary { get; set; } + public Dictionary m_StrikeTimersDictionary { get; set; } + public Dictionary m_NeedTrackersSerialized { get; set; } + public Dictionary m_UnlockableTrackersSerialized { get; set; } + public Dictionary m_TrustDecayDictionary { get; set; } + public Dictionary m_GracePeriodTimersDictionary { get; set; } + public Dictionary m_GracePeriodValuesDictionary { get; set; } + } + + public class MapDetailSaveData + { + public Dictionary m_MapDetailUnlockedStates { get; set; } + } + + public class WorldMapSaveData + { + public List m_UnlockedDetails { get; set; } + } + + public class MapSaveData + { + public Dictionary m_MapSaveDataDict { get; set; } + public Dictionary m_DetailSurveyPositions { get; set; } + public Dictionary m_DetailSurveyLastUpdateTimes { get; set; } + public List m_UnlockedRegionNames { get; set; } + } + + public class SkillsManagerSaveData + { + [Deserialize("m_Skill_FirestartingSerialized", true)] + public Skill_FirestartingSaveData Firestarting { get; set; } + [Deserialize("m_Skill_CarcassHarvestingSerialized", true)] + public Skill_CarcassHarvestingSaveData CarcassHarvesting { get; set; } + [Deserialize("m_Skill_CookingSerialized", true)] + public Skill_CookingSaveData Cooking { get; set; } + [Deserialize("m_Skill_IceFishingSerialized", true)] + public Skill_IceFishingSaveData IceFishing { get; set; } + [Deserialize("m_Skill_RifleSerialized", true)] + public Skill_RifleSaveData Rifle { get; set; } + [Deserialize("m_Skill_ArcherySerialized", true)] + public Skill_ArcherySaveData Archery { get; set; } + [Deserialize("m_Skill_ClothingRepairSerialized", true)] + public Skill_ClothingRepairSaveData ClothingRepair { get; set; } + [Deserialize("m_Skill_RevolverSerialized", true)] + public Skill_RevolverSaveData Revolver { get; set; } + [Deserialize("m_Skill_GunsmithingSerialized", true)] + public Skill_GunsmithingSaveData Gunsmith { get; set; } + } + + public class Skill_FirestartingSaveData + { + public int m_Points { get; set; } + } + + public class Skill_CarcassHarvestingSaveData + { + public int m_Points { get; set; } + public float m_NumHoursToConvertToSkillPoints { get; set; } + } + + public class Skill_CookingSaveData + { + public int m_Points { get; set; } + } + + public class Skill_IceFishingSaveData + { + public int m_Points { get; set; } + } + + public class Skill_RifleSaveData + { + public int m_Points { get; set; } + } + + public class Skill_ArcherySaveData + { + public int m_Points { get; set; } + } + + public class Skill_ClothingRepairSaveData + { + public int m_Points { get; set; } + } + + public class Skill_RevolverSaveData + { + public int m_Points { get; set; } + } + + public class Skill_GunsmithingSaveData + { + public int m_Points { get; set; } + } + + public class FeatEnabledTrackerSaveData + { + public List> m_FeatsEnabledThisSandbox { get; set; } + } + + public class CairnInfo + { + public string m_BackerLookupNum { get; set; } + public int m_JournalEntryNumber { get; set; } + } + + public class SerializedParams + { + public bool m_EnableFirstPersonHands { get; set; } + public string m_HandMeshState { get; set; } + } + + public class WellFedSaveDataProxy + { + public bool m_Active { get; set; } + public float m_ElapsedHoursNotStarving { get; set; } + } + + public class BoxCollider + { + public float[] center { get; set; } + public float[] size { get; set; } + public float[] extents { get; set; } + } + + public class SerializableBounds + { + public float[] m_Center { get; set; } + public float[] m_Size { get; set; } + } + +} diff --git a/src/TldSaveEditor.Core/GameData/GlobalSaveGameFormat.cs b/src/TldSaveEditor.Core/GameData/GlobalSaveGameFormat.cs new file mode 100644 index 0000000..e763651 --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/GlobalSaveGameFormat.cs @@ -0,0 +1,114 @@ +using The_Long_Dark_Save_Editor_2.Serialization; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + + public class GlobalSaveGameFormat + { + public int m_Version { get; set; } + [Deserialize("m_GameManagerSerialized", true)] + public GameManagerData GameManagerData { get; set; } + [Deserialize("m_HudManagerSerialized", true)] + public HudManagerSaveDataProxy HudManager { get; set; } + [Deserialize("m_TimeOfDay_Serialized", true)] + public TimeOfDaySaveDataProxy TimeOfDay { get; set; } + [Deserialize("m_Wind_Serialized", true)] + public WindSaveDataProxy Wind { get; set; } + [Deserialize("m_Weather_Serialized", true)] + public WeatherSaveDataProxy Weather { get; set; } + [Deserialize("m_WeatherTransition_Serialized", true)] + public WeatherTransitionSaveDataProxy WeatherTransition { get; set; } + [Deserialize("m_Condition_Serialized", true)] + public ConditionSaveDataProxy Condition { get; set; } + [Deserialize("m_Encumber_Serialized", true)] + public EncumberSaveDataProxy Encumber { get; set; } + [Deserialize("m_Hunger_Serialized", true)] + public HungerSaveDataProxy Hunger { get; set; } + [Deserialize("m_Thirst_Serialized", true)] + public ThirstSaveDataProxy Thirst { get; set; } + [Deserialize("m_Fatigue_Serialized", true)] + public FatigueSaveDataProxy Fatigue { get; set; } + [Deserialize("m_Freezing_Serialized", true)] + public FreezingSaveDataProxy Freezing { get; set; } + [Deserialize("m_Willpower_Serialized", true)] + public WillpowerSaveDataProxy WillPower { get; set; } + [Deserialize("m_Inventory_Serialized", true)] + public InventorySaveDataProxy Inventory { get; set; } + public string m_SandboxManagerSerialized { get; set; } + public string m_StoryManagerSerialized { get; set; } + [Deserialize("m_PlayerManagerSerialized", true)] + public PlayerManagerSaveDataProxy PlayerManager { get; set; } + [Deserialize("m_PlayerClimbRopeSerialized", true)] + public PlayerClimbRopeProxy PlayerClimbRope { get; set; } + [Deserialize("m_PlayerSkillsSerialized", true)] + public PlayerSkillsSaveData PlayerSkills { get; set; } + [Deserialize("m_PlayerGameStatsSerialized", true)] + public PlayerGameStatsProxy PlayerGameStats { get; set; } + [Deserialize("m_HypothermiaSerialized", true)] + public HypothermiaSaveDataProxy Hypothermia { get; set; } + [Deserialize("m_WellFedSerialized", true)] + public WellFedSaveDataProxy WellFed { get; set; } + [Deserialize("m_FrostbiteSerialized", true)] + public FrostbiteSaveDataProxy FrostBite { get; set; } + [Deserialize("m_FoodPoisoningSerialized", true)] + public FoodPoisoningSaveDataProxy FoodPoisoning { get; set; } + [Deserialize("m_DysenterySerialized", true)] + public DysenterySaveDataProxy Dysentery { get; set; } + [Deserialize("m_SprainedAnkleSerialized", true)] + public SprainedAnkleSaveDataProxy SprainedAnkle { get; set; } + [Deserialize("m_SprainedWristSerialized", true)] + public SprainedWristSaveDataProxy SprainedWrist { get; set; } + [Deserialize("m_BurnsSerialized", true)] + public BurnsSaveDataProxy Burns { get; set; } + [Deserialize("m_BurnsElectricSerialized", true)] + public BurnsElectricSaveDataProxy BurnsElectric { get; set; } + [Deserialize("m_BloodLossSerialized", true)] + public BloodLossSaveDataProxy BloodLoss { get; set; } + [Deserialize("m_BrokenRibSerialized", true)] + public BrokenRibSaveDataProxy BrokenRibs { get; set; } + [Deserialize("m_InfectionSerialized", true)] + public InfectionSaveDataProxy Infection { get; set; } + [Deserialize("m_InfectionRiskSerialized", true)] + public InfectionRiskSaveDataProxy InfectionRisk { get; set; } + [Deserialize("m_LogSerialized", true)] + public LogSaveDataProxy Log { get; set; } + [Deserialize("m_RestSerialized", true)] + public RestSaveDataProxy Rest { get; set; } + [Deserialize("m_FlyOverSerialized", true)] + public FlyoverDataProxy FlyOver { get; set; } + [Deserialize("m_AchievementManagerSerialized", true)] + public AchievementSaveData AchievementManager { get; set; } + [Deserialize("m_ExperienceModeManagerSerialized", true)] + public ExperienceModeManagerSaveDataProxy ExperienceModeManager { get; set; } + [Deserialize("m_PlayerMovementSerialized", true)] + public PlayerMovementSaveDataProxy PlayerMovement { get; set; } + public string m_PlayerStruggleSerialized { get; set; } + public string m_PanelStatsSerialized { get; set; } + [Deserialize("m_EmergencyStimSerialized", true)] + public EmergencyStimParams EmergencyStim { get; set; } + public string m_MusicEventManagerSerialized { get; set; } + public string m_ChimneyDataSerialized { get; set; } + [Deserialize("m_CabinFeverSerialized", true)] + public CabinFeverSaveDataProxy CabinFever { get; set; } + [Deserialize("m_IntestinalParasitesSerialized", true)] + public IntestinalParasitesSaveDataProxy IntestinalParasites { get; set; } + public string m_SnowPatchManagerSerialized { get; set; } + public string m_PlayerAnimationSerialized { get; set; } + [Deserialize("m_SkillsManagerSerialized", true)] + public SkillsManagerSaveData SkillsManager { get; set; } + public string m_LockCompanionsSerialized { get; set; } + [Deserialize("m_FeatsEnabledSerialized", true)] + public FeatEnabledTrackerSaveData FeatsEnabled { get; set; } + /*public string m_TrustManagerSerialized { get; set; } + public string m_WorldMapDataSerialized { get; set; } + public string m_MapDataSerialized { get; set; } + public string m_BearHuntSerialized { get; set; } + public string m_BearHuntReduxSerialized { get; set; } + public string m_KnowledgeManagerSerialized { get; set; } + public string m_UnlockedBlueprintsSerialized { get; set; } + public string m_CollectionManagerSerialized { get; set; } + public string m_AuroraScreenManagerSerialized { get; set; } + public string m_StoryMissionDataSerialized { get; set; } + public bool m_CurrentEpisodeComplete { get; set; }*/ + } +} diff --git a/src/TldSaveEditor.Core/GameData/ProfileState.cs b/src/TldSaveEditor.Core/GameData/ProfileState.cs new file mode 100644 index 0000000..41f6afd --- /dev/null +++ b/src/TldSaveEditor.Core/GameData/ProfileState.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using The_Long_Dark_Save_Editor_2.Serialization; + +namespace The_Long_Dark_Save_Editor_2.Game_data +{ + public class ProfileState + { + public List m_RewiredKeyboardMap { get; set; } + public List m_RewiredMouseMap { get; set; } + public List m_SandboxRecords { get; set; } + public List> m_UpsellsViewed { get; set; } + public List m_DaysCompleted4DON { get; set; } + public List m_DaysCompleted4DON2019 { get; set; } + public int m_Version { get; set; } + public bool m_ShowTimeOfDaySlider { get; set; } + public bool m_ShowFrametime { get; set; } + public float m_MasterVolume { get; set; } + public float m_SoundVolume { get; set; } + public float m_MusicVolume { get; set; } + public float m_VoiceVolume { get; set; } + public int m_QualityLevel { get; set; } + public EnumWrapper m_GraphicsMode { get; set; } + public int m_DisplayNumber { get; set; } + public Resolution m_Resolution { get; set; } + public bool m_SSAOEnabled { get; set; } + public EnumWrapper m_Units { get; set; } + public EnumWrapper m_HudPref { get; set; } + public EnumWrapper m_HudSize { get; set; } + public EnumWrapper m_HudType { get; set; } + public bool m_InvertY { get; set; } + public bool m_InvertX { get; set; } + public bool m_LockMouseToScreen { get; set; } + public bool m_EnableGamepad { get; set; } + [Obsolete("Use m_MouseSensitivityPercentage instead")] + public float[] m_MouseSensitivity { get; set; } + [Obsolete("Use m_ZoomSensitivityPercentage instead")] + public float[] m_ZoomSensitivity { get; set; } + [Obsolete("Use m_GamepadCameraSensitivityPercentage instead")] + public float[] m_AnalogSticksSensitivity { get; set; } + public float m_MouseSensitivityPercentage { get; set; } + public float m_ZoomSensitivityPercentage { get; set; } + public float m_GamepadCameraSensitivityPercentage { get; set; } + public bool m_ConsoleUnlocked { get; set; } + public float m_FieldOfView { get; set; } + public int m_NumGamesPlayed { get; set; } + public EnumWrapper m_VoicePersona { get; set; } + public EnumWrapper m_StartRegion { get; set; } + public Dictionary m_KeyBindings { get; set; } + public bool m_VsyncEnabled { get; set; } + public EnumWrapper m_SubtitlesState { get; set; } + public EnumWrapper m_LanguageState { get; set; } + public string m_Language { get; set; } + public bool m_CoastalRegionLocked { get; set; } + public bool m_RuralRegionLocked { get; set; } + public bool m_WhalingStationRegionLocked { get; set; } + public bool m_CrashMountainRegionLocked { get; set; } + public bool m_FrameDumperUnlocked { get; set; } + public bool m_HasSeenIntroVideo { get; set; } + public bool m_NoResumeSave { get; set; } + public string m_AllTimeStats { get; set; } + public float m_BestTimeHunted { get; set; } + public float m_BestTimeRescue { get; set; } + public float m_BestTimeWhiteout { get; set; } + public float m_BestTimeNomad { get; set; } + public float m_BestTimeHunted2 { get; set; } + public float m_BestTimeArchivist { get; set; } + public EnumWrapper m_MostRecentSandboxMode { get; set; } + public EnumWrapper m_MostRecentChallengeMode { get; set; } + public EnumWrapper m_MostRecentEpisodeMode { get; set; } + public float m_Brightness { get; set; } + public bool m_DoneBrightnessAdjustment { get; set; } + public List m_UnlockedBadgesViewed { get; set; } + public HashSet m_CinematicsViewed { get; set; } + [Deserialize("m_FeatsSerialized", true)] + public FeatsManagerSaveData Feats { get; set; } + public string m_EpisodeManagerSerialized { get; set; } + public string m_QualityLevelSettingsSerialized { get; set; } + public bool m_DisableClickHold { get; set; } + public int m_AutosaveMinutes { get; set; } + public string m_NewGameCustomModeString { get; set; } + public bool m_FoundAllCachesEpisodeOne { get; set; } + public bool m_FoundAllCachesEpisodeTwo { get; set; } + public List> m_UnlockedAchievements { get; set; } + public bool m_ReduceCameraMotion { get; set; } + public bool m_LargeSubtitles { get; set; } + public HashSet m_ViewedNotifications { get; set; } + } + + public class Resolution + { + public int m_Width { get; set; } + public int m_Height { get; set; } + public int m_RefreshRate { get; set; } + } + + public class FeatsManagerSaveData + { + [Deserialize("m_Feat_BookSmartsSerialized", true)] + public Feat_BookSmartsSaveData BookSmarts { get; set; } + [Deserialize("m_Feat_ColdFusionSerialized", true)] + public Feat_ColdFusionSaveData ColdFusion { get; set; } + [Deserialize("m_Feat_EfficientMachineSerialized", true)] + public Feat_EfficientMachineSaveData EfficientMachine { get; set; } + [Deserialize("m_Feat_FireMasterSerialized", true)] + public Feat_FireMasterSaveData FireMaster { get; set; } + [Deserialize("m_Feat_FreeRunnerSerialized", true)] + public Feat_FreeRunnerSaveData FreeRunner { get; set; } + [Deserialize("m_Feat_SnowWalkerSerialized", true)] + public Feat_SnowWalkerSaveData SnowWalker { get; set; } + [Deserialize("m_Feat_ExpertTrappererialized", true)] + public Feat_ExpertTrapperSaveData ExpertTrapper { get; set; } + [Deserialize("m_Feat_StraightToHeartSerialized", true)] + public Feat_StraightToHeartSaveData StraightToHeart { get; set; } + [Deserialize("m_Feat_BlizzardWalkerSerialized", true)] + public Feat_BlizzardWalkerSaveData BlizzardWalker { get; set; } + } + + public class Feat_BookSmartsSaveData + { + public int m_HoursResearch { get; set; } + } + + public class Feat_ColdFusionSaveData + { + public float m_ElapsedDays { get; set; } + public float m_HoursAccumulator { get; set; } + } + + public class Feat_EfficientMachineSaveData + { + public float m_ElapsedHours { get; set; } + public float m_HoursAccumulator { get; set; } + } + + public class Feat_FireMasterSaveData + { + public int m_NumFiresStarted { get; set; } + } + + public class Feat_FreeRunnerSaveData + { + public float m_ElapsedKilometers { get; set; } + public float m_MetersAccumulator { get; set; } + } + + public class Feat_SnowWalkerSaveData + { + public float m_ElapsedKilometers { get; set; } + public float m_MetersAccumulator { get; set; } + } + + public class Feat_ExpertTrapperSaveData + { + public int m_RabbitSnaredCount { get; set; } + } + public class Feat_StraightToHeartSaveData + { + public int m_ItemConsumedCount { get; set; } + } + public class Feat_BlizzardWalkerSaveData + { + public float m_BlizzardHoursOutside { get; set; } + public float m_BlizzardHoursOutsideAccumulator { get; set; } + } + + public class StatContainer + { + public int[] m_CachedHashIds { get; set; } + public Dictionary m_StatsDictionary { get; set; } + public int m_NumBurntHousesInCoastal { get; set; } + public bool m_HasDoneCoastalBurntHouseCheck { get; set; } + public bool m_HasDoneCorrectBurntHouseCheck { get; set; } + } + + public class SandboxRecord + { + public string m_SandboxName { get; set; } + public float m_ElapsedHours { get; set; } + public string m_EndDate { get; set; } + public EnumWrapper m_StartRegion { get; set; } + public string m_EndRegion { get; set; } + public EnumWrapper m_ExperienceModeType { get; set; } + public EnumWrapper m_VoicePersona { get; set; } + public string m_CauseOfDeathLocId { get; set; } + public string m_GeneralNotes { get; set; } + public List m_LogDayInfoList { get; set; } + // TODO: check if dynamic works correctly + public List m_CollectibleList { get; set; } + public List m_CollectibleNotesList { get; set; } + public List m_CollectibleCairnInfoList { get; set; } + public StatContainer m_Stats { get; set; } + } +} diff --git a/src/TldSaveEditor.Core/GameSave.cs b/src/TldSaveEditor.Core/GameSave.cs new file mode 100644 index 0000000..2a642a4 --- /dev/null +++ b/src/TldSaveEditor.Core/GameSave.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using The_Long_Dark_Save_Editor_2.Game_data; +using The_Long_Dark_Save_Editor_2.Helpers; +using The_Long_Dark_Save_Editor_2.Serialization; + +namespace The_Long_Dark_Save_Editor_2 +{ + public class GameSave + { + public static int MAX_BACKUPS = 20; + + // The game's JSON uses bareword Infinity/NaN for some floats and number-arrays for byte + // data. DynamicSerializable.Serialize() relies on JsonConvert.DefaultSettings to write + // them back the same way; without this, saving turns Infinity into the string "Infinity" + // (which then fails to re-parse) and byte arrays into base64 — both corrupt the save. + // Defined here so every consumer (WPF app and web server) shares one definition. + static GameSave() + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + FloatFormatHandling = FloatFormatHandling.Symbol, + Converters = new List { new ByteArrayConverter() }, + }; + } + + public long LastSaved { get; set; } + private DynamicSerializable dynamicBoot; + public BootSaveGameFormat Boot { get { return dynamicBoot.Obj; } } + + private DynamicSerializable dynamicGlobal; + public GlobalSaveGameFormat Global { get { return dynamicGlobal.Obj; } } + + public AfflictionsContainer Afflictions { get; set; } + + private DynamicSerializable dynamicSlotData; + public SlotData SlotData { get { return dynamicSlotData.Obj; } } + + public string OriginalRegion { get; set; } + + public string path; + + public void LoadSave(string path) + { + this.path = path; + string slotJson = EncryptString.Decompress(File.ReadAllBytes(path)); + dynamicSlotData = new DynamicSerializable(slotJson); + + var bootJson = EncryptString.Decompress(Convert.FromBase64String(SlotData.m_Dict["boot"])); + dynamicBoot = new DynamicSerializable(bootJson); + OriginalRegion = Boot.m_SceneName.Value; + + var globalJson = EncryptString.Decompress(Convert.FromBase64String(SlotData.m_Dict["global"])); + dynamicGlobal = new DynamicSerializable(globalJson); + + Afflictions = new AfflictionsContainer(Global); + } + + public void Save() + { + Backup(); + + LastSaved = DateTime.Now.Ticks; + var bootSerialized = dynamicBoot.Serialize(); + SlotData.m_Dict["boot"] = Convert.ToBase64String(EncryptString.Compress(bootSerialized)); + + if (Boot.m_SceneName.Value != OriginalRegion) + { + Global.GameManagerData.SceneTransition.m_ForceNextSceneLoadTriggerScene = null; + } + Global.GameManagerData.SceneTransition.m_SceneSaveFilenameCurrent = Boot.m_SceneName.Value; + Global.GameManagerData.SceneTransition.m_SceneSaveFilenameNextLoad = Boot.m_SceneName.Value; + Global.PlayerManager.m_CheatsUsed = true; + Afflictions.SerializeTo(Global); + + var globalSerialized = dynamicGlobal.Serialize(); + SlotData.m_Dict["global"] = Convert.ToBase64String(EncryptString.Compress(globalSerialized)); + + SlotData.m_Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + var slotDataSerialized = dynamicSlotData.Serialize(); + File.WriteAllBytes(this.path, EncryptString.Compress(slotDataSerialized)); + } + + public void Backup() + { + var backupDirectory = Path.Combine(Path.GetDirectoryName(this.path), "backups"); + Directory.CreateDirectory(backupDirectory); + + var oldBackups = new DirectoryInfo(backupDirectory).GetFiles().OrderByDescending(x => x.LastWriteTime).Skip(MAX_BACKUPS); + foreach (var file in oldBackups) + { + File.Delete(file.FullName); + } + + var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss", CultureInfo.InvariantCulture); + var i = 1; + var backupPath = Path.Combine(backupDirectory, timestamp + "-" + Path.GetFileName(this.path) + ".backup"); + while (File.Exists(backupPath)) + { + backupPath = Path.Combine(backupDirectory, timestamp + "-" + Path.GetFileName(this.path) + "(" + i++ + ")" + ".backup"); + } + File.Copy(this.path, backupPath); + } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/BindableBase.cs b/src/TldSaveEditor.Core/Helpers/BindableBase.cs new file mode 100644 index 0000000..89dabf9 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/BindableBase.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + public abstract class BindableBase : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + protected void SetProperty(ref T field, T newValue, [CallerMemberName] string propertyName = null) + { + if (!EqualityComparer.Default.Equals(field, newValue)) + { + field = newValue; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/CLZF.cs b/src/TldSaveEditor.Core/Helpers/CLZF.cs new file mode 100644 index 0000000..47bcc10 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/CLZF.cs @@ -0,0 +1,337 @@ +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + /* + * Improved version to C# LibLZF Port: + * Copyright (c) 2010 Roman Atachiants + * + * Original CLZF Port: + * Copyright (c) 2005 Oren J. Maurice + * + * Original LibLZF Library Algorithm: + * Copyright (c) 2000-2008 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License version 2 (the "GPL"), in which case the + * provisions of the GPL are applicable instead of the above. If you wish to + * allow the use of your version of this file only under the terms of the + * GPL and not to allow others to use your version of this file under the + * BSD license, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the GPL. If + * you do not delete the provisions above, a recipient may use your version + * of this file under either the BSD or the GPL. + */ + using System; + + /* Benchmark with Alice29 Canterbury Corpus + --------------------------------------- + (Compression) Original CLZF C# + Raw = 152089, Compressed = 101092 + 8292,4743 ms. + --------------------------------------- + (Compression) My LZF C# + Raw = 152089, Compressed = 101092 + 33,0019 ms. + --------------------------------------- + (Compression) Zlib using SharpZipLib + Raw = 152089, Compressed = 54388 + 8389,4799 ms. + --------------------------------------- + (Compression) QuickLZ C# + Raw = 152089, Compressed = 83494 + 80,0046 ms. + --------------------------------------- + (Decompression) Original CLZF C# + Decompressed = 152089 + 16,0009 ms. + --------------------------------------- + (Decompression) My LZF C# + Decompressed = 152089 + 15,0009 ms. + --------------------------------------- + (Decompression) Zlib using SharpZipLib + Decompressed = 152089 + 3577,2046 ms. + --------------------------------------- + (Decompression) QuickLZ C# + Decompressed = 152089 + 21,0012 ms. + */ + + + /// + /// Improved C# LZF Compressor, a very small data compression library. The compression algorithm is extremely fast. + public static class CLZF + { + private static readonly uint HLOG = 14; + private static readonly uint HSIZE = (1 << 14); + private static readonly uint MAX_LIT = (1 << 5); + private static readonly uint MAX_OFF = (1 << 13); + private static readonly uint MAX_REF = ((1 << 8) + (1 << 3)); + + /// + /// Hashtable, that can be allocated only once + /// + private static readonly long[] HashTable = new long[HSIZE]; + + // Compresses inputBytes + public static byte[] Compress(byte[] inputBytes) + { + // Starting guess, increase it later if needed + int outputByteCountGuess = inputBytes.Length * 2; + byte[] tempBuffer = new byte[outputByteCountGuess]; + int byteCount = lzf_compress(inputBytes, ref tempBuffer); + + // If byteCount is 0, then increase buffer and try again + while (byteCount == 0) + { + outputByteCountGuess *= 2; + tempBuffer = new byte[outputByteCountGuess]; + byteCount = lzf_compress(inputBytes, ref tempBuffer); + } + + byte[] outputBytes = new byte[byteCount]; + Buffer.BlockCopy(tempBuffer, 0, outputBytes, 0, byteCount); + return outputBytes; + } + + // Decompress outputBytes + public static byte[] Decompress(byte[] inputBytes) + { + // Starting guess, increase it later if needed + int outputByteCountGuess = inputBytes.Length * 2; + byte[] tempBuffer = new byte[outputByteCountGuess]; + int byteCount = lzf_decompress(inputBytes, ref tempBuffer); + + // If byteCount is 0, then increase buffer and try again + while (byteCount == 0) + { + outputByteCountGuess *= 2; + tempBuffer = new byte[outputByteCountGuess]; + byteCount = lzf_decompress(inputBytes, ref tempBuffer); + } + + byte[] outputBytes = new byte[byteCount]; + Buffer.BlockCopy(tempBuffer, 0, outputBytes, 0, byteCount); + return outputBytes; + } + + /// + /// Compresses the data using LibLZF algorithm + /// + /// Reference to the data to compress + /// Reference to a buffer which will contain the compressed data + /// The size of the compressed archive in the output buffer + public static int lzf_compress(byte[] input, ref byte[] output) + { + int inputLength = input.Length; + int outputLength = output.Length; + + Array.Clear(HashTable, 0, (int)HSIZE); + + long hslot; + uint iidx = 0; + uint oidx = 0; + long reference; + + uint hval = (uint)(((input[iidx]) << 8) | input[iidx + 1]); // FRST(in_data, iidx); + long off; + int lit = 0; + + for (;;) + { + if (iidx < inputLength - 2) + { + hval = (hval << 8) | input[iidx + 2]; + hslot = ((hval ^ (hval << 5)) >> (int)(((3 * 8 - HLOG)) - hval * 5) & (HSIZE - 1)); + reference = HashTable[hslot]; + HashTable[hslot] = (long)iidx; + + + if ((off = iidx - reference - 1) < MAX_OFF + && iidx + 4 < inputLength + && reference > 0 + && input[reference + 0] == input[iidx + 0] + && input[reference + 1] == input[iidx + 1] + && input[reference + 2] == input[iidx + 2] + ) + { + /* match found at *reference++ */ + uint len = 2; + uint maxlen = (uint)inputLength - iidx - len; + maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; + + if (oidx + lit + 1 + 3 >= outputLength) + return 0; + + do + len++; + while (len < maxlen && input[reference + len] == input[iidx + len]); + + if (lit != 0) + { + output[oidx++] = (byte)(lit - 1); + lit = -lit; + do + output[oidx++] = input[iidx + lit]; + while ((++lit) != 0); + } + + len -= 2; + iidx++; + + if (len < 7) + { + output[oidx++] = (byte)((off >> 8) + (len << 5)); + } + else + { + output[oidx++] = (byte)((off >> 8) + (7 << 5)); + output[oidx++] = (byte)(len - 7); + } + + output[oidx++] = (byte)off; + + iidx += len - 1; + hval = (uint)(((input[iidx]) << 8) | input[iidx + 1]); + + hval = (hval << 8) | input[iidx + 2]; + HashTable[((hval ^ (hval << 5)) >> (int)(((3 * 8 - HLOG)) - hval * 5) & (HSIZE - 1))] = iidx; + iidx++; + + hval = (hval << 8) | input[iidx + 2]; + HashTable[((hval ^ (hval << 5)) >> (int)(((3 * 8 - HLOG)) - hval * 5) & (HSIZE - 1))] = iidx; + iidx++; + continue; + } + } + else if (iidx == inputLength) + break; + + /* one more literal byte we must copy */ + lit++; + iidx++; + + if (lit == MAX_LIT) + { + if (oidx + 1 + MAX_LIT >= outputLength) + return 0; + + output[oidx++] = (byte)(MAX_LIT - 1); + lit = -lit; + do + output[oidx++] = input[iidx + lit]; + while ((++lit) != 0); + } + } + + if (lit != 0) + { + if (oidx + lit + 1 >= outputLength) + return 0; + + output[oidx++] = (byte)(lit - 1); + lit = -lit; + do + output[oidx++] = input[iidx + lit]; + while ((++lit) != 0); + } + + return (int)oidx; + } + + + /// + /// Decompresses the data using LibLZF algorithm + /// + /// Reference to the data to decompress + /// Reference to a buffer which will contain the decompressed data + /// Returns decompressed size + public static int lzf_decompress(byte[] input, ref byte[] output) + { + int inputLength = input.Length; + int outputLength = output.Length; + + uint iidx = 0; + uint oidx = 0; + + do + { + uint ctrl = input[iidx++]; + + if (ctrl < (1 << 5)) /* literal run */ + { + ctrl++; + + if (oidx + ctrl > outputLength) + { + //SET_ERRNO (E2BIG); + return 0; + } + + do + output[oidx++] = input[iidx++]; + while ((--ctrl) != 0); + } + else /* back reference */ + { + uint len = ctrl >> 5; + + int reference = (int)(oidx - ((ctrl & 0x1f) << 8) - 1); + + if (len == 7) + len += input[iidx++]; + + reference -= input[iidx++]; + + if (oidx + len + 2 > outputLength) + { + //SET_ERRNO (E2BIG); + return 0; + } + + if (reference < 0) + { + //SET_ERRNO (EINVAL); + return 0; + } + + output[oidx++] = output[reference++]; + output[oidx++] = output[reference++]; + + do + output[oidx++] = output[reference++]; + while ((--len) != 0); + } + } + while (iidx < inputLength); + + return (int)oidx; + } + + } + +} diff --git a/src/TldSaveEditor.Core/Helpers/CommandHandler.cs b/src/TldSaveEditor.Core/Helpers/CommandHandler.cs new file mode 100644 index 0000000..87b9961 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/CommandHandler.cs @@ -0,0 +1,28 @@ +using System; +using System.Windows.Input; + +namespace The_Long_Dark_Save_Editor_2.Helpers.Helpers +{ + public class CommandHandler : ICommand + { + private Action _action; + private bool _canExecute; + public CommandHandler(Action action) + { + _action = action; + _canExecute = true; + } + + public bool CanExecute(object parameter) + { + return _canExecute; + } + + public event EventHandler CanExecuteChanged; + + public void Execute(object parameter) + { + _action(); + } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/DictionaryExtension.cs b/src/TldSaveEditor.Core/Helpers/DictionaryExtension.cs new file mode 100644 index 0000000..4d3bce7 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/DictionaryExtension.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + static class DictionaryExtension + { + public static TValue GetOrDefault(this IDictionary dictionary, TKey key, TValue defaultValue) + { + TValue value; + return dictionary.TryGetValue(key, out value) ? value : defaultValue; + } + + public static TValue Get(this IDictionary dictionary, TKey key) where TValue : class + { + TValue value; + return dictionary.TryGetValue(key, out value) ? value : null; + } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/EncryptString.cs b/src/TldSaveEditor.Core/Helpers/EncryptString.cs new file mode 100644 index 0000000..b34bbc9 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/EncryptString.cs @@ -0,0 +1,17 @@ +using System.Text; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + public class EncryptString + { + public static byte[] Compress(string json) + { + return CLZF.Compress(Encoding.UTF8.GetBytes(json)); + } + + public static string Decompress(byte[] bytes) + { + return Encoding.UTF8.GetString(CLZF.Decompress(bytes)); + } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/EnumerationMember.cs b/src/TldSaveEditor.Core/Helpers/EnumerationMember.cs new file mode 100644 index 0000000..d86901f --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/EnumerationMember.cs @@ -0,0 +1,11 @@ +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + // Plain data holder used by enum-backed combo boxes. The XAML markup extension that + // produces these (EnumerationExtension) lives in the UI project; this POCO stays in Core + // so that Util / save loading can return display entries without a UI dependency. + public class EnumerationMember + { + public string Description { get; set; } + public object Value { get; set; } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/ItemDictionary.cs b/src/TldSaveEditor.Core/Helpers/ItemDictionary.cs new file mode 100644 index 0000000..39431cc --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/ItemDictionary.cs @@ -0,0 +1,535 @@ +using System.Collections.Generic; +using The_Long_Dark_Save_Editor_2.Game_data; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + + public class ItemInfo + { + public ItemCategory category; + public string defaultSerialized; + public bool hide; + public bool preventDelete; + } + + + public static class ItemDictionary + { + public static Dictionary itemInfo = new Dictionary(); + + private static void AddItemInfo(string itemID, ItemCategory category, string defaultSerialized, bool hide = false, bool preventDelete = false) + { + itemInfo.Add(itemID, new ItemInfo { category = category, defaultSerialized = defaultSerialized, hide = hide, preventDelete = preventDelete }); + } + + public static string GetInGameName(string name) + { + return Properties.Resources.ResourceManager.GetString(name, System.Globalization.CultureInfo.CurrentUICulture) ?? name; + } + + public static ItemCategory GetCategory(string name) + { + if (itemInfo.ContainsKey(name)) + return itemInfo[name].category; + return ItemCategory.Unknown; + } + + static ItemDictionary() + { + // First aid + AddItemInfo("GEAR_BottleAntibiotics", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_BottleHydrogenPeroxide", ItemCategory.FirstAid, @"{""LiquidItem"": {""m_LiquidLitersProxy"": 500000000,""m_LiquidQuality"": { ""Value"":""NonPotable""}}}"); + AddItemInfo("GEAR_BottlePainKillers", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_HeavyBandage", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_OldMansBeardDressing", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_WaterPurificationTablets", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_EmergencyStim", ItemCategory.FirstAid, @"{}"); + AddItemInfo("GEAR_ReishiPrepared", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_RosehipsPrepared", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_SodaEnergy", ItemCategory.FirstAid, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 100}}"); + AddItemInfo("GEAR_BirchbarkPrepared", ItemCategory.FirstAid, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BirchbarkTea", ItemCategory.FirstAid, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 125}}"); + + // Clothing + AddItemInfo("GEAR_AstridBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_AstridGloves", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_AstridJacket", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_AstridJeans", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_AstridSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_AstridToque", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_Balaclava", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BaseballCap", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BasicBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BasicGloves", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BasicShoes", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BasicWinterCoat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BasicWoolHat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BasicWoolScarf", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_BearSkinCoat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CargoPants", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CombatBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CombatPants", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CottonHoodie", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CottonScarf", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CottonShirt", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CottonSocks", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CowichanSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_DeerSkinBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_DeerSkinPants", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_DownParka", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_DownSkiJacket", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_DownVest", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_EarMuffs", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_FishermanSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_FleeceMittens", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_FleeceSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_Gauntlets", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_HeavyParka", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_HeavyWoolSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_InsulatedBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_InsulatedPants", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_InsulatedVest", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_Jeans", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_LeatherShoes", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_LightParka", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_LongUnderwear", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_LongUnderwearWool", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_MackinawJacket", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_MilitaryParka", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_Mittens", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_MuklukBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_PlaidShirt", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_PremiumWinterCoat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_QualityWinterCoat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_RabbitSkinMittens", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_SkiBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_SkiGloves", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_SkiJacket", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_TeeShirt", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_Toque", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WolfSkinCape", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WoolShirt", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WoolSocks", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WoolSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WoolWrap", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WoolWrapCap", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WorkBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WorkGloves", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WorkPants", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_ClimbingSocks", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillShirt", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillParka", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillSweater", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillToque", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillPants", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_GreyMotherBoots", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_MooseHideCloak", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_MooseHideBag", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillSweaterStart", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillShirtStart", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillBootsStart", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_WillPantsStart", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_RabbitskinHat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_CottonSocksStart", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_LongUnderwearStart", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_ImprovisedMittens", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_ImprovisedHat", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + AddItemInfo("GEAR_Crampons", ItemCategory.Clothing, @"{""ClothingItem"": {}}"); + + // Food + AddItemInfo("GEAR_AirlineFoodChick", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 620}}"); + AddItemInfo("GEAR_AirlineFoodVeg", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 560}}"); + AddItemInfo("GEAR_BeefJerky", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 350}}"); + AddItemInfo("GEAR_CandyBar", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 250}}"); + AddItemInfo("GEAR_CannedBeans", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 600}, ""SmashableItem"": {}}"); + AddItemInfo("GEAR_CannedSardines", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 300}, ""SmashableItem"": {}}"); + AddItemInfo("GEAR_CattailStalk", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 150}, ""StackableItem"":{""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_CattailPlant", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 150}, ""StackableItem"":{""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_CoffeeCup", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 100}}"); + AddItemInfo("GEAR_CoffeeTin", ItemCategory.Food, @"{""StackableItem"":{""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_CondensedMilk", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 750}}"); + AddItemInfo("GEAR_CookedLakeWhiteFish", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedMeatBear", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedMeatDeer", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedMeatRabbit", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedMeatWolf", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedRainbowTrout", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedSmallMouthBass", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_Crackers", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 600}}"); + AddItemInfo("GEAR_DogFood", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 500}, ""SmashableItem"": {}}"); + AddItemInfo("GEAR_EnergyBar", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 500}}"); + AddItemInfo("GEAR_GranolaBar", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 300}}"); + AddItemInfo("GEAR_GreenTeaCup", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 100}}"); + AddItemInfo("GEAR_GreenTeaPackage", ItemCategory.Food, @"{""StackableItem"":{""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_HomeMadeSoup", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 600}}"); + AddItemInfo("GEAR_MRE", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 1750}}"); + AddItemInfo("GEAR_PeanutButter", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 900}}"); + AddItemInfo("GEAR_PinnacleCanPeaches", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 450}, ""SmashableItem"": {}}"); + AddItemInfo("GEAR_RawCohoSalmon", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedCohoSalmon", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawLakeWhiteFish", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawMeatBear", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawMeatDeer", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawMeatRabbit", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawMeatWolf", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawRainbowTrout", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_RawSmallMouthBass", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_ReishiTea", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 100}}"); + AddItemInfo("GEAR_RoseHipTea", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 100}}"); + AddItemInfo("GEAR_Soda", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 250}}"); + AddItemInfo("GEAR_SodaGrape", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 250}}"); + AddItemInfo("GEAR_SodaOrange", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 250}}"); + AddItemInfo("GEAR_TomatoSoupCan", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 300}, ""SmashableItem"": {}}"); + AddItemInfo("GEAR_WaterSupplyNotPotable", ItemCategory.Food, @"{""WaterSupply"":{""m_VolumeProxy"": 1000000000}}", true); + AddItemInfo("GEAR_WaterSupplyPotable", ItemCategory.Food, @"{""WaterSupply"":{""m_VolumeProxy"": 1000000000}}", true); + AddItemInfo("GEAR_WolfQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); + AddItemInfo("GEAR_BearQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); + AddItemInfo("GEAR_StagQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); + AddItemInfo("GEAR_RabbitCarcass", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:1.5, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); + AddItemInfo("GEAR_MooseQuarter", ItemCategory.Food, @"{""BodyHarvest"": {m_QuarterBagWasteMultiplier:2, m_MeatAvailableKG: 1, m_Condition: 100, m_DamageSide:{Value:""DamageSideRight""}}}"); + AddItemInfo("GEAR_RawMeatMoose", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_CookedMeatMoose", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 200}}"); + AddItemInfo("GEAR_KetchupChips", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 300}}"); + AddItemInfo("GEAR_MapleSyrup", ItemCategory.Food, @"{""FoodItem"": {""m_CaloriesRemainingProxy"": 850}}"); + + // Tools + AddItemInfo("GEAR_Accelerant", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Arrow", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_ArrowShaft", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BrokenArrow", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BearSkinBedRoll", ItemCategory.Tools, @"{""Bed"": {}}"); + AddItemInfo("GEAR_BedRoll", ItemCategory.Tools, @"{""Bed"": {}}"); + AddItemInfo("GEAR_BlueFlare", ItemCategory.Tools, @"{""FlareItem"": {}}"); + AddItemInfo("GEAR_Bow", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Brand", ItemCategory.Tools, @"{""TorchItem"": {}}"); //Check!! + AddItemInfo("GEAR_Bullet", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_CarBattery", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_CanOpener", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Firestriker", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_FlareA", ItemCategory.Tools, @"{""FlareItem"": {}}"); + AddItemInfo("GEAR_FlareGunAmmoSingle", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_FlareGun", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_GunpowderCan", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Hacksaw", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Hammer", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Hatchet", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_HatchetImprovised", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_HighQualityTools", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Hook", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_HookAndLine", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_JerrycanRusty", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 2000000000,m_LiquidQuality:{Value:""NonPotable""}}}"); + AddItemInfo("GEAR_KeroseneLampB", ItemCategory.Tools, @"{""KeroseneLampItem"": {""m_CurrentFuelLitersProxy"": 1000000000}}"); + AddItemInfo("GEAR_Knife", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_KnifeImprovised", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_LampFuel", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 500000000,m_LiquidQuality:{Value:""NonPotable""}}}"); + AddItemInfo("GEAR_LampFuelFull", ItemCategory.Tools, @"{""LiquidItem"": {m_LiquidLitersProxy: 500000000,m_LiquidQuality:{Value:""NonPotable""}}}"); + AddItemInfo("GEAR_Line", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_MagnifyingLens", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_NewsprintRoll", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_PackMatches", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 10}, ""MatchesItem"": {}}"); + AddItemInfo("GEAR_Prybar", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_RevolverAmmoCasing", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_RifleAmmoCasing", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 6}}"); + AddItemInfo("GEAR_Rifle", ItemCategory.Tools, @"{""WeaponItem"": {""m_RoundsInClipProxy"": 10}}"); + AddItemInfo("GEAR_RifleAmmoBox", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 10}}"); + AddItemInfo("GEAR_RifleAmmoSingle", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_RifleCleaningKit", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Rope", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_SewingKit", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_SharpeningStone", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_SimpleTools", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_Snare", ItemCategory.Tools, @"{""SnareItem"": {}}"); + AddItemInfo("GEAR_SprayPaintCan", ItemCategory.Tools, @"{""SprayItem"": {""m_Colour"":{Value:""Orange""}}}"); + AddItemInfo("GEAR_Torch", ItemCategory.Tools, @"{""TorchItem"": {}}"); + AddItemInfo("GEAR_WoodMatches", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 10}, ""MatchesItem"": {}}"); + AddItemInfo("GEAR_Charcoal", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Stone", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Flashlight", ItemCategory.Tools, @"{""FlashlightItem"": {""m_CurrentBatteryCharge"": 100}}"); + AddItemInfo("GEAR_KnifeScrapMetal", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_JeremiahKnife", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_RifleHuntingLodge", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_BoltCutters", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_FireAxe", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_CookingPot", ItemCategory.Tools, @"{""CookingPot"": {}}"); + AddItemInfo("GEAR_RecycledCan", ItemCategory.Tools, @"{""CookingPot"": {""m_CanOnlyWarmUpFood"": true}}"); + AddItemInfo("GEAR_SpearHead", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_MedicalSupplies_hangar", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_FoodSupplies_hangar", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_FlareGunCase_hangar", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_AstridBackPack_hangar", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_HardCase_hangar", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_BearSpear", ItemCategory.Tools, @"{}"); + AddItemInfo("GEAR_BearSpearStory", ItemCategory.Tools, @"{}", true); + AddItemInfo("GEAR_BearSpearBrokenStory", ItemCategory.Tools, @"{}", true); + AddItemInfo("GEAR_RevolverAmmoSingle", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_RevolverAmmoBox", ItemCategory.Tools, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Revolver", ItemCategory.Tools, @"{""WeaponItem"": {""m_RoundsInClipProxy"": 5}}"); + + // Materials + AddItemInfo("GEAR_ArrowHead", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""InProgressItem"": {""m_PercentComplete"": 100}}"); + AddItemInfo("GEAR_BookA", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BookB", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookC", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookD", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookE", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookF", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookG", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookI", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookH", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookBopen", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookHopen", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookEopen", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_BookManual", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}", true); + AddItemInfo("GEAR_CattailTinder", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Cloth", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Coal", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_CrowFeather", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Firelog", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_PaperStack", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Hardwood", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Newsprint", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_OldMansBeardHarvested", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_ReclaimedWoodB", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_ReishiMushroom", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_RoseHip", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_ScrapMetal", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Softwood", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Stick", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Tinder", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BarkTinder", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BearHide", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_BearHideDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BirchSapling", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_BirchSaplingDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Gut", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_GutDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_Leather", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_LeatherDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_LeatherHide", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_LeatherHideDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_MapleSapling", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_MapleSaplingDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_RabbitPelt", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_RabbitPeltDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_WolfPelt", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_WolfPeltDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_MooseHide", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}, ""EvolveItem"": {}}"); + AddItemInfo("GEAR_MooseHideDried", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_ScrapLead", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_StumpRemover", ItemCategory.Materials, @"{}"); + AddItemInfo("GEAR_DustingSulfur", ItemCategory.Materials, @"{}"); + + // Books + AddItemInfo("GEAR_BookCarcassHarvesting", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookCooking", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookFireStarting", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookIceFishing", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookRifleFirearm", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookRifleFirearmAdvanced", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookArchery", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookMending", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookRevolverFirearm", ItemCategory.Books, @"{""ResearchItem"": {}}"); + AddItemInfo("GEAR_BookGunsmithing", ItemCategory.Books, @"{""ResearchItem"": {}}"); + + // Collectible + AddItemInfo("GEAR_CanneryCodeNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CanneryMemo", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CannerySurvivalPath", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ClimbersJournal", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForestTalkerThankyou", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForestTalkerThankyou2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonDepositBoxKey2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForgeBlueprints", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonDepositBoxKey3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForestTalkerFlyer", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HankJournal2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_FarmerDepositBoxKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BrokenRifle", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonDepositBoxKey1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BankManagerHouseKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForestTalkerHiddenItem", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_GreyMotherPearls", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForestTalkerMap", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CaveCacheNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_TrailerSupplies", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_OldLadyStolenItem", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LetterBundle", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_GreyMotherTrunkKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HankNeiceLetter", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BearEar", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HankHatchCode", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ChurchHymn", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ChurchNoteEP1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamControlRoomCodeNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamOfficeKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EmergencyKitNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HardCase", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MedicalSupplies", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MountainTownFarmKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MountainTownFarmNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MountainTownLockBoxKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_UtilitiesBill", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_WaterTowerNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_FixedRifle", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BankVaultCode", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BackerNote1C", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_DamFenceKey", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_AuroraHatchCode", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeCarterDam", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeCollapse1", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeCollapse2", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeCollapse3", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeCollapse4", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_MiltonGardenCache", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeMysteryLake", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_KnowledgeMilton", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_GMExtraSuppliesNote", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_RadioParts", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_TransponderParts", ItemCategory.Collectible, @"{}", true); + AddItemInfo("GEAR_SurvivalSchoolClothing", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_SurvivalSchoolDeerHunt", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_SurvivalSchoolFishing", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_SurvivalSchoolPlants", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_SurvivalSchoolRabbits", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_SurvivalSchoolWolfHunt", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeIncidentNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeTrailerKey1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CacheNote_ChurchMarshDir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HC_EP1_RW_RavineEnd_Dir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HC_EP1_ML_AlansCave_Dir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HC_EP1_ML_ClearCut_Dir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HC_EP1_FM_TreeRoots_Dir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HC_EP1_ML_TracksEnt_Dir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HC_EP1_RW_HunterLodge_Dir", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_AuroraObservationNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CampOfficeCollectible", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ConvictCorpseNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamCollectible1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamElevatorNotice", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamGarbageLetter", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamLockerKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_DamTrailerBCrewNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_ForestTalkerDamNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HankJournal1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_HankLockboxKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeCabinKey1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeCabinKey2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeCabinKey3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeDeerHuntNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LakeLetter1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_LilyClimbMap", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonCaveLetter", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonFlareGunNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonLetter1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonLetter2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonPostOfficeCollectible1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_MiltonStoreNotice", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_NoteMCU", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PrisonBusNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BlackrockConvictNote1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BlackrockConvictNote2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BlackrockConvictNote3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BlackrockMemo", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BookTallTalesFishing", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BookTallTalesGlowCave", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BookTallTalesStag", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_BookTallTalesYeti", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3_ChurchArtifact", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3_ChurchFlyer", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3_ChurchMotelLetter", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3_ChurchNewsClipping", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3_ChurchThankyouLetter", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3_ChurchTheftReport", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_JoplinBunkerNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_JoplinBunkerNote2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_JoplinCacheNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3ForestTalkers_FTCollectible1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3ForestTalkers_PVCollectible1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3ForestTalkers_PVCollectible2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3ForestTalkers_FTCollectible2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3ForestTalkers_PVCollectible3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3ForestTalkers_FTCollectible3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3HallFlyer", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3Rosary", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_Ep3TomsMap", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_KnowledgePVbook1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_KnowledgePVbook2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_KnowledgePVbook3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PassengerManifest", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID1", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID2", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID3", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID4", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID5", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID6", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID7", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID8", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID9", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PlaneCrashID10", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_RuralRegionFarmKey", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_PatientHistory01", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_PatientHistory02", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_PatientHistory03", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_PatientHistory04", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_PatientHistory05", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_EP3_PatientHistory06", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CanyonClimbersCaveNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CanyonDeadClimberNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CanyonFishingHutJournal", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_CanyonMinersNote", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_AC_CentralSpire", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_AC_TopShelf", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_BI_EchoOne-RadioTower", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_CR_AbandonedLookout", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_FM_ShortwaveTower", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_FM_MuskegOverlook", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_ML_ForestryLookout", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_ML_LakeOverlook", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_MT_RadioTower", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_PV_SignalHill", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_RV_Pensive", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_TM_AndresPeak", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_PostCard_TM_TailSection", ItemCategory.Collectible, @"{}"); + AddItemInfo("GEAR_TechnicalBackpack", ItemCategory.Collectible, @"{}"); + + + // Hidden + AddItemInfo("GEAR_AccelerantKerosene", ItemCategory.Hidden, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_AccelerantMedium", ItemCategory.Hidden, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_CompressionBandage", ItemCategory.Hidden, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_FishingLine", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_FlintAndSteel", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_LeatherStrips", ItemCategory.Hidden, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_PumpkinPie", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_Shovel", ItemCategory.Hidden, @"{}"); + + + /* + AddItemInfo("GEAR_BloodyHammer", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_AstridBackPack", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_BowString", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_BowWood", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_CollectibleNoteCommonReward", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_CollectibleNoteRareReward", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_DamCodeNote", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_FarmersAlmanac", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_FirstAidManual", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_HikersBackPack", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_HunterJournalPage", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_KnifeScrapMetal_Clean", ItemCategory.Materials, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_MapSnippetMt", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_MapToRailyard", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_Morphine", ItemCategory.Hidden, @"{""StackableItem"": {""m_UnitsProxy"": 1}}"); + AddItemInfo("GEAR_MountainTownMap", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_MountainTownStoreKey", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_OverpassBrochure", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_RicksJournal", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_RifleBlanks", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_RifleBullets", ItemCategory.Hidden, @"{}"); + AddItemInfo("GEAR_ScarfTorn", ItemCategory.Hidden, @"{}"); + */ + } + + } +} diff --git a/src/TldSaveEditor.Core/Helpers/MapDictionary.cs b/src/TldSaveEditor.Core/Helpers/MapDictionary.cs new file mode 100644 index 0000000..6d86780 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/MapDictionary.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Linq; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + // Per-region map metadata. Coordinate transforms are intentionally done with plain doubles + // (no System.Windows.Point) so this stays cross-platform; the client does the pixel<->game + // conversion using the origo / pixelsPerCoordinate exposed here. + public class MapInfo + { + public string inGameName; + public double origoX; + public double origoY; + public int width; + public int height; + public float pixelsPerCoordinate; + public string image; + + // game coords -> map-image pixel coords + public (double X, double Y) ToLayer(double x, double y) + => (x * pixelsPerCoordinate + origoX, y * -pixelsPerCoordinate + origoY); + + // map-image pixel coords -> game coords + public (double X, double Y) ToRegion(double px, double py) + => ((px - origoX) / pixelsPerCoordinate, (py - origoY) / -pixelsPerCoordinate); + } + + public static class MapDictionary + { + private static MapInfo M(double ox, double oy, int w, int h, float ppc, string image) + => new MapInfo { origoX = ox, origoY = oy, width = w, height = h, pixelsPerCoordinate = ppc, image = image }; + + private static readonly Dictionary dict = new Dictionary + { + { "CoastalRegion", M(1441, 1426, 2687, 2065, 0.98541666666f, "CoastalHighwaySF.png") }, + { "LakeRegion", M(343, 2037, 2330, 2330, 0.9999f, "MysteryLakeSF.png") }, + { "WhalingStationRegion", M(94.5, 2018.3, 1434, 1477, 0.98583333333f, "DesolationPointSF.png") }, + { "RuralRegion", M(-58, 2209, 2000, 2245, 0.68233333333f, "PleasantValleySF.png") }, + { "CrashMountainRegion", M(62.5, 2006, 2124, 2349, 0.98476190476f, "TimberwolfMountainSF.png") }, + { "MarshRegion", M(132, 2193, 1988, 2419, 0.937f, "ForlomMuskeg.png") }, + { "RavineTransitionZone", M(1275.5, 543.5, 1538, 958, 0.98538461538f, "RavineSF.png") }, + { "HighwayTransitionZone", M(88, 905.2, 1182, 787, 0.986f, "CrumblingHighwaySF.png") }, + { "TracksRegion", M(308, 1746, 1763, 2007, 0.9385f, "BrokenRailRoadSF.png") }, + { "RiverValleyRegion", M(99.18, 1832, 1968, 2092, 0.9385f, "HushedRiverValleySF.png") }, + { "MountainTownRegion", M(38.15, 2380, 2156, 2606, 0.9385f, "MountainTownSF.png") }, + { "CanneryRegion", M(1399, 1401, 2500, 2602, 1.0f, "CanneryRegion.png") }, + { "AshCanyonRegion", M(1133.7, 1118, 2274, 2655, 1.0f, "AshCanyonRegion.png") }, + }; + + public static List MapNames => dict.Keys.ToList(); + + public static MapInfo GetMapInfo(string mapName) => dict[mapName]; + + public static bool MapExists(string region) => region != null && dict.ContainsKey(region); + + public static string GetInGameName(string region) + => Properties.Resources.ResourceManager.GetString(region) ?? region; + } +} diff --git a/src/TldSaveEditor.Core/Helpers/Util.cs b/src/TldSaveEditor.Core/Helpers/Util.cs new file mode 100644 index 0000000..a87a036 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/Util.cs @@ -0,0 +1,158 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using The_Long_Dark_Save_Editor_2.Game_data; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + + public class SlotDataDisplayNameProxy + { + public string m_DisplayName { get; set; } + } + + public static class Util + { + public static T DeserializeObject(string json) where T : class + { + + if (json == null) + return null; + + return JsonConvert.DeserializeObject(json); + } + + public static T DeserializeObjectOrDefault(string json) where T : class, new() + { + if (json == null) + return new T(); + return JsonConvert.DeserializeObject(json); + } + + public static string SerializeObject(object o) + { + if (o == null) + return null; + return JsonConvert.SerializeObject(o); + } + + public static ObservableCollection GetSaveFiles(string folder) + { + + Regex reg = new Regex("^(ep[0-9])?(sandbox|challenge|story|relentless)[0-9]+$"); + var saves = new List(); + if (Directory.Exists(folder)) + saves.AddRange((from f in Directory.GetFiles(folder) orderby new FileInfo(f).LastWriteTime descending where reg.IsMatch(Path.GetFileName(f)) select f).ToList()); + + var result = new ObservableCollection(); + foreach (string saveFile in saves) + { + try + { + var member = CreateSaveEnumerationMember(saveFile, Path.GetFileName(saveFile)); + result.Add(member); + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + continue; + } + } + + return result; + } + + private static EnumerationMember CreateSaveEnumerationMember(string file, string name) + { + var member = new EnumerationMember(); + member.Value = file; + + var slotJson = EncryptString.Decompress(File.ReadAllBytes(file)); + var slotData = JsonConvert.DeserializeObject(slotJson); + + member.Description = slotData.m_DisplayName + " (" + name + ")"; + + return member; + } + + // The Long Dark's Steam app id, used to locate the Proton prefix on Linux. + private const string TldSteamAppId = "305620"; + + // Returns the directory that contains "Hinterland/TheLongDark/Survival". + // On Windows that is %LOCALAPPDATA% (AppData\Local). On Linux the game runs through + // Proton, so the same files live inside the Steam compatibility prefix. macOS keeps + // them under ~/Library/Application Support. + public static string GetLocalPath() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + return Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "Library", "Application Support"); + + // Linux: look for the Proton prefix's drive_c/users/steamuser/AppData/Local. + var candidates = GetLinuxProtonLocalAppDataCandidates().ToList(); + return candidates.FirstOrDefault(Directory.Exists) + ?? candidates.FirstOrDefault() + ?? string.Empty; + } + + private static IEnumerable GetLinuxProtonLocalAppDataCandidates() + { + var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + string customSteam = Environment.GetEnvironmentVariable("STEAM_ROOT") + ?? Environment.GetEnvironmentVariable("STEAM_BASE_FOLDER"); + + var steamRoots = new List(); + if (!string.IsNullOrEmpty(customSteam)) + steamRoots.Add(customSteam); + steamRoots.Add(Path.Combine(home, ".steam", "steam")); + steamRoots.Add(Path.Combine(home, ".local", "share", "Steam")); + steamRoots.Add(Path.Combine(home, ".var", "app", "com.valvesoftware.Steam", ".local", "share", "Steam")); + + var seen = new HashSet(); + foreach (var root in steamRoots) + { + foreach (var libRoot in EnumerateSteamLibraryRoots(root)) + { + var compat = Path.Combine(libRoot, "steamapps", "compatdata", TldSteamAppId, + "pfx", "drive_c", "users", "steamuser", "AppData", "Local"); + if (seen.Add(compat)) + yield return compat; + } + } + } + + // Yields a Steam install root plus any extra library folders declared in libraryfolders.vdf. + private static IEnumerable EnumerateSteamLibraryRoots(string steamRoot) + { + yield return steamRoot; + + string vdf = Path.Combine(steamRoot, "steamapps", "libraryfolders.vdf"); + if (!File.Exists(vdf)) + yield break; + + string content = null; + try { content = File.ReadAllText(vdf); } + catch { /* unreadable library index – ignore */ } + if (content == null) + yield break; + + // Match "path" "/some/library/folder" entries (Steam escapes backslashes). + foreach (Match m in Regex.Matches(content, "\"path\"\\s*\"([^\"]+)\"")) + { + var path = m.Groups[1].Value.Replace("\\\\", "/"); + if (!string.IsNullOrEmpty(path)) + yield return path; + } + } + } +} diff --git a/src/TldSaveEditor.Core/Helpers/VersionData.cs b/src/TldSaveEditor.Core/Helpers/VersionData.cs new file mode 100644 index 0000000..864b539 --- /dev/null +++ b/src/TldSaveEditor.Core/Helpers/VersionData.cs @@ -0,0 +1,49 @@ +using System; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + public class VersionData + { + public string version { get; set; } + public string url { get; set; } + public string changes { get; set; } + + public static bool operator <(VersionData v1, VersionData v2) + { + return CompareTo(v1, v2) < 0; + } + + public static bool operator >(VersionData v1, VersionData v2) + { + return CompareTo(v1, v2) > 0; + } + + public static int CompareTo(VersionData v1, VersionData v2) + { + string[] s1 = v1.version.Split('.'); + string[] s2 = v2.version.Split('.'); + + int major1 = Int32.Parse(s1[0]); + int major2 = Int32.Parse(s2[0]); + if (major1 > major2) return 1; + if (major1 < major2) return -1; + + int minor1 = Int32.Parse(s1[1]); + int minor2 = Int32.Parse(s2[1]); + if (minor1 > minor2) return 1; + if (minor1 < minor2) return -1; + + int patch1 = s1.Length >= 3 ? Int32.Parse(s1[2]) : 0; + int patch2 = s2.Length >= 3 ? Int32.Parse(s2[2]) : 0; + if (patch1 > patch2) return 1; + if (patch1 < patch2) return -1; + + return 0; + } + + public override string ToString() + { + return version; + } + } +} diff --git a/src/TldSaveEditor.Core/Profile.cs b/src/TldSaveEditor.Core/Profile.cs new file mode 100644 index 0000000..3984e82 --- /dev/null +++ b/src/TldSaveEditor.Core/Profile.cs @@ -0,0 +1,53 @@ +using System.IO; +using System.Text.RegularExpressions; +using The_Long_Dark_Save_Editor_2.Game_data; +using The_Long_Dark_Save_Editor_2.Helpers; +using The_Long_Dark_Save_Editor_2.Serialization; + +namespace The_Long_Dark_Save_Editor_2 +{ + public class Profile + { + public string path; + + private DynamicSerializable dynamicState; + public ProfileState State { get { return dynamicState.Obj; } } + + public Profile(string path) + { + this.path = path; + + var json = EncryptString.Decompress(File.ReadAllBytes(path)); + + // m_StatsDictionary is invalid json (unquoted keys), so fix it + json = Regex.Replace(json, @"(\\*\""m_StatsDictionary\\*\"":\{)((?:[-0-9\.]+:\\*\""[-+0-9eE\.]+\\*\""\,?)+)(\})", delegate (Match match) + { + string jsonSubStr = Regex.Replace(match.Groups[2].ToString(), @"([-0-9]+):(\\*\"")", delegate (Match matchSub) + { + var escapeStr = matchSub.Groups[2].ToString(); + return escapeStr + matchSub.Groups[1].ToString() + escapeStr + @":" + escapeStr; + }); + return match.Groups[1].ToString() + jsonSubStr + match.Groups[3].ToString(); + }); + + dynamicState = new DynamicSerializable(json); + } + + public void Save() + { + string json = dynamicState.Serialize(); + + // Game cannot read valid json for m_StatsDictionary so remove quotes from keys + json = Regex.Replace(json, @"(\\*\""m_StatsDictionary\\*\"":\{)((?:\\*\""[-0-9\.]+\\*\"":\\*\""[-+0-9eE\.]+\\*\""\,?)+)(\})", delegate (Match match) + { + string jsonSubStr = Regex.Replace(match.Groups[2].ToString(), @"\\*\""([-0-9]+)\\*\"":", delegate (Match matchSub) + { + return matchSub.Groups[1].ToString() + @":"; + }); + return match.Groups[1].ToString() + jsonSubStr + match.Groups[3].ToString(); + }); + + File.WriteAllBytes(path, EncryptString.Compress(json)); + } + } +} diff --git a/src/TldSaveEditor.Core/Properties/Resources.Designer.cs b/src/TldSaveEditor.Core/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a0052cb --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.Designer.cs @@ -0,0 +1,5571 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace The_Long_Dark_Save_Editor_2.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("The_Long_Dark_Save_Editor_2.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to About. + /// + public static string About { + get { + return ResourceManager.GetString("About", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cure. + /// + public static string ActionCure { + get { + return ResourceManager.GetString("ActionCure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add item. + /// + public static string AddItem { + get { + return ResourceManager.GetString("AddItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Afflictions. + /// + public static string Afflictions { + get { + return ResourceManager.GetString("Afflictions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood loss. + /// + public static string AfflictionType_BloodLoss { + get { + return ResourceManager.GetString("AfflictionType_BloodLoss", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Burns. + /// + public static string AfflictionType_Burns { + get { + return ResourceManager.GetString("AfflictionType_Burns", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Electric burns. + /// + public static string AfflictionType_BurnsElectric { + get { + return ResourceManager.GetString("AfflictionType_BurnsElectric", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cabin fever. + /// + public static string AfflictionType_CabinFever { + get { + return ResourceManager.GetString("AfflictionType_CabinFever", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cabin fever risk. + /// + public static string AfflictionType_CabinFeverRisk { + get { + return ResourceManager.GetString("AfflictionType_CabinFeverRisk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dysentery. + /// + public static string AfflictionType_Dysentery { + get { + return ResourceManager.GetString("AfflictionType_Dysentery", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Food poisoning. + /// + public static string AfflictionType_FoodPoisioning { + get { + return ResourceManager.GetString("AfflictionType_FoodPoisioning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Frostbite. + /// + public static string AfflictionType_Frostbite { + get { + return ResourceManager.GetString("AfflictionType_Frostbite", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Frostbite damage. + /// + public static string AfflictionType_FrostbiteDamage { + get { + return ResourceManager.GetString("AfflictionType_FrostbiteDamage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Frostbite risk. + /// + public static string AfflictionType_FrostbiteRisk { + get { + return ResourceManager.GetString("AfflictionType_FrostbiteRisk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hypothermia. + /// + public static string AfflictionType_Hypothermia { + get { + return ResourceManager.GetString("AfflictionType_Hypothermia", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hypothermia risk. + /// + public static string AfflictionType_HypothermiaRisk { + get { + return ResourceManager.GetString("AfflictionType_HypothermiaRisk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Improved rest. + /// + public static string AfflictionType_ImprovedRest { + get { + return ResourceManager.GetString("AfflictionType_ImprovedRest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Infection. + /// + public static string AfflictionType_Infection { + get { + return ResourceManager.GetString("AfflictionType_Infection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Infection risk. + /// + public static string AfflictionType_InfectionRisk { + get { + return ResourceManager.GetString("AfflictionType_InfectionRisk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Intestinal parasites. + /// + public static string AfflictionType_IntestinalParasites { + get { + return ResourceManager.GetString("AfflictionType_IntestinalParasites", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Intestinal parasites risk. + /// + public static string AfflictionType_IntestinalParasitesRisk { + get { + return ResourceManager.GetString("AfflictionType_IntestinalParasitesRisk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reduced fatigue. + /// + public static string AfflictionType_ReducedFatigue { + get { + return ResourceManager.GetString("AfflictionType_ReducedFatigue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sprained ankle. + /// + public static string AfflictionType_SprainedAnkle { + get { + return ResourceManager.GetString("AfflictionType_SprainedAnkle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sprained wrist. + /// + public static string AfflictionType_SprainedWrist { + get { + return ResourceManager.GetString("AfflictionType_SprainedWrist", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sprained wrist major. + /// + public static string AfflictionType_SprainedWristMajor { + get { + return ResourceManager.GetString("AfflictionType_SprainedWristMajor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warming up. + /// + public static string AfflictionType_WarmingUp { + get { + return ResourceManager.GetString("AfflictionType_WarmingUp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Amount. + /// + public static string Amount { + get { + return ResourceManager.GetString("Amount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Amount (liters). + /// + public static string AmountLiter { + get { + return ResourceManager.GetString("AmountLiter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Archery skillpoints. + /// + public static string ArcherySP { + get { + return ResourceManager.GetString("ArcherySP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Backups. + /// + public static string Backups { + get { + return ResourceManager.GetString("Backups", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 4 days of night 2019 badges unlocked. + /// + public static string Badges4DON2019CheckBox { + get { + return ResourceManager.GetString("Badges4DON2019CheckBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 4 days of night badges unlocked. + /// + public static string Badges4DONCheckBox { + get { + return ResourceManager.GetString("Badges4DONCheckBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blizzard walker progress. + /// + public static string BlizzardWalkerProgress { + get { + return ResourceManager.GetString("BlizzardWalkerProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Books. + /// + public static string Books { + get { + return ResourceManager.GetString("Books", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book smarts progress. + /// + public static string BookSmartProgress { + get { + return ResourceManager.GetString("BookSmartProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calories. + /// + public static string Calories { + get { + return ResourceManager.GetString("Calories", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cancel. + /// + public static string Cancel { + get { + return ResourceManager.GetString("Cancel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Carcass harvesting skillpoints. + /// + public static string CarcassHarvestingSP { + get { + return ResourceManager.GetString("CarcassHarvestingSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clothing. + /// + public static string Clothing { + get { + return ResourceManager.GetString("Clothing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clothing repairing skillpoints. + /// + public static string ClothingRepairSP { + get { + return ResourceManager.GetString("ClothingRepairSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cold fusion progress. + /// + public static string ColdFusionProgress { + get { + return ResourceManager.GetString("ColdFusionProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Collectible. + /// + public static string Collectible { + get { + return ResourceManager.GetString("Collectible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Condition. + /// + public static string Condition { + get { + return ResourceManager.GetString("Condition", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cooking skillpoints. + /// + public static string CookingSP { + get { + return ResourceManager.GetString("CookingSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current calories. + /// + public static string CurrentCalories { + get { + return ResourceManager.GetString("CurrentCalories", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Download. + /// + public static string Download { + get { + return ResourceManager.GetString("Download", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Efficient machine progress. + /// + public static string EfficientMachineProgress { + get { + return ResourceManager.GetString("EfficientMachineProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Experience mode. + /// + public static string ExperienceMode { + get { + return ResourceManager.GetString("ExperienceMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Challenge Archivist. + /// + public static string ExperienceModeType_ChallengeArchivist { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeArchivist", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to As the Dead Sleep. + /// + public static string ExperienceModeType_ChallengeDeadManWalking { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeDeadManWalking", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Hunted. + /// + public static string ExperienceModeType_ChallengeHunted { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeHunted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Hunted, Part 2. + /// + public static string ExperienceModeType_ChallengeHuntedPart2 { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeHuntedPart2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Nomad. + /// + public static string ExperienceModeType_ChallengeNomad { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeNomad", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hopeless Rescue. + /// + public static string ExperienceModeType_ChallengeRescue { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeRescue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whiteout. + /// + public static string ExperienceModeType_ChallengeWhiteout { + get { + return ResourceManager.GetString("ExperienceModeType_ChallengeWhiteout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom. + /// + public static string ExperienceModeType_Custom { + get { + return ResourceManager.GetString("ExperienceModeType_Custom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Four Days Of Night. + /// + public static string ExperienceModeType_FourDaysOfNight { + get { + return ResourceManager.GetString("ExperienceModeType_FourDaysOfNight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Interloper. + /// + public static string ExperienceModeType_Interloper { + get { + return ResourceManager.GetString("ExperienceModeType_Interloper", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pilgrim. + /// + public static string ExperienceModeType_Pilgrim { + get { + return ResourceManager.GetString("ExperienceModeType_Pilgrim", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stalker. + /// + public static string ExperienceModeType_Stalker { + get { + return ResourceManager.GetString("ExperienceModeType_Stalker", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Story. + /// + public static string ExperienceModeType_Story { + get { + return ResourceManager.GetString("ExperienceModeType_Story", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Story Fresh. + /// + public static string ExperienceModeType_StoryFresh { + get { + return ResourceManager.GetString("ExperienceModeType_StoryFresh", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Story Hardened. + /// + public static string ExperienceModeType_StoryHardened { + get { + return ResourceManager.GetString("ExperienceModeType_StoryHardened", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Voyageur. + /// + public static string ExperienceModeType_Voyageur { + get { + return ResourceManager.GetString("ExperienceModeType_Voyageur", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Expert trapper progress. + /// + public static string ExpertTrapperProgress { + get { + return ResourceManager.GetString("ExpertTrapperProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fatigue. + /// + public static string Fatigue { + get { + return ResourceManager.GetString("Fatigue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fire master progress. + /// + public static string FireMasterProgress { + get { + return ResourceManager.GetString("FireMasterProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fire starting skillpoints. + /// + public static string FireStartingSP { + get { + return ResourceManager.GetString("FireStartingSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Aid. + /// + public static string FirstAid { + get { + return ResourceManager.GetString("FirstAid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Food. + /// + public static string Food { + get { + return ResourceManager.GetString("Food", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Free runner progress. + /// + public static string FreeRunnerProgress { + get { + return ResourceManager.GetString("FreeRunnerProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Freezing. + /// + public static string Freezing { + get { + return ResourceManager.GetString("Freezing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Accelerant. + /// + public static string GEAR_Accelerant { + get { + return ResourceManager.GetString("GEAR_Accelerant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Accelerant. + /// + public static string GEAR_AccelerantKerosene { + get { + return ResourceManager.GetString("GEAR_AccelerantKerosene", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Accelerant. + /// + public static string GEAR_AccelerantMedium { + get { + return ResourceManager.GetString("GEAR_AccelerantMedium", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Airline Food - Chicken. + /// + public static string GEAR_AirlineFoodChick { + get { + return ResourceManager.GetString("GEAR_AirlineFoodChick", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Airline Food - Vegetarian. + /// + public static string GEAR_AirlineFoodVeg { + get { + return ResourceManager.GetString("GEAR_AirlineFoodVeg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Simple Arrow. + /// + public static string GEAR_Arrow { + get { + return ResourceManager.GetString("GEAR_Arrow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Arrowhead. + /// + public static string GEAR_ArrowHead { + get { + return ResourceManager.GetString("GEAR_ArrowHead", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Arrow Shaft. + /// + public static string GEAR_ArrowShaft { + get { + return ResourceManager.GetString("GEAR_ArrowShaft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Backpack. + /// + public static string GEAR_AstridBackPack { + get { + return ResourceManager.GetString("GEAR_AstridBackPack", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Backpack. + /// + public static string GEAR_AstridBackPack_hangar { + get { + return ResourceManager.GetString("GEAR_AstridBackPack_hangar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Boots. + /// + public static string GEAR_AstridBoots { + get { + return ResourceManager.GetString("GEAR_AstridBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Gloves. + /// + public static string GEAR_AstridGloves { + get { + return ResourceManager.GetString("GEAR_AstridGloves", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Jacket. + /// + public static string GEAR_AstridJacket { + get { + return ResourceManager.GetString("GEAR_AstridJacket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Jeans. + /// + public static string GEAR_AstridJeans { + get { + return ResourceManager.GetString("GEAR_AstridJeans", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Sweater. + /// + public static string GEAR_AstridSweater { + get { + return ResourceManager.GetString("GEAR_AstridSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid Toque. + /// + public static string GEAR_AstridToque { + get { + return ResourceManager.GetString("GEAR_AstridToque", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Aurora Hatch Door Entry Code. + /// + public static string GEAR_AuroraHatchCode { + get { + return ResourceManager.GetString("GEAR_AuroraHatchCode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Aurora Observation. + /// + public static string GEAR_AuroraObservationNote { + get { + return ResourceManager.GetString("GEAR_AuroraObservationNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Note Left Behind. + /// + public static string GEAR_BackerNote1C { + get { + return ResourceManager.GetString("GEAR_BackerNote1C", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Balaclava. + /// + public static string GEAR_Balaclava { + get { + return ResourceManager.GetString("GEAR_Balaclava", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bank Manager's House Key. + /// + public static string GEAR_BankManagerHouseKey { + get { + return ResourceManager.GetString("GEAR_BankManagerHouseKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bank Vault Code. + /// + public static string GEAR_BankVaultCode { + get { + return ResourceManager.GetString("GEAR_BankVaultCode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Birch Bark. + /// + public static string GEAR_BarkTinder { + get { + return ResourceManager.GetString("GEAR_BarkTinder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Baseball Cap. + /// + public static string GEAR_BaseballCap { + get { + return ResourceManager.GetString("GEAR_BaseballCap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trail Boots. + /// + public static string GEAR_BasicBoots { + get { + return ResourceManager.GetString("GEAR_BasicBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Driving Gloves. + /// + public static string GEAR_BasicGloves { + get { + return ResourceManager.GetString("GEAR_BasicGloves", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Running Shoes. + /// + public static string GEAR_BasicShoes { + get { + return ResourceManager.GetString("GEAR_BasicShoes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Windbreaker. + /// + public static string GEAR_BasicWinterCoat { + get { + return ResourceManager.GetString("GEAR_BasicWinterCoat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cotton Toque. + /// + public static string GEAR_BasicWoolHat { + get { + return ResourceManager.GetString("GEAR_BasicWoolHat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Scarf. + /// + public static string GEAR_BasicWoolScarf { + get { + return ResourceManager.GetString("GEAR_BasicWoolScarf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Old Bear's Ear. + /// + public static string GEAR_BearEar { + get { + return ResourceManager.GetString("GEAR_BearEar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Black Bear Hide. + /// + public static string GEAR_BearHide { + get { + return ResourceManager.GetString("GEAR_BearHide", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Black Bear Hide. + /// + public static string GEAR_BearHideDried { + get { + return ResourceManager.GetString("GEAR_BearHideDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bear Quarter. + /// + public static string GEAR_BearQuarter { + get { + return ResourceManager.GetString("GEAR_BearQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bear Skin Bedroll. + /// + public static string GEAR_BearSkinBedRoll { + get { + return ResourceManager.GetString("GEAR_BearSkinBedRoll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bearskin Coat. + /// + public static string GEAR_BearSkinCoat { + get { + return ResourceManager.GetString("GEAR_BearSkinCoat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bear Spear. + /// + public static string GEAR_BearSpear { + get { + return ResourceManager.GetString("GEAR_BearSpear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Broken Bear Spear. + /// + public static string GEAR_BearSpearBroken { + get { + return ResourceManager.GetString("GEAR_BearSpearBroken", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Broken Bear Spear. + /// + public static string GEAR_BearSpearBrokenStory { + get { + return ResourceManager.GetString("GEAR_BearSpearBrokenStory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bear Spear. + /// + public static string GEAR_BearSpearStory { + get { + return ResourceManager.GetString("GEAR_BearSpearStory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bedroll. + /// + public static string GEAR_BedRoll { + get { + return ResourceManager.GetString("GEAR_BedRoll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Beef Jerky. + /// + public static string GEAR_BeefJerky { + get { + return ResourceManager.GetString("GEAR_BeefJerky", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prepared Birch Bark . + /// + public static string GEAR_BirchbarkPrepared { + get { + return ResourceManager.GetString("GEAR_BirchbarkPrepared", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Birch Bark Tea. + /// + public static string GEAR_BirchbarkTea { + get { + return ResourceManager.GetString("GEAR_BirchbarkTea", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Green Birch Sapling. + /// + public static string GEAR_BirchSapling { + get { + return ResourceManager.GetString("GEAR_BirchSapling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Birch Sapling. + /// + public static string GEAR_BirchSaplingDried { + get { + return ResourceManager.GetString("GEAR_BirchSaplingDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Stained-Convict Note. + /// + public static string GEAR_BlackrockConvictNote1 { + get { + return ResourceManager.GetString("GEAR_BlackrockConvictNote1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Convict Note. + /// + public static string GEAR_BlackrockConvictNote2 { + get { + return ResourceManager.GetString("GEAR_BlackrockConvictNote2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Convict Cache Directions. + /// + public static string GEAR_BlackrockConvictNote3 { + get { + return ResourceManager.GetString("GEAR_BlackrockConvictNote3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blackrock Penitentiary Memo. + /// + public static string GEAR_BlackrockMemo { + get { + return ResourceManager.GetString("GEAR_BlackrockMemo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bloody Hammer. + /// + public static string GEAR_BloodyHammer { + get { + return ResourceManager.GetString("GEAR_BloodyHammer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Marine Flare. + /// + public static string GEAR_BlueFlare { + get { + return ResourceManager.GetString("GEAR_BlueFlare", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bolt Cutters. + /// + public static string GEAR_BoltCutters { + get { + return ResourceManager.GetString("GEAR_BoltCutters", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookA { + get { + return ResourceManager.GetString("GEAR_BookA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stay On Target. + /// + public static string GEAR_BookArchery { + get { + return ResourceManager.GetString("GEAR_BookArchery", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookB { + get { + return ResourceManager.GetString("GEAR_BookB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookBopen { + get { + return ResourceManager.GetString("GEAR_BookBopen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookC { + get { + return ResourceManager.GetString("GEAR_BookC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Field Dressing Your Kill, Vol. I. + /// + public static string GEAR_BookCarcassHarvesting { + get { + return ResourceManager.GetString("GEAR_BookCarcassHarvesting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wilderness Kitchen. + /// + public static string GEAR_BookCooking { + get { + return ResourceManager.GetString("GEAR_BookCooking", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookD { + get { + return ResourceManager.GetString("GEAR_BookD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookE { + get { + return ResourceManager.GetString("GEAR_BookE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookEopen { + get { + return ResourceManager.GetString("GEAR_BookEopen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookF { + get { + return ResourceManager.GetString("GEAR_BookF", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Survive the Outdoors!. + /// + public static string GEAR_BookFireStarting { + get { + return ResourceManager.GetString("GEAR_BookFireStarting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookFopen { + get { + return ResourceManager.GetString("GEAR_BookFopen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookG { + get { + return ResourceManager.GetString("GEAR_BookG", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Practical Gunsmithing. + /// + public static string GEAR_BookGunsmithing { + get { + return ResourceManager.GetString("GEAR_BookGunsmithing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookH { + get { + return ResourceManager.GetString("GEAR_BookH", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookHopen { + get { + return ResourceManager.GetString("GEAR_BookHopen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookI { + get { + return ResourceManager.GetString("GEAR_BookI", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Frozen Angler. + /// + public static string GEAR_BookIceFishing { + get { + return ResourceManager.GetString("GEAR_BookIceFishing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Book. + /// + public static string GEAR_BookManual { + get { + return ResourceManager.GetString("GEAR_BookManual", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Sewing Primer. + /// + public static string GEAR_BookMending { + get { + return ResourceManager.GetString("GEAR_BookMending", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Small Arms Handbook. + /// + public static string GEAR_BookRevolverFirearm { + get { + return ResourceManager.GetString("GEAR_BookRevolverFirearm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Frontier Shooting Guide. + /// + public static string GEAR_BookRifleFirearm { + get { + return ResourceManager.GetString("GEAR_BookRifleFirearm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Advanced Guns Guns Guns!. + /// + public static string GEAR_BookRifleFirearmAdvanced { + get { + return ResourceManager.GetString("GEAR_BookRifleFirearmAdvanced", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Local Legends - The Big One. + /// + public static string GEAR_BookTallTalesFishing { + get { + return ResourceManager.GetString("GEAR_BookTallTalesFishing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Local Legends -The Lost Cave. + /// + public static string GEAR_BookTallTalesGlowCave { + get { + return ResourceManager.GetString("GEAR_BookTallTalesGlowCave", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Local Legends - Ghost Stag. + /// + public static string GEAR_BookTallTalesStag { + get { + return ResourceManager.GetString("GEAR_BookTallTalesStag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Local Legends - Sasquatch. + /// + public static string GEAR_BookTallTalesYeti { + get { + return ResourceManager.GetString("GEAR_BookTallTalesYeti", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Antibiotics. + /// + public static string GEAR_BottleAntibiotics { + get { + return ResourceManager.GetString("GEAR_BottleAntibiotics", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Antiseptic. + /// + public static string GEAR_BottleHydrogenPeroxide { + get { + return ResourceManager.GetString("GEAR_BottleHydrogenPeroxide", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Painkillers. + /// + public static string GEAR_BottlePainKillers { + get { + return ResourceManager.GetString("GEAR_BottlePainKillers", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Survival Bow. + /// + public static string GEAR_Bow { + get { + return ResourceManager.GetString("GEAR_Bow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bow String. + /// + public static string GEAR_BowString { + get { + return ResourceManager.GetString("GEAR_BowString", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bow Wood. + /// + public static string GEAR_BowWood { + get { + return ResourceManager.GetString("GEAR_BowWood", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Brand. + /// + public static string GEAR_Brand { + get { + return ResourceManager.GetString("GEAR_Brand", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Broken Arrow. + /// + public static string GEAR_BrokenArrow { + get { + return ResourceManager.GetString("GEAR_BrokenArrow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jeremiah's Broken Rifle. + /// + public static string GEAR_BrokenRifle { + get { + return ResourceManager.GetString("GEAR_BrokenRifle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bullet. + /// + public static string GEAR_Bullet { + get { + return ResourceManager.GetString("GEAR_Bullet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Milton Hidden Cache Note. + /// + public static string GEAR_CacheNote_ChurchMarshDir { + get { + return ResourceManager.GetString("GEAR_CacheNote_ChurchMarshDir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Park Notice. + /// + public static string GEAR_CampOfficeCollectible { + get { + return ResourceManager.GetString("GEAR_CampOfficeCollectible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Candy Bar. + /// + public static string GEAR_CandyBar { + get { + return ResourceManager.GetString("GEAR_CandyBar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pork and Beans. + /// + public static string GEAR_CannedBeans { + get { + return ResourceManager.GetString("GEAR_CannedBeans", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tin of Sardines. + /// + public static string GEAR_CannedSardines { + get { + return ResourceManager.GetString("GEAR_CannedSardines", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Communication Report. + /// + public static string GEAR_CanneryCodeNote { + get { + return ResourceManager.GetString("GEAR_CanneryCodeNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannery Memo. + /// + public static string GEAR_CanneryMemo { + get { + return ResourceManager.GetString("GEAR_CanneryMemo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Technician's Notebook. + /// + public static string GEAR_CannerySurvivalPath { + get { + return ResourceManager.GetString("GEAR_CannerySurvivalPath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can Opener. + /// + public static string GEAR_CanOpener { + get { + return ResourceManager.GetString("GEAR_CanOpener", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ash Canyon Climber's Cave Note. + /// + public static string GEAR_CanyonClimbersCaveNote { + get { + return ResourceManager.GetString("GEAR_CanyonClimbersCaveNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ash Canyon Dead Climber Note. + /// + public static string GEAR_CanyonDeadClimberNote { + get { + return ResourceManager.GetString("GEAR_CanyonDeadClimberNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ash Canyon Fishing Hut Journal. + /// + public static string GEAR_CanyonFishingHutJournal { + get { + return ResourceManager.GetString("GEAR_CanyonFishingHutJournal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ash Canyon Miner's Note. + /// + public static string GEAR_CanyonMinersNote { + get { + return ResourceManager.GetString("GEAR_CanyonMinersNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Car Battery. + /// + public static string GEAR_CarBattery { + get { + return ResourceManager.GetString("GEAR_CarBattery", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cargo Pants. + /// + public static string GEAR_CargoPants { + get { + return ResourceManager.GetString("GEAR_CargoPants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cat Tail Plant. + /// + public static string GEAR_CattailPlant { + get { + return ResourceManager.GetString("GEAR_CattailPlant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cat Tail Stalk. + /// + public static string GEAR_CattailStalk { + get { + return ResourceManager.GetString("GEAR_CattailStalk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cat Tail Head. + /// + public static string GEAR_CattailTinder { + get { + return ResourceManager.GetString("GEAR_CattailTinder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cave Hidden Cache Note. + /// + public static string GEAR_CaveCacheNote { + get { + return ResourceManager.GetString("GEAR_CaveCacheNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Charcoal. + /// + public static string GEAR_Charcoal { + get { + return ResourceManager.GetString("GEAR_Charcoal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Church Hymn. + /// + public static string GEAR_ChurchHymn { + get { + return ResourceManager.GetString("GEAR_ChurchHymn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Church Note EP 1. + /// + public static string GEAR_ChurchNoteEP1 { + get { + return ResourceManager.GetString("GEAR_ChurchNoteEP1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Climber's Journal Page. + /// + public static string GEAR_ClimbersJournal { + get { + return ResourceManager.GetString("GEAR_ClimbersJournal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Climbing Socks. + /// + public static string GEAR_ClimbingSocks { + get { + return ResourceManager.GetString("GEAR_ClimbingSocks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cloth. + /// + public static string GEAR_Cloth { + get { + return ResourceManager.GetString("GEAR_Cloth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Coal. + /// + public static string GEAR_Coal { + get { + return ResourceManager.GetString("GEAR_Coal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cup of Coffee. + /// + public static string GEAR_CoffeeCup { + get { + return ResourceManager.GetString("GEAR_CoffeeCup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tin of Coffee. + /// + public static string GEAR_CoffeeTin { + get { + return ResourceManager.GetString("GEAR_CoffeeTin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Collectible Note Common. + /// + public static string GEAR_CollectibleNoteCommonReward { + get { + return ResourceManager.GetString("GEAR_CollectibleNoteCommonReward", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Collectible Note Rare. + /// + public static string GEAR_CollectibleNoteRareReward { + get { + return ResourceManager.GetString("GEAR_CollectibleNoteRareReward", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Combat Boots. + /// + public static string GEAR_CombatBoots { + get { + return ResourceManager.GetString("GEAR_CombatBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Combat Pants. + /// + public static string GEAR_CombatPants { + get { + return ResourceManager.GetString("GEAR_CombatPants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Compression Bandage. + /// + public static string GEAR_CompressionBandage { + get { + return ResourceManager.GetString("GEAR_CompressionBandage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Condensed Milk. + /// + public static string GEAR_CondensedMilk { + get { + return ResourceManager.GetString("GEAR_CondensedMilk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Convict Journal Entry. + /// + public static string GEAR_ConvictCorpseNote { + get { + return ResourceManager.GetString("GEAR_ConvictCorpseNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Coho Salmon (Cooked). + /// + public static string GEAR_CookedCohoSalmon { + get { + return ResourceManager.GetString("GEAR_CookedCohoSalmon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lake Whitefish (Cooked). + /// + public static string GEAR_CookedLakeWhiteFish { + get { + return ResourceManager.GetString("GEAR_CookedLakeWhiteFish", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bear Meat (Cooked). + /// + public static string GEAR_CookedMeatBear { + get { + return ResourceManager.GetString("GEAR_CookedMeatBear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Venison (Cooked). + /// + public static string GEAR_CookedMeatDeer { + get { + return ResourceManager.GetString("GEAR_CookedMeatDeer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moose Meat (Cooked). + /// + public static string GEAR_CookedMeatMoose { + get { + return ResourceManager.GetString("GEAR_CookedMeatMoose", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rabbit (Cooked). + /// + public static string GEAR_CookedMeatRabbit { + get { + return ResourceManager.GetString("GEAR_CookedMeatRabbit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wolf Meat (Cooked). + /// + public static string GEAR_CookedMeatWolf { + get { + return ResourceManager.GetString("GEAR_CookedMeatWolf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rainbow Trout (Cooked). + /// + public static string GEAR_CookedRainbowTrout { + get { + return ResourceManager.GetString("GEAR_CookedRainbowTrout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Smallmouth Bass (Cooked). + /// + public static string GEAR_CookedSmallMouthBass { + get { + return ResourceManager.GetString("GEAR_CookedSmallMouthBass", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cooking Pot. + /// + public static string GEAR_CookingPot { + get { + return ResourceManager.GetString("GEAR_CookingPot", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hoodie. + /// + public static string GEAR_CottonHoodie { + get { + return ResourceManager.GetString("GEAR_CottonHoodie", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cotton Scarf. + /// + public static string GEAR_CottonScarf { + get { + return ResourceManager.GetString("GEAR_CottonScarf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dress Shirt. + /// + public static string GEAR_CottonShirt { + get { + return ResourceManager.GetString("GEAR_CottonShirt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sports Socks. + /// + public static string GEAR_CottonSocks { + get { + return ResourceManager.GetString("GEAR_CottonSocks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sports Socks (Start). + /// + public static string GEAR_CottonSocksStart { + get { + return ResourceManager.GetString("GEAR_CottonSocksStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cowichan Sweater. + /// + public static string GEAR_CowichanSweater { + get { + return ResourceManager.GetString("GEAR_CowichanSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Salty Crackers. + /// + public static string GEAR_Crackers { + get { + return ResourceManager.GetString("GEAR_Crackers", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Crampons. + /// + public static string GEAR_Crampons { + get { + return ResourceManager.GetString("GEAR_Crampons", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Crow Feather. + /// + public static string GEAR_CrowFeather { + get { + return ResourceManager.GetString("GEAR_CrowFeather", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dam Code Note. + /// + public static string GEAR_DamCodeNote { + get { + return ResourceManager.GetString("GEAR_DamCodeNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Carter Hydro Dam - Safety & Shutdown Notice. + /// + public static string GEAR_DamCollectible1 { + get { + return ResourceManager.GetString("GEAR_DamCollectible1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dam Control Room Code. + /// + public static string GEAR_DamControlRoomCodeNote { + get { + return ResourceManager.GetString("GEAR_DamControlRoomCodeNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Elevator Maintenance Notice. + /// + public static string GEAR_DamElevatorNotice { + get { + return ResourceManager.GetString("GEAR_DamElevatorNotice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Carter Hydro Staging Area Gate Key. + /// + public static string GEAR_DamFenceKey { + get { + return ResourceManager.GetString("GEAR_DamFenceKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trash Can Letter. + /// + public static string GEAR_DamGarbageLetter { + get { + return ResourceManager.GetString("GEAR_DamGarbageLetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Aid Station Medical Locker Key. + /// + public static string GEAR_DamLockerKey { + get { + return ResourceManager.GetString("GEAR_DamLockerKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dam Office Key. + /// + public static string GEAR_DamOfficeKey { + get { + return ResourceManager.GetString("GEAR_DamOfficeKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Breyerhouse Winter Crew Warning. + /// + public static string GEAR_DamTrailerBCrewNote { + get { + return ResourceManager.GetString("GEAR_DamTrailerBCrewNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deerskin Boots. + /// + public static string GEAR_DeerSkinBoots { + get { + return ResourceManager.GetString("GEAR_DeerSkinBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deerskin Pants. + /// + public static string GEAR_DeerSkinPants { + get { + return ResourceManager.GetString("GEAR_DeerSkinPants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dog Food. + /// + public static string GEAR_DogFood { + get { + return ResourceManager.GetString("GEAR_DogFood", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Urban Parka. + /// + public static string GEAR_DownParka { + get { + return ResourceManager.GetString("GEAR_DownParka", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ski Jacket. + /// + public static string GEAR_DownSkiJacket { + get { + return ResourceManager.GetString("GEAR_DownSkiJacket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Down Vest. + /// + public static string GEAR_DownVest { + get { + return ResourceManager.GetString("GEAR_DownVest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dusting Sulfur. + /// + public static string GEAR_DustingSulfur { + get { + return ResourceManager.GetString("GEAR_DustingSulfur", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Ear Wrap. + /// + public static string GEAR_EarMuffs { + get { + return ResourceManager.GetString("GEAR_EarMuffs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Emergency Kit Note. + /// + public static string GEAR_EmergencyKitNote { + get { + return ResourceManager.GetString("GEAR_EmergencyKitNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Emergency Stim. + /// + public static string GEAR_EmergencyStim { + get { + return ResourceManager.GetString("GEAR_EmergencyStim", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Energy Bar. + /// + public static string GEAR_EnergyBar { + get { + return ResourceManager.GetString("GEAR_EnergyBar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Church Artifact. + /// + public static string GEAR_Ep3_ChurchArtifact { + get { + return ResourceManager.GetString("GEAR_Ep3_ChurchArtifact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Church Flyer. + /// + public static string GEAR_Ep3_ChurchFlyer { + get { + return ResourceManager.GetString("GEAR_Ep3_ChurchFlyer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Undelivered Letter. + /// + public static string GEAR_Ep3_ChurchMotelLetter { + get { + return ResourceManager.GetString("GEAR_Ep3_ChurchMotelLetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Newspaper Clipping. + /// + public static string GEAR_Ep3_ChurchNewsClipping { + get { + return ResourceManager.GetString("GEAR_Ep3_ChurchNewsClipping", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thankyou Letter. + /// + public static string GEAR_Ep3_ChurchThankyouLetter { + get { + return ResourceManager.GetString("GEAR_Ep3_ChurchThankyouLetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Diocese Report. + /// + public static string GEAR_Ep3_ChurchTheftReport { + get { + return ResourceManager.GetString("GEAR_Ep3_ChurchTheftReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Joplin's Journal, Part One. + /// + public static string GEAR_EP3_JoplinBunkerNote { + get { + return ResourceManager.GetString("GEAR_EP3_JoplinBunkerNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Joplin's Journal, Part Two. + /// + public static string GEAR_EP3_JoplinBunkerNote2 { + get { + return ResourceManager.GetString("GEAR_EP3_JoplinBunkerNote2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Bunker Memo. + /// + public static string GEAR_EP3_JoplinCacheNote { + get { + return ResourceManager.GetString("GEAR_EP3_JoplinCacheNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_EP3_PatientHistory01 { + get { + return ResourceManager.GetString("GEAR_EP3_PatientHistory01", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_EP3_PatientHistory02 { + get { + return ResourceManager.GetString("GEAR_EP3_PatientHistory02", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_EP3_PatientHistory03 { + get { + return ResourceManager.GetString("GEAR_EP3_PatientHistory03", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_EP3_PatientHistory04 { + get { + return ResourceManager.GetString("GEAR_EP3_PatientHistory04", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_EP3_PatientHistory05 { + get { + return ResourceManager.GetString("GEAR_EP3_PatientHistory05", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_EP3_PatientHistory06 { + get { + return ResourceManager.GetString("GEAR_EP3_PatientHistory06", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Collectible, Part One. + /// + public static string GEAR_Ep3ForestTalkers_FTCollectible1 { + get { + return ResourceManager.GetString("GEAR_Ep3ForestTalkers_FTCollectible1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Collectible, Part Two. + /// + public static string GEAR_Ep3ForestTalkers_FTCollectible2 { + get { + return ResourceManager.GetString("GEAR_Ep3ForestTalkers_FTCollectible2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Collectible, Part Three. + /// + public static string GEAR_Ep3ForestTalkers_FTCollectible3 { + get { + return ResourceManager.GetString("GEAR_Ep3ForestTalkers_FTCollectible3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley Collectible, Part One. + /// + public static string GEAR_Ep3ForestTalkers_PVCollectible1 { + get { + return ResourceManager.GetString("GEAR_Ep3ForestTalkers_PVCollectible1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley Collectible, Part Two. + /// + public static string GEAR_Ep3ForestTalkers_PVCollectible2 { + get { + return ResourceManager.GetString("GEAR_Ep3ForestTalkers_PVCollectible2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley Collectible, Part Three. + /// + public static string GEAR_Ep3ForestTalkers_PVCollectible3 { + get { + return ResourceManager.GetString("GEAR_Ep3ForestTalkers_PVCollectible3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Community Hall Flyer. + /// + public static string GEAR_Ep3HallFlyer { + get { + return ResourceManager.GetString("GEAR_Ep3HallFlyer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rosary. + /// + public static string GEAR_Ep3Rosary { + get { + return ResourceManager.GetString("GEAR_Ep3Rosary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Map Of Pleasant Valley. + /// + public static string GEAR_Ep3TomsMap { + get { + return ResourceManager.GetString("GEAR_Ep3TomsMap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bank Deposit Box Key (#15). + /// + public static string GEAR_FarmerDepositBoxKey { + get { + return ResourceManager.GetString("GEAR_FarmerDepositBoxKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Farmer's Almanac. + /// + public static string GEAR_FarmersAlmanac { + get { + return ResourceManager.GetString("GEAR_FarmersAlmanac", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fire Axe. + /// + public static string GEAR_FireAxe { + get { + return ResourceManager.GetString("GEAR_FireAxe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Firelog. + /// + public static string GEAR_Firelog { + get { + return ResourceManager.GetString("GEAR_Firelog", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Firestriker. + /// + public static string GEAR_Firestriker { + get { + return ResourceManager.GetString("GEAR_Firestriker", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Aid Manual. + /// + public static string GEAR_FirstAidManual { + get { + return ResourceManager.GetString("GEAR_FirstAidManual", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fisherman's Sweater. + /// + public static string GEAR_FishermanSweater { + get { + return ResourceManager.GetString("GEAR_FishermanSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Line. + /// + public static string GEAR_FishingLine { + get { + return ResourceManager.GetString("GEAR_FishingLine", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jeremiah's Repaired Rifle. + /// + public static string GEAR_FixedRifle { + get { + return ResourceManager.GetString("GEAR_FixedRifle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Flare. + /// + public static string GEAR_FlareA { + get { + return ResourceManager.GetString("GEAR_FlareA", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Distress Pistol. + /// + public static string GEAR_FlareGun { + get { + return ResourceManager.GetString("GEAR_FlareGun", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Flare Shell. + /// + public static string GEAR_FlareGunAmmoSingle { + get { + return ResourceManager.GetString("GEAR_FlareGunAmmoSingle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Distress Pistol Kit. + /// + public static string GEAR_FlareGunCase_hangar { + get { + return ResourceManager.GetString("GEAR_FlareGunCase_hangar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Flashlight. + /// + public static string GEAR_Flashlight { + get { + return ResourceManager.GetString("GEAR_Flashlight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fleece Mittens. + /// + public static string GEAR_FleeceMittens { + get { + return ResourceManager.GetString("GEAR_FleeceMittens", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sweatshirt. + /// + public static string GEAR_FleeceSweater { + get { + return ResourceManager.GetString("GEAR_FleeceSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Flint & Steel. + /// + public static string GEAR_FlintAndSteel { + get { + return ResourceManager.GetString("GEAR_FlintAndSteel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Emergency Food. + /// + public static string GEAR_FoodSupplies_hangar { + get { + return ResourceManager.GetString("GEAR_FoodSupplies_hangar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Dam Note. + /// + public static string GEAR_ForestTalkerDamNote { + get { + return ResourceManager.GetString("GEAR_ForestTalkerDamNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Flyer. + /// + public static string GEAR_ForestTalkerFlyer { + get { + return ResourceManager.GetString("GEAR_ForestTalkerFlyer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Documents. + /// + public static string GEAR_ForestTalkerHiddenItem { + get { + return ResourceManager.GetString("GEAR_ForestTalkerHiddenItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Map Note. + /// + public static string GEAR_ForestTalkerMap { + get { + return ResourceManager.GetString("GEAR_ForestTalkerMap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Note. + /// + public static string GEAR_ForestTalkerThankyou { + get { + return ResourceManager.GetString("GEAR_ForestTalkerThankyou", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Note. + /// + public static string GEAR_ForestTalkerThankyou2 { + get { + return ResourceManager.GetString("GEAR_ForestTalkerThankyou2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forge Blueprints. + /// + public static string GEAR_ForgeBlueprints { + get { + return ResourceManager.GetString("GEAR_ForgeBlueprints", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Gauntlets. + /// + public static string GEAR_Gauntlets { + get { + return ResourceManager.GetString("GEAR_Gauntlets", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Winter Forecast. + /// + public static string GEAR_GMExtraSuppliesNote { + get { + return ResourceManager.GetString("GEAR_GMExtraSuppliesNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Granola Bar. + /// + public static string GEAR_GranolaBar { + get { + return ResourceManager.GetString("GEAR_GranolaBar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cup of Herbal Tea. + /// + public static string GEAR_GreenTeaCup { + get { + return ResourceManager.GetString("GEAR_GreenTeaCup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Herbal Tea. + /// + public static string GEAR_GreenTeaPackage { + get { + return ResourceManager.GetString("GEAR_GreenTeaPackage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountaineering Boots. + /// + public static string GEAR_GreyMotherBoots { + get { + return ResourceManager.GetString("GEAR_GreyMotherBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Grey Mother's Pearls. + /// + public static string GEAR_GreyMotherPearls { + get { + return ResourceManager.GetString("GEAR_GreyMotherPearls", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lily's Trunk Key. + /// + public static string GEAR_GreyMotherTrunkKey { + get { + return ResourceManager.GetString("GEAR_GreyMotherTrunkKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can of Gunpowder. + /// + public static string GEAR_GunpowderCan { + get { + return ResourceManager.GetString("GEAR_GunpowderCan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Gut. + /// + public static string GEAR_Gut { + get { + return ResourceManager.GetString("GEAR_Gut", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Gut. + /// + public static string GEAR_GutDried { + get { + return ResourceManager.GetString("GEAR_GutDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hacksaw. + /// + public static string GEAR_Hacksaw { + get { + return ResourceManager.GetString("GEAR_Hacksaw", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Heavy Hammer. + /// + public static string GEAR_Hammer { + get { + return ResourceManager.GetString("GEAR_Hammer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hank's Prepper Cache Code. + /// + public static string GEAR_HankHatchCode { + get { + return ResourceManager.GetString("GEAR_HankHatchCode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hank's Journal - Part One. + /// + public static string GEAR_HankJournal1 { + get { + return ResourceManager.GetString("GEAR_HankJournal1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hank's Journal - Part Two. + /// + public static string GEAR_HankJournal2 { + get { + return ResourceManager.GetString("GEAR_HankJournal2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hank's Lock Box Key. + /// + public static string GEAR_HankLockboxKey { + get { + return ResourceManager.GetString("GEAR_HankLockboxKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Letter for Hank's Niece. + /// + public static string GEAR_HankNeiceLetter { + get { + return ResourceManager.GetString("GEAR_HankNeiceLetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Hardcase. + /// + public static string GEAR_HardCase { + get { + return ResourceManager.GetString("GEAR_HardCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Astrid's Hardcase. + /// + public static string GEAR_HardCase_hangar { + get { + return ResourceManager.GetString("GEAR_HardCase_hangar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fir Firewood. + /// + public static string GEAR_Hardwood { + get { + return ResourceManager.GetString("GEAR_Hardwood", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hatchet. + /// + public static string GEAR_Hatchet { + get { + return ResourceManager.GetString("GEAR_Hatchet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Improvised Hatchet. + /// + public static string GEAR_HatchetImprovised { + get { + return ResourceManager.GetString("GEAR_HatchetImprovised", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Charcoal Note. + /// + public static string GEAR_HC_EP1_FM_TreeRoots_Dir { + get { + return ResourceManager.GetString("GEAR_HC_EP1_FM_TreeRoots_Dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Crumpled Note. + /// + public static string GEAR_HC_EP1_ML_AlansCave_Dir { + get { + return ResourceManager.GetString("GEAR_HC_EP1_ML_AlansCave_Dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Simple Note. + /// + public static string GEAR_HC_EP1_ML_ClearCut_Dir { + get { + return ResourceManager.GetString("GEAR_HC_EP1_ML_ClearCut_Dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Illegible Note. + /// + public static string GEAR_HC_EP1_ML_TracksEnt_Dir { + get { + return ResourceManager.GetString("GEAR_HC_EP1_ML_TracksEnt_Dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Handwritten Note. + /// + public static string GEAR_HC_EP1_RW_HunterLodge_Dir { + get { + return ResourceManager.GetString("GEAR_HC_EP1_RW_HunterLodge_Dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Soaked Note. + /// + public static string GEAR_HC_EP1_RW_RavineEnd_Dir { + get { + return ResourceManager.GetString("GEAR_HC_EP1_RW_RavineEnd_Dir", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bandage. + /// + public static string GEAR_HeavyBandage { + get { + return ResourceManager.GetString("GEAR_HeavyBandage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Old Fashioned Parka. + /// + public static string GEAR_HeavyParka { + get { + return ResourceManager.GetString("GEAR_HeavyParka", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thick Wool Sweater. + /// + public static string GEAR_HeavyWoolSweater { + get { + return ResourceManager.GetString("GEAR_HeavyWoolSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Quality Tools. + /// + public static string GEAR_HighQualityTools { + get { + return ResourceManager.GetString("GEAR_HighQualityTools", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hiker's Backpack. + /// + public static string GEAR_HikersBackPack { + get { + return ResourceManager.GetString("GEAR_HikersBackPack", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Home-made Soup. + /// + public static string GEAR_HomeMadeSoup { + get { + return ResourceManager.GetString("GEAR_HomeMadeSoup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hook. + /// + public static string GEAR_Hook { + get { + return ResourceManager.GetString("GEAR_Hook", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fishing Tackle. + /// + public static string GEAR_HookAndLine { + get { + return ResourceManager.GetString("GEAR_HookAndLine", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hunter Journal Page. + /// + public static string GEAR_HunterJournalPage { + get { + return ResourceManager.GetString("GEAR_HunterJournalPage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Improvised Head Wrap. + /// + public static string GEAR_ImprovisedHat { + get { + return ResourceManager.GetString("GEAR_ImprovisedHat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Improvised Hand Wraps. + /// + public static string GEAR_ImprovisedMittens { + get { + return ResourceManager.GetString("GEAR_ImprovisedMittens", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Insulated Boots. + /// + public static string GEAR_InsulatedBoots { + get { + return ResourceManager.GetString("GEAR_InsulatedBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Snow Pants. + /// + public static string GEAR_InsulatedPants { + get { + return ResourceManager.GetString("GEAR_InsulatedPants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sport Vest. + /// + public static string GEAR_InsulatedVest { + get { + return ResourceManager.GetString("GEAR_InsulatedVest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jeans. + /// + public static string GEAR_Jeans { + get { + return ResourceManager.GetString("GEAR_Jeans", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jeremiah's Knife. + /// + public static string GEAR_JeremiahKnife { + get { + return ResourceManager.GetString("GEAR_JeremiahKnife", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jeremiah's Bearskin Coat. + /// + public static string GEAR_JeremiahsCoat { + get { + return ResourceManager.GetString("GEAR_JeremiahsCoat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jerry Can. + /// + public static string GEAR_JerrycanRusty { + get { + return ResourceManager.GetString("GEAR_JerrycanRusty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Storm Lantern. + /// + public static string GEAR_KeroseneLampB { + get { + return ResourceManager.GetString("GEAR_KeroseneLampB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ketchup Chips. + /// + public static string GEAR_KetchupChips { + get { + return ResourceManager.GetString("GEAR_KetchupChips", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hunting Knife. + /// + public static string GEAR_Knife { + get { + return ResourceManager.GetString("GEAR_Knife", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Improvised Knife. + /// + public static string GEAR_KnifeImprovised { + get { + return ResourceManager.GetString("GEAR_KnifeImprovised", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scrap Metal Shard. + /// + public static string GEAR_KnifeScrapMetal { + get { + return ResourceManager.GetString("GEAR_KnifeScrapMetal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Knife Scrap Metal Clean. + /// + public static string GEAR_KnifeScrapMetal_Clean { + get { + return ResourceManager.GetString("GEAR_KnifeScrapMetal_Clean", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Carter Hydro Dam. + /// + public static string GEAR_KnowledgeCarterDam { + get { + return ResourceManager.GetString("GEAR_KnowledgeCarterDam", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History of The Collapse, Part One. + /// + public static string GEAR_KnowledgeCollapse1 { + get { + return ResourceManager.GetString("GEAR_KnowledgeCollapse1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History of The Collapse, Part Two. + /// + public static string GEAR_KnowledgeCollapse2 { + get { + return ResourceManager.GetString("GEAR_KnowledgeCollapse2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History of The Collapse, Part Three. + /// + public static string GEAR_KnowledgeCollapse3 { + get { + return ResourceManager.GetString("GEAR_KnowledgeCollapse3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History of the Collapse, Part Four. + /// + public static string GEAR_KnowledgeCollapse4 { + get { + return ResourceManager.GetString("GEAR_KnowledgeCollapse4", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Town of Milton. + /// + public static string GEAR_KnowledgeMilton { + get { + return ResourceManager.GetString("GEAR_KnowledgeMilton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mystery Lake & Area. + /// + public static string GEAR_KnowledgeMysteryLake { + get { + return ResourceManager.GetString("GEAR_KnowledgeMysteryLake", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley History, Part One. + /// + public static string GEAR_KnowledgePVbook1 { + get { + return ResourceManager.GetString("GEAR_KnowledgePVbook1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley History, Part Two. + /// + public static string GEAR_KnowledgePVbook2 { + get { + return ResourceManager.GetString("GEAR_KnowledgePVbook2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley History, Part Three. + /// + public static string GEAR_KnowledgePVbook3 { + get { + return ResourceManager.GetString("GEAR_KnowledgePVbook3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Key To Lake Cabin #1. + /// + public static string GEAR_LakeCabinKey1 { + get { + return ResourceManager.GetString("GEAR_LakeCabinKey1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Key To Lake Cabin #2. + /// + public static string GEAR_LakeCabinKey2 { + get { + return ResourceManager.GetString("GEAR_LakeCabinKey2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Key To Lake Cabin #3. + /// + public static string GEAR_LakeCabinKey3 { + get { + return ResourceManager.GetString("GEAR_LakeCabinKey3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Torn Paper. + /// + public static string GEAR_LakeDeerHuntNote { + get { + return ResourceManager.GetString("GEAR_LakeDeerHuntNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Crumpled Note. + /// + public static string GEAR_LakeIncidentNote { + get { + return ResourceManager.GetString("GEAR_LakeIncidentNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Off Season Fun. + /// + public static string GEAR_LakeLetter1 { + get { + return ResourceManager.GetString("GEAR_LakeLetter1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Logging Camp Trailer Key. + /// + public static string GEAR_LakeTrailerKey1 { + get { + return ResourceManager.GetString("GEAR_LakeTrailerKey1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lantern Fuel. + /// + public static string GEAR_LampFuel { + get { + return ResourceManager.GetString("GEAR_LampFuel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lantern Fuel. + /// + public static string GEAR_LampFuelFull { + get { + return ResourceManager.GetString("GEAR_LampFuelFull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Leather. + /// + public static string GEAR_Leather { + get { + return ResourceManager.GetString("GEAR_Leather", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Leather. + /// + public static string GEAR_LeatherDried { + get { + return ResourceManager.GetString("GEAR_LeatherDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Deer Hide. + /// + public static string GEAR_LeatherHide { + get { + return ResourceManager.GetString("GEAR_LeatherHide", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Deer Hide. + /// + public static string GEAR_LeatherHideDried { + get { + return ResourceManager.GetString("GEAR_LeatherHideDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Leather Shoes. + /// + public static string GEAR_LeatherShoes { + get { + return ResourceManager.GetString("GEAR_LeatherShoes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Leather. + /// + public static string GEAR_LeatherStrips { + get { + return ResourceManager.GetString("GEAR_LeatherStrips", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jeremiah's Letters. + /// + public static string GEAR_LetterBundle { + get { + return ResourceManager.GetString("GEAR_LetterBundle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Simple Parka. + /// + public static string GEAR_LightParka { + get { + return ResourceManager.GetString("GEAR_LightParka", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lily's Map. + /// + public static string GEAR_LilyClimbMap { + get { + return ResourceManager.GetString("GEAR_LilyClimbMap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Line. + /// + public static string GEAR_Line { + get { + return ResourceManager.GetString("GEAR_Line", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thermal Underwear. + /// + public static string GEAR_LongUnderwear { + get { + return ResourceManager.GetString("GEAR_LongUnderwear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thermal Underwear (Start). + /// + public static string GEAR_LongUnderwearStart { + get { + return ResourceManager.GetString("GEAR_LongUnderwearStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Longjohns. + /// + public static string GEAR_LongUnderwearWool { + get { + return ResourceManager.GetString("GEAR_LongUnderwearWool", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackinaw Jacket. + /// + public static string GEAR_MackinawJacket { + get { + return ResourceManager.GetString("GEAR_MackinawJacket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Magnifying Lens. + /// + public static string GEAR_MagnifyingLens { + get { + return ResourceManager.GetString("GEAR_MagnifyingLens", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Green Maple Sapling. + /// + public static string GEAR_MapleSapling { + get { + return ResourceManager.GetString("GEAR_MapleSapling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Maple Sapling. + /// + public static string GEAR_MapleSaplingDried { + get { + return ResourceManager.GetString("GEAR_MapleSaplingDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Maple Syrup. + /// + public static string GEAR_MapleSyrup { + get { + return ResourceManager.GetString("GEAR_MapleSyrup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Map Snippet Mt. + /// + public static string GEAR_MapSnippetMt { + get { + return ResourceManager.GetString("GEAR_MapSnippetMt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Map To Railyard. + /// + public static string GEAR_MapToRailyard { + get { + return ResourceManager.GetString("GEAR_MapToRailyard", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Carter Hydro Medical Supplies. + /// + public static string GEAR_MedicalSupplies { + get { + return ResourceManager.GetString("GEAR_MedicalSupplies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Aid Kit. + /// + public static string GEAR_MedicalSupplies_hangar { + get { + return ResourceManager.GetString("GEAR_MedicalSupplies_hangar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Military Coat. + /// + public static string GEAR_MilitaryParka { + get { + return ResourceManager.GetString("GEAR_MilitaryParka", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lost In The Storm. + /// + public static string GEAR_MiltonCaveLetter { + get { + return ResourceManager.GetString("GEAR_MiltonCaveLetter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bank Deposit Box Key (#7). + /// + public static string GEAR_MiltonDepositBoxKey1 { + get { + return ResourceManager.GetString("GEAR_MiltonDepositBoxKey1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bank Deposit Box Key (#13). + /// + public static string GEAR_MiltonDepositBoxKey2 { + get { + return ResourceManager.GetString("GEAR_MiltonDepositBoxKey2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bank Deposit Box Key (#20). + /// + public static string GEAR_MiltonDepositBoxKey3 { + get { + return ResourceManager.GetString("GEAR_MiltonDepositBoxKey3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Highway Robbery. + /// + public static string GEAR_MiltonFlareGunNote { + get { + return ResourceManager.GetString("GEAR_MiltonFlareGunNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Medicine in my backyard. + /// + public static string GEAR_MiltonGardenCache { + get { + return ResourceManager.GetString("GEAR_MiltonGardenCache", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tearful Letter. + /// + public static string GEAR_MiltonLetter1 { + get { + return ResourceManager.GetString("GEAR_MiltonLetter1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Betrayal. + /// + public static string GEAR_MiltonLetter2 { + get { + return ResourceManager.GetString("GEAR_MiltonLetter2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Milton Post Office Note. + /// + public static string GEAR_MiltonPostOfficeCollectible1 { + get { + return ResourceManager.GetString("GEAR_MiltonPostOfficeCollectible1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Orca Gas Store Notice. + /// + public static string GEAR_MiltonStoreNotice { + get { + return ResourceManager.GetString("GEAR_MiltonStoreNotice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Mittens. + /// + public static string GEAR_Mittens { + get { + return ResourceManager.GetString("GEAR_Mittens", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Moose Hide. + /// + public static string GEAR_MooseHide { + get { + return ResourceManager.GetString("GEAR_MooseHide", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moose-Hide Satchel. + /// + public static string GEAR_MooseHideBag { + get { + return ResourceManager.GetString("GEAR_MooseHideBag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moose-Hide Cloak. + /// + public static string GEAR_MooseHideCloak { + get { + return ResourceManager.GetString("GEAR_MooseHideCloak", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Moose Hide. + /// + public static string GEAR_MooseHideDried { + get { + return ResourceManager.GetString("GEAR_MooseHideDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moose Quarter. + /// + public static string GEAR_MooseQuarter { + get { + return ResourceManager.GetString("GEAR_MooseQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Morphine. + /// + public static string GEAR_Morphine { + get { + return ResourceManager.GetString("GEAR_Morphine", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Paradise Meadows Farm Key. + /// + public static string GEAR_MountainTownFarmKey { + get { + return ResourceManager.GetString("GEAR_MountainTownFarmKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountain Town Farm Note. + /// + public static string GEAR_MountainTownFarmNote { + get { + return ResourceManager.GetString("GEAR_MountainTownFarmNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountain Town Lock Box Key. + /// + public static string GEAR_MountainTownLockBoxKey { + get { + return ResourceManager.GetString("GEAR_MountainTownLockBoxKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountain Town Map. + /// + public static string GEAR_MountainTownMap { + get { + return ResourceManager.GetString("GEAR_MountainTownMap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountain Town Store Key. + /// + public static string GEAR_MountainTownStoreKey { + get { + return ResourceManager.GetString("GEAR_MountainTownStoreKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Military-Grade MRE. + /// + public static string GEAR_MRE { + get { + return ResourceManager.GetString("GEAR_MRE", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mukluks. + /// + public static string GEAR_MuklukBoots { + get { + return ResourceManager.GetString("GEAR_MuklukBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Newsprint. + /// + public static string GEAR_Newsprint { + get { + return ResourceManager.GetString("GEAR_Newsprint", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Newsprint Roll. + /// + public static string GEAR_NewsprintRoll { + get { + return ResourceManager.GetString("GEAR_NewsprintRoll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Milton Credit Union Letter. + /// + public static string GEAR_NoteMCU { + get { + return ResourceManager.GetString("GEAR_NoteMCU", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Grey Mother's Safety Deposit Box. + /// + public static string GEAR_OldLadyStolenItem { + get { + return ResourceManager.GetString("GEAR_OldLadyStolenItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Old Man's Beard Wound Dressing. + /// + public static string GEAR_OldMansBeardDressing { + get { + return ResourceManager.GetString("GEAR_OldMansBeardDressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Old Man's Beard Lichen. + /// + public static string GEAR_OldMansBeardHarvested { + get { + return ResourceManager.GetString("GEAR_OldMansBeardHarvested", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overpass Brochure. + /// + public static string GEAR_OverpassBrochure { + get { + return ResourceManager.GetString("GEAR_OverpassBrochure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cardboard Matches. + /// + public static string GEAR_PackMatches { + get { + return ResourceManager.GetString("GEAR_PackMatches", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stack of Papers. + /// + public static string GEAR_PaperStack { + get { + return ResourceManager.GetString("GEAR_PaperStack", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Passenger Manifest. + /// + public static string GEAR_PassengerManifest { + get { + return ResourceManager.GetString("GEAR_PassengerManifest", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Peanut Butter. + /// + public static string GEAR_PeanutButter { + get { + return ResourceManager.GetString("GEAR_PeanutButter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pinnacle Peaches. + /// + public static string GEAR_PinnacleCanPeaches { + get { + return ResourceManager.GetString("GEAR_PinnacleCanPeaches", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rabbit Carcass. + /// + public static string GEAR_Placeholder { + get { + return ResourceManager.GetString("GEAR_Placeholder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Plaid Shirt. + /// + public static string GEAR_PlaidShirt { + get { + return ResourceManager.GetString("GEAR_PlaidShirt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: S. Gagne. + /// + public static string GEAR_PlaneCrashID1 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: G. Russel. + /// + public static string GEAR_PlaneCrashID10 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID10", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: K. Morrison. + /// + public static string GEAR_PlaneCrashID2 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: F. Leblanc. + /// + public static string GEAR_PlaneCrashID3 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: D. Belanger. + /// + public static string GEAR_PlaneCrashID4 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID4", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: R. Tan. + /// + public static string GEAR_PlaneCrashID5 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID5", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: V. Singh. + /// + public static string GEAR_PlaneCrashID6 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID6", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: A. Lewis. + /// + public static string GEAR_PlaneCrashID7 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID7", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: T. Chan. + /// + public static string GEAR_PlaneCrashID8 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID8", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ID: O. Gould. + /// + public static string GEAR_PlaneCrashID9 { + get { + return ResourceManager.GetString("GEAR_PlaneCrashID9", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Ash Canyon High Meadow. + /// + public static string GEAR_PostCard_AC_CentralSpire { + get { + return ResourceManager.GetString("GEAR_PostCard_AC_CentralSpire", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Ash Canyon Wolf's Jaw Overlook. + /// + public static string GEAR_PostCard_AC_TopShelf { + get { + return ResourceManager.GetString("GEAR_PostCard_AC_TopShelf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Bleak Inlet Echo One Radio Tower. + /// + public static string GEAR_PostCard_BI_EchoOne_RadioTower { + get { + return ResourceManager.GetString("GEAR_PostCard_BI_EchoOne-RadioTower", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Coastal Highway Abandoned Lookout. + /// + public static string GEAR_PostCard_CR_AbandonedLookout { + get { + return ResourceManager.GetString("GEAR_PostCard_CR_AbandonedLookout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Forlorn Muskeg Muskeg Overlook. + /// + public static string GEAR_PostCard_FM_MuskegOverlook { + get { + return ResourceManager.GetString("GEAR_PostCard_FM_MuskegOverlook", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Forlorn Muskeg Shortwave Tower. + /// + public static string GEAR_PostCard_FM_ShortwaveTower { + get { + return ResourceManager.GetString("GEAR_PostCard_FM_ShortwaveTower", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Mystery Lake Forestry Lookout. + /// + public static string GEAR_PostCard_ML_ForestryLookout { + get { + return ResourceManager.GetString("GEAR_PostCard_ML_ForestryLookout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Mystery Lake Lake Overlook. + /// + public static string GEAR_PostCard_ML_LakeOverlook { + get { + return ResourceManager.GetString("GEAR_PostCard_ML_LakeOverlook", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Mountain Town Radio Tower. + /// + public static string GEAR_PostCard_MT_RadioTower { + get { + return ResourceManager.GetString("GEAR_PostCard_MT_RadioTower", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Pleasant Valley Signal Hill. + /// + public static string GEAR_PostCard_PV_SignalHill { + get { + return ResourceManager.GetString("GEAR_PostCard_PV_SignalHill", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Hushed River Valley Pensive Vista. + /// + public static string GEAR_PostCard_RV_Pensive { + get { + return ResourceManager.GetString("GEAR_PostCard_RV_Pensive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Timberwolf Mountain Andre's Peak. + /// + public static string GEAR_PostCard_TM_AndresPeak { + get { + return ResourceManager.GetString("GEAR_PostCard_TM_AndresPeak", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polaroid Timberwolf Mountain Tail Section. + /// + public static string GEAR_PostCard_TM_TailSection { + get { + return ResourceManager.GetString("GEAR_PostCard_TM_TailSection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Expedition Parka. + /// + public static string GEAR_PremiumWinterCoat { + get { + return ResourceManager.GetString("GEAR_PremiumWinterCoat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prison Transport Manifest. + /// + public static string GEAR_PrisonBusNote { + get { + return ResourceManager.GetString("GEAR_PrisonBusNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prybar. + /// + public static string GEAR_Prybar { + get { + return ResourceManager.GetString("GEAR_Prybar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pumpkin Pie. + /// + public static string GEAR_PumpkinPie { + get { + return ResourceManager.GetString("GEAR_PumpkinPie", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mariner's Pea Coat. + /// + public static string GEAR_QualityWinterCoat { + get { + return ResourceManager.GetString("GEAR_QualityWinterCoat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rabbit Carcass. + /// + public static string GEAR_RabbitCarcass { + get { + return ResourceManager.GetString("GEAR_RabbitCarcass", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Rabbit Pelt. + /// + public static string GEAR_RabbitPelt { + get { + return ResourceManager.GetString("GEAR_RabbitPelt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Rabbit Pelt. + /// + public static string GEAR_RabbitPeltDried { + get { + return ResourceManager.GetString("GEAR_RabbitPeltDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rabbitskin Hat. + /// + public static string GEAR_RabbitskinHat { + get { + return ResourceManager.GetString("GEAR_RabbitskinHat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rabbitskin Mitts. + /// + public static string GEAR_RabbitSkinMittens { + get { + return ResourceManager.GetString("GEAR_RabbitSkinMittens", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Radio Parts. + /// + public static string GEAR_RadioParts { + get { + return ResourceManager.GetString("GEAR_RadioParts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Coho Salmon (Raw). + /// + public static string GEAR_RawCohoSalmon { + get { + return ResourceManager.GetString("GEAR_RawCohoSalmon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lake Whitefish (Raw). + /// + public static string GEAR_RawLakeWhiteFish { + get { + return ResourceManager.GetString("GEAR_RawLakeWhiteFish", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Black Bear Meat. + /// + public static string GEAR_RawMeatBear { + get { + return ResourceManager.GetString("GEAR_RawMeatBear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Venison (Raw). + /// + public static string GEAR_RawMeatDeer { + get { + return ResourceManager.GetString("GEAR_RawMeatDeer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moose Meat. + /// + public static string GEAR_RawMeatMoose { + get { + return ResourceManager.GetString("GEAR_RawMeatMoose", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rabbit (Raw). + /// + public static string GEAR_RawMeatRabbit { + get { + return ResourceManager.GetString("GEAR_RawMeatRabbit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wolf Meat (Raw). + /// + public static string GEAR_RawMeatWolf { + get { + return ResourceManager.GetString("GEAR_RawMeatWolf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rainbow Trout (Raw). + /// + public static string GEAR_RawRainbowTrout { + get { + return ResourceManager.GetString("GEAR_RawRainbowTrout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Smallmouth Bass (Raw). + /// + public static string GEAR_RawSmallMouthBass { + get { + return ResourceManager.GetString("GEAR_RawSmallMouthBass", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reclaimed Wood. + /// + public static string GEAR_ReclaimedWoodB { + get { + return ResourceManager.GetString("GEAR_ReclaimedWoodB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Recycled Can. + /// + public static string GEAR_RecycledCan { + get { + return ResourceManager.GetString("GEAR_RecycledCan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reishi Mushroom. + /// + public static string GEAR_ReishiMushroom { + get { + return ResourceManager.GetString("GEAR_ReishiMushroom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prepared Reishi Mushrooms. + /// + public static string GEAR_ReishiPrepared { + get { + return ResourceManager.GetString("GEAR_ReishiPrepared", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reishi Tea. + /// + public static string GEAR_ReishiTea { + get { + return ResourceManager.GetString("GEAR_ReishiTea", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Revolver. + /// + public static string GEAR_Revolver { + get { + return ResourceManager.GetString("GEAR_Revolver", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Revolver Ammunition. + /// + public static string GEAR_RevolverAmmoBox { + get { + return ResourceManager.GetString("GEAR_RevolverAmmoBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Revolver Shell Casing. + /// + public static string GEAR_RevolverAmmoCasing { + get { + return ResourceManager.GetString("GEAR_RevolverAmmoCasing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Revolver Cartridge. + /// + public static string GEAR_RevolverAmmoSingle { + get { + return ResourceManager.GetString("GEAR_RevolverAmmoSingle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rick's Journal. + /// + public static string GEAR_RicksJournal { + get { + return ResourceManager.GetString("GEAR_RicksJournal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hunting Rifle. + /// + public static string GEAR_Rifle { + get { + return ResourceManager.GetString("GEAR_Rifle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rifle Ammunition. + /// + public static string GEAR_RifleAmmoBox { + get { + return ResourceManager.GetString("GEAR_RifleAmmoBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rifle Shell Casing. + /// + public static string GEAR_RifleAmmoCasing { + get { + return ResourceManager.GetString("GEAR_RifleAmmoCasing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rifle Cartridge. + /// + public static string GEAR_RifleAmmoSingle { + get { + return ResourceManager.GetString("GEAR_RifleAmmoSingle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rifle Blanks. + /// + public static string GEAR_RifleBlanks { + get { + return ResourceManager.GetString("GEAR_RifleBlanks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rifle Bullets. + /// + public static string GEAR_RifleBullets { + get { + return ResourceManager.GetString("GEAR_RifleBullets", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Firearm Cleaning Kit. + /// + public static string GEAR_RifleCleaningKit { + get { + return ResourceManager.GetString("GEAR_RifleCleaningKit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hunting Rifle. + /// + public static string GEAR_RifleHuntingLodge { + get { + return ResourceManager.GetString("GEAR_RifleHuntingLodge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountaineering Rope. + /// + public static string GEAR_Rope { + get { + return ResourceManager.GetString("GEAR_Rope", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rose Hip. + /// + public static string GEAR_RoseHip { + get { + return ResourceManager.GetString("GEAR_RoseHip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prepared Rose hips. + /// + public static string GEAR_RosehipsPrepared { + get { + return ResourceManager.GetString("GEAR_RosehipsPrepared", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rose Hip Tea. + /// + public static string GEAR_RoseHipTea { + get { + return ResourceManager.GetString("GEAR_RoseHipTea", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Basement Key. + /// + public static string GEAR_RuralRegionFarmKey { + get { + return ResourceManager.GetString("GEAR_RuralRegionFarmKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scrap Lead. + /// + public static string GEAR_ScrapLead { + get { + return ResourceManager.GetString("GEAR_ScrapLead", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scrap Metal. + /// + public static string GEAR_ScrapMetal { + get { + return ResourceManager.GetString("GEAR_ScrapMetal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sewing Kit. + /// + public static string GEAR_SewingKit { + get { + return ResourceManager.GetString("GEAR_SewingKit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whetstone. + /// + public static string GEAR_SharpeningStone { + get { + return ResourceManager.GetString("GEAR_SharpeningStone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shovel. + /// + public static string GEAR_Shovel { + get { + return ResourceManager.GetString("GEAR_Shovel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Simple Tools. + /// + public static string GEAR_SimpleTools { + get { + return ResourceManager.GetString("GEAR_SimpleTools", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ski Boots. + /// + public static string GEAR_SkiBoots { + get { + return ResourceManager.GetString("GEAR_SkiBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ski Gloves. + /// + public static string GEAR_SkiGloves { + get { + return ResourceManager.GetString("GEAR_SkiGloves", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Light Shell. + /// + public static string GEAR_SkiJacket { + get { + return ResourceManager.GetString("GEAR_SkiJacket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Snare. + /// + public static string GEAR_Snare { + get { + return ResourceManager.GetString("GEAR_Snare", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Summit Soda. + /// + public static string GEAR_Soda { + get { + return ResourceManager.GetString("GEAR_Soda", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go! Energy Drink. + /// + public static string GEAR_SodaEnergy { + get { + return ResourceManager.GetString("GEAR_SodaEnergy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stacy's Grape Soda. + /// + public static string GEAR_SodaGrape { + get { + return ResourceManager.GetString("GEAR_SodaGrape", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Orange Soda. + /// + public static string GEAR_SodaOrange { + get { + return ResourceManager.GetString("GEAR_SodaOrange", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cedar Firewood. + /// + public static string GEAR_Softwood { + get { + return ResourceManager.GetString("GEAR_Softwood", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Spear Head. + /// + public static string GEAR_SpearHead { + get { + return ResourceManager.GetString("GEAR_SpearHead", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Spray Paint. + /// + public static string GEAR_SprayPaintCan { + get { + return ResourceManager.GetString("GEAR_SprayPaintCan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deer Quarter. + /// + public static string GEAR_StagQuarter { + get { + return ResourceManager.GetString("GEAR_StagQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stick. + /// + public static string GEAR_Stick { + get { + return ResourceManager.GetString("GEAR_Stick", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stone. + /// + public static string GEAR_Stone { + get { + return ResourceManager.GetString("GEAR_Stone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stump Remover. + /// + public static string GEAR_StumpRemover { + get { + return ResourceManager.GetString("GEAR_StumpRemover", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Sewing Primer. + /// + public static string GEAR_SurvivalSchoolClothing { + get { + return ResourceManager.GetString("GEAR_SurvivalSchoolClothing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Frontier Shooting Guide. + /// + public static string GEAR_SurvivalSchoolDeerHunt { + get { + return ResourceManager.GetString("GEAR_SurvivalSchoolDeerHunt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Frozen Angler. + /// + public static string GEAR_SurvivalSchoolFishing { + get { + return ResourceManager.GetString("GEAR_SurvivalSchoolFishing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Medicinal Plants of Great Bear. + /// + public static string GEAR_SurvivalSchoolPlants { + get { + return ResourceManager.GetString("GEAR_SurvivalSchoolPlants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Field Dressing Your Kill, Vol. I. + /// + public static string GEAR_SurvivalSchoolRabbits { + get { + return ResourceManager.GetString("GEAR_SurvivalSchoolRabbits", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Advanced Guns Guns Guns!. + /// + public static string GEAR_SurvivalSchoolWolfHunt { + get { + return ResourceManager.GetString("GEAR_SurvivalSchoolWolfHunt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Technical Backpack. + /// + public static string GEAR_TechnicalBackpack { + get { + return ResourceManager.GetString("GEAR_TechnicalBackpack", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to T-Shirt. + /// + public static string GEAR_TeeShirt { + get { + return ResourceManager.GetString("GEAR_TeeShirt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tinder Plug. + /// + public static string GEAR_Tinder { + get { + return ResourceManager.GetString("GEAR_Tinder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tomato Soup. + /// + public static string GEAR_TomatoSoupCan { + get { + return ResourceManager.GetString("GEAR_TomatoSoupCan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Toque. + /// + public static string GEAR_Toque { + get { + return ResourceManager.GetString("GEAR_Toque", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Torch. + /// + public static string GEAR_Torch { + get { + return ResourceManager.GetString("GEAR_Torch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forest Talker Supplies. + /// + public static string GEAR_TrailerSupplies { + get { + return ResourceManager.GetString("GEAR_TrailerSupplies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Transponder Parts. + /// + public static string GEAR_TransponderParts { + get { + return ResourceManager.GetString("GEAR_TransponderParts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Utilities Bill. + /// + public static string GEAR_UtilitiesBill { + get { + return ResourceManager.GetString("GEAR_UtilitiesBill", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Water Bottle. + /// + public static string GEAR_Water1000ml { + get { + return ResourceManager.GetString("GEAR_Water1000ml", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Water Bottle. + /// + public static string GEAR_Water500ml { + get { + return ResourceManager.GetString("GEAR_Water500ml", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Water Purification Tablets. + /// + public static string GEAR_WaterPurificationTablets { + get { + return ResourceManager.GetString("GEAR_WaterPurificationTablets", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Water (Unsafe). + /// + public static string GEAR_WaterSupplyNotPotable { + get { + return ResourceManager.GetString("GEAR_WaterSupplyNotPotable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Water (Potable). + /// + public static string GEAR_WaterSupplyPotable { + get { + return ResourceManager.GetString("GEAR_WaterSupplyPotable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Water Tower Note. + /// + public static string GEAR_WaterTowerNote { + get { + return ResourceManager.GetString("GEAR_WaterTowerNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Boots. + /// + public static string GEAR_WillBoots { + get { + return ResourceManager.GetString("GEAR_WillBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Boots (Start). + /// + public static string GEAR_WillBootsStart { + get { + return ResourceManager.GetString("GEAR_WillBootsStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Pants. + /// + public static string GEAR_WillPants { + get { + return ResourceManager.GetString("GEAR_WillPants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Pants (Start). + /// + public static string GEAR_WillPantsStart { + get { + return ResourceManager.GetString("GEAR_WillPantsStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Parka. + /// + public static string GEAR_WillParka { + get { + return ResourceManager.GetString("GEAR_WillParka", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Parka. + /// + public static string GEAR_WillParka_Tossed { + get { + return ResourceManager.GetString("GEAR_WillParka_Tossed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Shirt. + /// + public static string GEAR_WillShirt { + get { + return ResourceManager.GetString("GEAR_WillShirt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Shirt (Start). + /// + public static string GEAR_WillShirtStart { + get { + return ResourceManager.GetString("GEAR_WillShirtStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Sweater. + /// + public static string GEAR_WillSweater { + get { + return ResourceManager.GetString("GEAR_WillSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Sweater (Start). + /// + public static string GEAR_WillSweaterStart { + get { + return ResourceManager.GetString("GEAR_WillSweaterStart", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mackenzie's Toque. + /// + public static string GEAR_WillToque { + get { + return ResourceManager.GetString("GEAR_WillToque", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wolf Carcass. + /// + public static string GEAR_WolfCarcass { + get { + return ResourceManager.GetString("GEAR_WolfCarcass", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fresh Wolf Pelt. + /// + public static string GEAR_WolfPelt { + get { + return ResourceManager.GetString("GEAR_WolfPelt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cured Wolf Pelt. + /// + public static string GEAR_WolfPeltDried { + get { + return ResourceManager.GetString("GEAR_WolfPeltDried", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wolf Quarter. + /// + public static string GEAR_WolfQuarter { + get { + return ResourceManager.GetString("GEAR_WolfQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wolfskin Coat. + /// + public static string GEAR_WolfSkinCape { + get { + return ResourceManager.GetString("GEAR_WolfSkinCape", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wood Matches. + /// + public static string GEAR_WoodMatches { + get { + return ResourceManager.GetString("GEAR_WoodMatches", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Shirt. + /// + public static string GEAR_WoolShirt { + get { + return ResourceManager.GetString("GEAR_WoolShirt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wool Socks. + /// + public static string GEAR_WoolSocks { + get { + return ResourceManager.GetString("GEAR_WoolSocks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thin Wool Sweater. + /// + public static string GEAR_WoolSweater { + get { + return ResourceManager.GetString("GEAR_WoolSweater", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Long Wool Scarf. + /// + public static string GEAR_WoolWrap { + get { + return ResourceManager.GetString("GEAR_WoolWrap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fleece Cowl. + /// + public static string GEAR_WoolWrapCap { + get { + return ResourceManager.GetString("GEAR_WoolWrapCap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Work Boots. + /// + public static string GEAR_WorkBoots { + get { + return ResourceManager.GetString("GEAR_WorkBoots", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Work Gloves. + /// + public static string GEAR_WorkGloves { + get { + return ResourceManager.GetString("GEAR_WorkGloves", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Work Pants. + /// + public static string GEAR_WorkPants { + get { + return ResourceManager.GetString("GEAR_WorkPants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Gunsmithing skillpoints. + /// + public static string GunsmithingSkillSP { + get { + return ResourceManager.GetString("GunsmithingSkillSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Guts. + /// + public static string GutAmount { + get { + return ResourceManager.GetString("GutAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Health. + /// + public static string Health { + get { + return ResourceManager.GetString("Health", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hidden. + /// + public static string Hidden { + get { + return ResourceManager.GetString("Hidden", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hides. + /// + public static string HideAmount { + get { + return ResourceManager.GetString("HideAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ice fishing skillpoints. + /// + public static string IceFishingSP { + get { + return ResourceManager.GetString("IceFishingSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Infinite carry. + /// + public static string InfiniteCarry { + get { + return ResourceManager.GetString("InfiniteCarry", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Injuries. + /// + public static string Injuries { + get { + return ResourceManager.GetString("Injuries", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Inventory. + /// + public static string Inventory { + get { + return ResourceManager.GetString("Inventory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invulnerable. + /// + public static string Invulnerable { + get { + return ResourceManager.GetString("Invulnerable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Books. + /// + public static string ItemCategory_Books { + get { + return ResourceManager.GetString("ItemCategory_Books", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clothing. + /// + public static string ItemCategory_Clothing { + get { + return ResourceManager.GetString("ItemCategory_Clothing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Collectible. + /// + public static string ItemCategory_Collectible { + get { + return ResourceManager.GetString("ItemCategory_Collectible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Aid. + /// + public static string ItemCategory_FirstAid { + get { + return ResourceManager.GetString("ItemCategory_FirstAid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Food. + /// + public static string ItemCategory_Food { + get { + return ResourceManager.GetString("ItemCategory_Food", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hidden. + /// + public static string ItemCategory_Hidden { + get { + return ResourceManager.GetString("ItemCategory_Hidden", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Materials. + /// + public static string ItemCategory_Materials { + get { + return ResourceManager.GetString("ItemCategory_Materials", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tools. + /// + public static string ItemCategory_Tools { + get { + return ResourceManager.GetString("ItemCategory_Tools", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown. + /// + public static string ItemCategory_Unknown { + get { + return ResourceManager.GetString("ItemCategory_Unknown", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Map. + /// + public static string Map { + get { + return ResourceManager.GetString("Map", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Materials. + /// + public static string Materials { + get { + return ResourceManager.GetString("Materials", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Meat (kg). + /// + public static string MeatAmount { + get { + return ResourceManager.GetString("MeatAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Never die. + /// + public static string NeverDie { + get { + return ResourceManager.GetString("NeverDie", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open map. + /// + public static string OpenMapCommand { + get { + return ResourceManager.GetString("OpenMapCommand", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Player. + /// + public static string Player { + get { + return ResourceManager.GetString("Player", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Position. + /// + public static string Position { + get { + return ResourceManager.GetString("Position", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Profile. + /// + public static string Profile { + get { + return ResourceManager.GetString("Profile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Progress. + /// + public static string Progress { + get { + return ResourceManager.GetString("Progress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Refresh. + /// + public static string Refresh { + get { + return ResourceManager.GetString("Refresh", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Region. + /// + public static string Region { + get { + return ResourceManager.GetString("Region", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ash Canyon. + /// + public static string RegionsWithMap_AshCanyonRegion { + get { + return ResourceManager.GetString("RegionsWithMap_AshCanyonRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bleak Inlet. + /// + public static string RegionsWithMap_CanneryRegion { + get { + return ResourceManager.GetString("RegionsWithMap_CanneryRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Coastal Highway. + /// + public static string RegionsWithMap_CoastalRegion { + get { + return ResourceManager.GetString("RegionsWithMap_CoastalRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Timberwolf Mountain. + /// + public static string RegionsWithMap_CrashMountainRegion { + get { + return ResourceManager.GetString("RegionsWithMap_CrashMountainRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Crumbling Highway. + /// + public static string RegionsWithMap_HighwayTransitionZone { + get { + return ResourceManager.GetString("RegionsWithMap_HighwayTransitionZone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mystery Lake. + /// + public static string RegionsWithMap_LakeRegion { + get { + return ResourceManager.GetString("RegionsWithMap_LakeRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forlorn Muskeg. + /// + public static string RegionsWithMap_MarshRegion { + get { + return ResourceManager.GetString("RegionsWithMap_MarshRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mountain Town. + /// + public static string RegionsWithMap_MountainTownRegion { + get { + return ResourceManager.GetString("RegionsWithMap_MountainTownRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ravine. + /// + public static string RegionsWithMap_RavineTransitionZone { + get { + return ResourceManager.GetString("RegionsWithMap_RavineTransitionZone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hushed River Valley. + /// + public static string RegionsWithMap_RiverValleyRegion { + get { + return ResourceManager.GetString("RegionsWithMap_RiverValleyRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pleasant Valley. + /// + public static string RegionsWithMap_RuralRegion { + get { + return ResourceManager.GetString("RegionsWithMap_RuralRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Broken Railroad. + /// + public static string RegionsWithMap_TracksRegion { + get { + return ResourceManager.GetString("RegionsWithMap_TracksRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Desolation Point. + /// + public static string RegionsWithMap_WhalingStationRegion { + get { + return ResourceManager.GetString("RegionsWithMap_WhalingStationRegion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remove. + /// + public static string Remove { + get { + return ResourceManager.GetString("Remove", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remove all. + /// + public static string RemoveAll { + get { + return ResourceManager.GetString("RemoveAll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Repair all. + /// + public static string RepairAll { + get { + return ResourceManager.GetString("RepairAll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Revolver skillpoints. + /// + public static string RevolverSkillSP { + get { + return ResourceManager.GetString("RevolverSkillSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rifle skillpoints. + /// + public static string RifleSP { + get { + return ResourceManager.GetString("RifleSP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rounds in clip. + /// + public static string RoundsInClip { + get { + return ResourceManager.GetString("RoundsInClip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string Save { + get { + return ResourceManager.GetString("Save", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Skills. + /// + public static string Skills { + get { + return ResourceManager.GetString("Skills", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Snow walker progress. + /// + public static string SnowWalkerProgress { + get { + return ResourceManager.GetString("SnowWalkerProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Straight to the heart progress. + /// + public static string StraightToHeartProgress { + get { + return ResourceManager.GetString("StraightToHeartProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test branch. + /// + public static string TestBranch { + get { + return ResourceManager.GetString("TestBranch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thirst. + /// + public static string Thirst { + get { + return ResourceManager.GetString("Thirst", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time spent evolving (hours). + /// + public static string TimeEvolving { + get { + return ResourceManager.GetString("TimeEvolving", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Long Dark (v2.27) Save Editor. + /// + public static string Title { + get { + return ResourceManager.GetString("Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tools. + /// + public static string Tools { + get { + return ResourceManager.GetString("Tools", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Traits. + /// + public static string Traits { + get { + return ResourceManager.GetString("Traits", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown. + /// + public static string Unknown { + get { + return ResourceManager.GetString("Unknown", resourceCulture); + } + } + } +} diff --git a/src/TldSaveEditor.Core/Properties/Resources.de-DE.Designer.cs b/src/TldSaveEditor.Core/Properties/Resources.de-DE.Designer.cs new file mode 100644 index 0000000..e69de29 diff --git a/src/TldSaveEditor.Core/Properties/Resources.de-DE.resx b/src/TldSaveEditor.Core/Properties/Resources.de-DE.resx new file mode 100644 index 0000000..2ec8ba4 --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.de-DE.resx @@ -0,0 +1,1991 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Antibiotika + + + Antiseptikum + + + Schmerzmittel + + + Binde + + + Bart-Wundverband des alten Mannes + literal translation + + + Wasseraufbereitungstabletten + + + Notfallstimulation + + + Sturmhaube + + + Baseball Kappe + + + Trail Boots + + + Trail-Stiefel + + + Laufschuhe + + + Windjacke + + + Baumwolle Drehmoment + + + Wollschal + + + Bärenfellmantel + + + Cargohosen + + + Kampfstiefel + + + Kampfhosen + + + Kapuzenpullover + + + Baumwollschal + + + Anzughemd + + + Sportsocken + + + Hirschlederstiefel + + + Hirschlederhose + + + Stadtparka + + + Skijacke + + + Daunenweste + + + Wollohrwickel + + + Fischerpullover + + + Fleecehandschuhe + + + Sweatshirt + same in EN as in DE + + + Stulpen + + + Altmodischer Parka + + + Dicker Wollpullover + + + Isolierte Stiefel + + + Schneehose + + + Sportweste + + + Jeans + + + Lederschuhe + + + Simple Parka + + + Thermounterwäsche + + + Lange Unterhose aus Wolle + + + Mackinaw-Jacke + + + Militärmantel + + + Wollfäustlinge + + + Mukluks + ????? + + + Kariertes Hemd + + + Expeditionsparka + + + Erbsenmantel des Seemanns + + + Handschuhe aus Kaninchenfell + + + Skischuh + + + Skihandschuhe + + + Skijacke + + + T-Shirt + + + Wollmütze + + + Wolfsledermantel + + + Wollhemd + + + Wollsocken + + + Dünner Wollpullover + + + Langer Wollschal + + + Fleece Kapuze + + + Arbeitsschuhe + + + Arbeitshandschuhe + + + Arbeitshosen + + + Trockenfleisch vom Rind + + + Schokoriegel + + + Schweinefleisch und Bohnen + + + Dose mit Sardinen + + + Katzenschwanzstiel + + + Katzenschwanzpflanze + + + Tasse Kaffee + + + Dose Kaffee + + + Condensed Milk + + + See Felchen (Gekocht) + + + Bärenfleisch (Gekocht) + + + Wild (Gekocht) + + + Kaninchen (Gekocht) + + + Wolfsfleisch (Gekocht) + + + Regenbogenforelle (Gekocht) + + + Schwarzbarsch (Gekocht) + + + Salzige Cracker + + + Hundefutter + + + Energieriegel + + + Müsliriegel + + + Tasse Kräutertee + + + Kräutertee + + + Einmannpackung in Militärqualität + + + Erdnussbutter + + + Höhepunkt Pfirsiche + + + Coho Lachs (Roh) + + + Coho-Lachs (Gekocht) + + + Birkenrinde + + + See Felchen (Roh) + + + Schwarzbärenfleisch + + + Wild (Roh) + + + Kaninchen (Roh) + + + Wolfsfleisch (Roh) + + + Regenbogenforelle (Roh) + + + Kleinmaulbarsch (Roh) + + + Reishi Tee + + + Hagebuttentee + + + Gipfelsoda + + + Stacy's Trauben Soda + + + Orangenlimonade + + + Tomatensuppe + + + Wasser (Unsicher) + + + Wasser (Trinkwasser) + + + Beschleuniger + + + Einfacher Pfeil + + + Gebrochener Pfeil + + + Pfeilschaft + + + Schlafrolle aus Bärenhaut + + + Schlafsack + + + Überlebensbogen + + + Dosenöffner + + + Feuerstürmer + + + Fackel + + + Flare Muschel + + + Notpistole + + + Säge + + + Schwerer Hammer + + + Beil + + + Improvisiertes Kriegsbeil + + + Qualitätswerkzeuge + + + Hook + + + Angelzubehör + + + Kanister + + + Sturmlaterne + + + Jagdmesser + + + Improvisiertes Messer + + + Laternenbrennstoff + + + Zeile + + + Vergrößerungslinse + + + Zeitungspapierrolle + + + Streichhölzer aus Pappe + + + Stemmeisen + + + Jagdgewehr + + + Gewehrmunition + + + Gewehrpatrone + + + Waffenreinigungsset + + + Bergsteigerseil + + + Flickzeug + + + Wetzstein + + + Einfache Werkzeuge + + + Schlinge + + + Taschenlampe + + + Streichhölzer + + + Pfeilspitze + + + Frisches Schwarzbärenfell + + + Ausgehärtetes Schwarzbärenfell + + + Grüner Birkensetzling + + + Ausgehärteter Birkensetzling + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Buch + + + Katzenschwanzkopf + + + Tuch + + + Kohle + + + Krähenfeder + + + Feuerlog + + + Frischer Darm + + + Geheilter Darm + + + Tanne Brennholz + + + Frisches Leder + + + Ausgehärtetes Leder + + + Frisches Hirschfell + + + Geheilte Hirschhaut + + + Grüner Ahornsetzling + + + Ausgehärteter Ahornsetzling + + + Zeitungspapier + + + Bartflechte des alten Mannes + + + Frisches Kaninchenfell + + + Geheiltes Kaninchenfell + + + Altholz + + + Reishi Pilz + + + Hagebutte + + + Altmetall + + + Brennholz aus Zedernholz + + + Stock + + + Tinder Stecker + + + Frischer Wolfspelz + + + Geheilter Wolfspelz + + + Feldvorbereitung Ihre Fangen, Vol. I + Literally translated as "Preparing your catches in the field" + + + Wildnisküche + + + Überlebe die Draußen! + + + Der Gefrorene Angler + + + Leitfaden für Grenzschießereien + + + Fortgeschrittene Waffen Waffen Waffen! + + + Beschleuniger + + + Beschleuniger + + + Bolzenschneider + + + Autobatterie + + + Kompressionsverband + + + Feuer Axt + + + Leine + + + Feuerstein & Stahl + + + Frisches Leder + + + Stapel Papiere + + + Kürbiskuchen + + + Schaufel + + + Blutiger Hammer + + + Astrid's Rucksack + + + Kirchenhymne + + + Kirchennotiz EP 1 + + + Hinweis zum Wasserkraftwerk-Code + + + Wasserkraftwerk Kontrollraum Code + + + Wasserkraftwerk Büroschlüssel + + + Hinweis zur Notfallausrüstung + + + Bauernalmanach + + + Erste Hilfe Handbuch + + + Astrid's Aktentasche + Used breifcase for the translation + + + Wanderrucksack + + + Jägertagebuchseite + + + Schrottscherbe + + + Carter Wasserkraftwerk Medizinbedarf + + + Paradise Meadows Farmschlüssel + + + Gewehrkugeln + + + Klettersocken + + + Wasserflasche + + + Wasserflasche + + + Elchviertel + + + Elchfleisch (Roh) + + + Elchfleisch (Gekocht) + + + Eine zurückgelassene Notiz + + + Der Gefrorene Angler + + + Carter Wasserkraftwerk + + + Transponderteile + + + Notfallnahrung + + + Geschichte des Zusammenbruchs, Teil 1 + + + Fortgeschrittene Waffen Waffen Waffen! + + + Hasenfellmütze + + + Zerknitterte Notiz + + + Speerkopf + + + Gebrochener Bärenspeer + + + Radioteile + + + Heilpflanzen des Great Bear + + + Bärenspeer + + + Zugangscode für die Tür der Aurora-Luke + + + Thermounterwäsche (Start) + + + Leitfaden für Grenzschießereien + + + Mackenzie's Stiefel (Start) + + + Sportsocken (Start) + + + Astrid's Aktentasche + Used breifcase for the translation + + + Winterprognose + + + Sanitätskasten + + + Stadt Milton + + + Mackenzie's Parka + + + Medizin in meinem Hintergarten + + + Astrid's Rucksack + + + Carter Wasserkraftwerk Gate-Schlüssel des Bereitstellungsbereichs + + + Mystery Lake & Umgebung + + + Bärenspeer + + + Mackenzie's Pullover (Start) + + + Geschichte des Zusammenbruchs, Teil 3 + + + Eine Nähanleitung + + + Mackenzie's Hose (Start) + + + Geschichte des Zusammenbruchs, Teil 4 + + + Feldvorbereitung Ihre Fangen, Vol. I + Literally translated as "Preparing your catches in the field" + + + Mackenzie's Shirt (Start) + + + Geschichte des Zusammenbruchs, Teil 2 + + + Notpistolen Kit + + + Taschenlampe + + + Waldsprecher Notiz + + + Waldsprecher Notiz + + + Zerknitterte Notiz + + + Jagdgewehr + + + Bankschließfachschlüssel (#13) + + + Jeremiah's Messer + + + Jeremiah's Repariertes Gewehr + + + Blaupausen Schmieden + + + Bankschließfachschlüssel (#20) + + + Handschriftliche Notiz + + + Holzkohle Hinweis + + + Hinweis zum versteckten Cache von Milton + + + Unleserlicher Hinweis + + + Jeremiah's Bärenfellmantel + + + Banktresorcode + + + Logging Camp Trailer-Schlüssel + + + Blutgetränkte Notiz + + + Waldsprecher Flugblatt + + + Hank's Tagebuch - Teil 2 + + + Bankschließfachschlüssel (#15) + + + Jeremiah's zerbrochenes Gewehr + + + Bankschließfachschlüssel (#7) + + + Hausschlüssel des Bankmanagers + + + Waldsprecher Unterlagen + + + Grey Mother's Perlen + + + Einfacher Hinweis + + + Hinweis zu verstecktem Cache in Höhlen + + + Zubehör für Waldsprecher + + + Grey Mother's Safe + + + Lily's Stammschlüssel + + + Brief für Hank's Nichte + + + Mackenzie's Shirt + + + Mackenzie's Parka + + + Mackenzie's Pullover + + + Mackenzie's Stiefel + + + Mackenzie's Drehmoment + + + Mackenzie's Hose + + + Bergsteigerschuhe + + + Das Ohr des alten Bären + + + Zubereitete Reishi Pilze + + + Zubereitete Hagebutten + + + Hank's Prepper Zwischenspeicher Code + No idea what the best translation for prepper is - if there is a German term for "doomsday prepper" I dont know it + + + Bleib Fokussiert + + + Eine Nähanleitung + + + Geheilte Elchhaut + + + Elchledertasche + + + Elchlederumhang + + + Frische Elchhaut + + + Kochtopf + + + Recycelte Dose + + + Wolfsviertel + + + Wolfskadaver + + + Bärenviertel + + + Hirschviertel + + + Kaninchenkadaver + + + Stein + + + Holzkohle + + + Buch + + + Laternenbrennstoff + + + Kaninchenkadaver + + + Über + + + Artikel hinzufügen + + + Betragen + + + Betragen (Liter) + + + Bogenschießen + + + Bücher + + + Buch-intelligenter Fortschritt + + + Kalorien + + + Abbrechen + + + Schlachtkörperernte-Fähigkeit + + + Kleidung + + + Fähigkeit zum Reparieren von Kleidung + + + Fortschritt der Kalten Fusion + + + Sammlerstück + + + Zustand + + + Kochkünste + + + Aktuelle Kalorien + + + Herunterladen + + + Effizienter Maschinenfortschritt + + + Ermüdung + + + Fortschritt des Feuermeisters + + + Feuerstart-Fertigkeitspunkte + + + Erste Hilfe + + + Essen + + + Free Runner-Fortschritt + + + Einfrieren + + + Gesundheit + + + Versteckt + + + Fähigkeit zum Eisfischen + + + Unendlich tragen + + + Verletzungen + + + Inventar + + + Unverwundbar + + + Materialien + + + Niemals sterben + + + Spieler + + + Profil + + + Fortschritt + + + Aktualisierung + + + Entfernen + + + Alles entfernen + + + Alles reparieren + + + Gewehrfertigkeit + + + Runden im Clip + + + Speichern + + + Fähigkeiten + + + Fortschritte beim Schneewanderer + + + Testzweig + + + Durst + + + Entwicklungszeit (Stunden) + + + The Long Dark (v2.27) Editor speichern + + + Werkzeuge + + + Züge + + + Unbekannt + + + Symptome + + + Heilung + + + Blutverlust + + + Verbrennungen + + + Ruhr + + + Infektion + + + Lebensmittelvergiftung + + + Verstauchter Knöchel + + + Infektionsgefahr + + + Verstauchtes Handgelenk + + + Erfrierung + + + Unterkühlung + + + Reduzierte Müdigkeit + + + Verbesserte Ruhe + + + Aufwärmen + + + Hypothermierisiko + + + Lagerkoller + + + Darmparasitenrisiko + + + Darmparasiten + + + Kabinenfiebergefahr + + + Erfrierungsgefahr + + + Erste Hilfe + + + Clothing + + + Essen + + + Werkzeuge + + + Materialien + + + Sammlerstück + + + Bücher + + + Versteckt + + + Unbekannt + + + Erfahrungsmodus + + + Pilger + + + Voyageur + + + Pirschjäger + + + Geschichte + + + Hoffnungslose Rettung + + + Die Gejagten + + + Schneesturm + As far as I know, there is no German term for whiteout, the closest would be "Schneesturm" or "Snow Storm" + + + Die Gejagten, Teil 2 + + + Eindringling + + + Geschichte frisch + + + Geschichte gehärtet + + + Vier Tage Nacht + + + Herausforderung Archivar + + + Benutzerdefiniert + + + Position + + + Coastal Highway + + + Mystery Lake + + + Desolation Point + + + Pleasant Valley + + + Timberwolf Mountain + + + Forlorn Muskeg + + + Ravine + + + Crumbling Highway + + + Karte + + + Innereien + + + Versteckt + + + Fleisch (kg) + + + Mountain Town + + + Broken Railroad + + + Hushed River Valley + + + Gebrochener Bärenspeer + + + Gehen! Energiegetränk + + + Improvisierte Handwickel + + + Improvisierter Kopfwickel + + + Revolverpatrone + + + Revolvermunition + + + Zubereitete Birkenrinde + + + Birkenrindentee + + + Revolver + + + Revolver-Fähigkeit + + + Handbuch für Kleinwaffen + + + Sicherungen + + + 4 Tage Nacht 2019 Abzeichen freigeschaltet + + + 4 Tage Nachtabzeichen freigeschaltet + + + Fortschritte beim Blizzard Gehhilfe + + + Fortschritte beim Fallensteller-Experten + + + Direkt zum Herzensfortschritt + + + Cowichan-Pullover + + + Marke + + + Bergsteiger Tagebuchseite + + + Bogensehne + + + Bogenholz + + + Sammelnotiz Allgemein + + + Sammelnotiz Allgemein + + + Erfrierungen Schaden + + + Schrottmesser (Sauber) + + + Kartenausschnitt Mt + + + Karte zum Bahnhof + + + Morphium + + + Mountain Town Bauernhof Hinweis + + + Mountain Town Schlüssel zum Schlosskasten + + + Mountain Town Karte + + + Mountain Town Store-Schlüssel + + + Überführungsbroschüre + + + Rick's Tagebuch + + + Gewehrrohlinge + + + Stromrechnung + + + Hinweis zum Wasserturm + + + Waldsprecher Hinweis zur Karte + + + Stark verstauchtes Handgelenk + + + Nomadisch + german has no neutral translation for this, with Nomadin (f) and Nomade (m) being the only options. I have elected to translated this as "Nomadic" to maintain the neutrality of the term + + + Region + + + Jeremiah's Briefe + + + Karte öffnen + + + Meeresfackel + + + Praktische Büchsenmacherei + + + Geschoss + + + Kommunikationsbericht + + + Konservenfabrik Memo + + + Das Notizbuch des Technikers + + + Schwefel Abstäuben + + + Dose Schießpulver + + + Revolvermantelgehäuse + + + Gewehrschalengehäuse + + + Blei verschrotten + + + Stumpfentferner + + + Büchsenmacher Fähigkeit + + + Elektrische Verbrennungen + + + Wie die Toten schlafen + + + Flugnahrung - Hähnchen + Used "flight food" for the translation of airline food + + + Flugnahrung - Vegetarierin + Used "flight food" for the translation of airline food; and the female form of vegetarian as there is no neutral form + + + Astrid's Stiefel + + + Astrid's Handschuhe + + + Astrid's Jacke + + + Astrid's Jeans + + + Astrid's Pullover + + + Astrid's Drehmoment + + + Aurora-Beobachtung + + + Verurteilte blutbefleckte Notiz + + + Sträflingsnotiz + + + Wegbeschreibung zum Sträflings-Cache + + + Memo des Schwarzfelsgefängnisses + + + Lokale Legenden - Der Große + + + Lokale Legenden - Die verlorene Höhle + + + Lokale Legenden - Geisterhirsch + + + Lokale Legenden -Sasquatch + + + Parkhinweis + + + Kondensmilch + + + Carter Wasserkraftwerk - Sicherheits- und Abschalthinweis + + + Wartungshinweis für Aufzüge + + + Mülleimer Brief + + + Schlüssel für medizinisches Schließfach der Krankenstation + + + Breyerhouse Wintercrew Warnung + + + Waldsprecher Sammlerstück, Teil 1 + I am not sure how to translate this but I assume the literal translation of "Forest Talker" is to be used + + + Waldsprecher Sammlerstück, Teil 2 + I am not sure how to translate this but I assume the literal translation of "Forest Talker" is to be used + + + Waldsprecher Sammlerstück, Teil 3 + I am not sure how to translate this but I assume the literal translation of "Forest Talker" is to be used + + + Pleasant Valley Sammlerstück, Teil 1 + + + Pleasant Valley Sammlerstück, Teil 2 + + + Pleasant Valley Sammlerstück, Teil 3 + + + Flyer der Gemeindehalle + + + Rosenkranz + + + Karte von Pleasant Valley + + + Kirchenartefakt + + + Kirchenflyer + + + Nicht zugestellter Brief + + + Zeitungsausschnitt + + + Dankesschreiben + + + Diözesanbericht + + + Joplin's Tagebuch, Teil 1 + + + Joplin's Tagebuch, Teil 2 + + + Waldsprecher Bunker Memo + I am not sure how to translate this but I assume the literal translation of "Forest Talker" is to be used + + + Blutgetränkte Notiz + + + Blutgetränkte Notiz + + + Blutgetränkte Notiz + + + Blutgetränkte Notiz + + + Blutgetränkte Notiz + + + Blutgetränkte Notiz + + + Waldsprecher Wasserkraftwerk Notiz + + + Hank's Tagebuch - Teil 1 + + + Hank's Schlüssel zum Schlosskasten + + + Hausgemachte Suppe + + + Pleasant Valley Geschichte, Teil 1 + + + Pleasant Valley Geschichte, Teil 2 + + + Pleasant Valley Geschichte, Teil 3 + + + Schlüssel zur Seehütte #1 + + + Schlüssel zur Seehütte #2 + + + Schlüssel zur Seehütte #3 + + + Zerrissenes Papier + + + Spaß in der Nebensaison + + + Lily's Einfacher Parka + also corrected spelling from "Lyly's" to "Lily's" + + + Im Sturm verloren + + + Straßenraub + + + Tränenreicher Brief + + + Verrat + + + Milton Postamt Hinweis + + + Hinweis zur Orca-Tankstelle + + + Brief der Milton Kreditgenossenschaft + + + Passagiermanifest + + + ID: S. Gagne + + + ID: G. Russel + + + ID: K. Morrison + + + ID: F. Leblanc + + + ID: D. Belanger + + + ID: R. Tan + + + ID: V. Singh + + + ID: A. Lewis + + + ID: T. Chan + + + ID: O. Gould + + + Manifest für den Gefängnistransport + + + Kellerschlüssel + + + Sprühfarbe + + + Bleak Inlet + + + Steigeisen + + + Ketchup Chips + ????? + + + Ahornsirup + + + Hinweis zur Höhle des Ash Canyon Kletterer + Was not sure if Ash Canyon should be translated or not, so I have left this + + + Ash Canyon Toter Kletterer Hinweis + Was not sure if Ash Canyon should be translated or not, so I have left this + + + Ash Canyon Angelhütten-Tagebuch + Was not sure if Ash Canyon should be translated or not, so I have left this + + + Ash Canyon Hinweis des Bergmanns + Was not sure if Ash Canyon should be translated or not, so I have left this + + + Polaroid Ash Canyon High Meadow + ??? + + + Polaroid Ash Canyon Wolf's Jaw Overlook + ??? + + + Polaroid Bleak Inlet Echo One Radio Tower + ??? + + + Polaroid Coastal Highway Abandoned Lookout + ??? + + + Polaroid Forlorn Muskeg Shortwave Tower + ??? + + + Polaroid Forlorn Muskeg Muskeg Overlook + ??? + + + Polaroid Mystery Lake Forestry Lookout + ??? + + + Polaroid Mystery Lake Lake Overlook + ??? + + + Polaroid Mountain Town Radio Tower + ??? + + + Polaroid Pleasant Valley Signal Hill + ??? + + + Polaroid Hushed River Valley Pensive Vista + ??? + + + Polaroid Timberwolf Mountain Andre's Peak + ??? + + + Polaroid Timberwolf Mountain Tail Section + ??? + + + Ash Canyon + + + Technischer Rucksack + + \ No newline at end of file diff --git a/src/TldSaveEditor.Core/Properties/Resources.it-IT.resx b/src/TldSaveEditor.Core/Properties/Resources.it-IT.resx new file mode 100644 index 0000000..beab26e --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.it-IT.resx @@ -0,0 +1,1956 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Antibiotici + + + Antisettico + + + Antidolorifici + + + Benda + + + Unguento curativo di Vitalba + + + Compresse per purificazione dell'acqua + + + Stimolatore d'emergenza + + + Balaclava + + + Cappello da Baseball + + + Stivali da trekking + + + Guanti da guida + + + Scarpe sportive + + + Giacca a vento + + + Cappello in cotone + + + Sciarpa in lana + + + Cappotto in pelle di Orso + + + Pantaloni Cargo + + + Stivali da combattimento + + + Pantaloni da combattimento + + + Felpa con cappuccio + + + Sciarpa in cotone + + + Camicia + + + Calzini sportivi + + + Stivali in pelle di Cervo + + + Pntaloni in pelle di Cervo + + + Parka urbano + + + Giacca da sci + + + Gilet imbottito + + + Copriorecchie di lana + + + Maglione da pesca + + + Guanti in cotone + + + Pullover + + + Guanti lunghi + + + Eskimo + + + Maglione in lana + + + Stivali isolati + + + Pantaloni da sci + + + Giubbotto sportivo + + + Jeans + + + Scarpe in pelle + + + Parka semplice + + + Intimo termico + + + Calzamaglia in lana + + + Giacca Canadese + + + Giubbotto militare + + + Guanti in lana + + + Stivali tradizionali + + + Camicia a quardi + + + Parka Accessoriato + + + Doppiopetto da marinaio + + + Guanti in pelle di Coniglio + + + Stivali da sci + + + Guanti da sci + + + Tagliavento + + + T-Shirt + + + Cappello in lana canadese + + + Cappotto in pelle di Lupo + + + Camicia in lana + + + Calzini in lana + + + Maglione di lana sottile + + + Sciarpone di lana + + + Cappuccio in pile + + + Scarponi da lavoro + + + Guanti da lavoro + + + Pantaloni da lavoro + + + Carne essicata + + + Merendina + + + Fagioli con maiale + + + Scatoletta di sardine + + + Gambo di stiancia + + + Pianta di stiancia + + + Tazza di caffè + + + Barattolo di caffè + + + Latte condensato + + + Coregone di lago (Cotto) + + + Carne d'Orso (Cotta) + + + Carne di Cervo (Cotta) + + + Coniglio (Cotto) + + + Carne di Lupo (Cotta) + + + Trota iridea (Cotta) + + + Persico Trota (Cotta) + + + Crackers salati + + + Cibo per cani + + + Barretta energetica + + + Barretta ai cereali + + + Tazza di Tè + + + Scatola di Tè + + + Cibo militare MRE + + + Burro d'arachidi + + + Pesche sciroppate + + + Salmone (Crudo) + + + Salmone (Cotto) + + + Corteccia di Betulla + + + Coregone di Lago (Crudo) + + + Carne d'Orso Nero (Cruda) + + + Carne di Cervo (Cruda) + + + Coniglio (Cruda) + + + Carne di Lupo (Cruda) + + + Trota iridea (Cruda) + + + Persico Trota (Crudo) + + + Tè Reishi + + + Tè alla rosa canina + + + Summit Soda + + + Stacy's Grape Soda + + + Orange Soda + + + Zuppa di pomodoro + + + Acqua (Non Sicura) + + + Acqua (Potabile) + + + Accellerante + + + Freccia semplice + + + Freccia rotta + + + Asta per freccia + + + Sacco a pelo in pelle d'Orso + + + Sacco a pelo + + + Arco di fortuna + + + Apriscatole + + + Acciarino + + + Bengala + + + Bengala (colpo pistola) + + + Pistola lanciarazzi + + + Segaccio + + + Mazza + + + Accetta + + + Accetta improvvisata + + + Atrezzi di qualita' + + + Amo + + + Lenza da pesca + + + Tanica di Benzina + + + Lanterna ad Olio + + + Coltello da caccia + + + Coltello improvvisato + + + Combustibile per lanterna + + + Filo + + + Lente d'ingrandimento + + + Giornale arrotolato + + + Fiammiferi di cartone + + + Piede di porco + + + Fucile da caccia + + + Scatola di munizioni per fucile + + + Munizione per fucile + + + Kit di pulizia Revolver + + + Corda da arrampicata + + + Kit da cucito + + + Cote + + + Strumenti semplici + + + Trappola per conigli + + + Torcia + + + Fiammiferi in legno + + + Punta di freccia + + + Pelle d'Orso fresca + + + Pelle d'Orso seccata + + + Alberello di Betulla verde + + + Alberello di Betulla seccato + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Libro + + + Testa di stiancia + + + Panno + + + Carbone + + + Piuma di Corvo + + + ceppo per camino + + + Budelli freschi + + + Budelli seccati + + + Legna d'Abete + + + Pelle fresca + + + Pelle seccata + + + Pelle di Cervo Fresca + + + Pelle di Cervo seccata + + + Alberello d'Acero verde + + + Alberello d'Acero seccato + + + Giornale + + + Lichene Vitalba + + + Pelle di Coniglio fresca + + + Pelle di Coniglio seccata + + + Legno di recupero + + + Fungo Reishi + + + Rosa Canina + + + Rottami di ferro + + + Legna di Cedro + + + Bastone + + + Esca per fuoco + + + Pelle di Lupo fresca + + + Pelle di Lupo seccata + + + Eviscerare le carcasse, Vol. I + + + La cucina selvatica + + + Sopravvivi nella natura! + + + Il pescator ghiacciato + + + Guida del pioniere alle armi da fuoco + + + Pistole a go-go per esperti + + + Accellerante + + + Accellerante + + + Tronchesi + + + Batteria d'auto + + + Compression Bandage + + + Ascia antincentido + + + Filo da Pesca + + + Acciarino + + + Pelle fresca + + + Pila di fogli + + + Torta di zucca + + + Pala + + + Martello insanguinato + + + Zaino di Astrid + + + Emblema della chiesa + + + Nota della Chiesa EP 1 + + + Codice della Diga + + + Codice della sala controllo della Diga + + + Chiave ufficio Diga + + + Nota del Kit d'emergenza + + + Almanacco del Contadino + + + Manuale di primo soccorso + + + Valigetta Astrid + + + Zaino dell'escursionista + + + Pagina di diario del Cacciatore + + + Frammento di ferraglia + + + Provviste mediche della Diga Carter + + + Chiave della fattoria Paradise Meadows + + + Proiettile di fucile + + + Calzini d'alpinismo + + + Bottiglia d'acqua + + + Bottiglia d'acqua + + + Quarto di Alce + + + Carne d'Alce cruda + + + Carne d'Alce (Cotta) + + + A Note Left Behind + + + Manuale d'istruzione della pesca su ghiaccio + + + Diga idroelettrica Carter + + + Parti del transponder + + + Cibo d'emergenza + + + La storia del declino, Parte Uno + + + Armi a go-go per esperti + + + Cappello in pelle di Coniglio + + + Nota sgualcita + + + Testa della lancia + + + Lancia dell'Orso rotta + + + Parti radio + + + Piante medicinali di Great Bear + + + Lancia d'Orso + + + Aurora Hatch Door Entry Code + + + Intimo termico (Inizio) + + + Guida del pioniere alle armi da fuoco + + + Scarponi di Mackenzie (Inizio) + + + Calzini sportivi (Inizio) + + + Valigetta di Astrid + + + _Winter Forecast + + + Kit di primo soccorso + + + Città di Milton + + + Parka di Mackenzie + + + Medicina nel mio cortile + + + Zaino di Astrid + + + Chiave del cancello dell'area di scarico della diga Carter + + + Mystery Lake & Area + + + Lancia dell'Orso + + + Maglione di Mackenzie (Inizio) + + + La storia del declino, Parte Tre + + + Introduzione al cucito + + + Pantaloni Mackenzie (Inizio) + + + La storia del declino, Parte Quattro + + + Eviscerare le carcasse, Vol. I + + + Maglia di Mackenzie (Inizio) + + + La storia del declino, Parte Due + + + Kit pistola lanciarazzi + + + Torcia + + + Nota dei Forest Talker + + + Nota dei Forest Talker + + + Nota sgualcita + + + Fucile da caccia + + + Chiave del deposito bancario (#13) + + + Coltello di Jeremiah + + + Fucile di Jeremiah riparato + + + Progetto della forgia + + + Chiave del deposito bancario (#20) + + + Nota scritta a mano + + + Nota in carbone + + + Nota della scorta nascosta di Milton + + + Nota illeggibile + + + Cappotto di pelle d'Orso di Jeremiah + + + Codice del Vault bancario + + + Chiave dei caravan del campo di disboscamento + + + Nota insanguinata + + + Volantino dei Forest Talker + + + Diario di Hank - Parte Due + + + Chiave del deposito bancario (#15) + + + Fucile di Jeremiah rotto + + + Chiave del deposito bancario (#7) + + + Chiave della casa del manager della banca + + + Documenti dei Forest Talker + + + Perle di Grey Mother + + + Nota semplice + + + Nota della scorta nascosta nella grotta + + + Scorte dei Forest Talker + + + Cassetta di sicurezza di Grey Mother + + + Chiave del portaoggetti di Lily + + + Lettera per il nipote di Hank + + + Maglia di Mackenzie + + + Parka di Mackenzie + + + Maglione di Mackenzie + + + Stivali di Mackenzie + + + Cappello di Mackenzie + + + Pantaloni di Mackenzie + + + Stivali d'alpinismo + + + Orecchio del Vecchio Orso + + + Preparato di funghi Reishi + + + Preparato di Rosa canina + + + Codice del bunker di Hank + + + Sempre sul bersaglio + + + Introduzione al cucito + + + Pelle d'Alce seccata + + + Sacca di pelle d'Alce + + + Mantello d'Alce + + + Pelle d'Alce fresca + + + Pentola + + + Lattina riciclata + + + Quarto di Lupo + + + Carcassa di Lupo + + + Quarto d'Orso + + + Quarto di Cervo + + + Carcassa di Coniglio + + + Pietra + + + Carbone + + + Libro + + + Combustibili per lanterne + + + Carcassa di Coniglio + + + Riguardo noi + + + Aggiungi oggetto + + + Quantità + + + Quantità (Litri) + + + Punti abilità Arco + + + Libri + + + Progresso libro d'apprendimento + + + Calorie + + + Cancella + + + Punti abilità raccolta delle carcasse + + + Vestiario + + + Punti abilità riparazione vestiti + + + Progressi Fusione Fredda + + + Collezionabile + + + Condizione + + + Punti abilità cucina + + + Calorie correnti + + + Scarica + + + Progresso Macchina Efficiente + + + Fatica + + + Progressi Mastro dei Fuochi + + + Punti abilità accendi fuochi + + + Primo soccorso + + + Cibo + + + Progressi Corridore + + + Congelamento + + + Vita + + + Nascondi + + + Punti abilità pesca ghiacciata + + + Carico infinito + + + Lesioni + + + Inventario + + + Invulnerabile + + + Materiali + + + Immortalità + + + Giocatore + + + Profilo + + + Progressi + + + Ricarica + + + Rimuovi + + + Rimuovi tutto + + + Ripara tutto + + + Punti abilità fucile + + + Rounds in clip + + + Salva + + + Abilità + + + Progressi Camminatore della Neve + + + Test branch + + + Sete + + + Tempo speso in evoluzioni (Ore) + + + The Long Dark (v1.89) Save Editor + + + Strumenti + + + Tratti + + + Sconosciuto + + + Afflizioni + + + Cura + + + Sanguinamento + + + Ustione + + + Dissenteria + + + Infezione + + + Avvelenamento da cibo + + + Caviglia slogata + + + Rischio di infezione + + + Polso slogato + + + Assideramento + + + Ipotermia + + + Riduzione della fatica + + + Sonno migliorato + + + Riscaldamento + + + Rischio di ipotermia + + + Claustrofobia + + + Rischio di parassiti intestinali + + + Parassiti intestinali + + + Rischio di claustrofobia + + + Rischio di congelamento + + + Primo soccorso + + + Vestiti + + + Cibo + + + Strumenti + + + Materiali + + + Collezionabili + + + Libri + + + Nascosto + + + Sconosciuto + + + Modalità Esperienza + + + Pellegrino + + + Viaggiatore + + + Inseguitore + + + Storia + + + Salvataggio senza speranza + + + La Caccia + + + Whiteout + + + La Caccia, Parte 2 + + + Intruso + + + Storia fresca + + + Storia difficile + + + Quattro giorni di neve + + + Sfida dell'Archivista + + + Personalizzato + + + Posizione + + + Autostrada Costiera + + + Mystery Lake + + + Desolation Point + + + Pleasant Valley + + + Timberwolf Mountain + + + Forlorn Muskeg + + + Burrone + + + Crumbling Highway + + + Mappa + + + Budelli + + + Pelli + + + Carne (kg) + + + Villaggio di Montagna + + + Autostrada danneggiata + + + Valle del fiume sommerso + + + Lancia dell'Orso rotta + + + Go! Energy Drink + + + Bende per mani improvvisate + + + Bende per testa improvvisate + + + Cartucce Revolver + + + Scatola di colpi per Revolver + + + Preparato di corteccia di Betulla + + + Tè di Betulla + + + Revolver + + + Punti abilità Revolver + + + Guida alle piccole armi + + + Backups + + + Sblocca 4 giorni di neve 2019 badges + + + Sblocca 4 gironi di neve badges + + + Progressi Camminatore della tormenta + + + Progressi Esperto di Trappole + + + Progresso dritto al cuore + + + Cowichan Sweater + + + Brand + + + Pagina di diario dell'alpinista + + + Corda per arco + + + Legno per arco + + + Collectible Note Common + + + Collectible Note Common + + + Danno da congelamento + + + Coltello di rottami di ferro pulito + + + Map Snippet Mt + + + Mappa del cantiere ferroviario + + + Morfina + + + Nota del contadino del Villaggio di Montagna + + + Chiave della cassetta di sicurezza del Villaggio di Montagna + + + Mappa del Villaggio di Montagna + + + Chiave del deposito del Villaggio di Montagna + + + Brochure del cavalcavia + + + Diario di Rick + + + Spazi vuoti per fucile + + + Bolletta delle utenze + + + Nota della torre idrica + + + Nota della mappa dei Forest Talker + + + Forte polso slogato + + + Nomade + + + Regione + + + Lettere di Jeremiah + + + Apri mappa + + + Razzo della marina + + + La produzione di armi per tutti + + + Proiettile + + + Report di comunicazione + + + Memo del conservificio + + + Notebook del tecnico + + + Zolfo in polvere + + + Barattolo di polvere da sparo + + + Bossolo di Revolver + + + Bossolo di fucile + + + Rottami di piombo + + + Nitrato di potassio + + + Punti abilità Creatore d'armi + + + Ustioni elettriche + + + As the Dead Sleep + + + Cibo di linea - Pollo + + + Cibo di linea - Vegetariano + + + Stivali di Astrid + + + Guanti di Astrid + + + Giacca di Astrid + + + Jeans di Astrid + + + Maglione di Astrid + + + Cappello di Astrid + + + Aurora Observation + + + Nota del detenuto macchiata di sangue + + + Nota del detenuto + + + Direzioni per la scorta nascosta dei detenuti + + + Promemoria del penitenziario di Blackrock + + + Leggende locali - Il più grosso + + + Leggende locali - La grotta perduta + + + Leggende locali - Il cervo fantasma + + + Leggende locali - Sasquatch + + + Avviso del parco + + + Diario del detenuto + + + Diga idroelettrica Carter - Avviso di sicurezza e spegnimento + + + Avviso di manutenzione dell'ascensore + + + Lettera cestinata + + + Chiave dell'armadietto medico + + + Avviso all'equipaggio invernale della Breyerhouse + + + Collezionabile dei Forest Talker, Parte Uno + + + Collezionabile dei Forest Talker, Parte Due + + + Collezionabile dei Forest Talker, Parte Tre + + + Collezionabile di Pleasant Valley, Parte Uno + + + Collezionabile di Pleasant Valley, Parte Due + + + Collezionabile di Pleasant Valley, Parte Tre + + + Volantino della Sala Comunale + + + Rosario + + + Mappa di Pleasant Valley + + + Artefatto della Chiesa + + + Volantino della Chiesa + + + Lettera non recapitata + + + Ritaglio di giornale + + + Lettera di ringraziamento + + + Rapporto diocesano + + + Diario di Joplin, Parte Uno + + + Diario di Joplin, Parte Due + + + Promemoria del bunker dei Forest Talker + + + Nota insanguinata + + + Nota insanguinata + + + Nota insanguinata + + + Nota insanguinata + + + Nota insanguinata + + + Nota insanguinata + + + Nota dei Forest Talker sulla diga + + + Diario di Hank - Parte Uno + + + Chiave della cassetta di sicurezza di Hank + + + Zuppa fatta in casa + + + Storia di Pleasant Valley, Parte Uno + + + Storia di Pleasant Valley, Parte Due + + + Storia di Pleasant Valley, Parte Tre + + + Chiave della Baita sul Lago #1 + + + Chiave della Baita sul Lago #2 + + + Chiave della Baita sul Lago #3 + + + Carta strappata + + + Divertimento fuori stagione + + + Mappa di Lyly + + + Perso nella tempesta + + + Rapina in autostrada + + + Lettera in lacrime + + + Tradimento + + + Nota dell'ufficio postake di Milton + + + Avviso della stazione di rifornimento Orca + + + Lettera della Milton Credit Union + + + Manifesto del passeggero + + + ID: S. Gagne + + + ID: G. Russel + + + ID: K. Morrison + + + ID: F. Leblanc + + + ID: D. Belanger + + + ID: R. Tan + + + ID: V. Singh + + + ID: A. Lewis + + + ID: T. Chan + + + ID: O. Gould + + + Manifesto del trasporto progionieri + + + Chiave del seminterrato + + + Bomboletta spray + + + Bleak Inlet + + + Ramponi + + + Patatine al Ketchup + + + Sciroppo d'Acero + + + Nota dello scalatore di grotte di Ash Canyon + + + Nota dello scalatore morto di Ash Canyon + + + Diario del capanno pesca a Ash Canyon + + + Nota del minatore di Ash Canyon + + + Polaroid Ash Canyon High Meadow + + + Polaroid Ash Canyon Wolf's Jaw Overlook + + + Polaroid Bleak Inlet Echo One Radio Tower + + + Polaroid Coastal Highway Abandoned Lookout + + + Polaroid Forlorn Muskeg Shortwave Tower + + + Polaroid Forlorn Muskeg Muskeg Overlook + + + Polaroid Mystery Lake Forestry Lookout + + + Polaroid Mystery Lake Lake Overlook + + + Polaroid Mountain Town Radio Tower + + + Polaroid Pleasant Valley Signal Hill + + + Polaroid Hushed River Valley Pensive Vista + + + Polaroid Timberwolf Mountain Andre's Peak + + + Polaroid Timberwolf Mountain Tail Section + + + Ash Canyon + + + Zaino tecnico + + \ No newline at end of file diff --git a/src/TldSaveEditor.Core/Properties/Resources.pl-PL.resx b/src/TldSaveEditor.Core/Properties/Resources.pl-PL.resx new file mode 100644 index 0000000..924ef67 --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.pl-PL.resx @@ -0,0 +1,1957 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Antybiotyki + + + Środek antybakteryjny + + + Środki przeciwbólowe + + + Bandaż + + + Opatrunek z brodaczki + + + Tabletki do oczyszczania wody + + + Wstrzykiwacz + + + Kominiarka + + + Czapka z daszkiem + + + Buty trekkingowe + + + Rękawiczki samochodowe + + + Buty do biegania + + + Kurtka wiatrówka + + + Bawełniany toczek + + + Wełniany szalik + + + Palto ze skóry niedźwiedzia + + + Bojówki + + + Buty Wojskowe + + + Spodnie Wojskowe + + + Bluza z kapturem + + + Bawełniany szalik + + + Koszula + + + Skarpety sportowe + + + Buty ze skóry jelenia + + + Spodnie ze skóry jelenia + + + Kurtka Miejska + + + Kurtka narciarska + + + Kamizelka puchowa + + + Opaska na uszy + + + Sweter Rybaka + + + Rękawice z polaru + + + Bluza sportowa + + + Rękawice Ochronne + + + Staromodna Kurtka + + + Gruby wełniany sweter + + + Ocieplane Buty + + + Spodnie Śniegowe + + + Kamizelka sportowa + + + Dżinsy + + + Buty skórzane + + + Prosta kurtka + + + Bielizna termoaktywna + + + Wełniane Kalesony + + + Kraciasta Kurtka + + + Kurtka Wojskowa + + + Wełniane rękawice + + + Buty Eskimosowe + + + Koszula w kratę + + + Kurtka Podróżnika + + + Kurtka Marynarska + + + Rękawice ze skóry królika + + + Buty narciarskie + + + Rękawice Narciarskie + + + Lekka kurtka + + + Koszulka + + + Wełniany toczek + + + Palto ze skóry wilka + + + Wełniana Koszula + + + Wełniane skarpety + + + Wełniany sweter + + + Wełniany Szalik + + + Kaptur z polaru + + + Buty robocze + + + Rękawice robocze + + + Spodnie Robocze + + + Suszone mięso + + + Baton + + + Fasolka po bretońsku + + + Sardynki w puszce + + + Łodyga Pałki + + + Pałka + + + Kubek kawy + + + Puszka Kawy + + + Mleko Skondensowane + + + Sieja Kanadyjska (gotowana) + + + Mięso niedźwiedzia (gotowane) + + + Jelenina (gotowana) + + + Królik (gotowany) + + + Mięso wilka (gotowane) + + + Pstrąg Tęczowy (gotowany) + + + Bass Małogębowy (gotowany) + + + Krakersy + + + Karma dla psa + + + Baton energetyczny + + + Batonik zbożowy + + + Kubek Herbaty Ziołowej + + + Herbata Ziołowa + + + Racje wojskowe + + + Masło Orzechowe + + + Brzoskwinie w puszce + + + Kiżucz (surowy) + + + Kiżusz (gotowany) + + + Kora brzozy + + + Sieja Kanadyjska (surowa) + + + Mięso niedźwiedzia czarnego + + + Jelenina (surowa) + + + Królik (surowy) + + + Mięso wilka (surowe) + + + Pstrąg Tęczowy (surowy) + + + Bass Małogębowy (surowy) + + + Herbata z grzyba reishi + + + Herbata z owoców dzikiej róży + + + Napój Summit + + + Napój winogronowy Stacy's + + + Napój o smaku pomarańczowym + + + Zupa Pomidorowa + + + Woda (nieuzdatniona) + + + Woda (zdatna do picia) + + + Katalizator + + + Zwykła strzała + + + Złamana strzała + + + Promień strzały + + + Śpiwór ze skóry niedźwiedzia + + + Śpiwór + + + Łuk survivalowy + + + Otwieracz do puszek + + + Podpalacz + + + Flara + + + Raca + + + Pistolet sygnałowy + + + Piła do metalu + + + Młot + + + Siekierka + + + Improwizowana siekierka + + + Narzędzia wysokiej jakości + + + Haczyk + + + Przybory wędkarskie + + + Kanister + + + Lampa naftowa + + + Nóż myśliwski + + + Improwizowany nóż + + + Paliwo do lampy + + + Żyłka + + + Lupa + + + Rolka papieru gazetowego + + + Tekturowe zapałki + + + Łom + + + Karabin myśliwski + + + Amunicja do karabinu + + + Pocisk do karabinu + + + Zestaw do czyszczenia broni palnej + + + Lina wspinaczkowa + + + Przybornik do szycia + + + Osełka + + + Proste narzędzia + + + Sidła + + + Pochodnia + + + Drewniane zapałki + + + Grot + + + Świeża skóra niedźwiedzia czarnego + + + Wysuszona skóra z niedźwiedzia czarnego + + + Świerzo ścięta gałąź brzozy + + + Wysuszona gałąź brzozy + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Książka + + + Kolba Pałki + + + Tkanina + + + Węgiel + + + Pióro kruka + + + Brykiet + + + Świeże jelito + + + Wysuszone jelito + + + Drewno jodły + + + Świeża skóra + + + Suszona skóra + + + Świeża skóra jelenia + + + Suszona skóra z jelenia + + + Świeżo ścięta gałąż klonu + + + Wysuszona gałąź klonu + + + Papier gazetowy + + + Brodaczka + + + Świeża skóra królika + + + Suszona skóra z królika + + + Drewno z odzysku + + + Grzyb reishi + + + Owoc dzikiej róży + + + Złom + + + Drewno cedrowe + + + Patyk + + + Gotowa podpałka + + + Świeża skóra z wilka + + + Suszona skóra z wilka + + + Oprawianie Zwierzyny, Tom I + + + Gotowanie na Łonie Natury + + + Przetrwaj w Dziczy! + + + Wędkowanie na Lodzie + + + Strzelectwo dla osadników + + + Broń palna dla zaawansowanych! + + + Katalizator + + + Katalizator + + + Nożyce do drutu + + + Bateria Samochodowa + + + Opaska Uciskowa + + + Topór Strażacki + + + Żyłka + + + Krzesiwo + + + Świeża skóra + + + Stos papierów + + + Ciasto dyniowe + + + Łopata + + + Krwawy młot + + + Plecak Astrid + + + Hymn Kościelny + + + Notatka Kościelna EP1 + + + Kod do Tamy + + + Kod do sterowni zapory + + + Klucz do biura + + + Notatka do zestawu bezpieczeństwa + + + Almanach Farmera + + + Poradnik Pierwszej Pomocy + + + Kasetka Astrid + + + Plecak Podróżnika + + + Strona z dziennika łowcy + + + Metalowy odłamek + + + Zapasy leków Carter Hydro + + + Klucz do farmy „Rajskie Łąki” + + + Kule do karabinu + + + Skarpety alpinistyczne + + + Butelka wody + + + Butelka wody + + + Kawałek łosia + + + Mięso łosia + + + Mięso łosia (gotowane) + + + Pozostawiona Notatka + + + Wędkowanie na lodzie + + + Zapora Cartera + + + Części transponderów + + + Racja żywnościowa + + + Historia Upadku, część pierwsza + + + Broń palna dla zaawansowanych! + + + Czapka ze skóry królika + + + Zmięta notatka + + + Grot włóczni + + + Złamana włócznia na niedźwiedzie + + + Części do radiostacji + + + Rośliny lecznicze Wielkiego Niedźwiedzia + + + Włócznia na niedźwiedzie + + + Kod otwierający właz przy zorzy + + + Bielizna termoaktywna + + + Strzelectwo dla osadników + + + Buty Mackenziego + + + Skarpety sportowe + + + Kasetka Astrid + + + Zimowa prognoza + + + Apteczka + + + Miasteczko Milton + + + Kurtka Mackenziego + + + Leki w ogródku za domem + + + Plecak Astrid + + + Klucz do bramy składu przy Zaporze Cartera + + + MIEJSCE: Jezioro Tajemnic i okolice + + + Włócznia na niedźwiedzie + + + Sweter Mackenziego + + + Historia Upadku, część trzecia + + + Jak spod igły + + + Spodnie Mackenziego + + + Historia Upadku, część czwarta + + + Oprawianie zwierzyny, tom I + + + Koszula Mackenziego + + + Historia Upadku, część druga + + + Pistolet sygnałowy + + + Latarka + + + Wiadomość od Leśnego Głosu + + + Wiadomość od Leśnego Głosu + + + Zmięta kartka + + + Karabin myśliwski + + + Klucz do sejfu bankowego nr 13 + + + Nóż Jeremiaha + + + Naprawiony karabin myśliwski Jeremiaha + + + Projekty hutnicze + + + Klucz do sejfu bankowego nr 20 + + + Ręcznie napisana wiadomość + + + Wiadomość napisana węglem + + + Kartka ze skrytki w Milton + + + Nieczytelna wiadomość + + + Kurka z niedźwiedzia Jeremiaha + + + Kod do skarbca bankowego + + + Klucz do przyczepy w obozowisku drwali + + + Wiadomość umazana krwią + + + Ulotka Leśnych Głosów + + + Dziennik Hanka – część druga + + + Klucz do sejfu bankowego nr 15 + + + Uszkodzony karabin myśliwski Jeremiaha + + + Klucz do sejfu bankowego nr 7 + + + Klucz do domu dyrektora banku + + + Dokumenty Leśnych Głosów + + + Perły Szarej Mateczki + + + Krótka wiadomość + + + Kartka ze skrytki w jaskini + + + Zapasy Leśnych Głosów + + + Sejf Szarej Mateczki + + + Klucz do kufra Lily + + + List do siostrzenicy Hanka + + + Koszula Mackenziego + + + Kurtka Mackenziego + + + Sweter Mackenziego + + + Buty Mackenziego + + + Czapka Mackenziego + + + Spodnie Mackenziego + + + Buty Górskie + + + Ucho starego niedźwiedzia + + + Przygotowane grzyby reishi + + + Przygotowane owoce dzikiej róży + + + Kod do skrytki Hanka + + + Oko na celu + + + Jak spod igły + + + Suszona skóra z łosia + + + Sakwa ze skóry łosia + + + Płaszcz ze skóry łosia + + + Świeża skóra z łosia + + + Garnek + + + Puszka z odzysku + + + Kawałek wilka + + + Tusza wilka + + + Kawałek niedźwiedzia + + + Kawałek jelenia + + + Tusza królika + + + Kamień + + + Węgiel drzewny + + + Książka + + + Paliwo do latarni + + + Tusza królika + + + O programie + + + Dodaj przedmiot + + + Ilość + + + Ilość (litry) + + + Umiejętności Łucznicze + + + Książki + + + Postęp Mola Książkowego + + + Kalorie + + + Anuluj + + + Umiejętność Oprawiania zwierzyny + + + Ubrania + + + Umiejętność Naprawiania Ubrań + + + Postęp Zimnej Fuzji + + + Znajdźki + + + Kondycja + + + Umiejętność Gotowania + + + Aktualne Kalorie + + + Pobierz + + + Postęp Wydajnej Maszyny + + + Zmęczenie + + + Postęp Mistrza Ognia + + + Umiejętność Rozpalania Ognia + + + Pierwsza Pomoc + + + Jedzenie + + + Postęp Biegacza + + + Zamarzanie + + + Zdrowie + + + Ukryte + + + Umiejętność Łowienia + + + Nielimitowany Udźwig + + + Obrażenia + + + Ekwipunek + + + Nieśmiertelność + + + Materiały + + + NeverDie + + + Gracz + + + Profil + + + Postęp + + + Odśwież + + + Usuń + + + Usuń wszystko + + + Napraw wszystko + + + Umiejętność obsługi karabinu + + + Kule w magazynku + + + Zapisz + + + Umiejętności + + + Postęp Człowieka Śniegu + + + Wersje Testowe + + + Pragnienie + + + Czas spędzony na ewolucji (godziny) + + + Edytor Zapisów Gry The Long Dark (v2.27) + + + Narzędzia + + + Cechy + + + Nieznane + + + Ryzyka + + + Wylecz + + + Krwawienie + + + Oparzenia + + + Dyzenteria + + + Infekcja + + + Zatrucie pokarmowe + + + Skręcona kostka + + + Ryzyko infekcji + + + Skręcony nadgarstek + + + Odmrożenie + + + Hipotermia + + + Obniżone zmęczenie + + + Poprawiony odpoczynek + + + Ogrzewanie + + + Ryzyko hipotermii + + + Klaustrofobia + + + Ryzyko pasożytów jelitowych + + + Pasożyty jelitowe + + + Ryzyko klaustrofobii + + + Ryzyko odmrożenia + + + Pierwsza pomoc + + + Ubrania + + + Jedzenie + + + Narzędzia + + + Materiały + + + Znajdźki + + + Książki + + + Ukryte + + + Nieznane + + + Tryb doświadczenia + + + Pielgrzym + + + Traper + + + Prześladowca + + + Historia + + + Beznadziejny ratunek + + + Polowanie, Część Pierwsza + + + Śnieżyca + + + Polowanie, Część Druga + + + Intruz + + + Historia: Świerzak + + + Historia: Zaprawiony + + + Cztery Dni Nocy + + + Wyzwanie: Archiwista + + + Niestandardowy + + + Pozycja + + + Przybrzeżna Autostrada + + + Jezioro Tajemnic + + + Pustkowie + + + Wesoła Dolina + + + Wilcza Góra + + + Opuszczone Torowisko + + + Dolina + + + Stara autostrada na wyspę + + + Mapa + + + Jelita + + + Skóry + + + Mięso (kg) + + + Górskie Miasto + + + Zniszczone tory kolejowe + + + Dolina spokojnej rzeki + + + Złamana włócznia na niedźwiedzie + + + Napój energetyczny Go! + + + Improwizowane owijki na ręce + + + Improwizowane nakrycie głowy + + + Pocisk do rewolweru + + + Amunicja do rewolweru + + + Suszona kora brzozy + + + Herbata z kory brzozy + + + Rewolwer + + + Umiejętność obsługi rewolweru + + + Podręcznik dotyczący planej broni ręcznej + + + Zapasowy + + + Odznaki 4 dni nocy 2019 odblokowane + + + Odblokowane 4 dni nocnych odznak + + + Postępy Blizzard Walker + + + Ekspert traper postęp + + + Straight to the heart progress + + + Cowichan Sweater + + + Piętno + + + Strona Dziennika Wspinacza + + + Łuk + + + Łuk drewna + + + Notatka kolekcjonerska - pospolita + + + Notatka kolekcjonerska - rzadka + + + Frostbite damage + + + Czyszczenie złomu noża + + + Fragment mapy Mt + + + Mapa do stacji kolejowej + + + Morfina + + + Uwaga na farmę w górach + + + Klucz do skrytki w Mountain Town + + + Górska mapa miasta + + + Klucz do sklepu Mountain Town + + + Broszura wiaduktu + + + Dziennik Ricka + + + Puste karabiny + + + Rachunek za media + + + Uwaga na wieżę ciśnień + + + Komentarz do mapy leśnego mówcy + + + Sprained wrist major + + + Koczownik + + + Region + + + Listy Jeremiasza + + + Otwórz Mapę + + + Rozbłysk Morski + + + Praktyczne Rusznikarstwo + + + Pocisk + + + Raport z komunikacji + + + Notatka o konserwach + + + Notatnik Technika + + + Odkurzanie siarki + + + Puszka prochu + + + Obudowa łuski rewolweru + + + Obudowa łuski karabinu + + + Ołów złomu + + + Narzędzie do usuwania kikutów + + + Punkty umiejętności rusznikarskich + + + Electric burns + + + Jak Martwy Sen + + + Jedzenie dla linii lotniczych — kurczak + + + Jedzenie dla linii lotniczych — wegetariańskie + + + Buty Astrid + + + Rękawiczki Astrid + + + Kurtka Astrid + + + Dżinsy Astrid + + + Sweter Astrid + + + Astrid Toczek + + + Obserwacja zorzy polarnej + + + Notatka skazana poplamiona krwią + + + Notatka skazana + + + Wskazówki dotyczące skazanych na pamięć podręczną + + + Notatka penitencjarna Blackrock + + + Lokalne legendy — Ta Wielka + + + Lokalne legendy – Zaginiona jaskinia + + + Legendy lokalne — Duch Stag + + + Lokalne Legendy - Sasquatch + + + Powiadomienie o parkowaniu + + + Wpis do dziennika skazanych + + + Carter Zapora hydroelektryczna - powiadomienie o bezpieczeństwie i wyłączeniu + + + Powiadomienie o konserwacji windy + + + List do kosza + + + Klucz do szafki medycznej do stacji pomocy + + + Ostrzeżenie o zimowej załodze w Breyerhouse + + + Kolekcjonerska mówca leśnego, część pierwsza + + + Kolekcjonerska mówca leśnego, część druga + + + Kolekcjonerski leśny mówca, część trzecia + + + Kolekcjonerska Pleasant Valley, część pierwsza + + + Kolekcjonerska Pleasant Valley, część druga + + + Kolekcjonerska Pleasant Valley, część trzecia + + + Ulotka Sali Wspólnoty + + + Różaniec + + + Mapa Przyjemnej Doliny + + + Artefakt kościelny + + + Ulotka kościelna + + + Niedostarczony list + + + Wycinek z gazety + + + List z podziękowaniami + + + Sprawozdanie diecezjalne + + + Dziennik Joplin, część pierwsza + + + Dziennik Joplin, część druga + + + Notatka z bunkra leśnego mówcy + + + Notatka przesiąknięta krwią + + + Notatka przesiąknięta krwią + + + Notatka przesiąknięta krwią + + + Notatka przesiąknięta krwią + + + Notatka przesiąknięta krwią + + + Notatka przesiąknięta krwią + + + Uwaga na tamę leśnego mówcy + + + Dziennik Hanka – część pierwsza + + + Klucz do skrzynki zamka Hanka + + + Domowa Zupa + + + Przyjemna historia doliny, część pierwsza + + + Przyjemna historia doliny, część druga + + + Przyjemna historia doliny, część trzecia + + + Klucz do domku nad jeziorem #1 + + + Klucz do domku nad jeziorem #2 + + + Klucz do domku nad jeziorem #3 + + + Podarty papier + + + Zabawa poza sezonem + + + Mapa Lily + + + Zagubieni w burzy + + + Napad na autostradę + + + Płaczliwy list + + + Zdrada + + + Uwaga na pocztę w Milton + + + Informacja o sklepie z gazem Orca + + + List z Milton Banku + used Bank in place of credit union + + + Manifest Pasażera + + + ID: S. Gagne + + + ID: G. Russel + + + ID: K. Morrison + + + ID: F. Leblanc + + + ID: D. Belanger + + + ID: R. Tan + + + ID: V. Singh + + + ID: A. Lewis + + + ID: T. Chan + + + ID: O. Gould + + + Manifest Transportu Więziennego + + + Klucz do piwnicy + + + Farba w sprayu + + + Ponury wlot + + + Notatka Jaskini Wspinacza w Popielnym Kanionie + + + Notatka od zmarłego wspinacza z kanionu popiołu + + + Dziennik chaty wędkarskiej Ash Canyon + + + Notatka górnika Ash Canyon + + + Crampons + + + Chipsy keczupowe + + + Syrop klonowy + + + Fragment mapy Mt + + + Polaroid Ash Canyon High Meadow + + + Polaroid Ash Canyon Wolf's Jaw Overlook + + + Polaroid Bleak Inlet Echo One Radio Tower + + + Polaroid Coastal Highway Abandoned Lookout + + + Polaroid Forlorn Muskeg Muskeg Overlook + + + Polaroid Forlorn Muskeg Shortwave Tower + + + Polaroid Mystery Lake Forestry Lookout + + + Polaroid Mystery Lake Lake Overlook + + + Polaroid Mountain Town Radio Tower + + + Polaroid Pleasant Valley Signal Hill + + + Polaroid Hushed River Valley Pensive Vista + + + Polaroid Timberwolf Mountain Andre's Peak + + + Polaroid Timberwolf Mountain Tail Section + + + Popielny Kanion + + \ No newline at end of file diff --git a/src/TldSaveEditor.Core/Properties/Resources.resx b/src/TldSaveEditor.Core/Properties/Resources.resx new file mode 100644 index 0000000..d85df13 --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.resx @@ -0,0 +1,1956 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Antibiotics + + + Antiseptic + + + Painkillers + + + Bandage + + + Old Man's Beard Wound Dressing + + + Water Purification Tablets + + + Emergency Stim + + + Balaclava + + + Baseball Cap + + + Trail Boots + + + Driving Gloves + + + Running Shoes + + + Windbreaker + + + Cotton Toque + + + Wool Scarf + + + Bearskin Coat + + + Cargo Pants + + + Combat Boots + + + Combat Pants + + + Hoodie + + + Cotton Scarf + + + Dress Shirt + + + Sports Socks + + + Deerskin Boots + + + Deerskin Pants + + + Urban Parka + + + Ski Jacket + + + Down Vest + + + Wool Ear Wrap + + + Fisherman's Sweater + + + Fleece Mittens + + + Sweatshirt + + + Gauntlets + + + Old Fashioned Parka + + + Thick Wool Sweater + + + Insulated Boots + + + Snow Pants + + + Sport Vest + + + Jeans + + + Leather Shoes + + + Simple Parka + + + Thermal Underwear + + + Wool Longjohns + + + Mackinaw Jacket + + + Military Coat + + + Wool Mittens + + + Mukluks + + + Plaid Shirt + + + Expedition Parka + + + Mariner's Pea Coat + + + Rabbitskin Mitts + + + Ski Boots + + + Ski Gloves + + + Light Shell + + + T-Shirt + + + Wool Toque + + + Wolfskin Coat + + + Wool Shirt + + + Wool Socks + + + Thin Wool Sweater + + + Long Wool Scarf + + + Fleece Cowl + + + Work Boots + + + Work Gloves + + + Work Pants + + + Beef Jerky + + + Candy Bar + + + Pork and Beans + + + Tin of Sardines + + + Cat Tail Stalk + + + Cat Tail Plant + + + Cup of Coffee + + + Tin of Coffee + + + Condensed Milk + + + Lake Whitefish (Cooked) + + + Bear Meat (Cooked) + + + Venison (Cooked) + + + Rabbit (Cooked) + + + Wolf Meat (Cooked) + + + Rainbow Trout (Cooked) + + + Smallmouth Bass (Cooked) + + + Salty Crackers + + + Dog Food + + + Energy Bar + + + Granola Bar + + + Cup of Herbal Tea + + + Herbal Tea + + + Military-Grade MRE + + + Peanut Butter + + + Pinnacle Peaches + + + Coho Salmon (Raw) + + + Coho Salmon (Cooked) + + + Birch Bark + + + Lake Whitefish (Raw) + + + Black Bear Meat + + + Venison (Raw) + + + Rabbit (Raw) + + + Wolf Meat (Raw) + + + Rainbow Trout (Raw) + + + Smallmouth Bass (Raw) + + + Reishi Tea + + + Rose Hip Tea + + + Summit Soda + + + Stacy's Grape Soda + + + Orange Soda + + + Tomato Soup + + + Water (Unsafe) + + + Water (Potable) + + + Accelerant + + + Simple Arrow + + + Broken Arrow + + + Arrow Shaft + + + Bear Skin Bedroll + + + Bedroll + + + Survival Bow + + + Can Opener + + + Firestriker + + + Flare + + + Flare Shell + + + Distress Pistol + + + Hacksaw + + + Heavy Hammer + + + Hatchet + + + Improvised Hatchet + + + Quality Tools + + + Hook + + + Fishing Tackle + + + Jerry Can + + + Storm Lantern + + + Hunting Knife + + + Improvised Knife + + + Lantern Fuel + + + Line + + + Magnifying Lens + + + Newsprint Roll + + + Cardboard Matches + + + Prybar + + + Hunting Rifle + + + Rifle Ammunition + + + Rifle Cartridge + + + Firearm Cleaning Kit + + + Mountaineering Rope + + + Sewing Kit + + + Whetstone + + + Simple Tools + + + Snare + + + Torch + + + Wood Matches + + + Arrowhead + + + Fresh Black Bear Hide + + + Cured Black Bear Hide + + + Green Birch Sapling + + + Cured Birch Sapling + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Book + + + Cat Tail Head + + + Cloth + + + Coal + + + Crow Feather + + + Firelog + + + Fresh Gut + + + Cured Gut + + + Fir Firewood + + + Fresh Leather + + + Cured Leather + + + Fresh Deer Hide + + + Cured Deer Hide + + + Green Maple Sapling + + + Cured Maple Sapling + + + Newsprint + + + Old Man's Beard Lichen + + + Fresh Rabbit Pelt + + + Cured Rabbit Pelt + + + Reclaimed Wood + + + Reishi Mushroom + + + Rose Hip + + + Scrap Metal + + + Cedar Firewood + + + Stick + + + Tinder Plug + + + Fresh Wolf Pelt + + + Cured Wolf Pelt + + + Field Dressing Your Kill, Vol. I + + + Wilderness Kitchen + + + Survive the Outdoors! + + + The Frozen Angler + + + Frontier Shooting Guide + + + Advanced Guns Guns Guns! + + + Accelerant + + + Accelerant + + + Bolt Cutters + + + Car Battery + + + Compression Bandage + + + Fire Axe + + + Line + + + Flint & Steel + + + Fresh Leather + + + Stack of Papers + + + Pumpkin Pie + + + Shovel + + + Bloody Hammer + + + Astrid's Backpack + + + Church Hymn + + + Church Note EP 1 + + + Dam Code Note + + + Dam Control Room Code + + + Dam Office Key + + + Emergency Kit Note + + + Farmer's Almanac + + + First Aid Manual + + + Astrid's Hardcase + + + Hiker's Backpack + + + Hunter Journal Page + + + Scrap Metal Shard + + + Carter Hydro Medical Supplies + + + Paradise Meadows Farm Key + + + Rifle Bullets + + + Climbing Socks + + + Water Bottle + + + Water Bottle + + + Moose Quarter + + + Moose Meat + + + Moose Meat (Cooked) + + + A Note Left Behind + + + The Frozen Angler + + + Carter Hydro Dam + + + Transponder Parts + + + Emergency Food + + + History of The Collapse, Part One + + + Advanced Guns Guns Guns! + + + Rabbitskin Hat + + + Crumpled Note + + + Spear Head + + + Broken Bear Spear + + + Radio Parts + + + Medicinal Plants of Great Bear + + + Bear Spear + + + Aurora Hatch Door Entry Code + + + Thermal Underwear (Start) + + + Frontier Shooting Guide + + + Mackenzie's Boots (Start) + + + Sports Socks (Start) + + + Astrid's Hardcase + + + Winter Forecast + + + First Aid Kit + + + Town of Milton + + + Mackenzie's Parka + + + Medicine in my backyard + + + Astrid's Backpack + + + Carter Hydro Staging Area Gate Key + + + Mystery Lake & Area + + + Bear Spear + + + Mackenzie's Sweater (Start) + + + History of The Collapse, Part Three + + + A Sewing Primer + + + Mackenzie's Pants (Start) + + + History of the Collapse, Part Four + + + Field Dressing Your Kill, Vol. I + + + Mackenzie's Shirt (Start) + + + History of The Collapse, Part Two + + + Distress Pistol Kit + + + Flashlight + + + Forest Talker Note + + + Forest Talker Note + + + Crumpled Note + + + Hunting Rifle + + + Bank Deposit Box Key (#13) + + + Jeremiah's Knife + + + Jeremiah's Repaired Rifle + + + Forge Blueprints + + + Bank Deposit Box Key (#20) + + + Handwritten Note + + + Charcoal Note + + + Milton Hidden Cache Note + + + Illegible Note + + + Jeremiah's Bearskin Coat + + + Bank Vault Code + + + Logging Camp Trailer Key + + + Blood Soaked Note + + + Forest Talker Flyer + + + Hank's Journal - Part Two + + + Bank Deposit Box Key (#15) + + + Jeremiah's Broken Rifle + + + Bank Deposit Box Key (#7) + + + Bank Manager's House Key + + + Forest Talker Documents + + + Grey Mother's Pearls + + + Simple Note + + + Cave Hidden Cache Note + + + Forest Talker Supplies + + + Grey Mother's Safety Deposit Box + + + Lily's Trunk Key + + + Letter for Hank's Niece + + + Mackenzie's Shirt + + + Mackenzie's Parka + + + Mackenzie's Sweater + + + Mackenzie's Boots + + + Mackenzie's Toque + + + Mackenzie's Pants + + + Mountaineering Boots + + + The Old Bear's Ear + + + Prepared Reishi Mushrooms + + + Prepared Rose hips + + + Hank's Prepper Cache Code + + + Stay On Target + + + A Sewing Primer + + + Cured Moose Hide + + + Moose-Hide Satchel + + + Moose-Hide Cloak + + + Fresh Moose Hide + + + Cooking Pot + + + Recycled Can + + + Wolf Quarter + + + Wolf Carcass + + + Bear Quarter + + + Deer Quarter + + + Rabbit Carcass + + + Stone + + + Charcoal + + + Book + + + Lantern Fuel + + + Rabbit Carcass + + + About + + + Add item + + + Amount + + + Amount (liters) + + + Archery skillpoints + + + Books + + + Book smarts progress + + + Calories + + + Cancel + + + Carcass harvesting skillpoints + + + Clothing + + + Clothing repairing skillpoints + + + Cold fusion progress + + + Collectible + + + Condition + + + Cooking skillpoints + + + Current calories + + + Download + + + Efficient machine progress + + + Fatigue + + + Fire master progress + + + Fire starting skillpoints + + + First Aid + + + Food + + + Free runner progress + + + Freezing + + + Health + + + Hidden + + + Ice fishing skillpoints + + + Infinite carry + + + Injuries + + + Inventory + + + Invulnerable + + + Materials + + + Never die + + + Player + + + Profile + + + Progress + + + Refresh + + + Remove + + + Remove all + + + Repair all + + + Rifle skillpoints + + + Rounds in clip + + + Save + + + Skills + + + Snow walker progress + + + Test branch + + + Thirst + + + Time spent evolving (hours) + + + The Long Dark (v2.27) Save Editor + + + Tools + + + Traits + + + Unknown + + + Afflictions + + + Cure + + + Blood loss + + + Burns + + + Dysentery + + + Infection + + + Food poisoning + + + Sprained ankle + + + Infection risk + + + Sprained wrist + + + Frostbite + + + Hypothermia + + + Reduced fatigue + + + Improved rest + + + Warming up + + + Hypothermia risk + + + Cabin fever + + + Intestinal parasites risk + + + Intestinal parasites + + + Cabin fever risk + + + Frostbite risk + + + First Aid + + + Clothing + + + Food + + + Tools + + + Materials + + + Collectible + + + Books + + + Hidden + + + Unknown + + + Experience mode + + + Pilgrim + + + Voyageur + + + Stalker + + + Story + + + Hopeless Rescue + + + The Hunted + + + Whiteout + + + The Hunted, Part 2 + + + Interloper + + + Story Fresh + + + Story Hardened + + + Four Days Of Night + + + Challenge Archivist + + + Custom + + + Position + + + Coastal Highway + + + Mystery Lake + + + Desolation Point + + + Pleasant Valley + + + Timberwolf Mountain + + + Forlorn Muskeg + + + Ravine + + + Crumbling Highway + + + Map + + + Guts + + + Hides + + + Meat (kg) + + + Mountain Town + + + Broken Railroad + + + Hushed River Valley + + + Broken Bear Spear + + + Go! Energy Drink + + + Improvised Hand Wraps + + + Improvised Head Wrap + + + Revolver Cartridge + + + Revolver Ammunition + + + Prepared Birch Bark + + + Birch Bark Tea + + + Revolver + + + Revolver skillpoints + + + Small Arms Handbook + + + Backups + + + 4 days of night 2019 badges unlocked + + + 4 days of night badges unlocked + + + Blizzard walker progress + + + Expert trapper progress + + + Straight to the heart progress + + + Cowichan Sweater + + + Brand + + + Climber's Journal Page + + + Bow String + + + Bow Wood + + + Collectible Note Common + + + Collectible Note Rare + + + Frostbite damage + + + Knife Scrap Metal Clean + + + Map Snippet Mt + + + Map To Railyard + + + Morphine + + + Mountain Town Farm Note + + + Mountain Town Lock Box Key + + + Mountain Town Map + + + Mountain Town Store Key + + + Overpass Brochure + + + Rick's Journal + + + Rifle Blanks + + + Utilities Bill + + + Water Tower Note + + + Forest Talker Map Note + + + Sprained wrist major + + + Nomad + + + Region + + + Jeremiah's Letters + + + Open map + + + Marine Flare + + + Practical Gunsmithing + + + Bullet + + + Communication Report + + + Cannery Memo + + + The Technician's Notebook + + + Dusting Sulfur + + + Can of Gunpowder + + + Revolver Shell Casing + + + Rifle Shell Casing + + + Scrap Lead + + + Stump Remover + + + Gunsmithing skillpoints + + + Electric burns + + + As the Dead Sleep + + + Airline Food - Chicken + + + Airline Food - Vegetarian + + + Astrid's Boots + + + Astrid's Gloves + + + Astrid's Jacket + + + Astrid's Jeans + + + Astrid's Sweater + + + Astrid Toque + + + Aurora Observation + + + Blood Stained-Convict Note + + + Convict Note + + + Convict Cache Directions + + + Blackrock Penitentiary Memo + + + Local Legends - The Big One + + + Local Legends -The Lost Cave + + + Local Legends - Ghost Stag + + + Local Legends - Sasquatch + + + Park Notice + + + Convict Journal Entry + + + Carter Hydro Dam - Safety & Shutdown Notice + + + Elevator Maintenance Notice + + + Trash Can Letter + + + Aid Station Medical Locker Key + + + Breyerhouse Winter Crew Warning + + + Forest Talker Collectible, Part One + + + Forest Talker Collectible, Part Two + + + Forest Talker Collectible, Part Three + + + Pleasant Valley Collectible, Part One + + + Pleasant Valley Collectible, Part Two + + + Pleasant Valley Collectible, Part Three + + + Community Hall Flyer + + + Rosary + + + Map Of Pleasant Valley + + + Church Artifact + + + Church Flyer + + + Undelivered Letter + + + Newspaper Clipping + + + Thankyou Letter + + + Diocese Report + + + Joplin's Journal, Part One + + + Joplin's Journal, Part Two + + + Forest Talker Bunker Memo + + + Blood Soaked Note + + + Blood Soaked Note + + + Blood Soaked Note + + + Blood Soaked Note + + + Blood Soaked Note + + + Blood Soaked Note + + + Forest Talker Dam Note + + + Hank's Journal - Part One + + + Hank's Lock Box Key + + + Home-made Soup + + + Pleasant Valley History, Part One + + + Pleasant Valley History, Part Two + + + Pleasant Valley History, Part Three + + + Key To Lake Cabin #1 + + + Key To Lake Cabin #2 + + + Key To Lake Cabin #3 + + + Torn Paper + + + Off Season Fun + + + Lily's Map + + + Lost In The Storm + + + Highway Robbery + + + Tearful Letter + + + Betrayal + + + Milton Post Office Note + + + Orca Gas Store Notice + + + Milton Credit Union Letter + + + Passenger Manifest + + + ID: S. Gagne + + + ID: G. Russel + + + ID: K. Morrison + + + ID: F. Leblanc + + + ID: D. Belanger + + + ID: R. Tan + + + ID: V. Singh + + + ID: A. Lewis + + + ID: T. Chan + + + ID: O. Gould + + + Prison Transport Manifest + + + Basement Key + + + Spray Paint + + + Bleak Inlet + + + Crampons + + + Ketchup Chips + + + Maple Syrup + + + Ash Canyon Climber's Cave Note + + + Ash Canyon Dead Climber Note + + + Ash Canyon Fishing Hut Journal + + + Ash Canyon Miner's Note + + + Polaroid Ash Canyon High Meadow + + + Polaroid Ash Canyon Wolf's Jaw Overlook + + + Polaroid Bleak Inlet Echo One Radio Tower + + + Polaroid Coastal Highway Abandoned Lookout + + + Polaroid Forlorn Muskeg Shortwave Tower + + + Polaroid Forlorn Muskeg Muskeg Overlook + + + Polaroid Mystery Lake Forestry Lookout + + + Polaroid Mystery Lake Lake Overlook + + + Polaroid Mountain Town Radio Tower + + + Polaroid Pleasant Valley Signal Hill + + + Polaroid Hushed River Valley Pensive Vista + + + Polaroid Timberwolf Mountain Andre's Peak + + + Polaroid Timberwolf Mountain Tail Section + + + Ash Canyon + + + Technical Backpack + + \ No newline at end of file diff --git a/src/TldSaveEditor.Core/Properties/Resources.ru-RU.Designer.cs b/src/TldSaveEditor.Core/Properties/Resources.ru-RU.Designer.cs new file mode 100644 index 0000000..e69de29 diff --git a/src/TldSaveEditor.Core/Properties/Resources.ru-RU.resx b/src/TldSaveEditor.Core/Properties/Resources.ru-RU.resx new file mode 100644 index 0000000..eda3828 --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.ru-RU.resx @@ -0,0 +1,1950 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Антибиотики + + + Антисептик + + + Обезболивающие + + + Повязка + + + Повязка из старого висящего мха + + + Таблетки для очистки воды + + + Шприц первой помощи + + + Балаклава + + + Бейсбольная кепка + + + Походные ботинки + + + Водительские перчатки + + + Кроссовки + + + Ветровка + + + Шапка из хлопка + + + Шерстяной шарф + + + Медвежья шуба + + + Штаны карго + + + Берцы + + + Армейские штаны + + + Худи + + + Шарф из хлопка + + + Сорочка + + + Спортивные носки + + + Обувь из оленьей кожи + + + Штаны из оленьей кожи + + + Городская парка + + + Лыжная куртка + + + Жилет-пуховик + + + Шерстяная повязка + + + Рыбацкий свитер + + + Флисовые варежки + + + Свитшот + + + Рукавицы + + + Старомодная парка + + + Толстый шерстяной свитер + + + Прорезиненная обувь + + + Зимние штаны + + + Спортивный жилет + + + Джинсы + + + Кожаные туфли + + + Обычная парка + + + Термобелье + + + Шерстяные подштанники + + + Куртка дровосека + + + Шинель + + + Шерстяные варежки + + + Унты + + + Клетчатая рубашка + + + Походная парка + + + Матросский бушлат + + + Варежки из меха кролика + + + Лыжные ботинки + + + Лыжные перчатки + + + Легкая тужурка + + + Футболка + + + Шерстяная шапка + + + Волчья шуба + + + Шерстяная рубашка + + + Шерстяные носки + + + Тонкий шерстяной свитер + + + Длинный шерстяной шарф + + + Флисовый капюшон + + + Рабочие ботинки + + + Рабочие перчатки + + + Рабочие штаны + + + Вяленая говядина + + + Шоколадный батончик + + + Свинина с фасолью + + + Банка сардин + + + Стебель тимофеевки луговой + + + Тимофеевка луговая + + + Чашка кофе + + + Банка кофе + + + Сгущёнка + + + Сельдевидный сиг (приготовленный) + + + Мясо медведя (приготовленное) + + + Оленина (приготовленная) + + + Крольчатина (приготовленная) + + + Мясо волка (приготовленное) + + + Радужная форель (приготовленная) + + + Малоротый окунь (приготовленный) + + + Солёный крекер + + + Корм для собак + + + Энергетический батончик + + + Злаковый батончик + + + Чашка травяного чая + + + Травяной чай + + + Армейский ИРП + + + Арахисовая паста + + + Персики + + + Кижуч (сырой) + + + Кижуч (приготовленный) + + + Березовая кора + + + Сельдевидный сиг (сырой) + + + Мясо черного медведя + + + Оленина (сырая) + + + Крольчатина (сырая) + + + Мясо волка (сырое) + + + Радужная форель (сырая) + + + Малоротый окунь (сырой) + + + Чай Рейши + + + Чай из шиповника + + + Газировка "САММИТ" + + + Виноградный лимонад + + + Апельсиновая содовая вода + + + Томатный суп + + + Вода (непитьевая) + + + Вода (питьевая) + + + Горючее + + + Простая стрела + + + Сломанная стрела + + + Древко стрелы + + + Спальный мешок из медвежьей шкуры + + + Спальный мешок + + + Лук для выживания + + + Консервный нож + + + Огниво + + + Факел + + + Факельная ракета + + + Сигнальный пистолет + + + Ножовка + + + Тяжелый молот + + + Топорик + + + Самодельный топор + + + Качественный инструмент + + + Крючок + + + Удочка + + + Канистра с горючим + + + Аварийный фонарь + + + Охотничий нож + + + Самодельный нож + + + Топливо для фонаря + + + Леска + + + Увеличительные стекла + + + Газетный рулон. + + + Картонные спички + + + Гвоздодёр + + + Ружьё + + + Патроны для ружья + + + Ружейный патрон + + + Набор для чистки огнестрельного оружия + + + Альпинистский трос + + + Набор для шитья + + + Точильный камень + + + Простые инструменты + + + Капкан + + + Фонарь + + + Деревянные спички + + + Наконечник стрелы + + + Свежая шкура черного медведя + + + Высушенная шкура черного медведя + + + Зеленое березовое деревце + + + Сухая молодая береза + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Книга + + + Сухой плод тимофеевки луговой + + + Ткань + + + Уголь + + + Перо ворона + + + Полено + + + Свежие кишки + + + Высушенные кишки + + + Еловые дрова + + + Свежая кожа + + + Высушенная кожа + + + Свежая оленья шкура + + + Высушенная оленья шкура + + + Зеленое кленовое деревце + + + Сухой молодой клен + + + Газета + + + Старый висящий мох + + + Свежая шкура кролика + + + Высушенная шкура кролика + + + Древесина + + + Гриб Рейши + + + Шиповник + + + Металлолом + + + Кедровые дрова + + + Палка + + + Трут + + + Свежая волчья шкура + + + Высушенная волчья шкура + + + Разделка туши в полевых условиях, том 1 + + + Дикая кухня + + + Выживите на свежем воздухе! + + + Замерзший рыболов + + + Стрельба на фронтире + + + Бах-бабах: продвинутое руководство + + + Горючее + + + Горючее + + + Болторез + + + Аккумулятор + + + Давящая повязка + + + Пожарный топор + + + Леска + + + Огниво + + + Свежая кожа + + + Стопка бумаги + + + Тыквенный пирог + + + Лопата + + + Окровавленый молоток + + + Рюкзак Астрид + + + Церковный гимн + + + Церковные записки, часть 1 + + + Записка с кодом ГЭС + + + Код от зала управления дамбой + + + Ключ от офиса ГЭС + + + Аптечка + + + Альманах фермера + + + Инструкция по первой помощи + + + Футляр Астрид + + + Рюкзак для пешеходных туристов + + + Страница охотничьего журнала + + + Металлический обломок + + + Аптечка ГЭС «Картер» + + + Ключ от фермы «Райские луга» + + + Пули для ружья + + + Альпинистские носки + + + Бутылка воды + + + Бутылка воды + + + Четверть туши лося + + + Мясо лося + + + Мясо лося (приготовленное) + + + Оставленная записка + + + Замерзший рыболов + + + ГЭС «Картер» + + + Детали передатчика + + + Сухпаек + + + История Разрухи. Часть 1 + + + Бах-бабах: продвинутое руководство + + + Шапка из кроличьего меха + + + Смятая записка + + + Острие копья + + + Сломанное копье для охоты на медведя + + + Детали радиопередатчиков + + + Целебные растения Дикого Медведя + + + Копье для охоты на медведя + + + Код от двери светочувствительного бункера + + + Термобелье + + + Стрельба на фронтире + + + Ботинки Маккензи + + + Спортивные носки + + + Футляр Астрид + + + Прогноз на зиму + + + Аптечка + + + Город Милтон + + + Парка Маккензи + + + Медикаменты у меня во дворе + + + Рюкзак Астрид + + + Ключ от ворот к месту временного размещения оборудования ГЭС «Картер» + + + МЕСТО: Загадочное озеро и окрестности + + + Копье для охоты на медведя + + + Свитер Маккензи + + + История Разрухи, часть 3 + + + Шитье для начинающих + + + Штаны Маккензи + + + История Разрухи, часть 4 + + + Разделка туши в полевых условиях, том 1 + + + Рубашка Маккензи + + + История Разрухи, часть 2 + + + Сигнальный пистолет + + + Фонарик + + + Записка Лесных ораторов + + + Записка Лесных ораторов + + + Смятая записка + + + Ружьё + + + Ключ от банковского сейфа (13) + + + Нож Джереми + + + Отремонтированное ружье Джереми + + + Кузнечные чертежи + + + Ключ от банковского сейфа (20) + + + Записка от руки + + + Нацарапанная углем записка + + + Тайник в Милтоне + + + Неразборчивая записка + + + Меховая куртка Джереми + + + Код от банковского хранилища + + + Ключ от вагончика на лесозаготовительной стоянке + + + Записка, испачканная кровью + + + Листовка Лесных ораторов + + + Дневник Хэнка — часть 2 + + + Ключ от банковского сейфа (15) + + + Сломанное ружье Джереми + + + Ключ от банковского сейфа (7) + + + Ключ от дома управляющего банком + + + Документы Лесных ораторов + + + Жемчуг Серой Матери + + + Просто записка + + + Тайник в пещере + + + Тайник Лесных ораторов + + + Сейф Серой Матери + + + Ключ от сундука Лилии + + + Письмо для племянницы Хэнка + + + Рубашка Маккензи + + + Парка Маккензи + + + Свитер Маккензи + + + Ботинки Маккензи + + + Шапка Маккензи + + + Штаны Маккензи + + + Альпинистские ботинки + + + Ухо старого медведя + + + Приготовленные грибы Рейши + + + Приготовленные плоды шиповника + + + Код от оборудованного Хэнком бункера + + + Не упусти цель + + + Шитье для начинающих + + + Высушенная лосиная шкура + + + Сумка из лосиной шкуры + + + Плащ из лосиной шкуры + + + Свежая лосиная шкура + + + Котелок + + + Пустая банка + + + Четверть туши волка + + + Остов волка + + + Четверть туши медведя + + + Четверть туши оленя + + + Туша кролика + + + Камень + + + Древесный уголь + + + Книга + + + Топливо для фонаря + + + Туша кролика + + + О программе + + + Добавить предмет + + + Колличество + + + Колличество (литры) + + + Стрельба из лука + + + Книги + + + Книжный червь + + + Калории + + + Отменить + + + Разделка туш + + + Одежда + + + Починка + + + Холодный синтез + + + Коллекция + + + Состояние + + + Кулинария + + + Текущие калории + + + Скачать + + + Как часы + + + Усталость + + + Эксперт по кострам + + + Разведение огня + + + Первая помощь + + + Еда + + + Бегущий человек + + + Замерзание + + + Здоровье + + + Спрятанное + + + Рыбалка на льду + + + Безграничная сила + + + Повреждение + + + Инвентарь + + + Неуязвимый + + + Материалы + + + Бессмертный + + + Игрок + + + Профиль + + + Прогресс + + + Обновить + + + Удалить + + + Удалить все + + + Починить все + + + Огнестрельное оружие + + + Патроны в обойме + + + Сохранить + + + Навыки + + + Снежный скиталец + + + Сборка "Test branch" + + + Жажда + + + Затраченное время (часы) + + + The Long Dark (v2.27) Редактор сохранений + + + Инструменты + + + Особенности + + + Неизвестное + + + Состояния + + + Лечение + + + Кровотечение + + + Ожоги + + + Дизентерия + + + Инфекция + + + Пищевое отравление + + + Вывих лодыжки + + + Риск заражения + + + Вывих кисти + + + Обморожение + + + Переохлаждение + + + Усталость снизилась + + + Более эффективный отдых + + + Согревание + + + Риск переохлаждения + + + Клаустрафобия + + + Риск кишечных паразитов + + + Кишечные паразиты + + + Риск клаустрафобии + + + Риск обморожения + + + Первая помощь + + + Одежда + + + Еда + + + Инструменты + + + Материалы + + + Коллекция + + + Книги + + + Спрятанное + + + Неизвестное + + + Сложность + + + Пилигрим + + + Скиталец + + + Сталкер + + + Способный выживший + + + Безнадежное спасение + + + Добыча: часть 1 + + + Белая мгла + + + Добыча: часть 2 + + + Незваный гость + + + Выживший-новичок + + + Матерый выживший + + + Четыре дня тьмы + + + Архивариус + + + Персональный + + + Позиция + + + Прибрежное шоссе + + + Загадочное озеро + + + Зона запустения + + + Отрадная долина + + + Волчья гора + + + Одинокая топь + + + Ущелье + + + Старый остров между зонами + + + Карта + + + Кишки (шт.) + + + Шкуры (шт.) + + + Мясо (кг) + + + Милтон + + + Разбитая железная дорога + + + Долина Тихой реки + + + Сломанное копье для охоты на медведя + + + Энергетический напиток Go! + + + Самодельные обмотки для рук + + + Самодельный головной платок + + + Патрон для револьвера + + + Патроны для револьвера + + + Приготовленная березовая кора + + + Березовый чай + + + Револьвер + + + Револьвер + + + Руководство по револьверам + + + Резерв + + + Значки 4DON2019 разблокированы + + + Значки 4DON разблокированы + + + Снежный скиталец + + + Мастер-зверолов + + + Прямо в сердце + + + Этнический свитер + + + Головешка + + + Страница журнала альпиниста + + + Тетива + + + Лук Древесина + + + Общие собранные записки + + + Общие собранные записки + + + Урон он холода + + + Нож для очистки металлолома + + + Фрагмент карты Mt + + + Карта на вокзал + + + Морфий + + + Записка фермы Горного городка + + + Ключ от запертого ящика Горного городка + + + Карта Горного городка + + + Ключ от склада Горного городка + + + Брошура эстакады + + + Журнал Рика + + + Заготовка для ружья + + + Счет за коммунальные услуги + + + Записка Водонапорной башни + + + Карта Лесных ораторов + + + Серьезное растяжение кисти + + + Кочевник + + + Регион + + + Письма Джереми + + + Open map + + + Морской фальшфеер + + + Практические советы для оружейников + + + Пуля + + + Отчет + + + Записка с завода + + + Блокнот техника + + + Серный порошок + + + Банка с порохом + + + Револьверная гильза + + + Ружейная гильза + + + Свинцовый лом + + + Растворитель пней + + + Оружейное дело + + + Электрический ожог + + + Пока мертвые спят + + + Еда из самолета - цыпленок + + + Еда из самолета - вегатарианкский обед + + + Ботинки Астрид + + + Перчатки Астрид + + + Куртка Астрид + + + Джинсы Астрид + + + Свитер Астрид + + + Шапка Астрид + + + Северное сияние + + + Саписка осужденного, испачканная кровью + + + Записка осужденного + + + Указания на тайник осужденных + + + Служебная записка тюрьмы "Черный камень" + + + Местные легенды: Большая рыба + + + Местные легенды: Заброшенная пещера + + + Местные легенды: Призрачный олень + + + Местные легенды: Снежный человек + + + Записка о закрытии парка + + + Запись из дневника осужденного + + + ГЭС "Кратер" - оповещение о закрытии + + + Код к лифтовой + + + Письмо из мусорной корзины + + + Ключ от аптечки в медпункте + + + Предупреждение команде по обслуживанию в зимний период + + + Запись лесного оратора, часть 1 + + + Запись лесного оратора, часть 2 + + + Запись лесного оратора, часть 3 + + + Запись жителя Отрадной Долины, часть 1 + + + Запись жителя Отрадной Долины, часть 2 + + + Запись жителя Отрадной Долины, часть 3 + + + Листовка общественного клуба + + + Четки + + + Карта Отрадной Долины + + + Церковная древность + + + Церковная листовка + + + Недоставленное письмо + + + Газетная вырезка + + + Благодарственное письмо + + + Отчет епархии + + + Журнал Джоплина, часть 1 + + + Журнал Джоплина, часть 2 + + + Записка лесного оратора про бункер + + + Записка, испачканная кровью + + + Записка, испачканная кровью + + + Записка, испачканная кровью + + + Записка, испачканная кровью + + + Записка, испачканная кровью + + + Записка, испачканная кровью + + + Записка лесного оратора с дамбы + + + Дневник Хэнка - часть 1 + + + Ключ от сейфа Хэнка + + + Домашний суп + + + История Отрадной Долины, часть 1 + + + История Отрадной Долины, часть 2 + + + История Отрадной Долины, часть 3 + + + Ключ от домика у озера №1 + + + Ключ от домика у озера №2 + + + Ключ от домика у озера №3 + + + Разорванная бумажка + + + Мертвый сезон + + + Карта Лилии + + + Потерянная в метели + + + На большой дороге + + + Закапанное слезами письмо + + + Измена + + + Записка из почтового отделения Милтона + + + Объявление в магазине АЗС "Косатка" + + + Письмо из кредитного союза Милтона + + + Пассажирский манифест + + + Документы: С. Ганье + + + Документы: Д. Рассел + + + Документы: К. Моррисон + + + Документы: Ф. Леблан + + + Документы: Д. Беланже + + + Документы: Р. Тэн + + + Документы: В. Сингх + + + Документы: А. Льюис + + + Документы: Т. Чэн + + + Документы: О. Гульд + + + Список перевозимых заключенных + + + Ключ от подвала + + + Балончик с краской + + + Бледная бухта + + + Ash Canyon Climber's Cave Note + + + Ash Canyon Dead Climber Note + + + Ash Canyon Fishing Hut Journal + + + Ash Canyon Miner's Note + + + Crampons + + + Кленовый сироп + + + Polaroid Ash Canyon High Meadow + + + Polaroid Ash Canyon Wolf's Jaw Overlook + + + Polaroid Bleak Inlet Echo One Radio Tower + + + Polaroid Coastal Highway Abandoned Lookout + + + Polaroid Forlorn Muskeg Muskeg Overlook + + + Polaroid Forlorn Muskeg Shortwave Tower + + + Polaroid Mystery Lake Forestry Lookout + + + Polaroid Mystery Lake Lake Overlook + + + Polaroid Mountain Town Radio Tower + + + Polaroid Pleasant Valley Signal Hill + + + Polaroid Hushed River Valley Pensive Vista + + + Polaroid Timberwolf Mountain Andre's Peak + + + Polaroid Timberwolf Mountain Tail Section + + + Technical Backpack + + \ No newline at end of file diff --git a/src/TldSaveEditor.Core/Properties/Resources.zh-CN.resx b/src/TldSaveEditor.Core/Properties/Resources.zh-CN.resx new file mode 100644 index 0000000..aa7d734 --- /dev/null +++ b/src/TldSaveEditor.Core/Properties/Resources.zh-CN.resx @@ -0,0 +1,1944 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 关于 + + + 治疗 + + + 添加物品 + + + 身体疾病 + + + 失血 + + + 烧伤 + + + 电气烧伤 + + + 幽居病 + + + 幽居病风险 + + + 痢疾 + + + 食物中毒 + + + 冻伤 + + + Frostbite damage + + + 冻伤风险 + + + 体温过低 + + + 体温过低风险 + + + 缓解疲劳 + + + 感染 + + + 感染风险 + + + 寄生虫病 + + + 寄生虫病风险 + + + 降低疲劳 + + + 踝关节扭伤 + + + 腕关节扭伤 + + + 严重腕关节扭伤 + + + 温暖 + + + 数量 + + + 数量 (公升) + + + 弓术 + + + 备份 + + + 暗无天日的四天徽章解锁 + + + 2019暗无天日四天徽章解锁 + + + 暴雪行者成就进度 + + + 技能书 + + + 书本智慧成就进度 + + + 卡路里 + + + 取消 + + + 尸骸采集 + + + 衣物 + + + 修补 + + + 冷聚变成就进度 + + + 可收藏的物品 + + + 耐久 + + + 烹调 + + + 卡路里 + + + 下载 + + + 高效机械成就进度 + + + 游戏模式 + + + 档案保管员 + + + 亡者沉眠 + + + 猎物 第一部分 + + + 猎物 第二部分 + + + 流浪者 + + + 无望的救援 + + + 白雪茫茫 + + + 自定义 + + + 暗无天日的四天 + + + 入侵者 + + + 朝圣者 + + + 潜行者 + + + 故事-合格生存者 + + + 故事-生存新人 + + + 故事-生存铁人 + + + 航行者 + + + 捕兽专家成就进度 + + + 疲劳度 + + + 生火大师成就进度 + + + 生火 + + + 医疗急救 + + + 食物 + + + 跑酷者成就进度 + + + 寒冷度 + + + 助燃剂 + + + 煤油助燃剂 + + + 中号助燃剂 + + + 航空配餐-鸡肉 + + + 航空配餐-素食 + + + 简单的箭 + + + 箭头 + + + 箭杆 + + + 阿斯特丽德的背包 + + + 阿斯特丽德的背包 (背包) + + + 阿斯特丽德的靴子 + + + 阿斯特丽德的手套 + + + 阿斯特丽德的夹克 + + + 阿斯特丽德的牛仔裤 + + + 阿斯特丽德的毛衣 + + + 阿斯特丽德的无檐羊毛帽 + + + Aurora Hatch Door Entry Code + + + 极光观察 + + + 留下的笔记 + + + 留下的笔记 + + + 巴拉克拉法帽 + + + 银行经理办公室钥匙 + + + 银行金库密码 + + + 桦树皮 + + + 棒球帽 + + + 越野靴 + + + 驾驶手套 + + + 跑鞋 + + + 风衣 + + + 棉布无檐毛线帽 + + + 羊毛围巾 + + + 大熊的耳朵 + + + 新鲜的熊皮 + + + 鞣制的熊皮 + + + 小块熊尸 + + + 熊皮睡袋 + + + 熊皮大衣 + + + 猎熊矛 + + + 损坏的猎熊矛 + + + 损坏的猎熊矛 + + + 猎熊矛 + + + 睡袋 + + + 牛肉干 + + + 加工过的桦树皮 + + + 桦树皮茶 + + + 绿色桦树苗 + + + 风干的桦树苗 + + + 染血的罪犯手记 + + + 罪犯手记 + + + 罪犯藏匿处指示 + + + "黑岩"监狱备忘录 + + + 嗜血锤 + + + 钓鱼用具 + + + 剪线钳 + + + 普通的书 + + + 《紧盯目标》 + + + 普通的书 + + + 打开的书 + + + 普通的书 + + + 《野外美食手册 第一册》 + + + 《荒野厨房》 + + + 普通的书 + + + 普通的书 + + + 打开的书 + + + 普通的书 + + + 《户外生存!》 + + + 打开的书 + + + 普通的书 + + + 《实用制枪术》 + + + 普通的书 + + + 打开的书 + + + 普通的书 + + + 《冰上钓鱼人》 + + + 普通的书 + + + 《初级缝纫指南》 + + + 《轻武器手册》 + + + 《前沿射击指南》 + + + 《铳·枪·炮—高级射击》 + + + 当地传说-湖主 + + + 当地传说-迷失洞穴 + + + 当地传说-幽灵鹿 + + + 当地传说-北美野人 + + + 抗生素 + + + 消毒液 + + + 止疼药 + + + + + + 弓弦 + + + 弓木 + + + 小火棍 + + + 断箭 + + + 耶利米的损坏步枪 + + + 弹头 + + + 米尔顿隐藏补给处 + + + 公园告示 + + + 糖果条 + + + 猪肉豆罐头 + + + 沙丁鱼罐头 + + + Communication Report + + + Cannery Memo + + + The Technician's Notebook + + + 开罐器 + + + 蓄电池 + + + 工装裤 + + + 香蒲 + + + 香蒲的茎干 + + + 香蒲的顶穗 + + + 洞穴隐藏贮藏处笔记 + + + 木炭 + + + 石头教堂 + + + 牧师的留言 + + + 攀岩者的日志 + + + 登山袜 + + + 布料 + + + 煤块 + + + 一杯咖啡 + + + 一罐咖啡 + + + 普通的可收藏信息 + + + 普通的可收藏信息 + + + 军靴 + + + 作战裤 + + + 压迫绷带 + + + 炼乳 + + + 罪犯的日志 + + + 银大马哈鱼 (已烤熟) + + + 湖白鲑 (已烤熟) + + + 熊肉 (已烤熟) + + + 鹿肉 (已烤熟) + + + 驼鹿肉 (已烤熟) + + + 兔肉 (已烤熟) + + + 狼肉 (已烤熟) + + + 虹鳟鱼 (已烤熟) + + + 小嘴鲈鱼 (已烤熟) + + + 锅子 + + + 连帽衫 + + + 棉布围巾 + + + 礼服衬衫 + + + 运动袜 + + + 运动袜 (初始) + + + 印第安式厚毛衣 + + + 咸饼干 + + + 乌鸦羽毛 + + + 大坝控制室密码 + + + 卡特水电大坝--安全与关停通知 + + + 大坝控制室代码信息 + + + 电梯维护说明 + + + Carter Hydro Staging Area Gate Key + + + 垃圾桶里的信件 + + + 急救站医药箱钥匙 + + + 大坝办公室钥匙 + + + 布雷耶豪斯冬季员工警告 + + + 鹿皮靴 + + + 鹿皮裤 + + + 狗粮 + + + 城市风雪大衣 + + + 滑雪衫 + + + 羽绒背心 + + + 硫分 + + + 羊毛耳套 + + + 急救箱说明 + + + 强心针 + + + 士力架 (能量棒) + + + 教堂圣器 + + + 教堂传单 + + + 未发出的信件 + + + 剪报 + + + 感谢信 + + + 教区报告 + + + 乔普林的日记-第一部分 + + + 乔普林的日记-第二部分 + + + 森林代言人地堡备忘录 + + + 沾血的笔记 + + + 沾血的笔记 + + + 沾血的笔记 + + + 沾血的笔记 + + + 沾血的笔记 + + + 沾血的笔记 + + + 森林代言人收藏品-第一部分 + + + 森林代言人收藏品-第二部分 + + + 森林代言人收藏品-第三部分 + + + 宜人山谷收藏品-第一部分 + + + 宜人山谷收藏品-第二部分 + + + 宜人山谷收藏品-第三部分 + + + 社区会堂传单 + + + 串珠 + + + 宜人山谷的地图 + + + 银行保管箱钥匙 (#15) + + + 年历 + + + 消防斧 + + + 加工木材 + + + 打火机 + + + 医疗急救 + + + 渔夫毛衣 + + + 鱼线 + + + 耶利米的步枪 + + + 信号棒 + + + 信号枪 + + + 照明弹 (信号弹) + + + 海军陆战队信号弹 + + + 手电 + + + 羊绒连指手套 + + + 运动衫 + + + 燧石 (打火石) + + + 应急食品 + + + 森林代言人大坝留言 + + + 森林代言人的传单 + + + 森林代言人的文件 + + + 森林代言人地图提示 + + + 森林代言人便条 + + + 森林代言人便条 + + + 锻造蓝图 + + + 长手套 + + + Winter Forecast + + + 格兰诺拉燕麦卷 + + + 一杯花茶 + + + 一罐花茶 + + + 登山靴 + + + 灰色母亲的珠宝 + + + 莉莉的储物箱钥匙 + + + 火药罐 + + + 新鲜的内脏 + + + 已风干的内脏 + + + 钢锯 + + + 重锤 + + + 汉克的生还者贮藏处密码 + + + 汉克的日记 第一部分 + + + 汉克的日记 第二部分 + + + 汉克的保管箱的钥匙 + + + 给汉克侄女的信 + + + 阿斯特丽德的结实小箱 + + + 阿斯特丽德的结实小箱 (背包) + + + 冷杉木 + + + 斧头 + + + 简易小斧 + + + 木炭便条 + + + 皱巴巴的笔记 EP1 + + + 简单的便条 + + + 字迹模糊的笔记 + + + 手写的笔记 + + + 沾染鲜血的便条 + + + 绷带 + + + 老式风雪大衣 + + + 厚羊毛衫 + + + 高级工具箱 + + + 徒步旅行者的背包 + + + 自制的汤 + + + 鱼钩 + + + 渔具 + + + 猎人日志 + + + 简易头巾 + + + 简易扎手带 + + + 橡胶靴 + + + 雪地裤 (雪花裤) + + + 运动背心 + + + 牛仔裤 + + + 耶利米的小刀 + + + 耶利米的熊皮大衣 + + + 油桶 + + + 防风油灯 + + + 番茄酱薯条 + + + 捕猎者小刀 + + + 简易小刀 + + + 小刀废金属 + + + 干净的小刀废金属 + + + Carter Hydro Dam + + + History of The Collapse, Part One + + + History of The Collapse, Part Two + + + History of The Collapse, Part Three + + + History of the Collapse, Part Four + + + Town of Milton + + + Mystery Lake & Area + + + 宜人山谷历史-第一部分 + + + 宜人山谷历史-第二部分 + + + 宜人山谷历史-第三部分 + + + 湖滨小屋钥匙 #1 + + + 湖滨小屋钥匙 #2 + + + 湖滨小屋钥匙 #3 + + + 撕裂的纸张 + + + 皱巴巴的笔记 + + + 非开放季节的快乐 + + + 伐木场活动房钥匙 + + + 灯油 + + + 灯油 + + + 皮革 + + + 已加工的皮革 + + + 新鲜的鹿皮 + + + 鞣制的鹿皮 + + + 皮鞋 + + + 新鲜的皮革 + + + 耶利米的信件 + + + 简易风雪大衣 + + + 莉莉的地图 + + + 鱼线 + + + 保暖内衣 + + + 保暖内衣 (初始) + + + 羊毛裤 + + + 麦基诺呢厚夹克 + + + 放大镜 + + + 绿色枫树苗 + + + 已风干的枫树苗 + + + 地图片段 Mt + + + 枫糖糖浆 + + + Map To Railyard + + + 卡特水电药品 + + + 急救箱 + + + 军用大衣 + + + 迷失在风暴中 + + + 银行保管箱钥匙 (#7) + + + 银行保管箱钥匙 (#13) + + + 银行保管箱钥匙 (#20) + + + 拦路抢劫 + + + Medicine in my backyard + + + 沾有泪水的信件 + + + 背叛 + + + 米尔顿邮局留言 + + + 欧卡加油站商店告示 + + + 羊毛连指手套 + + + 新鲜的驼鹿皮 + + + 驼鹿皮背包 + + + 驼鹿皮斗篷 + + + 鞣制的驼鹿皮 + + + 驼鹿尸块 + + + 吗啡 + + + “天堂草地”农场钥匙 + + + 邻居的便条 + + + 保管箱钥匙 + + + 山间小镇地图 + + + 山间小镇商店钥匙 + + + 军用速食口粮 + + + 皮制软靴 + + + 报纸 + + + 一卷报纸 + + + 米尔顿信用合作社信件 + + + 灰色母亲的保管箱 + + + 老君须 (胡须地衣) + + + 老君须伤口敷料 (胡须地衣伤口敷料) + + + 通关手册 + + + 盒装火柴 + + + 纸堆 + + + 乘客名单 + + + 花生酱 + + + 极品桃子 + + + 兔子尸体 + + + 格子花呢上衣 + + + ID: S. Gagne + + + ID: G. Russel + + + ID: K. Morrison + + + ID: F. Leblanc + + + ID: D. Belanger + + + ID: R. Tan + + + ID: V. Singh + + + ID: A. Lewis + + + ID: T. Chan + + + ID: O. Gould + + + 远征风雪大衣 + + + 囚犯转移名单 + + + 撬棍 + + + 南瓜派 + + + 陆战队扣领短上衣 + + + 兔子的尸骸 + + + 新鲜的兔皮 + + + 鞣制的兔皮 + + + 兔皮帽 + + + 兔皮连指手套 + + + Radio Parts + + + 银鲑鱼 (生) + + + 湖白鲑 (生) + + + 熊肉 (生) + + + 鹿肉 (生) + + + 驼鹿肉 (生) + + + 兔肉 (生) + + + 狼肉 (生) + + + 虹鳟鱼 (生) + + + 小嘴鲈鱼 (生) + + + 旧木材 + + + 回收的空罐 + + + 灵芝 + + + 制好的灵芝 + + + 灵芝茶 + + + 左轮手枪 + + + 一盒左轮手枪弹药 + + + 左轮手枪弹壳 + + + 左轮手枪子弹 + + + 瑞克的日志 + + + 猎枪 + + + 一盒猎枪弹药 + + + 步枪弹壳 + + + 猎枪子弹 + + + 空膛猎枪 + + + 猎枪子弹 + + + 猎枪清理套件 + + + 猎枪 + + + 登山绳 + + + 玫瑰果 + + + 制好的玫瑰果 + + + 玫瑰果茶 + + + 地下室钥匙 + + + 废铅 + + + 废金属 + + + 针线包 + + + 磨刀石 + + + 铲子 + + + 简易工具箱 + + + 滑雪靴 + + + 滑雪手套 + + + 滑雪衫 + + + 陷阱 + + + 尖峰饮料 (苏打汽水) + + + 动起来!能量饮料 + + + 史黛西牌葡萄汽水 + + + 橘子汽水 + + + 杉木 + + + 矛尖 + + + 油漆喷罐 + + + 小块鹿尸 + + + 小树枝 + + + 石块 + + + 树桩去除剂 + + + 《缝纫初级读本》 + + + 《前沿射击指南》 + + + 《冰上钓鱼人》 + + + 《大熊地区药用植物》 + + + 《猎物:荒野美食》第一卷 + + + 《铳·枪·炮—高级射击》 + + + T恤 + + + 火引 + + + 番茄汤 + + + 无檐羊毛帽 + + + 火把 + + + 森林代言人补给品 + + + Transponder Parts + + + 催缴单 + + + 水瓶1000ml + + + 水瓶500ml + + + 净水药片 + + + 水 (不安全) + + + 水 (适合饮用) + + + 水塔信息 + + + 麦肯齐的靴子 + + + 麦肯齐的靴子 (初始) + + + 麦肯齐的裤子 + + + 麦肯齐的裤子 (初始) + + + 麦肯齐的大衣 + + + 麦肯齐的大衣 + + + 麦肯齐的上衣 + + + 麦肯齐的上衣 (初始) + + + 麦肯齐的毛衣 + + + 麦肯齐的毛衣 (初始) + + + 麦肯齐的帽子 + + + 狼的尸体 + + + 新鲜的狼皮 + + + 鞣制的狼皮 + + + 小块狼尸 + + + 狼皮大衣 + + + 木质火柴 + + + 羊毛衬衫 + + + 羊毛袜 + + + 薄羊毛衫 + + + 长款羊毛围巾 + + + 羊毛帽 + + + 工作靴 + + + 工作手套 + + + 工作裤 + + + 制枪术 + + + 内脏 + + + 健康值 + + + 隐藏 + + + 隐藏量 + + + 损毁的高速公路 + + + 冰面钓鱼 + + + 无限负重 + + + 病痛 + + + 背包 + + + 免疫伤害 + + + 技能书 + + + 衣物 + + + 可收集物品 + + + 医疗急救 + + + 食物 + + + 隐藏物品 + + + 材料 + + + 工具 + + + 未知物品 + + + 地图 + + + 材料 + + + 肉(千克) + + + 永不死亡 + + + 开放地图 + + + 人物 + + + 位置 + + + 徽章 + + + 进度 + + + 刷新 + + + 区域 + + + 凄凉的入口 + + + 沿海公路 + + + 林狼雪岭 + + + 公路废墟 + + + 神秘湖 + + + 孤寂沼地 + + + 山间小镇 + + + 深谷 + + + 寂静河谷 + + + 宜人山谷 + + + 断开的铁路 + + + 荒芜据点 + + + 删除物品 + + + 删除所有物品 + + + 恢复所有物品耐久 + + + 左轮手枪 + + + 步枪火器 + + + 弹夹内子弹 + + + 保存修改 + + + 技能 + + + 雪地行者成就进度 + + + 发自内心成就进度 + + + 测试开关 + + + 口渴度 + + + 已加工时间 (小时) + + + The Long Dark 漫漫长夜 存档编辑器 版本 + + + 工具 + + + 徽章成就完成进度 + + + 未知 + + + Polaroid Ash Canyon High Meadow + + + Polaroid Ash Canyon Wolf's Jaw Overlook + + + Polaroid Bleak Inlet Echo One Radio Tower + + + Polaroid Coastal Highway Abandoned Lookout + + + Polaroid Forlorn Muskeg Muskeg Overlook + + + Polaroid Forlorn Muskeg Shortwave Tower + + + Polaroid Mystery Lake Forestry Lookout + + + Polaroid Mystery Lake Lake Overlook + + + Polaroid Mountain Town Radio Tower + + + Polaroid Pleasant Valley Signal Hill + + + Polaroid Hushed River Valley Pensive Vista + + + Polaroid Timberwolf Mountain Andre's Peak + + + Polaroid Timberwolf Mountain Tail Section + + + Ash Canyon + + \ No newline at end of file diff --git a/src/TldSaveEditor.Core/SaveGameManager.cs b/src/TldSaveEditor.Core/SaveGameManager.cs new file mode 100644 index 0000000..da62380 --- /dev/null +++ b/src/TldSaveEditor.Core/SaveGameManager.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace The_Long_Dark_Save_Editor_2.Helpers +{ + public static class SaveGameManager + { + public class SaveInfo + { + public string Name { get; set; } + public string Path { get; set; } + } + + public static List Saves { get; set; } + } +} diff --git a/src/TldSaveEditor.Core/Serialization/ByteArrayConverter.cs b/src/TldSaveEditor.Core/Serialization/ByteArrayConverter.cs new file mode 100644 index 0000000..ad37052 --- /dev/null +++ b/src/TldSaveEditor.Core/Serialization/ByteArrayConverter.cs @@ -0,0 +1,48 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace The_Long_Dark_Save_Editor_2.Serialization +{ + /* + * TLD serializes byte arrays as arrays of numbers, but JSON.net default behavior serializes + * them as base64 strings. That's why we need custom converter. Using base64 would reduce TLD + * save file sizes by ~50% btw... + */ + public class ByteArrayConverter : JsonConverter + { + public override bool CanRead + { + get { return false; } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + return; + } + + var data = (byte[])value; + writer.WriteStartArray(); + for (int i = 0; i < data.Length; i++) + { + writer.WriteValue(data[i]); + } + writer.WriteEndArray(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(byte[]); + } + + } + +} diff --git a/src/TldSaveEditor.Core/Serialization/CachedReflection.cs b/src/TldSaveEditor.Core/Serialization/CachedReflection.cs new file mode 100644 index 0000000..adf9543 --- /dev/null +++ b/src/TldSaveEditor.Core/Serialization/CachedReflection.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace The_Long_Dark_Save_Editor_2.Serialization +{ + static class MemberCustomAttributeCache + { + public static Dictionary cache = new Dictionary(); + public static Dictionary cacheNoInherit = new Dictionary(); + } + + static class CachedReflection + { + + public static T GetCustomAttributeCached(this MemberInfo memberInfo, bool inherit) where T : Attribute + { + var cache = inherit ? MemberCustomAttributeCache.cache : MemberCustomAttributeCache.cacheNoInherit; + if (cache.ContainsKey(memberInfo)) + { + return cache[memberInfo]; + } + var attr = memberInfo.GetCustomAttribute(false); + cache.Add(memberInfo, attr); + return attr; + } + } +} diff --git a/src/TldSaveEditor.Core/Serialization/DeserializeAttribute.cs b/src/TldSaveEditor.Core/Serialization/DeserializeAttribute.cs new file mode 100644 index 0000000..3a7cf85 --- /dev/null +++ b/src/TldSaveEditor.Core/Serialization/DeserializeAttribute.cs @@ -0,0 +1,20 @@ +using System; + +namespace The_Long_Dark_Save_Editor_2.Serialization +{ + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public class DeserializeAttribute : Attribute + { + public string From { get; private set; } + public bool Json { get; private set; } + public bool JsonItems { get; private set; } + + public DeserializeAttribute(string from, bool json = false, bool jsonItems = false) + { + From = from; + Json = json; + JsonItems = jsonItems; + } + } + +} diff --git a/src/TldSaveEditor.Core/Serialization/DynamicSerializable.cs b/src/TldSaveEditor.Core/Serialization/DynamicSerializable.cs new file mode 100644 index 0000000..bc39edf --- /dev/null +++ b/src/TldSaveEditor.Core/Serialization/DynamicSerializable.cs @@ -0,0 +1,279 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using The_Long_Dark_Save_Editor_2.Helpers; + +namespace The_Long_Dark_Save_Editor_2.Serialization +{ + public class DynamicSerializable where T : new() + { + + private static JsonLoadSettings jsonLoadSettings = new JsonLoadSettings() { LineInfoHandling = LineInfoHandling.Ignore }; + + private Dictionary>> extraFields = new Dictionary>>(); + public T Obj { get; private set; } + + public DynamicSerializable(string json) + { + Obj = Parse(JObject.Parse(json, jsonLoadSettings), typeof(T)); + + } + + private dynamic Parse(JToken token, Type t, DeserializeAttribute attr = null) + { + bool deserialize = attr?.Json ?? false; + bool deserializeItems = attr?.JsonItems ?? false; + + if (token.Type == JTokenType.Object) + { + if (typeof(IDictionary).IsAssignableFrom(t)) + return ParseDictionary((JObject)token, t, deserializeItems); + return ParseObject((JObject)token, t); + } + else if (token.Type == JTokenType.Array) + { + return ParseArray((JArray)token, t, deserializeItems); + } + else if (token.Type == JTokenType.Boolean) + { + return token.Value(); + } + else if (token.Type == JTokenType.Integer || token.Type == JTokenType.Float) + { + if (t == typeof(byte)) + return token.Value(); + else if (t == typeof(short)) + return token.Value(); + else if (t == typeof(ushort)) + return token.Value(); + else if (t == typeof(int)) + return token.Value(); + else if (t == typeof(uint)) + return token.Value(); + else if (t == typeof(long)) + return token.Value(); + else if (t == typeof(ulong)) + return token.Value(); + else if (t == typeof(float)) + return token.Value(); + else if (t == typeof(long)) + return token.Value(); + else if (t == typeof(decimal)) + return token.Value(); + else + throw new Exception("Unsupported type " + t.FullName); + } + else if (token.Type == JTokenType.String || t == typeof(string)) + { + string s = token.Value(); + if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(EnumWrapper<>)) + { + return Activator.CreateInstance(t, s); + } + else if (t == typeof(DateTime)) + { + return DateTime.Parse(s); + } + if (!deserialize) + return s; + return Parse(JToken.Parse(s, jsonLoadSettings), t); + } + else if (token.Type == JTokenType.Null) + { + return null; + } + else if (token.Type == JTokenType.Date && t == typeof(DateTime)) + { + return token.Value(); + } + else + { + throw new Exception("Invalid token type " + token.Type); + } + } + + private object ParseObject(JObject obj, Type t) + { + var result = Activator.CreateInstance(t); + var props = t.GetProperties(BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.GetCustomAttributeCached(false) == null) + .ToDictionary(p => MemberToName(p)); + var fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public) + .Where(f => f.GetCustomAttributeCached(false) == null) + .ToDictionary(p => MemberToName(p)); + + foreach (var child in obj) + { + if (props.ContainsKey(child.Key)) + { + var prop = props[child.Key]; + var attr = prop.GetCustomAttributeCached(false); + var childType = prop.PropertyType; + var childVal = Parse(child.Value, childType, attr); + try { prop.SetValue(result, childVal); } + catch (Exception ex) { throw DescribeAssignError(t, child.Key, childType, childVal, ex); } + } + else if (fields.ContainsKey(child.Key)) + { + var field = fields[child.Key]; + var attr = field.GetCustomAttributeCached(false); + var childType = field.FieldType; + var childVal = Parse(child.Value, childType, attr); + try { field.SetValue(result, childVal); } + catch (Exception ex) { throw DescribeAssignError(t, child.Key, childType, childVal, ex); } + } + else + { + if (!extraFields.ContainsKey(result)) + extraFields.Add(result, new List>()); + extraFields[result].Add(child); + } + } + return result; + } + + private static Exception DescribeAssignError(Type owner, string member, Type memberType, object value, Exception inner) + { + var valDesc = value == null ? "null" : $"{value.GetType().Name} '{value}'"; + return new Exception( + $"Failed to set {owner.Name}.{member} (declared {memberType.Name}) from {valDesc}: {inner.Message}", inner); + } + + private object ParseArray(JArray obj, Type t, bool deserializeItems) + { + Type elemType = t.GetElementType(); + if (!t.IsArray) + elemType = t.GetGenericArguments().Single(); + Array result = Array.CreateInstance(elemType, obj.Count); + int i = 0; + foreach (var child in obj) + { + result.SetValue(Parse(child, elemType, new DeserializeAttribute(null, deserializeItems)), i++); + } + return ReflectionUtil.ConvertArray(result, t); + } + + private object ParseDictionary(JObject obj, Type t, bool deserializeItems) + { + var dict = (IDictionary)Activator.CreateInstance(t); + var keyType = t.GetGenericArguments()[0]; + var valType = t.GetGenericArguments()[1]; + foreach (var child in obj) + { + dict.Add(Parse(child.Key, keyType), Parse(child.Value, valType, new DeserializeAttribute(null, deserializeItems))); + } + return dict; + } + + public string Serialize() + { + var res = ReconstructObject(Obj); + return JsonConvert.SerializeObject(res); + } + + public object Reconstruct(object o, DeserializeAttribute attr = null) + { + object result = null; + if (o == null) + result = null; + else + { + Type t = o.GetType(); + if (ReflectionUtil.IsBoxed(o) || o is string) + { + result = o; + } + else if (o is IDictionary) + { + result = ReconstructDictionary((IDictionary)o, attr?.JsonItems ?? false); + } + else if (o is ICollection || ReflectionUtil.ImplementsGenericInterface(o.GetType(), typeof(ICollection<>))) + { + result = ReconstructCollection(o, attr?.JsonItems ?? false); + } + else if (o.GetType().IsGenericType && o.GetType().GetGenericTypeDefinition() == typeof(EnumWrapper<>)) + { + return o.ToString(); + } + else + { + result = ReconstructObject(o); + } + } + + if (attr != null && result != null && attr.Json) + return JsonConvert.SerializeObject(result); + return result; + } + + public object ReconstructObject(object o) + { + var res = new Dictionary(); + var t = o.GetType(); + var props = t.GetProperties(BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.GetCustomAttributeCached(false) == null).ToArray(); + var fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.GetCustomAttributeCached(false) == null).ToArray(); + + foreach (var prop in props) + { + var attr = prop.GetCustomAttributeCached(false); + var name = attr?.From ?? prop.Name; + res.Add(name, Reconstruct(prop.GetValue(o), attr)); + } + foreach (var field in fields) + { + var attr = field.GetCustomAttributeCached(false); + var name = attr?.From ?? field.Name; + res.Add(name, Reconstruct(field.GetValue(o), attr)); + } + if (extraFields.ContainsKey(o)) + { + foreach (var kvp in extraFields[o]) + { + res.Add(kvp.Key, kvp.Value); + } + } + return res; + } + + public dynamic ReconstructCollection(dynamic col, bool serializeItems) + { + if (col.GetType() == typeof(byte[])) + { + return col; + } + var result = new List(); + foreach (var item in col) + { + result.Add(Reconstruct(item, new DeserializeAttribute(null, serializeItems))); + } + return result.ToArray(); + } + + public IDictionary ReconstructDictionary(IDictionary dict, bool serializeItems) + { + var res = new Dictionary(); + foreach (var key in dict.Keys) + { + res.Add(Reconstruct(key), Reconstruct(dict[key], new DeserializeAttribute(null, serializeItems))); + } + return res; + } + + private string MemberToName(MemberInfo m) + { + var attr = m.GetCustomAttributeCached(false); + if (attr != null) + return attr.From; + return m.Name; + } + + } +} diff --git a/src/TldSaveEditor.Core/Serialization/EnumWrapper.cs b/src/TldSaveEditor.Core/Serialization/EnumWrapper.cs new file mode 100644 index 0000000..628cfc1 --- /dev/null +++ b/src/TldSaveEditor.Core/Serialization/EnumWrapper.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.ObjectModel; +using The_Long_Dark_Save_Editor_2.Helpers; + +namespace The_Long_Dark_Save_Editor_2.Serialization +{ + public abstract class EnumWrapper : BindableBase + { + public abstract string Value { get; set; } + public abstract ObservableCollection Values { get; } + } + + public class EnumWrapper : EnumWrapper where T : Enum + { + static class EnumValues where T2 : Enum + { + public static ObservableCollection values = new ObservableCollection(Enum.GetNames(typeof(T2))); + } + + public EnumWrapper(string s) + { + Value = s; + } + + private string _value; + public override string Value + { + get { return _value; } + set + { + if (!EnumValues.values.Contains(value)) + { + EnumValues.values.Add(value); + } + SetProperty(ref _value, value); + } + } + + public override ObservableCollection Values + { + get + { + return EnumValues.values; + } + } + + public void SetValue(T val) + { + Value = val.ToString(); + } + + public override string ToString() + { + return _value; + } + + } +} diff --git a/src/TldSaveEditor.Core/Serialization/ReflectionUtil.cs b/src/TldSaveEditor.Core/Serialization/ReflectionUtil.cs new file mode 100644 index 0000000..89ef935 --- /dev/null +++ b/src/TldSaveEditor.Core/Serialization/ReflectionUtil.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace The_Long_Dark_Save_Editor_2.Serialization +{ + public static class ReflectionUtil + { + public static object ConvertArray(Array arr, Type t) + { + if (t.IsArray) + { + return Convert.ChangeType(arr, t); + } + else if ((typeof(IList).IsAssignableFrom(t))) + { + var list = (IList)Activator.CreateInstance(t); + foreach (var item in arr) + { + list.Add(item); + } + return list; + } + else if (t.IsGenericType && typeof(HashSet<>).IsAssignableFrom(t.GetGenericTypeDefinition())) + { + var set = Activator.CreateInstance(t); + MethodInfo method = set.GetType().GetMethod("Add", new Type[] { t.GetGenericArguments()[0] }); + foreach (var item in arr) + { + method.Invoke(set, new object[] { item }); + } + return set; + } + throw new Exception("Unsupported collection type " + t); + } + + public static bool IsBoxed(T value) + { + return + (typeof(T).IsInterface || typeof(T) == typeof(object)) && + value != null && + value.GetType().IsValueType; + } + + public static bool ImplementsGenericInterface(Type t, Type t2) + { + return t.GetInterfaces().Any(i => + i.IsGenericType && + i.GetGenericTypeDefinition() == t2); + } + + } +} diff --git a/src/TldSaveEditor.Core/Services/Dtos.cs b/src/TldSaveEditor.Core/Services/Dtos.cs new file mode 100644 index 0000000..d034594 --- /dev/null +++ b/src/TldSaveEditor.Core/Services/Dtos.cs @@ -0,0 +1,141 @@ +using System.Collections.Generic; + +namespace The_Long_Dark_Save_Editor_2.Services +{ + // UI-agnostic data-transfer objects. Any frontend (web, CLI, desktop) speaks in these + // instead of touching the raw game-data proxy graph. + + public class SaveSummary + { + public int Index { get; set; } + public string Name { get; set; } + public string Path { get; set; } + } + + public class PlayerDto + { + public float Health { get; set; } + public bool NeverDie { get; set; } + public bool Invulnerable { get; set; } + public bool InfiniteCarry { get; set; } + public float CarryWeightLimit { get; set; } + public float Calories { get; set; } + public float Thirst { get; set; } + public float Fatigue { get; set; } + public float Freezing { get; set; } + public float PositionX { get; set; } + public float PositionY { get; set; } + public float PositionZ { get; set; } + public string Region { get; set; } + public string ExperienceMode { get; set; } + public string CustomMode { get; set; } + } + + public class InventoryItemDto + { + public int InstanceId { get; set; } + public string PrefabName { get; set; } + public string DisplayName { get; set; } + public string Category { get; set; } + public float Condition { get; set; } + // Stack quantity for stackable items (matches, ammo, tinder…); null otherwise. + public int? Quantity { get; set; } + // Litres of liquid/fuel/water for items that hold any; null otherwise. + public double? Liters { get; set; } + // Rounds loaded in the clip for firearms; null for non-weapons. + public int? Rounds { get; set; } + } + + public class UpdateItemRequest + { + public float Condition { get; set; } + public int? Quantity { get; set; } + public double? Liters { get; set; } + public int? Rounds { get; set; } + } + + public class AvailableItemDto + { + public string PrefabName { get; set; } + public string DisplayName { get; set; } + public string Category { get; set; } + } + + public class BackupDto + { + public string Path { get; set; } + public string Label { get; set; } + } + + public class RestoreRequest + { + public string BackupPath { get; set; } + } + + public class LoadedSaveDto + { + public string Path { get; set; } + public string DisplayName { get; set; } + public string Region { get; set; } + public List AvailableRegions { get; set; } + public List AvailableModes { get; set; } + public bool HasProfile { get; set; } + } + + public class SkillsDto + { + public int Firestarting { get; set; } + public int CarcassHarvesting { get; set; } + public int Cooking { get; set; } + public int IceFishing { get; set; } + public int Rifle { get; set; } + public int Archery { get; set; } + public int ClothingRepair { get; set; } + public int Revolver { get; set; } + public int Gunsmith { get; set; } + } + + public class AfflictionDto + { + public int Index { get; set; } + public bool Positive { get; set; } + public string Type { get; set; } + public string DisplayName { get; set; } + } + + public class MapDto + { + public string Region { get; set; } + public bool HasMap { get; set; } + public string Image { get; set; } + public double OrigoX { get; set; } + public double OrigoY { get; set; } + public int Width { get; set; } + public int Height { get; set; } + public double PixelsPerCoordinate { get; set; } + public double PlayerX { get; set; } + public double PlayerY { get; set; } + } + + public class MapPositionRequest + { + public double X { get; set; } + public double Y { get; set; } + } + + public class ProfileDto + { + // Feat progress (units differ per feat; see the in-game requirement). + public int BookSmartsHoursResearch { get; set; } + public float ColdFusionElapsedDays { get; set; } + public float EfficientMachineElapsedHours { get; set; } + public int FireMasterFiresStarted { get; set; } + public float FreeRunnerKilometers { get; set; } + public float SnowWalkerKilometers { get; set; } + public int ExpertTrapperRabbitsSnared { get; set; } + public int StraightToHeartItemsConsumed { get; set; } + public float BlizzardWalkerHoursOutside { get; set; } + public bool Badge4DON { get; set; } + public bool Badge4DON2019 { get; set; } + } +} diff --git a/src/TldSaveEditor.Core/Services/SaveEditorService.cs b/src/TldSaveEditor.Core/Services/SaveEditorService.cs new file mode 100644 index 0000000..5cff7e0 --- /dev/null +++ b/src/TldSaveEditor.Core/Services/SaveEditorService.cs @@ -0,0 +1,550 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using The_Long_Dark_Save_Editor_2.Game_data; +using The_Long_Dark_Save_Editor_2.Helpers; + +namespace The_Long_Dark_Save_Editor_2.Services +{ + // UI-agnostic facade over the Core save model. Holds the currently loaded save in memory + // and exposes editable sections as plain DTOs plus the game's domain knowledge + // (item dictionary, regions). Consumed by the HTTP server today, reusable by a CLI later. + // + // A single save is edited at a time. The instance is shared (the server registers it as a + // singleton), so every public method is serialized behind _gate: requests can arrive + // concurrently and the in-memory object graph and the parser's static caches are not + // otherwise thread-safe. + public class SaveEditorService + { + private readonly object _gate = new object(); + + private GameSave _current; + private string _currentName; + private Profile _profile; + + // Directory that holds the survival save files. Defaults to the game's standard + // location, but can be overridden (e.g. for tests or non-standard installs). + public string SavesFolder { get; set; } + + public SaveEditorService() + { + SavesFolder = DefaultSavesFolder(); + } + + public static string DefaultSavesFolder() + { + var local = Util.GetLocalPath(); + return string.IsNullOrEmpty(local) + ? string.Empty + : Path.Combine(local, "Hinterland", "TheLongDark", "Survival"); + } + + public bool HasLoadedSave => _current != null; + + public IReadOnlyList ListSaves() + { + lock (_gate) + { + var members = Util.GetSaveFiles(SavesFolder); + return members + .Select((m, i) => new SaveSummary { Index = i, Name = m.Description, Path = (string)m.Value }) + .ToList(); + } + } + + public LoadedSaveDto Load(string path) + { + lock (_gate) + { + EnsureWithinSavesFolder(path); + if (!File.Exists(path)) + throw new FileNotFoundException("Save file not found", path); + + var save = new GameSave(); + save.LoadSave(path); + _current = save; + _currentName = Path.GetFileName(path); + _profile = TryLoadProfile(path); + return Describe(); + } + } + + public void Save() + { + lock (_gate) + { + EnsureLoaded(); + _current.Save(); + _profile?.Save(); + } + } + + // The global profile (feats, badges) is a user001.* file. It usually sits in the + // game's TheLongDark folder, i.e. the parent of the Survival saves folder — but we + // also check the save's own directory to be safe. The newest matching file wins. + private static Profile TryLoadProfile(string savePath) + { + try + { + var saveDir = Path.GetDirectoryName(savePath); + var parentDir = Path.GetDirectoryName(saveDir); + + var file = new[] { saveDir, parentDir } + .Where(d => !string.IsNullOrEmpty(d) && Directory.Exists(d)) + .SelectMany(d => Directory.GetFiles(d, "user001.*")) + .Where(f => !f.EndsWith(".backup", StringComparison.OrdinalIgnoreCase)) + .OrderByDescending(f => new FileInfo(f).LastWriteTime) + .FirstOrDefault(); + + return file != null ? new Profile(file) : null; + } + catch + { + return null; // profile is optional; ignore load failures + } + } + + private LoadedSaveDto Describe() + { + var scene = _current.Boot.m_SceneName; + var mode = _current.Global.ExperienceModeManager?.m_CurrentModeType; + return new LoadedSaveDto + { + Path = _current.path, + DisplayName = _currentName, + Region = scene?.Value, + AvailableRegions = scene?.Values?.ToList() ?? new List(), + AvailableModes = mode?.Values?.ToList() ?? new List(), + HasProfile = _profile != null, + }; + } + + // ---- Player --------------------------------------------------------- + + public PlayerDto GetPlayer() + { + lock (_gate) + { + EnsureLoaded(); + var g = _current.Global; + var pos = g.PlayerManager?.m_SaveGamePosition; + return new PlayerDto + { + Health = g.Condition.m_CurrentHPProxy, + NeverDie = g.Condition.m_NeverDieProxy, + Invulnerable = g.Condition.m_Invulnerable, + InfiniteCarry = g.Inventory.m_ForceOverrideWeight, + CarryWeightLimit = g.Inventory.m_OverridedWeight, + Calories = g.Hunger.m_CurrentReserveCaloriesProxy, + Thirst = g.Thirst.m_CurrentThirstProxy, + Fatigue = g.Fatigue.m_CurrentFatigueProxy, + Freezing = g.Freezing.m_CurrentFreezingProxy, + // UI convention from the original editor: X=[0], Y=[2], Z=[1]. + PositionX = PosAt(pos, 0), + PositionY = PosAt(pos, 2), + PositionZ = PosAt(pos, 1), + Region = _current.Boot.m_SceneName?.Value, + ExperienceMode = g.ExperienceModeManager?.m_CurrentModeType?.Value, + CustomMode = g.ExperienceModeManager?.m_CustomModeString, + }; + } + } + + public void UpdatePlayer(PlayerDto dto) + { + lock (_gate) + { + EnsureLoaded(); + var g = _current.Global; + g.Condition.m_CurrentHPProxy = dto.Health; + g.Condition.m_NeverDieProxy = dto.NeverDie; + g.Condition.m_Invulnerable = dto.Invulnerable; + g.Inventory.m_ForceOverrideWeight = dto.InfiniteCarry; + g.Inventory.m_OverridedWeight = dto.CarryWeightLimit; + g.Hunger.m_CurrentReserveCaloriesProxy = dto.Calories; + g.Thirst.m_CurrentThirstProxy = dto.Thirst; + g.Fatigue.m_CurrentFatigueProxy = dto.Fatigue; + g.Freezing.m_CurrentFreezingProxy = dto.Freezing; + + var pos = g.PlayerManager?.m_SaveGamePosition; + if (pos != null && pos.Count >= 3) + { + pos[0] = dto.PositionX; + pos[2] = dto.PositionY; + pos[1] = dto.PositionZ; + } + + if (!string.IsNullOrEmpty(dto.Region) && _current.Boot.m_SceneName != null) + _current.Boot.m_SceneName.Value = dto.Region; + + var emm = g.ExperienceModeManager; + if (!string.IsNullOrEmpty(dto.ExperienceMode) && emm?.m_CurrentModeType != null) + emm.m_CurrentModeType.Value = dto.ExperienceMode; + if (emm != null && dto.CustomMode != null) + emm.m_CustomModeString = dto.CustomMode; + } + } + + private static float PosAt(System.Collections.ObjectModel.ObservableCollection pos, int i) + => pos != null && pos.Count > i ? pos[i] : 0f; + + // ---- Inventory ------------------------------------------------------ + + public IReadOnlyList GetInventory() + { + lock (_gate) + { + EnsureLoaded(); + return _current.Global.Inventory.Items + .Select(it => new InventoryItemDto + { + InstanceId = it.Gear?.m_InstanceIDProxy ?? 0, + PrefabName = it.m_PrefabName, + DisplayName = it.InGameName, + Category = it.Category.ToString(), + Condition = it.Gear?.NormalizedCondition ?? 0f, + Quantity = it.Gear?.StackableItem?.m_UnitsProxy, + Liters = GetLiters(it.Gear), + Rounds = it.Gear?.WeaponItem?.m_RoundsInClipProxy, + }) + .ToList(); + } + } + + public void UpdateItem(int instanceId, UpdateItemRequest req) + { + lock (_gate) + { + EnsureLoaded(); + var item = _current.Global.Inventory.Items + .FirstOrDefault(it => it.Gear != null && it.Gear.m_InstanceIDProxy == instanceId); + if (item == null) + throw new ArgumentException("Item not found: " + instanceId); + + item.Gear.NormalizedCondition = req.Condition; + if (req.Quantity.HasValue && item.Gear.StackableItem != null) + item.Gear.StackableItem.m_UnitsProxy = req.Quantity.Value; + if (req.Liters.HasValue) + SetLiters(item.Gear, req.Liters.Value); + if (req.Rounds.HasValue && item.Gear.WeaponItem != null) + item.Gear.WeaponItem.m_RoundsInClipProxy = req.Rounds.Value; + } + } + + // Items that hold liquid expose it through one of three proxies (1 L == 1e9 internally, + // handled by the .Liters helpers). Returns null for items that hold no liquid. + private static double? GetLiters(GearItemSaveDataProxy g) + { + if (g == null) return null; + if (g.LiquidItem != null) return g.LiquidItem.Liters; + if (g.WaterSupply != null) return g.WaterSupply.Liters; + if (g.KeroseneLampItem != null) return g.KeroseneLampItem.Liters; + return null; + } + + private static void SetLiters(GearItemSaveDataProxy g, double liters) + { + if (g == null) return; + if (g.LiquidItem != null) g.LiquidItem.Liters = liters; + else if (g.WaterSupply != null) g.WaterSupply.Liters = liters; + else if (g.KeroseneLampItem != null) g.KeroseneLampItem.Liters = liters; + } + + public void AddItem(string prefabName) + { + lock (_gate) + { + EnsureLoaded(); + if (!ItemDictionary.itemInfo.TryGetValue(prefabName, out var info)) + throw new ArgumentException("Unknown item: " + prefabName); + + var item = new InventoryItemSaveData { m_PrefabName = prefabName }; + var gear = GearItemSaveDataProxy.Create(_current.Global); + JsonConvert.PopulateObject(info.defaultSerialized, gear); + item.Gear = gear; + _current.Global.Inventory.Items.Add(item); + } + } + + public void RemoveItem(int instanceId) + { + lock (_gate) + { + EnsureLoaded(); + var items = _current.Global.Inventory.Items; + var match = items.FirstOrDefault(it => it.Gear != null && it.Gear.m_InstanceIDProxy == instanceId); + if (match != null) + items.Remove(match); + } + } + + public IReadOnlyList GetAvailableItems() + { + // ItemDictionary.itemInfo is immutable after its static initialiser, so no lock needed. + return ItemDictionary.itemInfo + .Where(e => !e.Value.hide) + .Select(e => new AvailableItemDto + { + PrefabName = e.Key, + DisplayName = ItemDictionary.GetInGameName(e.Key), + Category = e.Value.category.ToString(), + }) + .OrderBy(e => e.Category) + .ThenBy(e => e.DisplayName) + .ToList(); + } + + // ---- Skills --------------------------------------------------------- + + public SkillsDto GetSkills() + { + lock (_gate) + { + EnsureLoaded(); + var s = _current.Global.SkillsManager; + return new SkillsDto + { + Firestarting = s.Firestarting.m_Points, + CarcassHarvesting = s.CarcassHarvesting.m_Points, + Cooking = s.Cooking.m_Points, + IceFishing = s.IceFishing.m_Points, + Rifle = s.Rifle.m_Points, + Archery = s.Archery.m_Points, + ClothingRepair = s.ClothingRepair.m_Points, + Revolver = s.Revolver.m_Points, + Gunsmith = s.Gunsmith.m_Points, + }; + } + } + + public void UpdateSkills(SkillsDto dto) + { + lock (_gate) + { + EnsureLoaded(); + var s = _current.Global.SkillsManager; + s.Firestarting.m_Points = dto.Firestarting; + s.CarcassHarvesting.m_Points = dto.CarcassHarvesting; + s.Cooking.m_Points = dto.Cooking; + s.IceFishing.m_Points = dto.IceFishing; + s.Rifle.m_Points = dto.Rifle; + s.Archery.m_Points = dto.Archery; + s.ClothingRepair.m_Points = dto.ClothingRepair; + s.Revolver.m_Points = dto.Revolver; + s.Gunsmith.m_Points = dto.Gunsmith; + } + } + + // ---- Afflictions ---------------------------------------------------- + + public IReadOnlyList GetAfflictions() + { + lock (_gate) + { + EnsureLoaded(); + var result = new List(); + var neg = _current.Afflictions.Negative; + for (int i = 0; i < neg.Count; i++) + result.Add(ToAfflictionDto(neg[i], i, positive: false)); + var pos = _current.Afflictions.Positive; + for (int i = 0; i < pos.Count; i++) + result.Add(ToAfflictionDto(pos[i], i, positive: true)); + return result; + } + } + + public void RemoveAffliction(bool positive, int index) + { + lock (_gate) + { + EnsureLoaded(); + var list = positive ? _current.Afflictions.Positive : _current.Afflictions.Negative; + if (index >= 0 && index < list.Count) + list.RemoveAt(index); + } + } + + public void CureAllAfflictions() + { + lock (_gate) + { + EnsureLoaded(); + _current.Afflictions.Negative.Clear(); + } + } + + private static AfflictionDto ToAfflictionDto(Affliction a, int index, bool positive) + { + var type = a.AfflictionType.ToString(); + // Best-effort friendly name; falls back to the raw enum name if no resource exists. + var display = Properties.Resources.ResourceManager.GetString("AfflictionType_" + type) ?? type; + return new AfflictionDto { Index = index, Positive = positive, Type = type, DisplayName = display }; + } + + // ---- Map ------------------------------------------------------------ + + public MapDto GetMap() + { + lock (_gate) + { + EnsureLoaded(); + var region = _current.Boot.m_SceneName?.Value; + var pos = _current.Global.PlayerManager?.m_SaveGamePosition; + var dto = new MapDto + { + Region = region, + HasMap = MapDictionary.MapExists(region), + PlayerX = PosAt(pos, 0), + PlayerY = PosAt(pos, 2), + }; + if (dto.HasMap) + { + var info = MapDictionary.GetMapInfo(region); + dto.Image = info.image; + dto.OrigoX = info.origoX; + dto.OrigoY = info.origoY; + dto.Width = info.width; + dto.Height = info.height; + dto.PixelsPerCoordinate = info.pixelsPerCoordinate; + } + return dto; + } + } + + public void SetMapPosition(double x, double y) + { + lock (_gate) + { + EnsureLoaded(); + var pos = _current.Global.PlayerManager?.m_SaveGamePosition; + if (pos != null && pos.Count >= 3) + { + pos[0] = (float)x; + pos[2] = (float)y; + } + } + } + + // ---- Profile (feats / badges) -------------------------------------- + + public ProfileDto GetProfile() + { + lock (_gate) + { + EnsureProfile(); + var f = _profile.State.Feats; + return new ProfileDto + { + BookSmartsHoursResearch = f.BookSmarts.m_HoursResearch, + ColdFusionElapsedDays = f.ColdFusion.m_ElapsedDays, + EfficientMachineElapsedHours = f.EfficientMachine.m_ElapsedHours, + FireMasterFiresStarted = f.FireMaster.m_NumFiresStarted, + FreeRunnerKilometers = f.FreeRunner.m_ElapsedKilometers, + SnowWalkerKilometers = f.SnowWalker.m_ElapsedKilometers, + ExpertTrapperRabbitsSnared = f.ExpertTrapper.m_RabbitSnaredCount, + StraightToHeartItemsConsumed = f.StraightToHeart.m_ItemConsumedCount, + BlizzardWalkerHoursOutside = f.BlizzardWalker.m_BlizzardHoursOutside, + Badge4DON = AllTrue(_profile.State.m_DaysCompleted4DON), + Badge4DON2019 = AllTrue(_profile.State.m_DaysCompleted4DON2019), + }; + } + } + + public void UpdateProfile(ProfileDto dto) + { + lock (_gate) + { + EnsureProfile(); + var f = _profile.State.Feats; + f.BookSmarts.m_HoursResearch = dto.BookSmartsHoursResearch; + f.ColdFusion.m_ElapsedDays = dto.ColdFusionElapsedDays; + f.EfficientMachine.m_ElapsedHours = dto.EfficientMachineElapsedHours; + f.FireMaster.m_NumFiresStarted = dto.FireMasterFiresStarted; + f.FreeRunner.m_ElapsedKilometers = dto.FreeRunnerKilometers; + f.SnowWalker.m_ElapsedKilometers = dto.SnowWalkerKilometers; + f.ExpertTrapper.m_RabbitSnaredCount = dto.ExpertTrapperRabbitsSnared; + f.StraightToHeart.m_ItemConsumedCount = dto.StraightToHeartItemsConsumed; + f.BlizzardWalker.m_BlizzardHoursOutside = dto.BlizzardWalkerHoursOutside; + _profile.State.m_DaysCompleted4DON = FourBadge(dto.Badge4DON); + _profile.State.m_DaysCompleted4DON2019 = FourBadge(dto.Badge4DON2019); + } + } + + private const int FourDaysOfNight = 4; + private static bool AllTrue(List l) => l != null && l.Count == FourDaysOfNight && l.All(b => b); + private static List FourBadge(bool on) => Enumerable.Repeat(on, FourDaysOfNight).ToList(); + + // ---- Backups -------------------------------------------------------- + + // Lists the auto-backups the editor made of the currently loaded save (newest first). + // Backups live in /backups and are named "-[(n)].backup". + public IReadOnlyList ListBackups() + { + lock (_gate) + { + EnsureLoaded(); + var dir = Path.Combine(Path.GetDirectoryName(_current.path), "backups"); + if (!Directory.Exists(dir)) + return new List(); + + var name = Path.GetFileName(_current.path); + var rx = new Regex("-" + Regex.Escape(name) + @"(\(\d+\))?\.backup$"); + return new DirectoryInfo(dir).GetFiles("*.backup") + .Where(f => rx.IsMatch(f.Name)) + .OrderByDescending(f => f.LastWriteTime) + .Select(f => new BackupDto + { + Path = f.FullName, + Label = f.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") + $" ({f.Length / 1024} KB)", + }) + .ToList(); + } + } + + // Restores a backup over the current save file, snapshotting the current state first + // (GameSave.Backup, which also prunes to MAX_BACKUPS) so the restore is reversible, + // then reloads the restored file. + public LoadedSaveDto RestoreBackup(string backupPath) + { + lock (_gate) + { + EnsureLoaded(); + EnsureWithinSavesFolder(backupPath); + if (!File.Exists(backupPath)) + throw new FileNotFoundException("Backup not found.", backupPath); + + var target = _current.path; + _current.Backup(); + File.Copy(backupPath, target, overwrite: true); + return Load(target); + } + } + + // Rejects paths that resolve outside the configured saves folder (defence-in-depth for + // the file-path endpoints, on top of the loopback-only binding). + private void EnsureWithinSavesFolder(string path) + { + if (string.IsNullOrEmpty(SavesFolder)) + return; + var root = Path.GetFullPath(SavesFolder); + var full = Path.GetFullPath(path); + if (full != root && !full.StartsWith(root + Path.DirectorySeparatorChar, StringComparison.Ordinal)) + throw new ArgumentException("Path is outside the saves folder."); + } + + private void EnsureLoaded() + { + if (_current == null) + throw new InvalidOperationException("No save is currently loaded."); + } + + private void EnsureProfile() + { + if (_profile == null) + throw new InvalidOperationException("No profile (user001) was found next to this save."); + } + } +} diff --git a/src/TldSaveEditor.Core/TldSaveEditor.Core.csproj b/src/TldSaveEditor.Core/TldSaveEditor.Core.csproj new file mode 100644 index 0000000..b910946 --- /dev/null +++ b/src/TldSaveEditor.Core/TldSaveEditor.Core.csproj @@ -0,0 +1,15 @@ + + + + net10.0 + disable + disable + The_Long_Dark_Save_Editor_2 + latest + + + + + + + diff --git a/src/TldSaveEditor.Server/Program.cs b/src/TldSaveEditor.Server/Program.cs new file mode 100644 index 0000000..04e10b0 --- /dev/null +++ b/src/TldSaveEditor.Server/Program.cs @@ -0,0 +1,131 @@ +using System.Diagnostics; +using System.Text.Json; +using The_Long_Dark_Save_Editor_2.Services; + +const string url = "http://127.0.0.1:5173"; + +var builder = WebApplication.CreateBuilder(args); + +// Local-only tool: bind to loopback so the editor is never exposed on the network. +builder.WebHost.UseUrls(url); + +// One in-memory editing session is enough for a single-user local tool. +builder.Services.AddSingleton(); +builder.Services.ConfigureHttpJsonOptions(o => +{ + o.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; +}); + +var app = builder.Build(); + +app.UseDefaultFiles(); +app.UseStaticFiles(); + +var api = app.MapGroup("/api"); + +api.MapGet("/saves-folder", (SaveEditorService svc) => Results.Ok(new { folder = svc.SavesFolder })); + +api.MapPost("/saves-folder", (SaveEditorService svc, FolderRequest req) => +{ + if (!string.IsNullOrWhiteSpace(req.Folder)) + svc.SavesFolder = req.Folder; + return Results.Ok(new { folder = svc.SavesFolder }); +}); + +api.MapGet("/saves", (SaveEditorService svc) => Guard(() => Results.Ok(svc.ListSaves()))); + +api.MapPost("/load", (SaveEditorService svc, LoadRequest req) => + Guard(() => Results.Ok(svc.Load(req.Path)))); + +api.MapGet("/player", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetPlayer()))); + +api.MapPut("/player", (SaveEditorService svc, PlayerDto dto) => + Guard(() => { svc.UpdatePlayer(dto); return Results.Ok(); })); + +api.MapGet("/inventory", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetInventory()))); + +api.MapPost("/inventory/add", (SaveEditorService svc, AddItemRequest req) => + Guard(() => { svc.AddItem(req.PrefabName); return Results.Ok(); })); + +api.MapPut("/inventory/{instanceId:int}", (SaveEditorService svc, int instanceId, UpdateItemRequest req) => + Guard(() => { svc.UpdateItem(instanceId, req); return Results.Ok(); })); + +api.MapDelete("/inventory/{instanceId:int}", (SaveEditorService svc, int instanceId) => + Guard(() => { svc.RemoveItem(instanceId); return Results.Ok(); })); + +api.MapGet("/items", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetAvailableItems()))); + +api.MapGet("/skills", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetSkills()))); + +api.MapPut("/skills", (SaveEditorService svc, SkillsDto dto) => + Guard(() => { svc.UpdateSkills(dto); return Results.Ok(); })); + +api.MapGet("/afflictions", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetAfflictions()))); + +api.MapPost("/afflictions/remove", (SaveEditorService svc, RemoveAfflictionRequest req) => + Guard(() => { svc.RemoveAffliction(req.Positive, req.Index); return Results.Ok(); })); + +api.MapPost("/afflictions/cure-all", (SaveEditorService svc) => + Guard(() => { svc.CureAllAfflictions(); return Results.Ok(); })); + +api.MapGet("/map", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetMap()))); + +api.MapPost("/map/position", (SaveEditorService svc, MapPositionRequest req) => + Guard(() => { svc.SetMapPosition(req.X, req.Y); return Results.Ok(); })); + +api.MapGet("/profile", (SaveEditorService svc) => Guard(() => Results.Ok(svc.GetProfile()))); + +api.MapPut("/profile", (SaveEditorService svc, ProfileDto dto) => + Guard(() => { svc.UpdateProfile(dto); return Results.Ok(); })); + +api.MapGet("/backups", (SaveEditorService svc) => Guard(() => Results.Ok(svc.ListBackups()))); + +api.MapPost("/restore", (SaveEditorService svc, RestoreRequest req) => + Guard(() => Results.Ok(svc.RestoreBackup(req.BackupPath)))); + +api.MapPost("/save", (SaveEditorService svc) => Guard(() => { svc.Save(); return Results.Ok(); })); + +Console.WriteLine($"TLD Save Editor — {url}"); + +// Open the default browser on startup unless told not to (e.g. headless / CI). +var openBrowser = !args.Contains("--no-browser") + && !string.Equals(Environment.GetEnvironmentVariable("TLD_NO_BROWSER"), "1"); +if (openBrowser) + app.Lifetime.ApplicationStarted.Register(() => OpenBrowser(url)); + +app.Run(); + +static void OpenBrowser(string target) +{ + try + { + if (OperatingSystem.IsWindows()) + Process.Start(new ProcessStartInfo(target) { UseShellExecute = true }); + else if (OperatingSystem.IsMacOS()) + Process.Start("open", target); + else + Process.Start("xdg-open", target); + } + catch { /* no browser available (headless) — the URL is printed above */ } +} + +// Maps service exceptions to appropriate status codes. Known/expected exceptions carry a +// safe, user-facing message; anything unexpected returns a generic 500 (the detail is logged +// server-side, not echoed to the client). +static IResult Guard(Func action) +{ + try { return action(); } + catch (FileNotFoundException ex) { return Results.NotFound(new { error = ex.Message }); } + catch (InvalidOperationException ex) { return Results.Conflict(new { error = ex.Message }); } + catch (ArgumentException ex) { return Results.BadRequest(new { error = ex.Message }); } + catch (Exception ex) + { + Console.Error.WriteLine(ex); + return Results.Problem("Unexpected error while processing the save.", statusCode: 500); + } +} + +record FolderRequest(string Folder); +record LoadRequest(string Path); +record AddItemRequest(string PrefabName); +record RemoveAfflictionRequest(bool Positive, int Index); diff --git a/src/TldSaveEditor.Server/Properties/launchSettings.json b/src/TldSaveEditor.Server/Properties/launchSettings.json new file mode 100644 index 0000000..d2d45a5 --- /dev/null +++ b/src/TldSaveEditor.Server/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://127.0.0.1:5173", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/TldSaveEditor.Server/TldSaveEditor.Server.csproj b/src/TldSaveEditor.Server/TldSaveEditor.Server.csproj new file mode 100644 index 0000000..376a66b --- /dev/null +++ b/src/TldSaveEditor.Server/TldSaveEditor.Server.csproj @@ -0,0 +1,13 @@ + + + + + + + + net10.0 + enable + enable + + + diff --git a/src/TldSaveEditor.Server/appsettings.Development.json b/src/TldSaveEditor.Server/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/TldSaveEditor.Server/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/TldSaveEditor.Server/appsettings.json b/src/TldSaveEditor.Server/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/src/TldSaveEditor.Server/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/TldSaveEditor.Server/wwwroot/app.js b/src/TldSaveEditor.Server/wwwroot/app.js new file mode 100644 index 0000000..abebe64 --- /dev/null +++ b/src/TldSaveEditor.Server/wwwroot/app.js @@ -0,0 +1,463 @@ +"use strict"; + +const $ = (id) => document.getElementById(id); +const statusEl = $("status"); + +function setStatus(msg, kind) { + statusEl.textContent = msg || ""; + statusEl.className = "status" + (kind ? " " + kind : ""); +} + +async function api(method, url, body) { + const opts = { method, headers: {} }; + if (body !== undefined) { + opts.headers["Content-Type"] = "application/json"; + opts.body = JSON.stringify(body); + } + const res = await fetch(url, opts); + const text = await res.text(); + const data = text ? JSON.parse(text) : null; + if (!res.ok) throw new Error((data && data.error) || res.statusText); + return data; +} + +function esc(s) { + return String(s ?? "").replace(/[&<>]/g, (c) => ({ "&": "&", "<": "<", ">": ">" }[c])); +} + +let hasProfile = false; +let mapState = null; + +// ---- Save list ----------------------------------------------------------- + +async function loadFolder() { + const r = await api("GET", "/api/saves-folder"); + $("folder").value = r.folder || ""; +} + +async function rescan() { + await api("POST", "/api/saves-folder", { folder: $("folder").value.trim() }); + await refreshSaves(); +} + +async function refreshSaves() { + const list = $("saveList"); + list.innerHTML = ""; + let saves = []; + try { saves = await api("GET", "/api/saves"); } + catch (e) { setStatus(e.message, "error"); } + if (!saves.length) { + const li = document.createElement("li"); + li.className = "empty"; + li.textContent = "No save files found in this folder."; + list.appendChild(li); + return; + } + for (const s of saves) { + const li = document.createElement("li"); + li.textContent = s.name; + li.title = s.path; + li.onclick = () => loadSave(s.path, li); + list.appendChild(li); + } +} + +async function loadSave(path, li) { + try { + setStatus("Loading…"); + const info = await api("POST", "/api/load", { path }); + document.querySelectorAll(".save-list li").forEach((x) => x.classList.remove("active")); + if (li) li.classList.add("active"); + await applyLoaded(info); + setStatus("Loaded", "ok"); + } catch (e) { + setStatus(e.message, "error"); + } +} + +// Populates every tab from a LoadedSaveDto. Shared by initial load and backup restore. +async function applyLoaded(info) { + hasProfile = info.hasProfile; + $("loadedName").textContent = info.displayName + (info.region ? " · " + info.region : ""); + fillRegions(info.availableRegions, info.region); + fillSelect("expMode", info.availableModes); + $("editor").classList.remove("hidden"); + await Promise.all([loadPlayer(), loadItems(), loadInventory(), loadSkills(), + loadAfflictions(), loadMap(), loadProfile(), loadBackups()]); +} + +async function loadBackups() { + const list = await api("GET", "/api/backups"); + const sel = $("backupSelect"), btn = $("restoreBtn"); + sel.innerHTML = ""; + if (!list.length) { + const o = document.createElement("option"); + o.value = ""; o.textContent = "No backups"; + sel.appendChild(o); sel.disabled = true; btn.disabled = true; + return; + } + sel.disabled = false; btn.disabled = false; + for (const b of list) { + const o = document.createElement("option"); + o.value = b.path; o.textContent = b.label; + sel.appendChild(o); + } +} + +async function restoreBackup() { + const bp = $("backupSelect").value; + if (!bp) return; + if (!confirm("Restore this backup? The current save file will be overwritten.\n(A snapshot of the current state is kept, so this is reversible.)")) + return; + try { + setStatus("Restoring…"); + const info = await api("POST", "/api/restore", { backupPath: bp }); + await applyLoaded(info); + setStatus("Restored from backup", "ok"); + } catch (e) { setStatus(e.message, "error"); } +} + +// ---- Player -------------------------------------------------------------- + +function fillRegions(regions, current) { fillSelect("region", regions, current); } + +function fillSelect(id, values, current) { + const sel = $(id); + sel.innerHTML = ""; + for (const v of values || []) { + const o = document.createElement("option"); + o.value = v; o.textContent = v; + if (v === current) o.selected = true; + sel.appendChild(o); + } +} + +function bindSlider(id) { + const inp = $(id), out = $(id + "Out"); + const upd = () => (out.value = inp.value); + inp.oninput = upd; + return upd; +} +const sliders = ["health", "thirst", "fatigue", "freezing"].map(bindSlider); + +async function loadPlayer() { + const p = await api("GET", "/api/player"); + $("health").value = Math.round(p.health); + $("thirst").value = Math.round(p.thirst); + $("fatigue").value = Math.round(p.fatigue); + $("freezing").value = Math.round(p.freezing); + $("calories").value = Math.round(p.calories); + $("posX").value = p.positionX; + $("posY").value = p.positionY; + $("posZ").value = p.positionZ; + $("neverDie").checked = p.neverDie; + $("invulnerable").checked = p.invulnerable; + $("infiniteCarry").checked = p.infiniteCarry; + $("carryWeight").value = round2(p.carryWeightLimit); + if (p.experienceMode) $("expMode").value = p.experienceMode; + $("customMode").value = p.customMode || ""; + sliders.forEach((f) => f()); +} + +function readPlayer() { + return { + health: +$("health").value, thirst: +$("thirst").value, fatigue: +$("fatigue").value, + freezing: +$("freezing").value, calories: +$("calories").value, + positionX: +$("posX").value, positionY: +$("posY").value, positionZ: +$("posZ").value, + neverDie: $("neverDie").checked, invulnerable: $("invulnerable").checked, + infiniteCarry: $("infiniteCarry").checked, carryWeightLimit: +$("carryWeight").value, + region: $("region").value, + experienceMode: $("expMode").value, customMode: $("customMode").value, + }; +} + +// ---- Skills -------------------------------------------------------------- + +const SKILLS = [ + ["firestarting", "Firestarting"], ["carcassHarvesting", "Carcass Harvesting"], + ["cooking", "Cooking"], ["iceFishing", "Ice Fishing"], ["rifle", "Rifle"], + ["archery", "Archery"], ["clothingRepair", "Clothing Repair"], + ["revolver", "Revolver"], ["gunsmith", "Gunsmithing"], +]; + +function buildNumberGrid(gridId, fields, prefix) { + const grid = $(gridId); + grid.innerHTML = ""; + for (const [key, label] of fields) { + const lab = document.createElement("label"); + lab.textContent = label; + const inp = document.createElement("input"); + inp.type = "number"; inp.step = "any"; inp.id = prefix + "_" + key; + grid.appendChild(lab); grid.appendChild(inp); + } +} + +async function loadSkills() { + buildNumberGrid("skillsGrid", SKILLS, "sk"); + const s = await api("GET", "/api/skills"); + for (const [key] of SKILLS) $("sk_" + key).value = s[key]; +} + +function readSkills() { + const out = {}; + for (const [key] of SKILLS) out[key] = +$("sk_" + key).value; + return out; +} + +// ---- Afflictions --------------------------------------------------------- + +async function loadAfflictions() { + const list = await api("GET", "/api/afflictions"); + const body = $("afflBody"); + body.innerHTML = ""; + if (!list.length) { + body.innerHTML = 'No afflictions.'; + return; + } + for (const a of list) { + const tr = document.createElement("tr"); + tr.innerHTML = `${esc(a.displayName)}${a.positive ? "Buff" : "Negative"}`; + const td = document.createElement("td"); + const btn = document.createElement("button"); + btn.className = "link"; btn.textContent = a.positive ? "Remove" : "Cure"; + btn.onclick = () => removeAffliction(a.positive, a.index); + td.appendChild(btn); tr.appendChild(td); body.appendChild(tr); + } +} + +async function removeAffliction(positive, index) { + try { await api("POST", "/api/afflictions/remove", { positive, index }); await loadAfflictions(); } + catch (e) { setStatus(e.message, "error"); } +} + +async function cureAll() { + try { await api("POST", "/api/afflictions/cure-all"); await loadAfflictions(); setStatus("All negative afflictions cured (Apply & Save to persist)", "ok"); } + catch (e) { setStatus(e.message, "error"); } +} + +// ---- Map ----------------------------------------------------------------- + +async function loadMap() { + const m = await api("GET", "/api/map"); + mapState = m; + const wrap = $("mapWrap"), img = $("mapImg"), info = $("mapInfo"); + if (!m.hasMap) { + wrap.classList.add("hidden"); + info.textContent = m.region + ? `No map image available for region "${m.region}". Position: ${fmt(m.playerX)}, ${fmt(m.playerY)}` + : "No region loaded."; + return; + } + wrap.classList.remove("hidden"); + info.textContent = `${m.region} — click the map to move the player. Position: ${fmt(m.playerX)}, ${fmt(m.playerY)}`; + img.onload = positionMarker; + img.src = "/maps/" + m.image; + if (img.complete) positionMarker(); +} + +function fmt(n) { return Math.round(n * 100) / 100; } + +function positionMarker() { + const marker = $("mapMarker"); + if (!mapState || !mapState.hasMap) { marker.classList.add("hidden"); return; } + const m = mapState; + const lx = m.playerX * m.pixelsPerCoordinate + m.origoX; + const ly = m.playerY * -m.pixelsPerCoordinate + m.origoY; + marker.style.left = (lx / m.width * 100) + "%"; + marker.style.top = (ly / m.height * 100) + "%"; + marker.title = `Player: ${fmt(m.playerX)}, ${fmt(m.playerY)}`; + marker.classList.remove("hidden"); +} + +async function mapClick(e) { + if (!mapState || !mapState.hasMap) return; + const img = $("mapImg"); + const rect = img.getBoundingClientRect(); + const fracX = (e.clientX - rect.left) / rect.width; + const fracY = (e.clientY - rect.top) / rect.height; + const lx = fracX * mapState.width, ly = fracY * mapState.height; + const x = (lx - mapState.origoX) / mapState.pixelsPerCoordinate; + const y = (ly - mapState.origoY) / -mapState.pixelsPerCoordinate; + try { + await api("POST", "/api/map/position", { x, y }); + await Promise.all([loadMap(), loadPlayer()]); + setStatus("Position set (Apply & Save to persist)", "ok"); + } catch (err) { setStatus(err.message, "error"); } +} + +// ---- Inventory ----------------------------------------------------------- + +async function loadItems() { + const items = await api("GET", "/api/items"); + const sel = $("addItem"); + sel.innerHTML = ""; + let group = null, optgroup = null; + for (const it of items) { + if (it.category !== group) { + group = it.category; + optgroup = document.createElement("optgroup"); + optgroup.label = group; + sel.appendChild(optgroup); + } + const o = document.createElement("option"); + o.value = it.prefabName; o.textContent = it.displayName; + optgroup.appendChild(o); + } +} + +async function loadInventory() { + const items = await api("GET", "/api/inventory"); + const body = $("invBody"); + $("invCount").textContent = `${items.length} item${items.length === 1 ? "" : "s"}`; + const frag = document.createDocumentFragment(); + for (const it of items) { + const tr = document.createElement("tr"); + tr.appendChild(cell(esc(it.displayName))); + tr.appendChild(cell(esc(it.category))); + + // Condition (% editable) + const condInput = numInput(Math.round((it.condition || 0) * 100), 0, 100, 1, "70px"); + tr.appendChild(wrapTd(condInput)); + + // Qty / Liters / In-clip: each shown only when the item has that attribute. + const qtyInput = optionalNum(tr, it.quantity, 0, null, 1, "70px"); + const litInput = optionalNum(tr, it.liters, 0, null, 0.1, "80px", round2); + const rndInput = optionalNum(tr, it.rounds, 0, null, 1, "70px"); + + const save = () => updateItem(it.instanceId, (+condInput.value) / 100, + qtyInput ? +qtyInput.value : null, + litInput ? +litInput.value : null, + rndInput ? +rndInput.value : null); + [condInput, qtyInput, litInput, rndInput].forEach((i) => { if (i) i.onchange = save; }); + + const td = document.createElement("td"); + const btn = document.createElement("button"); + btn.className = "link"; btn.textContent = "Remove"; + btn.onclick = () => removeItem(it.instanceId); + td.appendChild(btn); tr.appendChild(td); + frag.appendChild(tr); + } + body.replaceChildren(frag); +} + +function wrapTd(el) { const td = document.createElement("td"); td.appendChild(el); return td; } + +// Appends a numeric-input cell when `value` is present, otherwise an "—" cell. Returns the input (or null). +function optionalNum(tr, value, min, max, step, width, fmt) { + if (value === null || value === undefined) { tr.appendChild(cell("—")); return null; } + const inp = numInput(fmt ? fmt(value) : value, min, max, step, width); + tr.appendChild(wrapTd(inp)); + return inp; +} + +function cell(html) { const td = document.createElement("td"); td.innerHTML = html; return td; } +function round2(n) { return Math.round(n * 100) / 100; } +function numInput(value, min, max, step, width) { + const i = document.createElement("input"); + i.type = "number"; i.value = value; i.step = step; + if (min !== null) i.min = min; + if (max !== null) i.max = max; + i.style.width = width; + return i; +} + +async function updateItem(instanceId, condition, quantity, liters, rounds) { + try { + await api("PUT", "/api/inventory/" + instanceId, { condition, quantity, liters, rounds }); + setStatus("Item updated (Apply & Save to persist)", "ok"); + } catch (e) { setStatus(e.message, "error"); } +} + +async function addItem() { + const prefabName = $("addItem").value; + if (!prefabName) return; + try { await api("POST", "/api/inventory/add", { prefabName }); await loadInventory(); setStatus("Item added (Apply & Save to persist)", "ok"); } + catch (e) { setStatus(e.message, "error"); } +} + +async function removeItem(instanceId) { + try { await api("DELETE", "/api/inventory/" + instanceId); await loadInventory(); } + catch (e) { setStatus(e.message, "error"); } +} + +// ---- Profile (feats / badges) ------------------------------------------- + +const FEATS = [ + ["bookSmartsHoursResearch", "Book Smarts — hours research"], + ["coldFusionElapsedDays", "Cold Fusion — days"], + ["efficientMachineElapsedHours", "Efficient Machine — hours"], + ["fireMasterFiresStarted", "Fire Master — fires started"], + ["freeRunnerKilometers", "Free Runner — km"], + ["snowWalkerKilometers", "Snow Walker — km"], + ["expertTrapperRabbitsSnared", "Expert Trapper — rabbits snared"], + ["straightToHeartItemsConsumed", "Straight to the Heart — items consumed"], + ["blizzardWalkerHoursOutside", "Blizzard Walker — hours outside"], +]; + +async function loadProfile() { + const note = $("profileNote"), grid = $("profileGrid"); + if (!hasProfile) { + note.classList.remove("hidden"); + grid.innerHTML = ""; + return; + } + note.classList.add("hidden"); + buildNumberGrid("profileGrid", FEATS, "ft"); + // badges + for (const [key, label] of [["badge4DON", "4DON badge complete"], ["badge4DON2019", "4DON 2019 badge complete"]]) { + const lab = document.createElement("label"); lab.textContent = label; + const wrap = document.createElement("div"); + const cb = document.createElement("input"); cb.type = "checkbox"; cb.id = "ft_" + key; + wrap.appendChild(cb); grid.appendChild(lab); grid.appendChild(wrap); + } + const p = await api("GET", "/api/profile"); + for (const [key] of FEATS) $("ft_" + key).value = p[key]; + $("ft_badge4DON").checked = p.badge4DON; + $("ft_badge4DON2019").checked = p.badge4DON2019; +} + +function readProfile() { + const out = {}; + for (const [key] of FEATS) out[key] = +$("ft_" + key).value; + out.badge4DON = $("ft_badge4DON").checked; + out.badge4DON2019 = $("ft_badge4DON2019").checked; + return out; +} + +// ---- Save ---------------------------------------------------------------- + +async function saveAll() { + try { + setStatus("Saving…"); + await api("PUT", "/api/player", readPlayer()); + await api("PUT", "/api/skills", readSkills()); + if (hasProfile) await api("PUT", "/api/profile", readProfile()); + await api("POST", "/api/save"); + await loadBackups(); + setStatus("Saved (a backup of the original was created)", "ok"); + } catch (e) { setStatus(e.message, "error"); } +} + +// ---- Tabs & init --------------------------------------------------------- + +document.querySelectorAll(".tab").forEach((t) => { + t.onclick = () => { + document.querySelectorAll(".tab").forEach((x) => x.classList.remove("active")); + t.classList.add("active"); + document.querySelectorAll(".tab-panel").forEach((p) => p.classList.add("hidden")); + $("tab-" + t.dataset.tab).classList.remove("hidden"); + if (t.dataset.tab === "map") positionMarker(); + }; +}); + +$("rescan").onclick = rescan; +$("addBtn").onclick = addItem; +$("cureAllBtn").onclick = cureAll; +$("saveBtn").onclick = saveAll; +$("restoreBtn").onclick = restoreBackup; +$("mapImg").addEventListener("click", mapClick); + +(async function init() { + await loadFolder(); + await refreshSaves(); +})(); diff --git a/src/TldSaveEditor.Server/wwwroot/index.html b/src/TldSaveEditor.Server/wwwroot/index.html new file mode 100644 index 0000000..fb2e9fb --- /dev/null +++ b/src/TldSaveEditor.Server/wwwroot/index.html @@ -0,0 +1,138 @@ + + + + + + The Long Dark — Save Editor + + + +
+

The Long Dark — Save Editor

+ +
+ +
+ + + +
+ + + + diff --git a/src/TldSaveEditor.Server/wwwroot/maps/AshCanyonRegion.png b/src/TldSaveEditor.Server/wwwroot/maps/AshCanyonRegion.png new file mode 100644 index 0000000..adb8698 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/AshCanyonRegion.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/BrokenRailRoadSF.png b/src/TldSaveEditor.Server/wwwroot/maps/BrokenRailRoadSF.png new file mode 100644 index 0000000..fd5cf2d Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/BrokenRailRoadSF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/CanneryRegion.png b/src/TldSaveEditor.Server/wwwroot/maps/CanneryRegion.png new file mode 100644 index 0000000..42dc73e Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/CanneryRegion.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/CoastalHighwaySF.png b/src/TldSaveEditor.Server/wwwroot/maps/CoastalHighwaySF.png new file mode 100644 index 0000000..410c4a5 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/CoastalHighwaySF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/CrumblingHighwaySF.png b/src/TldSaveEditor.Server/wwwroot/maps/CrumblingHighwaySF.png new file mode 100644 index 0000000..53a2036 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/CrumblingHighwaySF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/DesolationPointSF.png b/src/TldSaveEditor.Server/wwwroot/maps/DesolationPointSF.png new file mode 100644 index 0000000..243d7b3 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/DesolationPointSF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/ForlomMuskeg.png b/src/TldSaveEditor.Server/wwwroot/maps/ForlomMuskeg.png new file mode 100644 index 0000000..73b589f Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/ForlomMuskeg.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/HushedRiverValleySF.png b/src/TldSaveEditor.Server/wwwroot/maps/HushedRiverValleySF.png new file mode 100644 index 0000000..c6611ca Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/HushedRiverValleySF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/MountainTownSF.png b/src/TldSaveEditor.Server/wwwroot/maps/MountainTownSF.png new file mode 100644 index 0000000..0c84ca0 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/MountainTownSF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/MysteryLakeSF.png b/src/TldSaveEditor.Server/wwwroot/maps/MysteryLakeSF.png new file mode 100644 index 0000000..1e4a4b3 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/MysteryLakeSF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/PleasantValleySF.png b/src/TldSaveEditor.Server/wwwroot/maps/PleasantValleySF.png new file mode 100644 index 0000000..3cdd439 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/PleasantValleySF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/RavineSF.png b/src/TldSaveEditor.Server/wwwroot/maps/RavineSF.png new file mode 100644 index 0000000..61dcfc4 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/RavineSF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/TimberwolfMountainSF.png b/src/TldSaveEditor.Server/wwwroot/maps/TimberwolfMountainSF.png new file mode 100644 index 0000000..f322530 Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/TimberwolfMountainSF.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/maps/location-indicator.png b/src/TldSaveEditor.Server/wwwroot/maps/location-indicator.png new file mode 100644 index 0000000..fba1dca Binary files /dev/null and b/src/TldSaveEditor.Server/wwwroot/maps/location-indicator.png differ diff --git a/src/TldSaveEditor.Server/wwwroot/style.css b/src/TldSaveEditor.Server/wwwroot/style.css new file mode 100644 index 0000000..099f518 --- /dev/null +++ b/src/TldSaveEditor.Server/wwwroot/style.css @@ -0,0 +1,123 @@ +:root { + --bg: #1b1f24; + --panel: #242a31; + --panel-2: #2c333c; + --text: #e6e9ed; + --muted: #93a1b0; + --accent: #4ea1ff; + --danger: #e5544b; + --border: #3a424c; +} + +* { box-sizing: border-box; } + +body { + margin: 0; + font-family: system-ui, "Segoe UI", Roboto, sans-serif; + background: var(--bg); + color: var(--text); +} + +header { + display: flex; + align-items: baseline; + gap: 16px; + padding: 12px 20px; + background: var(--panel); + border-bottom: 1px solid var(--border); +} +header h1 { font-size: 18px; margin: 0; font-weight: 600; } +.status { color: var(--muted); font-size: 13px; } +.status.error { color: var(--danger); } +.status.ok { color: #5fce7e; } + +main { display: flex; height: calc(100vh - 49px); } + +#sidebar { + width: 320px; + flex-shrink: 0; + background: var(--panel); + border-right: 1px solid var(--border); + display: flex; + flex-direction: column; + overflow: hidden; +} + +.folder-row { padding: 12px; border-bottom: 1px solid var(--border); display: grid; gap: 6px; } +.folder-row label { font-size: 12px; color: var(--muted); } +.folder-row input { width: 100%; } + +.save-list { list-style: none; margin: 0; padding: 6px; overflow-y: auto; flex: 1; } +.save-list li { + padding: 9px 10px; + border-radius: 6px; + cursor: pointer; + font-size: 13px; + line-height: 1.3; +} +.save-list li:hover { background: var(--panel-2); } +.save-list li.active { background: var(--accent); color: #08233f; font-weight: 600; } +.save-list .empty { color: var(--muted); cursor: default; } + +.editor { flex: 1; display: flex; flex-direction: column; overflow: hidden; } +.editor.hidden, .tab-panel.hidden, .hidden { display: none; } + +.loaded-bar { + display: flex; align-items: center; justify-content: space-between; + padding: 12px 20px; border-bottom: 1px solid var(--border); +} +#loadedName { font-weight: 600; } +.bar-actions { display: flex; align-items: center; gap: 8px; } +.bar-actions select { max-width: 240px; } + +.tabs { display: flex; gap: 4px; padding: 10px 20px 0; } +.tab { + background: none; border: none; color: var(--muted); + padding: 8px 14px; cursor: pointer; border-radius: 6px 6px 0 0; font-size: 14px; +} +.tab.active { color: var(--text); background: var(--panel); border-bottom: 2px solid var(--accent); } + +.tab-panel { padding: 20px; overflow-y: auto; flex: 1; } + +.grid { display: grid; grid-template-columns: 160px 1fr; gap: 14px 16px; max-width: 640px; align-items: center; } +.grid > label { color: var(--muted); font-size: 13px; } +.slider { display: flex; align-items: center; gap: 10px; } +.slider input[type=range] { flex: 1; } +.slider output { width: 44px; text-align: right; color: var(--muted); } +.pos { display: flex; gap: 8px; } +.pos input { width: 33%; } +.checks { display: flex; flex-direction: column; gap: 6px; } +.checks label { color: var(--text); font-size: 13px; } + +input, select, button { font: inherit; } +input[type=text], input[type=number], select { + background: var(--panel-2); color: var(--text); + border: 1px solid var(--border); border-radius: 6px; padding: 7px 9px; +} +button { + background: var(--panel-2); color: var(--text); + border: 1px solid var(--border); border-radius: 6px; padding: 7px 12px; cursor: pointer; +} +button:hover { border-color: var(--accent); } +button.primary { background: var(--accent); color: #08233f; border: none; font-weight: 600; } +button.link { background: none; border: none; color: var(--danger); padding: 2px 6px; } + +.add-row { display: flex; gap: 10px; margin-bottom: 16px; } +.add-row select { min-width: 280px; } + +.inv-table { width: 100%; border-collapse: collapse; font-size: 13px; } +.inv-table th, .inv-table td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border); } +.inv-table th { color: var(--muted); font-weight: 500; } + +.muted-note { color: var(--muted); font-size: 13px; margin: 0 0 14px; } + +.map-wrap { position: relative; display: inline-block; max-width: 100%; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; cursor: crosshair; } +.map-wrap img { display: block; max-width: 100%; height: auto; } +/* The pin's tip points at the player's coordinates: anchor bottom-centre. */ +.map-marker { + position: absolute; width: 34px; height: 34px; + transform: translate(-50%, -100%); + filter: drop-shadow(0 1px 3px #000c); + pointer-events: none; +} +.map-marker.hidden { display: none; }