using System; using System.Collections.Generic; using System.IO; using System.Text; using I2.Loc; using UnityEngine; using wf; namespace MaidStatus { public static class SubMaid { public static int Count { get { SubMaid.CreateData(); return SubMaid.commonIdManager.idMap.Count; } } public static bool Contains(string name) { return SubMaid.commonIdManager.nameMap.ContainsKey(name); } public static bool Contains(int id) { return SubMaid.commonIdManager.idMap.ContainsKey(id); } public static int uniqueNameToId(string name) { SubMaid.CreateData(); NDebug.Assert(SubMaid.commonIdManager.nameMap.ContainsKey(name), "Subメイド\nユニーク名[" + name + "]をIDに変換できませんでした"); return SubMaid.commonIdManager.nameMap[name]; } public static string IdToUniqueName(int id) { SubMaid.CreateData(); NDebug.Assert(SubMaid.commonIdManager.idMap.ContainsKey(id), "Subメイド\nID[" + id + "]をユニーク名に変換できませんでした"); return SubMaid.commonIdManager.idMap[id].Key; } public static SubMaid.Data GetData(int id) { SubMaid.CreateData(); NDebug.Assert(SubMaid.basicDatas.ContainsKey(id), "Subメイド\nID[" + id + "]のデータは存在しません"); return SubMaid.basicDatas[id]; } public static SubMaid.Data GetData(string uniqueName) { return SubMaid.GetData(SubMaid.uniqueNameToId(uniqueName)); } public static bool IsEnabled(string uniqueName) { SubMaid.CreateData(); return SubMaid.commonIdManager.enabledIdList.Contains(SubMaid.uniqueNameToId(uniqueName)); } public static bool IsEnabled(int id) { SubMaid.CreateData(); return SubMaid.commonIdManager.enabledIdList.Contains(id); } public static List GetAllDatas(bool onlyEnabled) { SubMaid.CreateData(); List list = new List(); foreach (KeyValuePair> keyValuePair in SubMaid.commonIdManager.idMap) { if (!onlyEnabled || SubMaid.commonIdManager.enabledIdList.Contains(keyValuePair.Key)) { list.Add(SubMaid.basicDatas[keyValuePair.Key]); } } return list; } public static void CreateData() { if (SubMaid.commonIdManager != null) { return; } SubMaid.commonIdManager = new CsvCommonIdManager("maid_status_submaid", "Subメイド", CsvCommonIdManager.Type.IdAndUniqueName, null); SubMaid.basicDatas = new Dictionary(); string[] array = new string[] { "list", "kiss_side_list" }; KeyValuePair[] array2 = new KeyValuePair[array.Length]; for (int i = 0; i < array2.Length; i++) { string text = "maid_status_submaid_" + array[i] + ".nei"; AFileBase afileBase = GameUty.FileSystem.FileOpen(text); CsvParser csvParser = new CsvParser(); bool condition = csvParser.Open(afileBase); NDebug.Assert(condition, text + "\nopen failed."); array2[i] = new KeyValuePair(afileBase, csvParser); } foreach (KeyValuePair> keyValuePair in SubMaid.commonIdManager.idMap) { SubMaid.basicDatas.Add(keyValuePair.Key, new SubMaid.Data(keyValuePair.Key, array2[0].Value, array2[1].Value)); } foreach (KeyValuePair keyValuePair2 in array2) { keyValuePair2.Value.Dispose(); keyValuePair2.Key.Dispose(); } } private const string csvTopCommonName = "maid_status_submaid"; private const string typeNameForErrorLog = "Subメイド"; private static CsvCommonIdManager commonIdManager; private static Dictionary basicDatas; public class Data { public Data(int id, CsvParser basicCsv, CsvParser kissSideCsv) { for (int i = 1; i < basicCsv.max_cell_y; i++) { if (basicCsv.IsCellToExistData(0, i) && basicCsv.GetCellAsInteger(0, i) == id) { int num = 1; this.id = id; this.uniqueName = basicCsv.GetCellAsString(num++, i); this.replaceText = basicCsv.GetCellAsString(num++, i); this.isEditPossible = (basicCsv.GetCellAsString(num++, i) == "〇"); this.status = new SubMaid.Data.CharacterStatus(this.id, this.uniqueName, false, basicCsv, i); break; } } for (int j = 1; j < kissSideCsv.max_cell_y; j++) { if (kissSideCsv.IsCellToExistData(0, j) && kissSideCsv.GetCellAsInteger(0, j) == id) { this.secondStatus = new SubMaid.Data.CharacterStatus(this.id, this.uniqueName, true, kissSideCsv, j); break; } } } public void ApplyStatus(Status status, bool refSecondStatus) { if (status == null) { return; } SubMaid.Data.CharacterStatus characterStatus = (!refSecondStatus || this.secondStatus == null) ? this.status : this.secondStatus; status.heroineType = HeroineType.Sub; status.subCharaData = this; status.lastName = characterStatus.lastName; status.firstName = characterStatus.firstName; if (Product.supportMultiLanguage) { string translation = LocalizationManager.GetTranslation(characterStatus.lastNameTerm, true, 0, true, false, null, Product.EnumConvert.ToI2LocalizeLanguageName(Product.defaultLanguage)); if (!string.IsNullOrEmpty(translation)) { status.lastName = translation; } translation = LocalizationManager.GetTranslation(characterStatus.firstNameTerm, true, 0, true, false, null, Product.EnumConvert.ToI2LocalizeLanguageName(Product.defaultLanguage)); if (!string.IsNullOrEmpty(translation)) { status.firstName = translation; } } status.contract = characterStatus.contract; status.initSeikeiken = (status.seikeiken = characterStatus.initSeikeiken); status.likability = characterStatus.likability; status.baseLovely = characterStatus.lovely; status.baseElegance = characterStatus.elegance; status.baseCharm = characterStatus.charm; status.baseCare = characterStatus.care; status.baseReception = characterStatus.reception; status.baseCooking = characterStatus.cooking; status.baseDance = characterStatus.dance; status.baseVocal = characterStatus.vocal; status.playCountNightWork = characterStatus.playCountNightWork; int num = characterStatus.hp; status.currentHp = num; status.baseMaxHp = num; num = characterStatus.mind; status.currentMind = num; status.baseMaxMind = num; status.baseInyoku = characterStatus.inyoku; status.baseMvalue = characterStatus.mvalue; status.baseHentai = characterStatus.hentai; status.baseHousi = characterStatus.housi; status.playCountYotogi = characterStatus.playCountYotogi; } public void ApplyPreset(Maid maid, bool refSecondStatus, bool setThumCard) { if (maid == null) { return; } SubMaid.Data.CharacterStatus characterStatus = (!refSecondStatus || this.secondStatus == null) ? this.status : this.secondStatus; CharacterMgr.npcDatas[characterStatus.presetName].Apply(maid, true); maid.status.UpdateBodyParam(); if (!string.IsNullOrEmpty(characterStatus.iconFileName)) { Texture2D texture2D = ImportCM.CreateTexture(characterStatus.iconFileName); if (texture2D.format == TextureFormat.DXT1 || texture2D.format == TextureFormat.DXT5) { Texture2D texture2D2 = new Texture2D(texture2D.width, texture2D.height, TextureFormat.ARGB32, false); texture2D2.SetPixels(texture2D.GetPixels()); texture2D2.Apply(); UnityEngine.Object.Destroy(texture2D); maid.SetThumIcon(texture2D2); } else { maid.SetThumIcon(texture2D); } } else { Debug.LogError(string.Concat(new string[] { "サブメイド[", characterStatus.firstName, "]のアイコンファイル[", characterStatus.iconFileName, "]が見つかりません" })); } if (setThumCard) { if (!string.IsNullOrEmpty(characterStatus.thumbnailFileName)) { Texture2D texture2D3 = ImportCM.CreateTexture(characterStatus.thumbnailFileName); if (texture2D3.format == TextureFormat.DXT1 || texture2D3.format == TextureFormat.DXT5) { Texture2D texture2D4 = new Texture2D(texture2D3.width, texture2D3.height, TextureFormat.ARGB32, false); texture2D4.SetPixels(texture2D3.GetPixels()); texture2D4.Apply(); UnityEngine.Object.Destroy(texture2D3); maid.SetThumCard(texture2D4); } else { maid.SetThumCard(texture2D3); } } else { Debug.LogError(string.Concat(new string[] { "サブメイド[", characterStatus.firstName, "]のアイコンファイル[", characterStatus.thumbnailFileName, "]が見つかりません" })); } } } public readonly int id; public readonly string uniqueName; public readonly string replaceText; public readonly bool isEditPossible; public readonly SubMaid.Data.CharacterStatus status; public readonly SubMaid.Data.CharacterStatus secondStatus; public class CharacterStatus { public CharacterStatus(int id, string uniqueName, bool kissSideNPC, CsvParser basicCsv, int lineY) { this.id = id; this.uniqueName = uniqueName; this.kissSideNPC = kissSideNPC; int num = 4; this.lastName = basicCsv.GetCellAsString(num++, lineY); this.firstName = basicCsv.GetCellAsString(num++, lineY); this.presetName = Path.GetFileNameWithoutExtension(basicCsv.GetCellAsString(num++, lineY)); this.iconFileName = Path.GetFileNameWithoutExtension(basicCsv.GetCellAsString(num++, lineY)) + ".tex"; this.thumbnailFileName = Path.GetFileNameWithoutExtension(basicCsv.GetCellAsString(num++, lineY)) + ".tex"; try { this.contract = (Contract)Enum.Parse(typeof(Contract), basicCsv.GetCellAsString(num++, lineY)); } catch (Exception e) { NDebug.AssertParseError("Contract", e); } this.contractText = basicCsv.GetCellAsString(num++, lineY); this.personalText = basicCsv.GetCellAsString(num++, lineY); this.relationText = basicCsv.GetCellAsString(num++, lineY); try { this.initSeikeiken = (Seikeiken)Enum.Parse(typeof(Seikeiken), basicCsv.GetCellAsString(num++, lineY)); } catch (Exception e2) { NDebug.AssertParseError("Seikeiken", e2); } this.jobClassText = JobClass.GetData(basicCsv.GetCellAsString(num++, lineY)).drawName; this.jobClassLevel = basicCsv.GetCellAsInteger(num++, lineY); this.yotogiClassText = basicCsv.GetCellAsString(num++, lineY); this.yotogiClassLevel = basicCsv.GetCellAsInteger(num++, lineY); this.likability = basicCsv.GetCellAsInteger(num++, lineY); this.lovely = basicCsv.GetCellAsInteger(num++, lineY); this.elegance = basicCsv.GetCellAsInteger(num++, lineY); this.charm = basicCsv.GetCellAsInteger(num++, lineY); this.care = basicCsv.GetCellAsInteger(num++, lineY); this.reception = basicCsv.GetCellAsInteger(num++, lineY); this.cooking = basicCsv.GetCellAsInteger(num++, lineY); this.dance = basicCsv.GetCellAsInteger(num++, lineY); this.vocal = basicCsv.GetCellAsInteger(num++, lineY); this.playCountNightWork = basicCsv.GetCellAsInteger(num++, lineY); this.hp = basicCsv.GetCellAsInteger(num++, lineY); this.mind = basicCsv.GetCellAsInteger(num++, lineY); this.inyoku = basicCsv.GetCellAsInteger(num++, lineY); this.mvalue = basicCsv.GetCellAsInteger(num++, lineY); this.hentai = basicCsv.GetCellAsInteger(num++, lineY); this.housi = basicCsv.GetCellAsInteger(num++, lineY); this.playCountYotogi = basicCsv.GetCellAsInteger(num++, lineY); if (basicCsv.GetCellAsString(num++, 0) == "合計値") { this.rehireEventId = -1; } else { this.rehireEventId = ((!basicCsv.IsCellToExistData(num - 1, lineY)) ? -1 : basicCsv.GetCellAsInteger(num - 1, lineY)); } } public string lastNameTerm { get { return "SubMaid/" + this.uniqueName + "/苗字"; } } public string firstNameTerm { get { return "SubMaid/" + this.uniqueName + "/名前"; } } public string contractTextTerm { get { return "MaidStatus/契約タイプ/" + this.contractText; } } public string personalTextTerm { get { return "SubMaid/" + this.uniqueName + "/性格"; } } public string relationTextTerm { get { return "SubMaid/" + this.uniqueName + "/状態"; } } public readonly int id; public readonly string uniqueName; public readonly bool kissSideNPC; public readonly string lastName; public readonly string firstName; public readonly string presetName; public readonly string iconFileName; public readonly string thumbnailFileName; public readonly Contract contract; public readonly string contractText; public readonly string personalText; public readonly string relationText; public readonly Seikeiken initSeikeiken; public readonly string jobClassText; public readonly int jobClassLevel; public readonly string yotogiClassText; public readonly int yotogiClassLevel; public readonly int likability; public readonly int lovely; public readonly int elegance; public readonly int charm; public readonly int care; public readonly int reception; public readonly int cooking; public readonly int dance; public readonly int vocal; public readonly int playCountNightWork; public readonly int hp; public readonly int mind; public readonly int inyoku; public readonly int mvalue; public readonly int hentai; public readonly int housi; public readonly int playCountYotogi; public readonly int rehireEventId; } } [Serializable] public class BackupStatus : ISerializationCallbackReceiver { private BackupStatus() { } public static SubMaid.BackupStatus CreateInstance(Maid maid) { Status status = maid.status; SubMaid.BackupStatus backupStatus = new SubMaid.BackupStatus(); backupStatus.subCharaUniqueName = status.subCharaData.uniqueName; backupStatus.lastName = status.lastName; backupStatus.firstName = status.firstName; backupStatus.employmentDay = status.employmentDay; backupStatus.relation = status.relation; backupStatus.additionalRelation = status.additionalRelation; backupStatus.seikeiken = status.seikeiken; backupStatus.likability = status.likability; backupStatus.playCountNightWork = status.playCountNightWork; backupStatus.sexPlayNumberOfPeople = status.sexPlayNumberOfPeople; backupStatus.sales = status.sales; backupStatus.totalSales = status.totalSales; backupStatus.totalEvaluations = status.totalEvaluations; backupStatus.evaluation = status.evaluation; int[] keyArray = status.workDatas.GetKeyArray(); MaidStatus.WorkData[] valueArray = status.workDatas.GetValueArray(); backupStatus.workData = new SubMaid.BackupStatus.WorkData[valueArray.Length]; for (int i = 0; i < valueArray.Length; i++) { backupStatus.workData[i] = new SubMaid.BackupStatus.WorkData(); backupStatus.workData[i].key = keyArray[i]; backupStatus.workData[i].id = valueArray[i].id; backupStatus.workData[i].playCount = valueArray[i].playCount; backupStatus.workData[i].level = valueArray[i].level; } backupStatus.maidFlagsKey = status.flags.GetKeyArray(); backupStatus.maidFlagsValue = status.flags.GetValueArray(); backupStatus.eventEndFlagsKey = status.eventEndFlags.GetKeyArray(); backupStatus.eventEndFlagsValue = status.eventEndFlags.GetValueArray(); backupStatus.iconBinary = maid.GetThumIcon().EncodeToPNG(); backupStatus.presetBinary = GameMain.Instance.CharacterMgr.PresetSaveNotWriteFile(maid, CharacterMgr.PresetType.All); return backupStatus; } public void Apply(Status status) { status.lastName = this.lastName; status.firstName = this.firstName; status.employmentDay = this.employmentDay; status.additionalRelation = this.additionalRelation; status.relation = this.relation; status.seikeiken = this.seikeiken; status.likability = this.likability; status.playCountNightWork = this.playCountNightWork; status.sexPlayNumberOfPeople = this.sexPlayNumberOfPeople; status.sales = this.sales; status.totalSales = this.totalSales; status.totalEvaluations = this.totalEvaluations; status.evaluation = this.evaluation; Dictionary dictionary = new Dictionary(); foreach (SubMaid.BackupStatus.WorkData workData in this.workData) { MaidStatus.WorkData workData2 = new MaidStatus.WorkData(); workData2.id = workData.id; workData2.level = workData.level; workData2.playCount = workData.playCount; dictionary.Add(workData.key, workData2); } status.SetWorkData(dictionary); status.RemoveFlagAll(); for (int j = 0; j < this.maidFlagsKey.Length; j++) { status.SetFlag(this.maidFlagsKey[j], this.maidFlagsValue[j]); } status.RemoveEventEndFlagAll(); for (int k = 0; k < this.eventEndFlagsKey.Length; k++) { status.SetEventEndFlag(this.eventEndFlagsKey[k], this.eventEndFlagsValue[k]); } if (this.iconBinary != null && this.iconBinary.Length > 0) { Texture2D texture2D = new Texture2D(4, 4, TextureFormat.ARGB32, false); texture2D.LoadImage(this.iconBinary); status.maid.SetThumIcon(texture2D); } if (this.presetBinary != null && this.presetBinary.Length > 0) { using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(this.presetBinary), Encoding.UTF8)) { CharacterMgr.Preset f_prest = GameMain.Instance.CharacterMgr.PresetLoad(binaryReader, string.Empty); GameMain.Instance.CharacterMgr.PresetSet(status.maid, f_prest, false); } } } public void OnBeforeSerialize() { this.version = 1000; } public void OnAfterDeserialize() { } private const int FixVersion = 1000; public int version = 1000; public string subCharaUniqueName; public string lastName; public string firstName; public int employmentDay; public Relation relation; private AdditionalRelation additionalRelation; public Seikeiken seikeiken; public int likability; public int playCountNightWork; public int sexPlayNumberOfPeople; public long sales; public long totalSales; public long totalEvaluations; public int evaluation; public SubMaid.BackupStatus.WorkData[] workData; public string[] maidFlagsKey; public int[] maidFlagsValue; public int[] eventEndFlagsKey; public bool[] eventEndFlagsValue; [NonSerialized] public byte[] iconBinary; [NonSerialized] public byte[] presetBinary; [Serializable] public class WorkData : ISerializationCallbackReceiver { public void OnBeforeSerialize() { this.version = 1000; } public void OnAfterDeserialize() { } public int version = 1000; public int key; public int id; public uint playCount; public int level; } } } }