denikson 5 years ago
parent
commit
c9ed992004
150 changed files with 14962 additions and 178 deletions
  1. 5 5
      Assembly-CSharp.sln
  2. 22 0
      Assembly-CSharp/AbstractSliderData.cs
  3. 97 1
      Assembly-CSharp/Assembly-CSharp.csproj
  4. 2 0
      Assembly-CSharp/BacklogCtrl.cs
  5. 72 1
      Assembly-CSharp/BaseKagManager.cs
  6. 1 1
      Assembly-CSharp/BasePhotoCustomObject.cs
  7. 1 1
      Assembly-CSharp/BasePhotoWindowManager.cs
  8. 1 0
      Assembly-CSharp/BlackjackGame.cs
  9. 4 4
      Assembly-CSharp/CMSystem.cs
  10. 3 3
      Assembly-CSharp/CharacterMgr.cs
  11. 4 4
      Assembly-CSharp/ChuBlipManager.cs
  12. 2 2
      Assembly-CSharp/ControllerShortcutSettingData.cs
  13. 1 1
      Assembly-CSharp/DeskManager.cs
  14. 4 4
      Assembly-CSharp/DesktopDuplication.cs
  15. 2 2
      Assembly-CSharp/DesktopScreen.cs
  16. 3 3
      Assembly-CSharp/DynamicBone.cs
  17. 1 1
      Assembly-CSharp/DynamicSkirtBone.cs
  18. 1 1
      Assembly-CSharp/EditMod.cs
  19. 1 1
      Assembly-CSharp/FacilityManager.cs
  20. 2 2
      Assembly-CSharp/FinishSyncrho.cs
  21. 1 0
      Assembly-CSharp/FreeModeSceneSelectBase.cs
  22. 2 2
      Assembly-CSharp/GameMain.cs
  23. 2 2
      Assembly-CSharp/GameUty.cs
  24. 2 2
      Assembly-CSharp/HandSignShortcut.cs
  25. 17 0
      Assembly-CSharp/I2/Loc/ArabicMapping.cs
  26. 82 0
      Assembly-CSharp/I2/Loc/ArabicTable.cs
  27. 13 0
      Assembly-CSharp/I2/Loc/AutoChangeCultureInfo.cs
  28. 85 0
      Assembly-CSharp/I2/Loc/BaseSpecializationManager.cs
  29. 18 0
      Assembly-CSharp/I2/Loc/CallbackNotification.cs
  30. 42 0
      Assembly-CSharp/I2/Loc/CoroutineManager.cs
  31. 28 0
      Assembly-CSharp/I2/Loc/CustomLocalizeCallback.cs
  32. 26 0
      Assembly-CSharp/I2/Loc/EventCallback.cs
  33. 31 0
      Assembly-CSharp/I2/Loc/Example_ChangeLanguage.cs
  34. 38 0
      Assembly-CSharp/I2/Loc/Example_LocalizedString.cs
  35. 49 0
      Assembly-CSharp/I2/Loc/GeneralArabicLetters.cs
  36. 20 0
      Assembly-CSharp/I2/Loc/GlobalParametersExample.cs
  37. 2700 0
      Assembly-CSharp/I2/Loc/GoogleLanguages.cs
  38. 574 0
      Assembly-CSharp/I2/Loc/GoogleTranslation.cs
  39. 87 0
      Assembly-CSharp/I2/Loc/HindiFixer.cs
  40. 239 0
      Assembly-CSharp/I2/Loc/I2BasePersistentStorage.cs
  41. 8 0
      Assembly-CSharp/I2/Loc/I2CustomPersistentStorage.cs
  42. 184 0
      Assembly-CSharp/I2/Loc/I2Utils.cs
  43. 9 0
      Assembly-CSharp/I2/Loc/ILocalizationParamsManager.cs
  44. 24 0
      Assembly-CSharp/I2/Loc/ILocalizeTarget.cs
  45. 17 0
      Assembly-CSharp/I2/Loc/ILocalizeTargetDescriptor.cs
  46. 10 0
      Assembly-CSharp/I2/Loc/IResourceManager_Bundles.cs
  47. 49 0
      Assembly-CSharp/I2/Loc/IsolatedArabicLetters.cs
  48. 68 0
      Assembly-CSharp/I2/Loc/LanguageData.cs
  49. 1644 0
      Assembly-CSharp/I2/Loc/LanguageSource.cs
  50. 1047 0
      Assembly-CSharp/I2/Loc/LocalizationManager.cs
  51. 97 0
      Assembly-CSharp/I2/Loc/LocalizationParamsManager.cs
  52. 214 0
      Assembly-CSharp/I2/Loc/LocalizationReader.cs
  53. 467 0
      Assembly-CSharp/I2/Loc/Localize.cs
  54. 75 0
      Assembly-CSharp/I2/Loc/LocalizeDropdown.cs
  55. 27 0
      Assembly-CSharp/I2/Loc/LocalizeTarget.cs
  56. 18 0
      Assembly-CSharp/I2/Loc/LocalizeTargetDesc.cs
  57. 12 0
      Assembly-CSharp/I2/Loc/LocalizeTargetDesc_Child.cs
  58. 12 0
      Assembly-CSharp/I2/Loc/LocalizeTargetDesc_Prefab.cs
  59. 25 0
      Assembly-CSharp/I2/Loc/LocalizeTargetDesc_Type.cs
  60. 115 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_NGUI_Label.cs
  61. 78 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_NGUI_Sprite.cs
  62. 64 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_NGUI_Texture.cs
  63. 69 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_AudioSource.cs
  64. 79 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_Child.cs
  65. 92 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_GUIText.cs
  66. 63 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_GUITexture.cs
  67. 114 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_Prefab.cs
  68. 63 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_SpriteRenderer.cs
  69. 93 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_TextMesh.cs
  70. 68 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityUI_Image.cs
  71. 64 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityUI_RawImage.cs
  72. 153 0
      Assembly-CSharp/I2/Loc/LocalizeTarget_UnityUI_Text.cs
  73. 44 0
      Assembly-CSharp/I2/Loc/LocalizedString.cs
  74. 24 0
      Assembly-CSharp/I2/Loc/NGUI_LanguagePopup.cs
  75. 107 0
      Assembly-CSharp/I2/Loc/PersistentStorage.cs
  76. 86 0
      Assembly-CSharp/I2/Loc/RTLFixer.cs
  77. 415 0
      Assembly-CSharp/I2/Loc/RTLFixerTool.cs
  78. 136 0
      Assembly-CSharp/I2/Loc/RealTimeTranslation.cs
  79. 26 0
      Assembly-CSharp/I2/Loc/RegisterBundlesManager.cs
  80. 27 0
      Assembly-CSharp/I2/Loc/RegisterGlobalParameters.cs
  81. 183 0
      Assembly-CSharp/I2/Loc/ResourceManager.cs
  82. 24 0
      Assembly-CSharp/I2/Loc/SetLanguage.cs
  83. 43 0
      Assembly-CSharp/I2/Loc/SetLanguageDropdown.cs
  84. 12 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSON.cs
  85. 139 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSONArray.cs
  86. 15 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSONBinaryTag.cs
  87. 203 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSONClass.cs
  88. 92 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSONData.cs
  89. 198 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSONLazyCreator.cs
  90. 621 0
      Assembly-CSharp/I2/Loc/SimpleJSON/JSONNode.cs
  91. 163 0
      Assembly-CSharp/I2/Loc/SpecializationManager.cs
  92. 76 0
      Assembly-CSharp/I2/Loc/StringObfucator.cs
  93. 17 0
      Assembly-CSharp/I2/Loc/TashkeelLocation.cs
  94. 120 0
      Assembly-CSharp/I2/Loc/TermData.cs
  95. 15 0
      Assembly-CSharp/I2/Loc/TermsPopup.cs
  96. 25 0
      Assembly-CSharp/I2/Loc/ToggleLanguage.cs
  97. 10 0
      Assembly-CSharp/I2/Loc/TranslationFlag.cs
  98. 25 0
      Assembly-CSharp/I2/Loc/TranslationJob.cs
  99. 74 0
      Assembly-CSharp/I2/Loc/TranslationJob_GET.cs
  100. 113 0
      Assembly-CSharp/I2/Loc/TranslationJob_Main.cs
  101. 54 0
      Assembly-CSharp/I2/Loc/TranslationJob_POST.cs
  102. 158 0
      Assembly-CSharp/I2/Loc/TranslationJob_WEB.cs
  103. 19 0
      Assembly-CSharp/I2/Loc/TranslationJob_WWW.cs
  104. 19 0
      Assembly-CSharp/I2/Loc/TranslationQuery.cs
  105. 11 0
      Assembly-CSharp/I2/Loc/eLanguageDataFlags.cs
  106. 14 0
      Assembly-CSharp/I2/Loc/ePluralType.cs
  107. 12 0
      Assembly-CSharp/I2/Loc/eSpreadsheetUpdateMode.cs
  108. 19 0
      Assembly-CSharp/I2/Loc/eTermType.cs
  109. 11 0
      Assembly-CSharp/IOnaholeNodeButton.cs
  110. 1 1
      Assembly-CSharp/Kasizuki/KasizukiManager.cs
  111. 3 3
      Assembly-CSharp/Maid.cs
  112. 1 1
      Assembly-CSharp/MaidParts.cs
  113. 1 1
      Assembly-CSharp/MaidProp.cs
  114. 1 1
      Assembly-CSharp/MaidStatus/Status.cs
  115. 66 60
      Assembly-CSharp/Menu.cs
  116. 2 0
      Assembly-CSharp/MessageWindowCtrl.cs
  117. 6 0
      Assembly-CSharp/MessageWindowMgr.cs
  118. 1 1
      Assembly-CSharp/Misc.cs
  119. 1 1
      Assembly-CSharp/ModCompile.cs
  120. 48 0
      Assembly-CSharp/Monitor.cs
  121. 30 0
      Assembly-CSharp/NodeButtonData.cs
  122. 12 3
      Assembly-CSharp/OnHoverTaskIcon.cs
  123. 390 0
      Assembly-CSharp/OnaholeBaseNodeMenuManager.cs
  124. 94 0
      Assembly-CSharp/OnaholeChuBlipDevice.cs
  125. 2 2
      Assembly-CSharp/OnaholeEstrusMode.cs
  126. 123 0
      Assembly-CSharp/OnaholeNodeButton.cs
  127. 82 0
      Assembly-CSharp/OnaholeNodeIconButton.cs
  128. 384 0
      Assembly-CSharp/OnaholeNodeMenuChildSecondRow.cs
  129. 80 0
      Assembly-CSharp/OnaholeNodeMenuChildThirdRow.cs
  130. 238 0
      Assembly-CSharp/OnaholeNodeMenuManager.cs
  131. 111 0
      Assembly-CSharp/OnaholeNodeSlider.cs
  132. 202 0
      Assembly-CSharp/OnaholeNodeTouchMenuManager.cs
  133. 4 0
      Assembly-CSharp/OvrGrabObj.cs
  134. 2 2
      Assembly-CSharp/OvrIK.cs
  135. 1 1
      Assembly-CSharp/PhotoModeSaveAndLoad.cs
  136. 1 1
      Assembly-CSharp/PlayerStatus/Status.cs
  137. 9 2
      Assembly-CSharp/SceneCasino.cs
  138. 9 2
      Assembly-CSharp/SceneCasinoShop.cs
  139. 8 4
      Assembly-CSharp/Schedule/ScheduleAPI.cs
  140. 28 2
      Assembly-CSharp/ScheduleCtrl.cs
  141. 2 1
      Assembly-CSharp/ScriptManager.cs
  142. 2 2
      Assembly-CSharp/SoundMgr.cs
  143. 49 29
      Assembly-CSharp/SubtitleDisplayManager.cs
  144. 37 9
      Assembly-CSharp/SubtitleMovieManager.cs
  145. 52 0
      Assembly-CSharp/TBodySkin.cs
  146. 3 3
      Assembly-CSharp/THair1.cs
  147. 8 2
      Assembly-CSharp/UndressingManager.cs
  148. 1 1
      Assembly-CSharp/WindowPartsFingerPreset.cs
  149. 54 0
      Assembly-CSharp/YotogiManager.cs
  150. 56 0
      Assembly-CSharp/Yotogis/Skill.cs

+ 5 - 5
Assembly-CSharp.sln

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 15
 VisualStudioVersion = 15.0.26228.4
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp\Assembly-CSharp.csproj", "{B6C45622-5B63-417E-81F1-36F0C3010B2C}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp\Assembly-CSharp.csproj", "{3C774868-C2C7-4676-938B-45C4722B18E8}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -11,10 +11,10 @@ Global
 		Release|Any CPU = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{B6C45622-5B63-417E-81F1-36F0C3010B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{B6C45622-5B63-417E-81F1-36F0C3010B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{B6C45622-5B63-417E-81F1-36F0C3010B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{B6C45622-5B63-417E-81F1-36F0C3010B2C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3C774868-C2C7-4676-938B-45C4722B18E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3C774868-C2C7-4676-938B-45C4722B18E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3C774868-C2C7-4676-938B-45C4722B18E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3C774868-C2C7-4676-938B-45C4722B18E8}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 22 - 0
Assembly-CSharp/AbstractSliderData.cs

@@ -0,0 +1,22 @@
+using System;
+using UnityEngine;
+
+public abstract class AbstractSliderData
+{
+	public AbstractSliderData(MonoBehaviour parent)
+	{
+		this.parent_ = parent;
+	}
+
+	public abstract void SetUISliderObject(UISlider set_slider);
+
+	public abstract void Update();
+
+	public abstract void ChangeSliderValue();
+
+	public abstract UISlider slider { get; }
+
+	public abstract float cur_val_slider_pos { get; }
+
+	protected MonoBehaviour parent_;
+}

+ 97 - 1
Assembly-CSharp/Assembly-CSharp.csproj

@@ -4,7 +4,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{B6C45622-5B63-417E-81F1-36F0C3010B2C}</ProjectGuid>
+    <ProjectGuid>{3C774868-C2C7-4676-938B-45C4722B18E8}</ProjectGuid>
     <OutputType>Library</OutputType>
     <RootNamespace>Assembly-CSharp</RootNamespace>
     <AssemblyName>Assembly-CSharp</AssemblyName>
@@ -84,6 +84,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AbstractFreeModeItem.cs" />
+    <Compile Include="AbstractSliderData.cs" />
     <Compile Include="AcquiredAttributeUnit.cs" />
     <Compile Include="AcquiredSkillUnit.cs" />
     <Compile Include="ActionCase.cs" />
@@ -418,6 +419,90 @@
     <Compile Include="HideScrollEventCatch.cs" />
     <Compile Include="HyperlinkText\ObjectPool.cs" />
     <Compile Include="HyperText.cs" />
+    <Compile Include="I2\Loc\ArabicMapping.cs" />
+    <Compile Include="I2\Loc\ArabicTable.cs" />
+    <Compile Include="I2\Loc\AutoChangeCultureInfo.cs" />
+    <Compile Include="I2\Loc\BaseSpecializationManager.cs" />
+    <Compile Include="I2\Loc\CallbackNotification.cs" />
+    <Compile Include="I2\Loc\CoroutineManager.cs" />
+    <Compile Include="I2\Loc\CustomLocalizeCallback.cs" />
+    <Compile Include="I2\Loc\eLanguageDataFlags.cs" />
+    <Compile Include="I2\Loc\ePluralType.cs" />
+    <Compile Include="I2\Loc\eSpreadsheetUpdateMode.cs" />
+    <Compile Include="I2\Loc\eTermType.cs" />
+    <Compile Include="I2\Loc\EventCallback.cs" />
+    <Compile Include="I2\Loc\Example_ChangeLanguage.cs" />
+    <Compile Include="I2\Loc\Example_LocalizedString.cs" />
+    <Compile Include="I2\Loc\GeneralArabicLetters.cs" />
+    <Compile Include="I2\Loc\GlobalParametersExample.cs" />
+    <Compile Include="I2\Loc\GoogleLanguages.cs" />
+    <Compile Include="I2\Loc\GoogleTranslation.cs" />
+    <Compile Include="I2\Loc\HindiFixer.cs" />
+    <Compile Include="I2\Loc\I2BasePersistentStorage.cs" />
+    <Compile Include="I2\Loc\I2CustomPersistentStorage.cs" />
+    <Compile Include="I2\Loc\I2Utils.cs" />
+    <Compile Include="I2\Loc\ILocalizationParamsManager.cs" />
+    <Compile Include="I2\Loc\ILocalizeTarget.cs" />
+    <Compile Include="I2\Loc\ILocalizeTargetDescriptor.cs" />
+    <Compile Include="I2\Loc\IResourceManager_Bundles.cs" />
+    <Compile Include="I2\Loc\IsolatedArabicLetters.cs" />
+    <Compile Include="I2\Loc\LanguageData.cs" />
+    <Compile Include="I2\Loc\LanguageSource.cs" />
+    <Compile Include="I2\Loc\LocalizationManager.cs" />
+    <Compile Include="I2\Loc\LocalizationParamsManager.cs" />
+    <Compile Include="I2\Loc\LocalizationReader.cs" />
+    <Compile Include="I2\Loc\Localize.cs" />
+    <Compile Include="I2\Loc\LocalizeDropdown.cs" />
+    <Compile Include="I2\Loc\LocalizedString.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget.cs" />
+    <Compile Include="I2\Loc\LocalizeTargetDesc.cs" />
+    <Compile Include="I2\Loc\LocalizeTargetDesc_Child.cs" />
+    <Compile Include="I2\Loc\LocalizeTargetDesc_Prefab.cs" />
+    <Compile Include="I2\Loc\LocalizeTargetDesc_Type.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_NGUI_Label.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_NGUI_Sprite.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_NGUI_Texture.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_AudioSource.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_Child.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_GUIText.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_GUITexture.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_Prefab.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_SpriteRenderer.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityStandard_TextMesh.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityUI_Image.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityUI_RawImage.cs" />
+    <Compile Include="I2\Loc\LocalizeTarget_UnityUI_Text.cs" />
+    <Compile Include="I2\Loc\NGUI_LanguagePopup.cs" />
+    <Compile Include="I2\Loc\PersistentStorage.cs" />
+    <Compile Include="I2\Loc\RealTimeTranslation.cs" />
+    <Compile Include="I2\Loc\RegisterBundlesManager.cs" />
+    <Compile Include="I2\Loc\RegisterGlobalParameters.cs" />
+    <Compile Include="I2\Loc\ResourceManager.cs" />
+    <Compile Include="I2\Loc\RTLFixer.cs" />
+    <Compile Include="I2\Loc\RTLFixerTool.cs" />
+    <Compile Include="I2\Loc\SetLanguage.cs" />
+    <Compile Include="I2\Loc\SetLanguageDropdown.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSON.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSONArray.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSONBinaryTag.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSONClass.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSONData.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSONLazyCreator.cs" />
+    <Compile Include="I2\Loc\SimpleJSON\JSONNode.cs" />
+    <Compile Include="I2\Loc\SpecializationManager.cs" />
+    <Compile Include="I2\Loc\StringObfucator.cs" />
+    <Compile Include="I2\Loc\TashkeelLocation.cs" />
+    <Compile Include="I2\Loc\TermData.cs" />
+    <Compile Include="I2\Loc\TermsPopup.cs" />
+    <Compile Include="I2\Loc\ToggleLanguage.cs" />
+    <Compile Include="I2\Loc\TranslationFlag.cs" />
+    <Compile Include="I2\Loc\TranslationJob.cs" />
+    <Compile Include="I2\Loc\TranslationJob_GET.cs" />
+    <Compile Include="I2\Loc\TranslationJob_Main.cs" />
+    <Compile Include="I2\Loc\TranslationJob_POST.cs" />
+    <Compile Include="I2\Loc\TranslationJob_WEB.cs" />
+    <Compile Include="I2\Loc\TranslationJob_WWW.cs" />
+    <Compile Include="I2\Loc\TranslationQuery.cs" />
     <Compile Include="IDisposableBase.cs" />
     <Compile Include="IExperienceSystem.cs" />
     <Compile Include="IFade.cs" />
@@ -436,6 +521,7 @@
     <Compile Include="InvEquipment.cs" />
     <Compile Include="InvGameItem.cs" />
     <Compile Include="InvStat.cs" />
+    <Compile Include="IOnaholeNodeButton.cs" />
     <Compile Include="ItemInfoWnd.cs" />
     <Compile Include="ItemTypeRandomPresetButton.cs" />
     <Compile Include="jiggleBone.cs" />
@@ -640,6 +726,7 @@
     <Compile Include="ModCompile.cs" />
     <Compile Include="ModExport.cs" />
     <Compile Include="MoneySetttingUI.cs" />
+    <Compile Include="Monitor.cs" />
     <Compile Include="MonoSingleton.cs" />
     <Compile Include="MotionAction_Mgr.cs" />
     <Compile Include="MotionKagManager.cs" />
@@ -660,6 +747,7 @@
     <Compile Include="NGUIText.cs" />
     <Compile Include="NGUITools.cs" />
     <Compile Include="NightTaskUnit.cs" />
+    <Compile Include="NodeButtonData.cs" />
     <Compile Include="NoteBase.cs" />
     <Compile Include="NoteEffect.cs" />
     <Compile Include="NoteGrid.cs" />
@@ -668,12 +756,20 @@
     <Compile Include="ObjectCopier.cs" />
     <Compile Include="ObjectCreateWindow.cs" />
     <Compile Include="ObjectManagerWindow.cs" />
+    <Compile Include="OnaholeBaseNodeMenuManager.cs" />
     <Compile Include="OnaholeCharaManager.cs" />
     <Compile Include="OnaholeChuBlipDevice.cs" />
     <Compile Include="OnaholeEstrusMode.cs" />
     <Compile Include="OnaholeExpression.cs" />
     <Compile Include="OnaholeFeelings.cs" />
     <Compile Include="OnaholeMotion.cs" />
+    <Compile Include="OnaholeNodeButton.cs" />
+    <Compile Include="OnaholeNodeIconButton.cs" />
+    <Compile Include="OnaholeNodeMenuChildSecondRow.cs" />
+    <Compile Include="OnaholeNodeMenuChildThirdRow.cs" />
+    <Compile Include="OnaholeNodeMenuManager.cs" />
+    <Compile Include="OnaholeNodeSlider.cs" />
+    <Compile Include="OnaholeNodeTouchMenuManager.cs" />
     <Compile Include="OnaholeOnedari.cs" />
     <Compile Include="OnaholeReactionManager.cs" />
     <Compile Include="OnaholeReactionSwitcher.cs" />

+ 2 - 0
Assembly-CSharp/BacklogCtrl.cs

@@ -86,6 +86,8 @@ public class BacklogCtrl : MonoBehaviour
 
 		public string m_msg { get; set; }
 
+		public string m_subtitlemsg { get; set; }
+
 		public string m_voiceId { get; set; }
 
 		public int m_voicePitch { get; set; }

+ 72 - 1
Assembly-CSharp/BaseKagManager.cs

@@ -161,6 +161,10 @@ public class BaseKagManager : IDisposable
 		this.kag_.AddTagCallBack("setmcskip", new KagScript.KagTagCallBack(this.TagSetMcSkip));
 		this.kag_.AddTagCallBack("addeventdisplay", new KagScript.KagTagCallBack(this.TagAddedEventDisplay));
 		this.kag_.AddTagCallBack("tutorialstart", new KagScript.KagTagCallBack(this.TagTutorialStart));
+		this.kag_.AddTagCallBack("loadsubtitlefile", new KagScript.KagTagCallBack(this.TagLoadSubtitleFile));
+		this.kag_.AddTagCallBack("endsubtitledisplay", new KagScript.KagTagCallBack(this.TagEndSubtitleDisplay));
+		this.kag_.AddTagCallBack("subtitledisplayforplayvoice", new KagScript.KagTagCallBack(this.TagSubtitleDisplayForPlayVoice));
+		this.kag_.AddTagCallBack("subtitledisplay", new KagScript.KagTagCallBack(this.TagSubtitleDisplay));
 	}
 
 	public virtual void Update()
@@ -1652,12 +1656,17 @@ public class BaseKagManager : IDisposable
 		{
 			millisecond = tag_data.GetTagProperty("fade").AsInteger();
 		}
+		int num = -1;
 		if (!tag_data.IsValid("dummy"))
 		{
 			Maid maidAndMan = this.GetMaidAndMan(tag_data);
 			if (maidAndMan != null && maidAndMan.Visible)
 			{
 				maidAndMan.AudioMan.LoadPlay(text, GameUty.MillisecondToSecond(millisecond), true, f_bLoop);
+				if (maidAndMan.AudioMan.isPlay() && maidAndMan.AudioMan.audiosource.clip != null)
+				{
+					num = (int)(maidAndMan.AudioMan.audiosource.clip.length * 1000f);
+				}
 				if (tag_data.IsValid("wait"))
 				{
 					result = this.SetMaidVoiceWait(maidAndMan);
@@ -1671,11 +1680,24 @@ public class BaseKagManager : IDisposable
 		else
 		{
 			GameMain.Instance.SoundMgr.PlayDummyVoice(text, GameUty.MillisecondToSecond(millisecond), true, f_bLoop, 50);
+			if (GameMain.Instance.SoundMgr.m_AudioDummyVoice.isPlay() && GameMain.Instance.SoundMgr.m_AudioDummyVoice.audiosource.clip != null)
+			{
+				num = (int)(GameMain.Instance.SoundMgr.m_AudioDummyVoice.audiosource.clip.length * 1000f);
+			}
 			if (tag_data.IsValid("wait"))
 			{
 				result = this.SetDummyVoiceWait();
 			}
 		}
+		if (!string.IsNullOrEmpty(this.subtitle_data.text) && (0 <= this.subtitle_data.displayTime || 0 < num))
+		{
+			SubtitleMovieManager globalInstance = SubtitleMovieManager.GetGlobalInstance(this.subtitle_data.casinoType);
+			globalInstance.autoDestroy = true;
+			int num2 = (0 > this.subtitle_data.displayTime) ? num : this.subtitle_data.displayTime;
+			num2 += this.subtitle_data.addDisplayTime;
+			globalInstance.Play(this.subtitle_data.text, num2);
+			this.subtitle_data.Clear();
+		}
 		return result;
 	}
 
@@ -3847,6 +3869,27 @@ public class BaseKagManager : IDisposable
 		return true;
 	}
 
+	public bool TagLoadSubtitleFile(KagTagSupport tag_data)
+	{
+		return false;
+	}
+
+	public bool TagEndSubtitleDisplay(KagTagSupport tag_data)
+	{
+		SubtitleMovieManager.DestroyGlobalInstance();
+		return false;
+	}
+
+	public bool TagSubtitleDisplayForPlayVoice(KagTagSupport tag_data)
+	{
+		return false;
+	}
+
+	public bool TagSubtitleDisplay(KagTagSupport tag_data)
+	{
+		return false;
+	}
+
 	protected virtual void PlayMaidMotion(Maid maid, string fn, bool additive = false, bool loop = false, bool boAddQue = false, float val = 0.5f)
 	{
 		if (!GameMain.Instance.ScriptMgr.is_motion_blend)
@@ -4075,6 +4118,7 @@ public class BaseKagManager : IDisposable
 
 	private void OnScenarioLoadEvent(string file_name, string label_name)
 	{
+		this.subtitle_data.Clear();
 	}
 
 	public virtual string GetKagClassName()
@@ -4101,7 +4145,7 @@ public class BaseKagManager : IDisposable
 	public void Serialize(BinaryWriter binary)
 	{
 		binary.Write("CM3D2_KAG");
-		binary.Write(1150);
+		binary.Write(1160);
 		byte[] array = this.kag_.Serialize();
 		int value = array.Length;
 		binary.Write(value);
@@ -4122,6 +4166,7 @@ public class BaseKagManager : IDisposable
 		this.enabled = binary.ReadBoolean();
 		this.exec_wait_data_.Clear();
 		this.wait_event_list_.Clear();
+		this.subtitle_data.Clear();
 	}
 
 	public bool enabled { get; set; }
@@ -4140,6 +4185,8 @@ public class BaseKagManager : IDisposable
 
 	protected Dictionary<string, WaitEventList> wait_event_list_ = new Dictionary<string, WaitEventList>();
 
+	protected BaseKagManager.SubtitleData subtitle_data = new BaseKagManager.SubtitleData();
+
 	private bool is_disposed_;
 
 	[CompilerGenerated]
@@ -4485,4 +4532,28 @@ public class BaseKagManager : IDisposable
 			base.Clear();
 		}
 	}
+
+	protected class SubtitleData
+	{
+		public SubtitleData()
+		{
+			this.Clear();
+		}
+
+		public void Clear()
+		{
+			this.text = string.Empty;
+			this.displayTime = -1;
+			this.addDisplayTime = 0;
+			this.casinoType = false;
+		}
+
+		public string text;
+
+		public int displayTime;
+
+		public int addDisplayTime;
+
+		public bool casinoType;
+	}
 }

+ 1 - 1
Assembly-CSharp/BasePhotoCustomObject.cs

@@ -173,7 +173,7 @@ public abstract class BasePhotoCustomObject : MonoBehaviour, IComparable<BasePho
 			using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
 			{
 				binaryWriter.Write("COM3D2_PHOTO_CUSTOM_OBJECT");
-				binaryWriter.Write(1150);
+				binaryWriter.Write(1160);
 				binaryWriter.Write(this.type.ToString());
 				binaryWriter.Write(this.scale_);
 				binaryWriter.Write(this.enabledTextureColor_);

+ 1 - 1
Assembly-CSharp/BasePhotoWindowManager.cs

@@ -153,7 +153,7 @@ public abstract class BasePhotoWindowManager : MonoBehaviour
 			using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
 			{
 				binaryWriter.Write(this.save_header_uidata);
-				binaryWriter.Write(1150);
+				binaryWriter.Write(1160);
 				binaryWriter.Write(this.save_data_.Count);
 				foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, string>>> keyValuePair3 in this.save_data_)
 				{

+ 1 - 0
Assembly-CSharp/BlackjackGame.cs

@@ -513,6 +513,7 @@ public class BlackjackGame : MonoBehaviour
 
 	public void BJEnd()
 	{
+		SubtitleMovieManager.DestroyGlobalInstance();
 		this.m_UIRaycaster.enabled = false;
 		GameMain.Instance.SysDlg.Close();
 		BetSetUI.Instance.FadeOut();

+ 4 - 4
Assembly-CSharp/CMSystem.cs

@@ -808,7 +808,7 @@ public class CMSystem
 	{
 		XElement xelement = new XElement("Config", new object[]
 		{
-			new XAttribute("Version", 1150),
+			new XAttribute("Version", 1160),
 			new XElement("System", new XElement("SysButtonShowAlways", this.SysButtonShowAlways)),
 			new XElement("Screen", new object[]
 			{
@@ -1125,7 +1125,7 @@ public class CMSystem
 		MemoryStream memoryStream = new MemoryStream();
 		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 		binaryWriter.Write("CM3D2_SYSTEM2");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		binaryWriter.Write(this.m_dicEditColorPresetData.Count);
 		foreach (KeyValuePair<int, Dictionary<string, int>> keyValuePair in this.m_dicEditColorPresetData)
 		{
@@ -1697,7 +1697,7 @@ public class CMSystem
 
 		public void OnBeforeSerialize()
 		{
-			this.m_nVersion = 1150;
+			this.m_nVersion = 1160;
 		}
 
 		public void OnAfterDeserialize()
@@ -1705,7 +1705,7 @@ public class CMSystem
 		}
 
 		[SerializeField]
-		private int m_nVersion = 1150;
+		private int m_nVersion = 1160;
 
 		[SerializeField]
 		private string m_strDShowFilter = "Microsoft DTV-DVD Video Decoder";

+ 3 - 3
Assembly-CSharp/CharacterMgr.cs

@@ -949,7 +949,7 @@ public class CharacterMgr : MonoBehaviour
 		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 		string result = string.Empty;
 		binaryWriter.Write("CM3D2_PRESET_S");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		binaryWriter.Write((char)presset_type);
 		maid.SerializePropLowCapacity(binaryWriter);
 		maid.SerializeMultiColor(binaryWriter);
@@ -966,7 +966,7 @@ public class CharacterMgr : MonoBehaviour
 		MemoryStream memoryStream = new MemoryStream();
 		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 		binaryWriter.Write("CM3D2_PRESET");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		binaryWriter.Write((int)f_type);
 		if (texture2D != null)
 		{
@@ -1246,7 +1246,7 @@ public class CharacterMgr : MonoBehaviour
 	public bool Serialize(BinaryWriter bwWrite)
 	{
 		bwWrite.Write("CM3D2_CHR_MGR");
-		bwWrite.Write(1150);
+		bwWrite.Write(1160);
 		this.m_PlayerStatus.Serialize(bwWrite);
 		bwWrite.Write(this.m_listStockMan.Count);
 		for (int i = 0; i < this.m_listStockMan.Count; i++)

+ 4 - 4
Assembly-CSharp/ChuBlipManager.cs

@@ -4,6 +4,10 @@ using UnityEngine;
 
 public class ChuBlipManager : MonoBehaviour
 {
+	public OnaholeEstrusMode estrusMode { get; private set; }
+
+	public FinishSyncrho finishSyncrho { get; private set; }
+
 	public Dictionary<string, OnaholeCharaManager> OnahoCharaDic
 	{
 		get
@@ -36,10 +40,6 @@ public class ChuBlipManager : MonoBehaviour
 
 	private AutoPiston autoPiston;
 
-	private OnaholeEstrusMode estrusMode;
-
-	private FinishSyncrho finishSyncrho;
-
 	private GameObject rayHitObj;
 
 	private float dot;

+ 2 - 2
Assembly-CSharp/ControllerShortcutSettingData.cs

@@ -33,7 +33,7 @@ public static class ControllerShortcutSettingData
 	{
 		public void OnBeforeSerialize()
 		{
-			this.m_nVersion = 1150;
+			this.m_nVersion = 1160;
 		}
 
 		public void OnAfterDeserialize()
@@ -261,7 +261,7 @@ public static class ControllerShortcutSettingData
 		private const string CONF_NAME = "OvrControllerShortcutConfig.json";
 
 		[SerializeField]
-		private int m_nVersion = 1150;
+		private int m_nVersion = 1160;
 
 		[SerializeField]
 		private bool IsDirectShortcutMode = true;

+ 1 - 1
Assembly-CSharp/DeskManager.cs

@@ -143,7 +143,7 @@ internal class DeskManager
 	public static void SerializeSingleSaveData(BinaryWriter binary)
 	{
 		binary.Write("CM3D2_DeskCustomize");
-		binary.Write(1150);
+		binary.Write(1160);
 		binary.Write(DeskManager.item_inst_data_.Count);
 		for (int i = 0; i < DeskManager.item_inst_data_.Count; i++)
 		{

+ 4 - 4
Assembly-CSharp/DesktopDuplication.cs

@@ -8,14 +8,14 @@ public class DesktopDuplication : MonoBehaviour
 	public bool CreateDesktopDuplication(string display_device_name)
 	{
 		NDebug.Assert(this.class_pointer_ == IntPtr.Zero, "CreateDesktopDuplication二重に作成しようとしました。");
-		if (!global::DesktopDuplication.class_pointer_cache_.TryGetValue(display_device_name, out this.class_pointer_))
+		if (!DesktopDuplication.class_pointer_cache_.TryGetValue(display_device_name, out this.class_pointer_))
 		{
 			this.class_pointer_ = DLLDesktopDuplication.CreateDesktopDuplication(display_device_name);
 			if (this.class_pointer_ == IntPtr.Zero)
 			{
 				return false;
 			}
-			global::DesktopDuplication.class_pointer_cache_.Add(display_device_name, this.class_pointer_);
+			DesktopDuplication.class_pointer_cache_.Add(display_device_name, this.class_pointer_);
 		}
 		this.render_event_func_ptr_ = DLLDesktopDuplication.GetDesktopDuplicationRenderEventFunc();
 		this.render_event_id_ = DLLDesktopDuplication.GetDesktopDuplicationRenderID(this.class_pointer_);
@@ -57,14 +57,14 @@ public class DesktopDuplication : MonoBehaviour
 
 	public void OnApplicationQuit()
 	{
-		foreach (KeyValuePair<string, IntPtr> keyValuePair in global::DesktopDuplication.class_pointer_cache_)
+		foreach (KeyValuePair<string, IntPtr> keyValuePair in DesktopDuplication.class_pointer_cache_)
 		{
 			if (keyValuePair.Value != IntPtr.Zero)
 			{
 				DLLDesktopDuplication.DeleteDesktopDuplication(keyValuePair.Value);
 			}
 		}
-		global::DesktopDuplication.class_pointer_cache_.Clear();
+		DesktopDuplication.class_pointer_cache_.Clear();
 		this.class_pointer_ = IntPtr.Zero;
 	}
 

+ 2 - 2
Assembly-CSharp/DesktopScreen.cs

@@ -9,7 +9,7 @@ public class DesktopScreen : MonoBehaviour
 		this.m_nDisplayNo = GameMain.Instance.CMSystem.DesktopCaptureMonitorNo;
 		Material sharedMaterial = base.GetComponent<Renderer>().sharedMaterial;
 		sharedMaterial.mainTexture = Resources.Load<Texture2D>("System/Texture/unsupported");
-		this.m_dup = base.gameObject.AddComponent<global::DesktopDuplication>();
+		this.m_dup = base.gameObject.AddComponent<DesktopDuplication>();
 		bool flag = this.m_dup.CreateDesktopDuplication("\\\\.\\DISPLAY" + this.m_nDisplayNo.ToString());
 		Size<float> size;
 		if (flag && this.m_dup.width != 0 && this.m_dup.height != 0)
@@ -57,7 +57,7 @@ public class DesktopScreen : MonoBehaviour
 
 	public float m_fSize = 0.3f;
 
-	private global::DesktopDuplication m_dup;
+	private DesktopDuplication m_dup;
 
 	private Transform m_trCursor;
 

+ 3 - 3
Assembly-CSharp/DynamicBone.cs

@@ -30,7 +30,7 @@ public class DynamicBone : MonoBehaviour
 			return false;
 		};
 		f_bw.Write("CM3D21_PHY");
-		f_bw.Write(1150);
+		f_bw.Write(1160);
 		if (this.m_Root == null)
 		{
 			NDebug.MessageBox("エラー", "×物理ルートボーンが設定されていません。");
@@ -94,7 +94,7 @@ public class DynamicBone : MonoBehaviour
 	public bool SerializeWriteCollider(BinaryWriter f_bw, string f_strFileName)
 	{
 		f_bw.Write("CM3D21_COL");
-		f_bw.Write(1150);
+		f_bw.Write(1160);
 		if (this.m_Colliders == null || this.m_Colliders.Count == 0)
 		{
 			NDebug.MessageBox("エラー", "×物理Collidersは空です。");
@@ -110,7 +110,7 @@ public class DynamicBone : MonoBehaviour
 			else
 			{
 				f_bw.Write(this.m_Colliders[i].TypeName);
-				this.m_Colliders[i].Serialize(f_bw, 1150);
+				this.m_Colliders[i].Serialize(f_bw, 1160);
 			}
 		}
 		this.m_ColliderFileName = f_strFileName;

+ 1 - 1
Assembly-CSharp/DynamicSkirtBone.cs

@@ -18,7 +18,7 @@ public class DynamicSkirtBone : MonoBehaviour
 	public bool SerializeWrite(BinaryWriter f_bw)
 	{
 		f_bw.Write("CM3D21_PSK");
-		f_bw.Write(1150);
+		f_bw.Write(1160);
 		f_bw.Write(this.m_fPanierRadius);
 		this.SerializeWriteAnimationCurve(f_bw, this.m_PanierRadiusDistrib);
 		int num = (this.m_PanierRadiusDistribGroup == null) ? 0 : this.m_PanierRadiusDistribGroup.Length;

+ 1 - 1
Assembly-CSharp/EditMod.cs

@@ -265,7 +265,7 @@ public class EditMod : MonoBehaviour
 		MemoryStream memoryStream = new MemoryStream();
 		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 		binaryWriter.Write("CM3D2_MOD");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		binaryWriter.Write(value);
 		binaryWriter.Write(text2.ToLower());
 		binaryWriter.Write(value2);

+ 1 - 1
Assembly-CSharp/FacilityManager.cs

@@ -657,7 +657,7 @@ public class FacilityManager : MonoBehaviour
 		Stopwatch stopwatch = new Stopwatch();
 		stopwatch.Start();
 		brWrite.Write("CM3D21_FACILITY_MGR");
-		brWrite.Write(1150);
+		brWrite.Write(1160);
 		brWrite.Write("5");
 		int num = 0;
 		for (int i = 0; i < this.m_FacilityArray.Count; i++)

+ 2 - 2
Assembly-CSharp/FinishSyncrho.cs

@@ -3,14 +3,14 @@ using UnityEngine;
 
 public class FinishSyncrho : MonoBehaviour
 {
+	public bool systemEnable { get; private set; }
+
 	[SerializeField]
 	private UIButton buttonFinishSyncrho;
 
 	[SerializeField]
 	private UIButton buttonFinish;
 
-	private bool systemEnable;
-
 	private Color buttonDefaultColor = default(Color);
 
 	[SerializeField]

+ 1 - 0
Assembly-CSharp/FreeModeSceneSelectBase.cs

@@ -21,6 +21,7 @@ public class FreeModeSceneSelectBase : WfScreenChildren
 
 	protected override void OnCall()
 	{
+		SubtitleMovieManager.DestroyGlobalInstance();
 		this.is_scenario_load_ = false;
 		if (this.maid_ != null)
 		{

+ 2 - 2
Assembly-CSharp/GameMain.cs

@@ -666,7 +666,7 @@ public class GameMain : MonoSingleton<GameMain>
 		serializeHeader.nMaidNum = this.m_CharacterMgr.GetStockMaidCount();
 		serializeHeader.strComment = f_strComment;
 		binaryWriter.Write("COM3D2_SAVE");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		this.SerializeWriteHeader(binaryWriter, serializeHeader);
 		binaryWriter.Write("bookmark_kk_01");
 		GameMain.BinaryBookmark binaryBookmark = new GameMain.BinaryBookmark(binaryWriter);
@@ -780,7 +780,7 @@ public class GameMain : MonoSingleton<GameMain>
 		MemoryStream memoryStream = new MemoryStream();
 		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 		binaryWriter.Write("COM3D2_SAVE");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		this.SerializeWriteHeader(binaryWriter, saveDataHeader);
 		binaryWriter.Write(array, (int)saveDataHeader.lHeaderSize, (int)((long)array.Length - saveDataHeader.lHeaderSize));
 		File.WriteAllBytes(path, memoryStream.ToArray());

+ 2 - 2
Assembly-CSharp/GameUty.cs

@@ -912,14 +912,14 @@ public class GameUty
 
 	public static string GetBuildVersionText()
 	{
-		int num = 1150;
+		int num = 1160;
 		return (num >= 1000) ? ((float)num / 1000f).ToString("F2") : ((float)num / 100f).ToString("F2");
 	}
 
 	public static string GetGameVersionText()
 	{
 		string text = "COM3D2x64.exe";
-		int num = 1150;
+		int num = 1160;
 		string path = Path.GetFullPath(".\\") + "update.lst";
 		string[] array = new string[0];
 		if (File.Exists(path))

+ 2 - 2
Assembly-CSharp/HandSignShortcut.cs

@@ -494,7 +494,7 @@ public class HandSignShortcut : MonoBehaviour
 	{
 		public void OnBeforeSerialize()
 		{
-			this.m_nVersion = 1150;
+			this.m_nVersion = 1160;
 		}
 
 		public void OnAfterDeserialize()
@@ -803,7 +803,7 @@ public class HandSignShortcut : MonoBehaviour
 		private const string CONF_NAME = "MaidFingerDataList.json";
 
 		[SerializeField]
-		private int m_nVersion = 1150;
+		private int m_nVersion = 1160;
 
 		[SerializeField]
 		private List<HandSignShortcut.MaidFingerData> MaidFingerDataList = new List<HandSignShortcut.MaidFingerData>();

+ 17 - 0
Assembly-CSharp/I2/Loc/ArabicMapping.cs

@@ -0,0 +1,17 @@
+using System;
+
+namespace I2.Loc
+{
+	internal class ArabicMapping
+	{
+		public ArabicMapping(int from, int to)
+		{
+			this.from = from;
+			this.to = to;
+		}
+
+		public int from;
+
+		public int to;
+	}
+}

+ 82 - 0
Assembly-CSharp/I2/Loc/ArabicTable.cs

@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+
+namespace I2.Loc
+{
+	internal class ArabicTable
+	{
+		private ArabicTable()
+		{
+			ArabicTable.mapList = new List<ArabicMapping>();
+			ArabicTable.mapList.Add(new ArabicMapping(1569, 65152));
+			ArabicTable.mapList.Add(new ArabicMapping(1575, 65165));
+			ArabicTable.mapList.Add(new ArabicMapping(1571, 65155));
+			ArabicTable.mapList.Add(new ArabicMapping(1572, 65157));
+			ArabicTable.mapList.Add(new ArabicMapping(1573, 65159));
+			ArabicTable.mapList.Add(new ArabicMapping(1609, 64508));
+			ArabicTable.mapList.Add(new ArabicMapping(1574, 65161));
+			ArabicTable.mapList.Add(new ArabicMapping(1576, 65167));
+			ArabicTable.mapList.Add(new ArabicMapping(1578, 65173));
+			ArabicTable.mapList.Add(new ArabicMapping(1579, 65177));
+			ArabicTable.mapList.Add(new ArabicMapping(1580, 65181));
+			ArabicTable.mapList.Add(new ArabicMapping(1581, 65185));
+			ArabicTable.mapList.Add(new ArabicMapping(1582, 65189));
+			ArabicTable.mapList.Add(new ArabicMapping(1583, 65193));
+			ArabicTable.mapList.Add(new ArabicMapping(1584, 65195));
+			ArabicTable.mapList.Add(new ArabicMapping(1585, 65197));
+			ArabicTable.mapList.Add(new ArabicMapping(1586, 65199));
+			ArabicTable.mapList.Add(new ArabicMapping(1587, 65201));
+			ArabicTable.mapList.Add(new ArabicMapping(1588, 65205));
+			ArabicTable.mapList.Add(new ArabicMapping(1589, 65209));
+			ArabicTable.mapList.Add(new ArabicMapping(1590, 65213));
+			ArabicTable.mapList.Add(new ArabicMapping(1591, 65217));
+			ArabicTable.mapList.Add(new ArabicMapping(1592, 65221));
+			ArabicTable.mapList.Add(new ArabicMapping(1593, 65225));
+			ArabicTable.mapList.Add(new ArabicMapping(1594, 65229));
+			ArabicTable.mapList.Add(new ArabicMapping(1601, 65233));
+			ArabicTable.mapList.Add(new ArabicMapping(1602, 65237));
+			ArabicTable.mapList.Add(new ArabicMapping(1603, 65241));
+			ArabicTable.mapList.Add(new ArabicMapping(1604, 65245));
+			ArabicTable.mapList.Add(new ArabicMapping(1605, 65249));
+			ArabicTable.mapList.Add(new ArabicMapping(1606, 65253));
+			ArabicTable.mapList.Add(new ArabicMapping(1607, 65257));
+			ArabicTable.mapList.Add(new ArabicMapping(1608, 65261));
+			ArabicTable.mapList.Add(new ArabicMapping(1610, 65265));
+			ArabicTable.mapList.Add(new ArabicMapping(1570, 65153));
+			ArabicTable.mapList.Add(new ArabicMapping(1577, 65171));
+			ArabicTable.mapList.Add(new ArabicMapping(1662, 64342));
+			ArabicTable.mapList.Add(new ArabicMapping(1670, 64378));
+			ArabicTable.mapList.Add(new ArabicMapping(1688, 64394));
+			ArabicTable.mapList.Add(new ArabicMapping(1711, 64402));
+			ArabicTable.mapList.Add(new ArabicMapping(1705, 64398));
+		}
+
+		internal static ArabicTable ArabicMapper
+		{
+			get
+			{
+				if (ArabicTable.arabicMapper == null)
+				{
+					ArabicTable.arabicMapper = new ArabicTable();
+				}
+				return ArabicTable.arabicMapper;
+			}
+		}
+
+		internal int Convert(int toBeConverted)
+		{
+			foreach (ArabicMapping arabicMapping in ArabicTable.mapList)
+			{
+				if (arabicMapping.from == toBeConverted)
+				{
+					return arabicMapping.to;
+				}
+			}
+			return toBeConverted;
+		}
+
+		private static List<ArabicMapping> mapList;
+
+		private static ArabicTable arabicMapper;
+	}
+}

+ 13 - 0
Assembly-CSharp/I2/Loc/AutoChangeCultureInfo.cs

@@ -0,0 +1,13 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class AutoChangeCultureInfo : MonoBehaviour
+	{
+		public void Start()
+		{
+			LocalizationManager.EnableChangingCultureInfo(true);
+		}
+	}
+}

+ 85 - 0
Assembly-CSharp/I2/Loc/BaseSpecializationManager.cs

@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+
+namespace I2.Loc
+{
+	public class BaseSpecializationManager
+	{
+		public virtual void InitializeSpecializations()
+		{
+			this.mSpecializations = new string[]
+			{
+				"Any",
+				"PC",
+				"Touch",
+				"Controller",
+				"VR",
+				"XBox",
+				"PS4",
+				"OculusVR",
+				"ViveVR",
+				"GearVR",
+				"Android",
+				"IOS"
+			};
+			this.mSpecializationsFallbacks = new Dictionary<string, string>
+			{
+				{
+					"XBox",
+					"Controller"
+				},
+				{
+					"PS4",
+					"Controller"
+				},
+				{
+					"OculusVR",
+					"VR"
+				},
+				{
+					"ViveVR",
+					"VR"
+				},
+				{
+					"GearVR",
+					"VR"
+				},
+				{
+					"Android",
+					"Touch"
+				},
+				{
+					"IOS",
+					"Touch"
+				}
+			};
+		}
+
+		public virtual string GetCurrentSpecialization()
+		{
+			if (this.mSpecializations == null)
+			{
+				this.InitializeSpecializations();
+			}
+			return "PC";
+		}
+
+		public virtual string GetFallbackSpecialization(string specialization)
+		{
+			if (this.mSpecializationsFallbacks == null)
+			{
+				this.InitializeSpecializations();
+			}
+			string result;
+			if (this.mSpecializationsFallbacks.TryGetValue(specialization, out result))
+			{
+				return result;
+			}
+			return "Any";
+		}
+
+		public string[] mSpecializations;
+
+		public Dictionary<string, string> mSpecializationsFallbacks;
+	}
+}

+ 18 - 0
Assembly-CSharp/I2/Loc/CallbackNotification.cs

@@ -0,0 +1,18 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class CallbackNotification : MonoBehaviour
+	{
+		public void OnModifyLocalization()
+		{
+			if (string.IsNullOrEmpty(Localize.MainTranslation))
+			{
+				return;
+			}
+			string translation = LocalizationManager.GetTranslation("Color/Red", true, 0, true, false, null, null);
+			Localize.MainTranslation = Localize.MainTranslation.Replace("{PLAYER_COLOR}", translation);
+		}
+	}
+}

+ 42 - 0
Assembly-CSharp/I2/Loc/CoroutineManager.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class CoroutineManager : MonoBehaviour
+	{
+		private static CoroutineManager pInstance
+		{
+			get
+			{
+				if (CoroutineManager.mInstance == null)
+				{
+					GameObject gameObject = new GameObject("_Coroutiner");
+					gameObject.hideFlags = HideFlags.HideAndDontSave;
+					CoroutineManager.mInstance = gameObject.AddComponent<CoroutineManager>();
+					if (Application.isPlaying)
+					{
+						UnityEngine.Object.DontDestroyOnLoad(gameObject);
+					}
+				}
+				return CoroutineManager.mInstance;
+			}
+		}
+
+		private void Awake()
+		{
+			if (Application.isPlaying)
+			{
+				UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
+			}
+		}
+
+		public static Coroutine Start(IEnumerator coroutine)
+		{
+			return CoroutineManager.pInstance.StartCoroutine(coroutine);
+		}
+
+		private static CoroutineManager mInstance;
+	}
+}

+ 28 - 0
Assembly-CSharp/I2/Loc/CustomLocalizeCallback.cs

@@ -0,0 +1,28 @@
+using System;
+using UnityEngine;
+using UnityEngine.Events;
+
+namespace I2.Loc
+{
+	[AddComponentMenu("I2/Localization/I2 Localize Callback")]
+	public class CustomLocalizeCallback : MonoBehaviour
+	{
+		public void Enable()
+		{
+			LocalizationManager.OnLocalizeEvent -= this.OnLocalize;
+			LocalizationManager.OnLocalizeEvent += this.OnLocalize;
+		}
+
+		public void OnDisable()
+		{
+			LocalizationManager.OnLocalizeEvent -= this.OnLocalize;
+		}
+
+		public void OnLocalize()
+		{
+			this._OnLocalize.Invoke();
+		}
+
+		public UnityEvent _OnLocalize = new UnityEvent();
+	}
+}

+ 26 - 0
Assembly-CSharp/I2/Loc/EventCallback.cs

@@ -0,0 +1,26 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	[Serializable]
+	public class EventCallback
+	{
+		public void Execute(UnityEngine.Object Sender = null)
+		{
+			if (this.HasCallback() && Application.isPlaying)
+			{
+				this.Target.gameObject.SendMessage(this.MethodName, Sender, SendMessageOptions.DontRequireReceiver);
+			}
+		}
+
+		public bool HasCallback()
+		{
+			return this.Target != null && !string.IsNullOrEmpty(this.MethodName);
+		}
+
+		public MonoBehaviour Target;
+
+		public string MethodName = string.Empty;
+	}
+}

+ 31 - 0
Assembly-CSharp/I2/Loc/Example_ChangeLanguage.cs

@@ -0,0 +1,31 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class Example_ChangeLanguage : MonoBehaviour
+	{
+		public void SetLanguage_English()
+		{
+			this.SetLanguage("English");
+		}
+
+		public void SetLanguage_French()
+		{
+			this.SetLanguage("French");
+		}
+
+		public void SetLanguage_Spanish()
+		{
+			this.SetLanguage("Spanish");
+		}
+
+		public void SetLanguage(string LangName)
+		{
+			if (LocalizationManager.HasLanguage(LangName, true, true, true))
+			{
+				LocalizationManager.CurrentLanguage = LangName;
+			}
+		}
+	}
+}

+ 38 - 0
Assembly-CSharp/I2/Loc/Example_LocalizedString.cs

@@ -0,0 +1,38 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class Example_LocalizedString : MonoBehaviour
+	{
+		public void Start()
+		{
+			Debug.Log(this._MyLocalizedString);
+			Debug.Log(LocalizationManager.GetTranslation(this._NormalString, true, 0, true, false, null, null));
+			Debug.Log(LocalizationManager.GetTranslation(this._StringWithTermPopup, true, 0, true, false, null, null));
+			LocalizedString s = "Term2";
+			string message = s;
+			Debug.Log(message);
+			LocalizedString myLocalizedString = this._MyLocalizedString;
+			Debug.Log(myLocalizedString);
+			LocalizedString localizedString = "Term3";
+			Debug.Log(localizedString);
+			LocalizedString localizedString2 = "Term3";
+			localizedString2.mRTL_IgnoreArabicFix = true;
+			Debug.Log(localizedString2);
+			LocalizedString localizedString3 = "Term3";
+			localizedString3.mRTL_ConvertNumbers = true;
+			localizedString3.mRTL_MaxLineLength = 20;
+			Debug.Log(localizedString3);
+			LocalizedString localizedString4 = localizedString3;
+			Debug.Log(localizedString4);
+		}
+
+		public LocalizedString _MyLocalizedString;
+
+		public string _NormalString;
+
+		[TermsPopup("")]
+		public string _StringWithTermPopup;
+	}
+}

+ 49 - 0
Assembly-CSharp/I2/Loc/GeneralArabicLetters.cs

@@ -0,0 +1,49 @@
+using System;
+
+namespace I2.Loc
+{
+	internal enum GeneralArabicLetters
+	{
+		Hamza = 1569,
+		Alef = 1575,
+		AlefHamza = 1571,
+		WawHamza,
+		AlefMaksoor,
+		AlefMagsora = 1609,
+		HamzaNabera = 1574,
+		Ba = 1576,
+		Ta = 1578,
+		Tha2,
+		Jeem,
+		H7aa,
+		Khaa2,
+		Dal,
+		Thal,
+		Ra2,
+		Zeen,
+		Seen,
+		Sheen,
+		S9a,
+		Dha,
+		T6a,
+		T6ha,
+		Ain,
+		Gain,
+		Fa = 1601,
+		Gaf,
+		Kaf,
+		Lam,
+		Meem,
+		Noon,
+		Ha,
+		Waw,
+		Ya = 1610,
+		AlefMad = 1570,
+		TaMarboota = 1577,
+		PersianPe = 1662,
+		PersianChe = 1670,
+		PersianZe = 1688,
+		PersianGaf = 1711,
+		PersianGaf2 = 1705
+	}
+}

+ 20 - 0
Assembly-CSharp/I2/Loc/GlobalParametersExample.cs

@@ -0,0 +1,20 @@
+using System;
+
+namespace I2.Loc
+{
+	public class GlobalParametersExample : RegisterGlobalParameters
+	{
+		public override string GetParameterValue(string ParamName)
+		{
+			if (ParamName == "WINNER")
+			{
+				return "Javier";
+			}
+			if (ParamName == "NUM PLAYERS")
+			{
+				return 5.ToString();
+			}
+			return null;
+		}
+	}
+}

File diff suppressed because it is too large
+ 2700 - 0
Assembly-CSharp/I2/Loc/GoogleLanguages.cs


+ 574 - 0
Assembly-CSharp/I2/Loc/GoogleTranslation.cs

@@ -0,0 +1,574 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public static class GoogleTranslation
+	{
+		public static bool CanTranslate()
+		{
+			return LocalizationManager.Sources.Count > 0 && !string.IsNullOrEmpty(LocalizationManager.GetWebServiceURL(null));
+		}
+
+		public static void Translate(string text, string LanguageCodeFrom, string LanguageCodeTo, Action<string, string> OnTranslationReady)
+		{
+			LocalizationManager.InitializeIfNeeded();
+			if (!GoogleTranslation.CanTranslate())
+			{
+				OnTranslationReady(null, "WebService is not set correctly or needs to be reinstalled");
+				return;
+			}
+			if (LanguageCodeTo == LanguageCodeFrom)
+			{
+				OnTranslationReady(text, null);
+				return;
+			}
+			Dictionary<string, TranslationQuery> queries = new Dictionary<string, TranslationQuery>();
+			if (string.IsNullOrEmpty(LanguageCodeTo))
+			{
+				OnTranslationReady(string.Empty, null);
+				return;
+			}
+			GoogleTranslation.CreateQueries(text, LanguageCodeFrom, LanguageCodeTo, queries);
+			GoogleTranslation.Translate(queries, delegate(Dictionary<string, TranslationQuery> results, string error)
+			{
+				if (!string.IsNullOrEmpty(error) || results.Count == 0)
+				{
+					OnTranslationReady(null, error);
+					return;
+				}
+				string arg = GoogleTranslation.RebuildTranslation(text, queries, LanguageCodeTo);
+				OnTranslationReady(arg, null);
+			}, true);
+		}
+
+		public static string ForceTranslate(string text, string LanguageCodeFrom, string LanguageCodeTo)
+		{
+			Dictionary<string, TranslationQuery> dictionary = new Dictionary<string, TranslationQuery>();
+			GoogleTranslation.AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dictionary);
+			TranslationJob_Main translationJob_Main = new TranslationJob_Main(dictionary, null);
+			TranslationJob.eJobState state;
+			do
+			{
+				state = translationJob_Main.GetState();
+			}
+			while (state == TranslationJob.eJobState.Running);
+			if (state == TranslationJob.eJobState.Failed)
+			{
+				return null;
+			}
+			return GoogleTranslation.GetQueryResult(text, string.Empty, dictionary);
+		}
+
+		public static void Translate(Dictionary<string, TranslationQuery> requests, Action<Dictionary<string, TranslationQuery>, string> OnTranslationReady, bool usePOST = true)
+		{
+			GoogleTranslation.AddTranslationJob(new TranslationJob_Main(requests, OnTranslationReady));
+		}
+
+		public static bool ForceTranslate(Dictionary<string, TranslationQuery> requests, bool usePOST = true)
+		{
+			TranslationJob_Main translationJob_Main = new TranslationJob_Main(requests, null);
+			TranslationJob.eJobState state;
+			do
+			{
+				state = translationJob_Main.GetState();
+			}
+			while (state == TranslationJob.eJobState.Running);
+			return state != TranslationJob.eJobState.Failed;
+		}
+
+		public static List<string> ConvertTranslationRequest(Dictionary<string, TranslationQuery> requests, bool encodeGET)
+		{
+			List<string> list = new List<string>();
+			StringBuilder stringBuilder = new StringBuilder();
+			foreach (KeyValuePair<string, TranslationQuery> keyValuePair in requests)
+			{
+				TranslationQuery value = keyValuePair.Value;
+				if (stringBuilder.Length > 0)
+				{
+					stringBuilder.Append("<I2Loc>");
+				}
+				stringBuilder.Append(GoogleLanguages.GetGoogleLanguageCode(value.LanguageCode));
+				stringBuilder.Append(":");
+				for (int i = 0; i < value.TargetLanguagesCode.Length; i++)
+				{
+					if (i != 0)
+					{
+						stringBuilder.Append(",");
+					}
+					stringBuilder.Append(GoogleLanguages.GetGoogleLanguageCode(value.TargetLanguagesCode[i]));
+				}
+				stringBuilder.Append("=");
+				string text = (!(GoogleTranslation.TitleCase(value.Text) == value.Text)) ? value.Text : value.Text.ToLowerInvariant();
+				if (!encodeGET)
+				{
+					stringBuilder.Append(text);
+				}
+				else
+				{
+					stringBuilder.Append(Uri.EscapeDataString(text));
+					if (stringBuilder.Length > 4000)
+					{
+						list.Add(stringBuilder.ToString());
+						stringBuilder.Length = 0;
+					}
+				}
+			}
+			list.Add(stringBuilder.ToString());
+			return list;
+		}
+
+		private static void AddTranslationJob(TranslationJob job)
+		{
+			GoogleTranslation.mTranslationJobs.Add(job);
+			if (GoogleTranslation.mTranslationJobs.Count == 1)
+			{
+				CoroutineManager.Start(GoogleTranslation.WaitForTranslations());
+			}
+		}
+
+		private static IEnumerator WaitForTranslations()
+		{
+			while (GoogleTranslation.mTranslationJobs.Count > 0)
+			{
+				TranslationJob[] jobs = GoogleTranslation.mTranslationJobs.ToArray();
+				foreach (TranslationJob translationJob in jobs)
+				{
+					if (translationJob.GetState() != TranslationJob.eJobState.Running)
+					{
+						GoogleTranslation.mTranslationJobs.Remove(translationJob);
+					}
+				}
+				yield return null;
+			}
+			yield break;
+		}
+
+		public static string ParseTranslationResult(string html, Dictionary<string, TranslationQuery> requests)
+		{
+			if (!html.StartsWith("<!DOCTYPE html>") && !html.StartsWith("<HTML>"))
+			{
+				string[] array = html.Split(new string[]
+				{
+					"<I2Loc>"
+				}, StringSplitOptions.None);
+				string[] separator = new string[]
+				{
+					"<i2>"
+				};
+				int num = 0;
+				string[] array2 = requests.Keys.ToArray<string>();
+				foreach (string text in array2)
+				{
+					TranslationQuery value = GoogleTranslation.FindQueryFromOrigText(text, requests);
+					string text2 = array[num++];
+					if (value.Tags != null)
+					{
+						int j = 0;
+						int num2 = value.Tags.Length;
+						while (j < num2)
+						{
+							text2 = text2.Replace(((char)(9728 + j)).ToString(), value.Tags[j]);
+							j++;
+						}
+					}
+					value.Results = text2.Split(separator, StringSplitOptions.None);
+					if (GoogleTranslation.TitleCase(text) == text)
+					{
+						for (int k = 0; k < value.Results.Length; k++)
+						{
+							value.Results[k] = GoogleTranslation.TitleCase(value.Results[k]);
+						}
+					}
+					requests[value.OrigText] = value;
+				}
+				return null;
+			}
+			if (html.Contains("The script completed but did not return anything"))
+			{
+				return "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version.";
+			}
+			if (html.Contains("Service invoked too many times in a short time"))
+			{
+				return string.Empty;
+			}
+			return "There was a problem contacting the WebService. Please try again later\n" + html;
+		}
+
+		public static bool IsTranslating()
+		{
+			return GoogleTranslation.mCurrentTranslations.Count > 0 || GoogleTranslation.mTranslationJobs.Count > 0;
+		}
+
+		public static void CancelCurrentGoogleTranslations()
+		{
+			GoogleTranslation.mCurrentTranslations.Clear();
+			foreach (TranslationJob translationJob in GoogleTranslation.mTranslationJobs)
+			{
+				translationJob.Dispose();
+			}
+			GoogleTranslation.mTranslationJobs.Clear();
+		}
+
+		public static void CreateQueries(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict)
+		{
+			if (!text.Contains("[i2s_"))
+			{
+				GoogleTranslation.CreateQueries_Plurals(text, LanguageCodeFrom, LanguageCodeTo, dict);
+				return;
+			}
+			Dictionary<string, string> specializations = SpecializationManager.GetSpecializations(text, null);
+			foreach (KeyValuePair<string, string> keyValuePair in specializations)
+			{
+				GoogleTranslation.CreateQueries_Plurals(keyValuePair.Value, LanguageCodeFrom, LanguageCodeTo, dict);
+			}
+		}
+
+		private static void CreateQueries_Plurals(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict)
+		{
+			bool flag = text.Contains("{[#");
+			bool flag2 = text.Contains("[i2p_");
+			if (!GoogleTranslation.HasParameters(text) || (!flag && !flag2))
+			{
+				GoogleTranslation.AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict);
+				return;
+			}
+			bool forceTag = flag;
+			for (ePluralType ePluralType = ePluralType.Zero; ePluralType <= ePluralType.Plural; ePluralType++)
+			{
+				string pluralType = ePluralType.ToString();
+				if (GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType))
+				{
+					string text2 = GoogleTranslation.GetPluralText(text, pluralType);
+					int pluralTestNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, ePluralType);
+					string pluralParameter = GoogleTranslation.GetPluralParameter(text2, forceTag);
+					if (!string.IsNullOrEmpty(pluralParameter))
+					{
+						text2 = text2.Replace(pluralParameter, pluralTestNumber.ToString());
+					}
+					GoogleTranslation.AddQuery(text2, LanguageCodeFrom, LanguageCodeTo, dict);
+				}
+			}
+		}
+
+		public static void AddQuery(string text, string LanguageCodeFrom, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict)
+		{
+			if (string.IsNullOrEmpty(text))
+			{
+				return;
+			}
+			if (!dict.ContainsKey(text))
+			{
+				TranslationQuery value = new TranslationQuery
+				{
+					OrigText = text,
+					LanguageCode = LanguageCodeFrom,
+					TargetLanguagesCode = new string[]
+					{
+						LanguageCodeTo
+					}
+				};
+				value.Text = text;
+				GoogleTranslation.ParseNonTranslatableElements(ref value);
+				dict[text] = value;
+			}
+			else
+			{
+				TranslationQuery value2 = dict[text];
+				if (Array.IndexOf<string>(value2.TargetLanguagesCode, LanguageCodeTo) < 0)
+				{
+					value2.TargetLanguagesCode = value2.TargetLanguagesCode.Concat(new string[]
+					{
+						LanguageCodeTo
+					}).Distinct<string>().ToArray<string>();
+				}
+				dict[text] = value2;
+			}
+		}
+
+		private static string GetTranslation(string text, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict)
+		{
+			if (!dict.ContainsKey(text))
+			{
+				return null;
+			}
+			TranslationQuery translationQuery = dict[text];
+			int num = Array.IndexOf<string>(translationQuery.TargetLanguagesCode, LanguageCodeTo);
+			if (num < 0)
+			{
+				return string.Empty;
+			}
+			if (translationQuery.Results == null)
+			{
+				return string.Empty;
+			}
+			return translationQuery.Results[num];
+		}
+
+		private static TranslationQuery FindQueryFromOrigText(string origText, Dictionary<string, TranslationQuery> dict)
+		{
+			foreach (KeyValuePair<string, TranslationQuery> keyValuePair in dict)
+			{
+				if (keyValuePair.Value.OrigText == origText)
+				{
+					return keyValuePair.Value;
+				}
+			}
+			return default(TranslationQuery);
+		}
+
+		public static bool HasParameters(string text)
+		{
+			int num = text.IndexOf("{[");
+			return num >= 0 && text.IndexOf("]}", num) > 0;
+		}
+
+		public static string GetPluralParameter(string text, bool forceTag)
+		{
+			int num = text.IndexOf("{[#");
+			if (num < 0)
+			{
+				if (forceTag)
+				{
+					return null;
+				}
+				num = text.IndexOf("{[");
+			}
+			if (num < 0)
+			{
+				return null;
+			}
+			int num2 = text.IndexOf("]}", num + 2);
+			if (num2 < 0)
+			{
+				return null;
+			}
+			return text.Substring(num, num2 - num + 2);
+		}
+
+		public static string GetPluralText(string text, string pluralType)
+		{
+			pluralType = "[i2p_" + pluralType + "]";
+			int num = text.IndexOf(pluralType);
+			if (num >= 0)
+			{
+				num += pluralType.Length;
+				int num2 = text.IndexOf("[i2p_", num);
+				if (num2 < 0)
+				{
+					num2 = text.Length;
+				}
+				return text.Substring(num, num2 - num);
+			}
+			num = text.IndexOf("[i2p_");
+			if (num < 0)
+			{
+				return text;
+			}
+			if (num > 0)
+			{
+				return text.Substring(0, num);
+			}
+			num = text.IndexOf("]");
+			if (num < 0)
+			{
+				return text;
+			}
+			num++;
+			int num3 = text.IndexOf("[i2p_", num);
+			if (num3 < 0)
+			{
+				num3 = text.Length;
+			}
+			return text.Substring(num, num3 - num);
+		}
+
+		private static int FindClosingTag(string tag, MatchCollection matches, int startIndex)
+		{
+			int i = startIndex;
+			int count = matches.Count;
+			while (i < count)
+			{
+				string captureMatch = GoogleTranslation.GetCaptureMatch(matches[i]);
+				if (captureMatch[0] == '/' && tag.StartsWith(captureMatch.Substring(1)))
+				{
+					return i;
+				}
+				i++;
+			}
+			return -1;
+		}
+
+		private static string GetCaptureMatch(Match match)
+		{
+			for (int i = match.Groups.Count - 1; i >= 0; i--)
+			{
+				if (match.Groups[i].Success)
+				{
+					return match.Groups[i].ToString();
+				}
+			}
+			return match.ToString();
+		}
+
+		private static void ParseNonTranslatableElements(ref TranslationQuery query)
+		{
+			MatchCollection matchCollection = Regex.Matches(query.Text, "\\{\\[(.*?)]}|\\[(.*?)]|\\<(.*?)>");
+			if (matchCollection == null || matchCollection.Count == 0)
+			{
+				return;
+			}
+			string text = query.Text;
+			List<string> list = new List<string>();
+			int i = 0;
+			int count = matchCollection.Count;
+			while (i < count)
+			{
+				string captureMatch = GoogleTranslation.GetCaptureMatch(matchCollection[i]);
+				int num = GoogleTranslation.FindClosingTag(captureMatch, matchCollection, i);
+				if (num < 0)
+				{
+					string text2 = matchCollection[i].ToString();
+					if (text2.StartsWith("{[") && text2.EndsWith("]}"))
+					{
+						text = text.Replace(text2, ((char)(9728 + list.Count)).ToString());
+						list.Add(text2);
+					}
+				}
+				else if (captureMatch == "i2nt")
+				{
+					string text3 = query.Text.Substring(matchCollection[i].Index, matchCollection[num].Index - matchCollection[i].Index + matchCollection[num].Length);
+					text = text.Replace(text3, ((char)(9728 + list.Count)).ToString());
+					list.Add(text3);
+				}
+				else
+				{
+					string text4 = matchCollection[i].ToString();
+					text = text.Replace(text4, ((char)(9728 + list.Count)).ToString());
+					list.Add(text4);
+					string text5 = matchCollection[num].ToString();
+					text = text.Replace(text5, ((char)(9728 + list.Count)).ToString());
+					list.Add(text5);
+				}
+				i++;
+			}
+			query.Text = text;
+			query.Tags = list.ToArray();
+		}
+
+		public static string GetQueryResult(string text, string LanguageCodeTo, Dictionary<string, TranslationQuery> dict)
+		{
+			if (!dict.ContainsKey(text))
+			{
+				return null;
+			}
+			TranslationQuery translationQuery = dict[text];
+			if (translationQuery.Results == null || translationQuery.Results.Length < 0)
+			{
+				return null;
+			}
+			if (string.IsNullOrEmpty(LanguageCodeTo))
+			{
+				return translationQuery.Results[0];
+			}
+			int num = Array.IndexOf<string>(translationQuery.TargetLanguagesCode, LanguageCodeTo);
+			if (num < 0)
+			{
+				return null;
+			}
+			return translationQuery.Results[num];
+		}
+
+		public static string RebuildTranslation(string text, Dictionary<string, TranslationQuery> dict, string LanguageCodeTo)
+		{
+			if (!text.Contains("[i2s_"))
+			{
+				return GoogleTranslation.RebuildTranslation_Plural(text, dict, LanguageCodeTo);
+			}
+			Dictionary<string, string> specializations = SpecializationManager.GetSpecializations(text, null);
+			Dictionary<string, string> dictionary = new Dictionary<string, string>();
+			foreach (KeyValuePair<string, string> keyValuePair in specializations)
+			{
+				dictionary[keyValuePair.Key] = GoogleTranslation.RebuildTranslation_Plural(keyValuePair.Value, dict, LanguageCodeTo);
+			}
+			return SpecializationManager.SetSpecializedText(dictionary);
+		}
+
+		private static string RebuildTranslation_Plural(string text, Dictionary<string, TranslationQuery> dict, string LanguageCodeTo)
+		{
+			bool flag = text.Contains("{[#");
+			bool flag2 = text.Contains("[i2p_");
+			if (!GoogleTranslation.HasParameters(text) || (!flag && !flag2))
+			{
+				return GoogleTranslation.GetTranslation(text, LanguageCodeTo, dict);
+			}
+			StringBuilder stringBuilder = new StringBuilder();
+			string b = null;
+			bool forceTag = flag;
+			for (ePluralType ePluralType = ePluralType.Plural; ePluralType >= ePluralType.Zero; ePluralType--)
+			{
+				string text2 = ePluralType.ToString();
+				if (GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, text2))
+				{
+					string text3 = GoogleTranslation.GetPluralText(text, text2);
+					int pluralTestNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, ePluralType);
+					string pluralParameter = GoogleTranslation.GetPluralParameter(text3, forceTag);
+					if (!string.IsNullOrEmpty(pluralParameter))
+					{
+						text3 = text3.Replace(pluralParameter, pluralTestNumber.ToString());
+					}
+					string text4 = GoogleTranslation.GetTranslation(text3, LanguageCodeTo, dict);
+					if (!string.IsNullOrEmpty(pluralParameter))
+					{
+						text4 = text4.Replace(pluralTestNumber.ToString(), pluralParameter);
+					}
+					if (ePluralType == ePluralType.Plural)
+					{
+						b = text4;
+					}
+					else
+					{
+						if (text4 == b)
+						{
+							goto IL_117;
+						}
+						stringBuilder.AppendFormat("[i2p_{0}]", text2);
+					}
+					stringBuilder.Append(text4);
+				}
+				IL_117:;
+			}
+			return stringBuilder.ToString();
+		}
+
+		public static string UppercaseFirst(string s)
+		{
+			if (string.IsNullOrEmpty(s))
+			{
+				return string.Empty;
+			}
+			char[] array = s.ToLower().ToCharArray();
+			array[0] = char.ToUpper(array[0]);
+			return new string(array);
+		}
+
+		public static string TitleCase(string s)
+		{
+			if (string.IsNullOrEmpty(s))
+			{
+				return string.Empty;
+			}
+			return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s);
+		}
+
+		private static List<WWW> mCurrentTranslations = new List<WWW>();
+
+		private static List<TranslationJob> mTranslationJobs = new List<TranslationJob>();
+	}
+}

+ 87 - 0
Assembly-CSharp/I2/Loc/HindiFixer.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Linq;
+
+namespace I2.Loc
+{
+	public class HindiFixer
+	{
+		internal static string Fix(string text)
+		{
+			char[] array = text.ToCharArray();
+			bool flag = false;
+			for (int i = 0; i < array.Length; i++)
+			{
+				if (array[i] == 'ि' && !char.IsWhiteSpace(array[i - 1]) && array[i - 1] != '\0')
+				{
+					array[i] = array[i - 1];
+					array[i - 1] = 'ि';
+					flag = true;
+				}
+				if (i != array.Length - 1)
+				{
+					if (array[i] == 'इ' && array[i + 1] == '़')
+					{
+						array[i] = 'ऌ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == 'ृ' && array[i + 1] == '़')
+					{
+						array[i] = 'ॄ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == 'ँ' && array[i + 1] == '़')
+					{
+						array[i] = 'ॐ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == 'ऋ' && array[i + 1] == '़')
+					{
+						array[i] = 'ॠ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == 'ई' && array[i + 1] == '़')
+					{
+						array[i] = 'ॡ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == 'ि' && array[i + 1] == '़')
+					{
+						array[i] = 'ॢ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == 'ी' && array[i + 1] == '़')
+					{
+						array[i] = 'ॣ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+					if (array[i] == '।' && array[i + 1] == '़')
+					{
+						array[i] = 'ऽ';
+						array[i + 1] = '\0';
+						flag = true;
+					}
+				}
+			}
+			if (!flag)
+			{
+				return text;
+			}
+			string text2 = new string((from x in array
+			where x != '\0'
+			select x).ToArray<char>());
+			if (text2 == text)
+			{
+				return text2;
+			}
+			text = text2;
+			return text;
+		}
+	}
+}

+ 239 - 0
Assembly-CSharp/I2/Loc/I2BasePersistentStorage.cs

@@ -0,0 +1,239 @@
+using System;
+using System.IO;
+using System.Text;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public abstract class I2BasePersistentStorage
+	{
+		public virtual void SetSetting_String(string key, string value)
+		{
+			try
+			{
+				int length = value.Length;
+				int num = 8000;
+				if (length <= num)
+				{
+					PlayerPrefs.SetString(key, value);
+				}
+				else
+				{
+					int num2 = Mathf.CeilToInt((float)length / (float)num);
+					for (int i = 0; i < num2; i++)
+					{
+						int num3 = num * i;
+						PlayerPrefs.SetString(string.Format("[I2split]{0}{1}", i, key), value.Substring(num3, Mathf.Min(num, length - num3)));
+					}
+					PlayerPrefs.SetString(key, "[$I2#@div$]" + num2);
+				}
+			}
+			catch (Exception)
+			{
+				Debug.LogError("Error saving PlayerPrefs " + key);
+			}
+		}
+
+		public virtual string GetSetting_String(string key, string defaultValue)
+		{
+			string result;
+			try
+			{
+				string text = PlayerPrefs.GetString(key, defaultValue);
+				if (!string.IsNullOrEmpty(text) && text.StartsWith("[I2split]"))
+				{
+					int num = int.Parse(text.Substring("[I2split]".Length));
+					text = string.Empty;
+					for (int i = 0; i < num; i++)
+					{
+						text += PlayerPrefs.GetString(string.Format("[I2split]{0}{1}", i, key), string.Empty);
+					}
+				}
+				result = text;
+			}
+			catch (Exception)
+			{
+				Debug.LogError("Error loading PlayerPrefs " + key);
+				result = defaultValue;
+			}
+			return result;
+		}
+
+		public virtual void DeleteSetting(string key)
+		{
+			try
+			{
+				string @string = PlayerPrefs.GetString(key, null);
+				if (!string.IsNullOrEmpty(@string) && @string.StartsWith("[I2split]"))
+				{
+					int num = int.Parse(@string.Substring("[I2split]".Length));
+					for (int i = 0; i < num; i++)
+					{
+						PlayerPrefs.DeleteKey(string.Format("[I2split]{0}{1}", i, key));
+					}
+				}
+				PlayerPrefs.DeleteKey(key);
+			}
+			catch (Exception)
+			{
+				Debug.LogError("Error deleting PlayerPrefs " + key);
+			}
+		}
+
+		public virtual void ForceSaveSettings()
+		{
+			PlayerPrefs.Save();
+		}
+
+		public virtual bool HasSetting(string key)
+		{
+			return PlayerPrefs.HasKey(key);
+		}
+
+		public virtual bool CanAccessFiles()
+		{
+			return true;
+		}
+
+		private string UpdateFilename(PersistentStorage.eFileType fileType, string fileName)
+		{
+			if (fileType != PersistentStorage.eFileType.Persistent)
+			{
+				if (fileType != PersistentStorage.eFileType.Temporal)
+				{
+					if (fileType == PersistentStorage.eFileType.Streaming)
+					{
+						fileName = Application.streamingAssetsPath + "/" + fileName;
+					}
+				}
+				else
+				{
+					fileName = Application.temporaryCachePath + "/" + fileName;
+				}
+			}
+			else
+			{
+				fileName = Application.persistentDataPath + "/" + fileName;
+			}
+			return fileName;
+		}
+
+		public virtual bool SaveFile(PersistentStorage.eFileType fileType, string fileName, string data, bool logExceptions = true)
+		{
+			if (!this.CanAccessFiles())
+			{
+				return false;
+			}
+			bool result;
+			try
+			{
+				fileName = this.UpdateFilename(fileType, fileName);
+				File.WriteAllText(fileName, data, Encoding.UTF8);
+				result = true;
+			}
+			catch (Exception ex)
+			{
+				if (logExceptions)
+				{
+					Debug.LogError(string.Concat(new object[]
+					{
+						"Error saving file '",
+						fileName,
+						"'\n",
+						ex
+					}));
+				}
+				result = false;
+			}
+			return result;
+		}
+
+		public virtual string LoadFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
+		{
+			if (!this.CanAccessFiles())
+			{
+				return null;
+			}
+			string result;
+			try
+			{
+				fileName = this.UpdateFilename(fileType, fileName);
+				result = File.ReadAllText(fileName, Encoding.UTF8);
+			}
+			catch (Exception ex)
+			{
+				if (logExceptions)
+				{
+					Debug.LogError(string.Concat(new object[]
+					{
+						"Error loading file '",
+						fileName,
+						"'\n",
+						ex
+					}));
+				}
+				result = null;
+			}
+			return result;
+		}
+
+		public virtual bool DeleteFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
+		{
+			if (!this.CanAccessFiles())
+			{
+				return false;
+			}
+			bool result;
+			try
+			{
+				fileName = this.UpdateFilename(fileType, fileName);
+				File.Delete(fileName);
+				result = true;
+			}
+			catch (Exception ex)
+			{
+				if (logExceptions)
+				{
+					Debug.LogError(string.Concat(new object[]
+					{
+						"Error deleting file '",
+						fileName,
+						"'\n",
+						ex
+					}));
+				}
+				result = false;
+			}
+			return result;
+		}
+
+		public virtual bool HasFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
+		{
+			if (!this.CanAccessFiles())
+			{
+				return false;
+			}
+			bool result;
+			try
+			{
+				fileName = this.UpdateFilename(fileType, fileName);
+				result = File.Exists(fileName);
+			}
+			catch (Exception ex)
+			{
+				if (logExceptions)
+				{
+					Debug.LogError(string.Concat(new object[]
+					{
+						"Error requesting file '",
+						fileName,
+						"'\n",
+						ex
+					}));
+				}
+				result = false;
+			}
+			return result;
+		}
+	}
+}

+ 8 - 0
Assembly-CSharp/I2/Loc/I2CustomPersistentStorage.cs

@@ -0,0 +1,8 @@
+using System;
+
+namespace I2.Loc
+{
+	public class I2CustomPersistentStorage : I2BasePersistentStorage
+	{
+	}
+}

+ 184 - 0
Assembly-CSharp/I2/Loc/I2Utils.cs

@@ -0,0 +1,184 @@
+using System;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+namespace I2.Loc
+{
+	public static class I2Utils
+	{
+		public static string ReverseText(string source)
+		{
+			int length = source.Length;
+			char[] array = new char[length];
+			for (int i = 0; i < length; i++)
+			{
+				array[length - 1 - i] = source[i];
+			}
+			return new string(array);
+		}
+
+		public static string RemoveNonASCII(string text, bool allowCategory = false)
+		{
+			if (string.IsNullOrEmpty(text))
+			{
+				return text;
+			}
+			return new string((from c in text.ToCharArray()
+			select (!char.IsControl(c) && (c != '\\' || allowCategory)) ? c : ' ').ToArray<char>());
+		}
+
+		public static string SplitLine(string line, int maxCharacters)
+		{
+			if (maxCharacters <= 0 || line.Length < maxCharacters)
+			{
+				return line;
+			}
+			char[] array = line.ToCharArray();
+			bool flag = true;
+			bool flag2 = false;
+			int i = 0;
+			int num = 0;
+			while (i < array.Length)
+			{
+				if (flag)
+				{
+					num++;
+					if (array[i] == '\n')
+					{
+						num = 0;
+					}
+					if (num >= maxCharacters && char.IsWhiteSpace(array[i]))
+					{
+						array[i] = '\n';
+						flag = false;
+						flag2 = false;
+					}
+				}
+				else if (!char.IsWhiteSpace(array[i]))
+				{
+					flag = true;
+					num = 0;
+				}
+				else if (array[i] != '\n')
+				{
+					array[i] = '\0';
+				}
+				else
+				{
+					if (!flag2)
+					{
+						array[i] = '\0';
+					}
+					flag2 = true;
+				}
+				i++;
+			}
+			return new string((from c in array
+			where c != '\0'
+			select c).ToArray<char>());
+		}
+
+		public static bool FindNextTag(string line, int iStart, out int tagStart, out int tagEnd)
+		{
+			tagStart = -1;
+			tagEnd = -1;
+			int length = line.Length;
+			for (tagStart = iStart; tagStart < length; tagStart++)
+			{
+				if (line[tagStart] == '[' || line[tagStart] == '(' || line[tagStart] == '{')
+				{
+					break;
+				}
+			}
+			if (tagStart == length)
+			{
+				return false;
+			}
+			bool flag = false;
+			for (tagEnd = tagStart + 1; tagEnd < length; tagEnd++)
+			{
+				char c = line[tagEnd];
+				if (c == ']' || c == ')' || c == '}')
+				{
+					return !flag || I2Utils.FindNextTag(line, tagEnd + 1, out tagStart, out tagEnd);
+				}
+				if (c > 'ÿ')
+				{
+					flag = true;
+				}
+			}
+			return false;
+		}
+
+		public static bool IsPlaying()
+		{
+			return Application.isPlaying;
+		}
+
+		public static string GetPath(this Transform tr)
+		{
+			Transform parent = tr.parent;
+			if (tr == null)
+			{
+				return tr.name;
+			}
+			return parent.GetPath() + "/" + tr.name;
+		}
+
+		public static Transform FindObject(string objectPath)
+		{
+			return I2Utils.FindObject(SceneManager.GetActiveScene(), objectPath);
+		}
+
+		public static Transform FindObject(Scene scene, string objectPath)
+		{
+			GameObject[] rootGameObjects = scene.GetRootGameObjects();
+			for (int i = 0; i < rootGameObjects.Length; i++)
+			{
+				Transform transform = rootGameObjects[i].transform;
+				if (transform.name == objectPath)
+				{
+					return transform;
+				}
+				if (objectPath.StartsWith(transform.name + "/"))
+				{
+					return I2Utils.FindObject(transform, objectPath.Substring(transform.name.Length + 1));
+				}
+			}
+			return null;
+		}
+
+		public static Transform FindObject(Transform root, string objectPath)
+		{
+			for (int i = 0; i < root.childCount; i++)
+			{
+				Transform child = root.GetChild(i);
+				if (child.name == objectPath)
+				{
+					return child;
+				}
+				if (objectPath.StartsWith(child.name + "/"))
+				{
+					return I2Utils.FindObject(child, objectPath.Substring(child.name.Length + 1));
+				}
+			}
+			return null;
+		}
+
+		public static H FindInParents<H>(Transform tr) where H : Component
+		{
+			if (!tr)
+			{
+				return (H)((object)null);
+			}
+			H component = tr.GetComponent<H>();
+			while (!component && tr)
+			{
+				component = tr.GetComponent<H>();
+				tr = tr.parent;
+			}
+			return component;
+		}
+	}
+}

+ 9 - 0
Assembly-CSharp/I2/Loc/ILocalizationParamsManager.cs

@@ -0,0 +1,9 @@
+using System;
+
+namespace I2.Loc
+{
+	public interface ILocalizationParamsManager
+	{
+		string GetParameterValue(string Param);
+	}
+}

+ 24 - 0
Assembly-CSharp/I2/Loc/ILocalizeTarget.cs

@@ -0,0 +1,24 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public abstract class ILocalizeTarget : ScriptableObject
+	{
+		public abstract bool IsValid(Localize cmp);
+
+		public abstract void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm);
+
+		public abstract void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation);
+
+		public abstract bool CanUseSecondaryTerm();
+
+		public abstract bool AllowMainTermToBeRTL();
+
+		public abstract bool AllowSecondTermToBeRTL();
+
+		public abstract eTermType GetPrimaryTermType(Localize cmp);
+
+		public abstract eTermType GetSecondaryTermType(Localize cmp);
+	}
+}

+ 17 - 0
Assembly-CSharp/I2/Loc/ILocalizeTargetDescriptor.cs

@@ -0,0 +1,17 @@
+using System;
+
+namespace I2.Loc
+{
+	public abstract class ILocalizeTargetDescriptor
+	{
+		public abstract bool CanLocalize(Localize cmp);
+
+		public abstract ILocalizeTarget CreateTarget(Localize cmp);
+
+		public abstract Type GetTargetType();
+
+		public string Name;
+
+		public int Priority;
+	}
+}

+ 10 - 0
Assembly-CSharp/I2/Loc/IResourceManager_Bundles.cs

@@ -0,0 +1,10 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public interface IResourceManager_Bundles
+	{
+		UnityEngine.Object LoadFromBundle(string path, Type assetType);
+	}
+}

+ 49 - 0
Assembly-CSharp/I2/Loc/IsolatedArabicLetters.cs

@@ -0,0 +1,49 @@
+using System;
+
+namespace I2.Loc
+{
+	internal enum IsolatedArabicLetters
+	{
+		Hamza = 65152,
+		Alef = 65165,
+		AlefHamza = 65155,
+		WawHamza = 65157,
+		AlefMaksoor = 65159,
+		AlefMaksora = 64508,
+		HamzaNabera = 65161,
+		Ba = 65167,
+		Ta = 65173,
+		Tha2 = 65177,
+		Jeem = 65181,
+		H7aa = 65185,
+		Khaa2 = 65189,
+		Dal = 65193,
+		Thal = 65195,
+		Ra2 = 65197,
+		Zeen = 65199,
+		Seen = 65201,
+		Sheen = 65205,
+		S9a = 65209,
+		Dha = 65213,
+		T6a = 65217,
+		T6ha = 65221,
+		Ain = 65225,
+		Gain = 65229,
+		Fa = 65233,
+		Gaf = 65237,
+		Kaf = 65241,
+		Lam = 65245,
+		Meem = 65249,
+		Noon = 65253,
+		Ha = 65257,
+		Waw = 65261,
+		Ya = 65265,
+		AlefMad = 65153,
+		TaMarboota = 65171,
+		PersianPe = 64342,
+		PersianChe = 64378,
+		PersianZe = 64394,
+		PersianGaf = 64402,
+		PersianGaf2 = 64398
+	}
+}

+ 68 - 0
Assembly-CSharp/I2/Loc/LanguageData.cs

@@ -0,0 +1,68 @@
+using System;
+
+namespace I2.Loc
+{
+	[Serializable]
+	public class LanguageData
+	{
+		public bool IsEnabled()
+		{
+			return (this.Flags & 1) == 0;
+		}
+
+		public void SetEnabled(bool bEnabled)
+		{
+			if (bEnabled)
+			{
+				this.Flags = (byte)((int)this.Flags & -2);
+			}
+			else
+			{
+				this.Flags |= 1;
+			}
+		}
+
+		public bool IsLoaded()
+		{
+			return (this.Flags & 4) == 0;
+		}
+
+		public bool CanBeUnloaded()
+		{
+			return (this.Flags & 2) == 0;
+		}
+
+		public void SetLoaded(bool loaded)
+		{
+			if (loaded)
+			{
+				this.Flags = (byte)((int)this.Flags & -5);
+			}
+			else
+			{
+				this.Flags |= 4;
+			}
+		}
+
+		public void SetCanBeUnLoaded(bool allowUnloading)
+		{
+			if (allowUnloading)
+			{
+				this.Flags = (byte)((int)this.Flags & -3);
+			}
+			else
+			{
+				this.Flags |= 2;
+			}
+		}
+
+		public string Name;
+
+		public string Code;
+
+		public byte Flags;
+
+		[NonSerialized]
+		public bool Compressed;
+	}
+}

File diff suppressed because it is too large
+ 1644 - 0
Assembly-CSharp/I2/Loc/LanguageSource.cs


File diff suppressed because it is too large
+ 1047 - 0
Assembly-CSharp/I2/Loc/LocalizationManager.cs


+ 97 - 0
Assembly-CSharp/I2/Loc/LocalizationParamsManager.cs

@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizationParamsManager : MonoBehaviour, ILocalizationParamsManager
+	{
+		public string GetParameterValue(string ParamName)
+		{
+			if (this._Params != null)
+			{
+				int i = 0;
+				int count = this._Params.Count;
+				while (i < count)
+				{
+					if (this._Params[i].Name == ParamName)
+					{
+						return this._Params[i].Value;
+					}
+					i++;
+				}
+			}
+			return null;
+		}
+
+		public void SetParameterValue(string ParamName, string ParamValue, bool localize = true)
+		{
+			bool flag = false;
+			int i = 0;
+			int count = this._Params.Count;
+			while (i < count)
+			{
+				if (this._Params[i].Name == ParamName)
+				{
+					LocalizationParamsManager.ParamValue value = this._Params[i];
+					value.Value = ParamValue;
+					this._Params[i] = value;
+					flag = true;
+					break;
+				}
+				i++;
+			}
+			if (!flag)
+			{
+				this._Params.Add(new LocalizationParamsManager.ParamValue
+				{
+					Name = ParamName,
+					Value = ParamValue
+				});
+			}
+			if (localize)
+			{
+				this.OnLocalize();
+			}
+		}
+
+		public void OnLocalize()
+		{
+			Localize component = base.GetComponent<Localize>();
+			if (component != null)
+			{
+				component.OnLocalize(true);
+			}
+		}
+
+		public virtual void OnEnable()
+		{
+			this.DoAutoRegister();
+		}
+
+		public void DoAutoRegister()
+		{
+			if (!LocalizationManager.ParamManagers.Contains(this))
+			{
+				LocalizationManager.ParamManagers.Add(this);
+				LocalizationManager.LocalizeAll(true);
+			}
+		}
+
+		public void OnDisable()
+		{
+			LocalizationManager.ParamManagers.Remove(this);
+		}
+
+		[SerializeField]
+		public List<LocalizationParamsManager.ParamValue> _Params = new List<LocalizationParamsManager.ParamValue>();
+
+		[Serializable]
+		public struct ParamValue
+		{
+			public string Name;
+
+			public string Value;
+		}
+	}
+}

+ 214 - 0
Assembly-CSharp/I2/Loc/LocalizationReader.cs

@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizationReader
+	{
+		public static Dictionary<string, string> ReadTextAsset(TextAsset asset)
+		{
+			string text = Encoding.UTF8.GetString(asset.bytes, 0, asset.bytes.Length);
+			text = text.Replace("\r\n", "\n");
+			text = text.Replace("\r", "\n");
+			StringReader stringReader = new StringReader(text);
+			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
+			string line;
+			while ((line = stringReader.ReadLine()) != null)
+			{
+				string text2;
+				string value;
+				string text3;
+				string text4;
+				string text5;
+				if (LocalizationReader.TextAsset_ReadLine(line, out text2, out value, out text3, out text4, out text5))
+				{
+					if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(value))
+					{
+						dictionary[text2] = value;
+					}
+				}
+			}
+			return dictionary;
+		}
+
+		public static bool TextAsset_ReadLine(string line, out string key, out string value, out string category, out string comment, out string termType)
+		{
+			key = string.Empty;
+			category = string.Empty;
+			comment = string.Empty;
+			termType = string.Empty;
+			value = string.Empty;
+			int num = line.LastIndexOf("//");
+			if (num >= 0)
+			{
+				comment = line.Substring(num + 2).Trim();
+				comment = LocalizationReader.DecodeString(comment);
+				line = line.Substring(0, num);
+			}
+			int num2 = line.IndexOf("=");
+			if (num2 < 0)
+			{
+				return false;
+			}
+			key = line.Substring(0, num2).Trim();
+			value = line.Substring(num2 + 1).Trim();
+			value = value.Replace("\r\n", "\n").Replace("\n", "\\n");
+			value = LocalizationReader.DecodeString(value);
+			if (key.Length > 2 && key[0] == '[')
+			{
+				int num3 = key.IndexOf(']');
+				if (num3 >= 0)
+				{
+					termType = key.Substring(1, num3 - 1);
+					key = key.Substring(num3 + 1);
+				}
+			}
+			LocalizationReader.ValidateFullTerm(ref key);
+			return true;
+		}
+
+		public static string ReadCSVfile(string Path, Encoding encoding)
+		{
+			string text = string.Empty;
+			using (StreamReader streamReader = new StreamReader(Path, encoding))
+			{
+				text = streamReader.ReadToEnd();
+			}
+			text = text.Replace("\r\n", "\n");
+			text = text.Replace("\r", "\n");
+			return text;
+		}
+
+		public static List<string[]> ReadCSV(string Text, char Separator = ',')
+		{
+			int i = 0;
+			List<string[]> list = new List<string[]>();
+			while (i < Text.Length)
+			{
+				string[] array = LocalizationReader.ParseCSVline(Text, ref i, Separator);
+				if (array == null)
+				{
+					break;
+				}
+				list.Add(array);
+			}
+			return list;
+		}
+
+		private static string[] ParseCSVline(string Line, ref int iStart, char Separator)
+		{
+			List<string> list = new List<string>();
+			int length = Line.Length;
+			int num = iStart;
+			bool flag = false;
+			while (iStart < length)
+			{
+				char c = Line[iStart];
+				if (flag)
+				{
+					if (c == '"')
+					{
+						if (iStart + 1 >= length || Line[iStart + 1] != '"')
+						{
+							flag = false;
+						}
+						else if (iStart + 2 < length && Line[iStart + 2] == '"')
+						{
+							flag = false;
+							iStart += 2;
+						}
+						else
+						{
+							iStart++;
+						}
+					}
+				}
+				else if (c == '\n' || c == Separator)
+				{
+					LocalizationReader.AddCSVtoken(ref list, ref Line, iStart, ref num);
+					if (c == '\n')
+					{
+						iStart++;
+						break;
+					}
+				}
+				else if (c == '"')
+				{
+					flag = true;
+				}
+				iStart++;
+			}
+			if (iStart > num)
+			{
+				LocalizationReader.AddCSVtoken(ref list, ref Line, iStart, ref num);
+			}
+			return list.ToArray();
+		}
+
+		private static void AddCSVtoken(ref List<string> list, ref string Line, int iEnd, ref int iWordStart)
+		{
+			string text = Line.Substring(iWordStart, iEnd - iWordStart);
+			iWordStart = iEnd + 1;
+			text = text.Replace("\"\"", "\"");
+			if (text.Length > 1 && text[0] == '"' && text[text.Length - 1] == '"')
+			{
+				text = text.Substring(1, text.Length - 2);
+			}
+			list.Add(text);
+		}
+
+		public static List<string[]> ReadI2CSV(string Text)
+		{
+			string[] separator = new string[]
+			{
+				"[*]"
+			};
+			string[] separator2 = new string[]
+			{
+				"[ln]"
+			};
+			List<string[]> list = new List<string[]>();
+			foreach (string text in Text.Split(separator2, StringSplitOptions.None))
+			{
+				list.Add(text.Split(separator, StringSplitOptions.None));
+			}
+			return list;
+		}
+
+		public static void ValidateFullTerm(ref string Term)
+		{
+			Term = Term.Replace('\\', '/');
+			int num = Term.IndexOf('/');
+			if (num < 0)
+			{
+				return;
+			}
+			int startIndex;
+			while ((startIndex = Term.LastIndexOf('/')) != num)
+			{
+				Term = Term.Remove(startIndex, 1);
+			}
+		}
+
+		public static string EncodeString(string str)
+		{
+			if (string.IsNullOrEmpty(str))
+			{
+				return string.Empty;
+			}
+			return str.Replace("\r\n", "<\\n>").Replace("\r", "<\\n>").Replace("\n", "<\\n>");
+		}
+
+		public static string DecodeString(string str)
+		{
+			if (string.IsNullOrEmpty(str))
+			{
+				return string.Empty;
+			}
+			return str.Replace("<\\n>", "\r\n");
+		}
+	}
+}

+ 467 - 0
Assembly-CSharp/I2/Loc/Localize.cs

@@ -0,0 +1,467 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+using UnityEngine.Events;
+
+namespace I2.Loc
+{
+	[AddComponentMenu("I2/Localization/I2 Localize")]
+	public class Localize : MonoBehaviour
+	{
+		public string Term
+		{
+			get
+			{
+				return this.mTerm;
+			}
+			set
+			{
+				this.SetTerm(value);
+			}
+		}
+
+		public string SecondaryTerm
+		{
+			get
+			{
+				return this.mTermSecondary;
+			}
+			set
+			{
+				this.SetTerm(null, value);
+			}
+		}
+
+		private void Awake()
+		{
+			this.UpdateAssetDictionary();
+			this.FindTarget();
+			if (this.LocalizeOnAwake)
+			{
+				this.OnLocalize(false);
+			}
+		}
+
+		private void OnEnable()
+		{
+			this.OnLocalize(false);
+		}
+
+		public bool HasCallback()
+		{
+			return this.LocalizeCallBack.HasCallback() || this.LocalizeEvent.GetPersistentEventCount() > 0;
+		}
+
+		public void OnLocalize(bool Force = false)
+		{
+			if (!Force && (!base.enabled || base.gameObject == null || !base.gameObject.activeInHierarchy))
+			{
+				return;
+			}
+			if (string.IsNullOrEmpty(LocalizationManager.CurrentLanguage))
+			{
+				return;
+			}
+			if (!this.AlwaysForceLocalize && !Force && !this.HasCallback() && this.LastLocalizedLanguage == LocalizationManager.CurrentLanguage)
+			{
+				return;
+			}
+			this.LastLocalizedLanguage = LocalizationManager.CurrentLanguage;
+			if (string.IsNullOrEmpty(this.FinalTerm) || string.IsNullOrEmpty(this.FinalSecondaryTerm))
+			{
+				this.GetFinalTerms(out this.FinalTerm, out this.FinalSecondaryTerm);
+			}
+			bool flag = I2Utils.IsPlaying() && this.HasCallback();
+			if (!flag && string.IsNullOrEmpty(this.FinalTerm) && string.IsNullOrEmpty(this.FinalSecondaryTerm))
+			{
+				return;
+			}
+			Localize.CallBackTerm = this.FinalTerm;
+			Localize.CallBackSecondaryTerm = this.FinalSecondaryTerm;
+			Localize.MainTranslation = ((!string.IsNullOrEmpty(this.FinalTerm) && !(this.FinalTerm == "-")) ? LocalizationManager.GetTranslation(this.FinalTerm, false, 0, true, false, null, null) : null);
+			Localize.SecondaryTranslation = ((!string.IsNullOrEmpty(this.FinalSecondaryTerm) && !(this.FinalSecondaryTerm == "-")) ? LocalizationManager.GetTranslation(this.FinalSecondaryTerm, false, 0, true, false, null, null) : null);
+			if (!flag && string.IsNullOrEmpty(this.FinalTerm) && string.IsNullOrEmpty(Localize.SecondaryTranslation))
+			{
+				return;
+			}
+			Localize.CurrentLocalizeComponent = this;
+			this.LocalizeCallBack.Execute(this);
+			this.LocalizeEvent.Invoke();
+			LocalizationManager.ApplyLocalizationParams(ref Localize.MainTranslation, base.gameObject);
+			if (!this.FindTarget())
+			{
+				return;
+			}
+			bool flag2 = LocalizationManager.IsRight2Left && !this.IgnoreRTL;
+			if (Localize.MainTranslation != null)
+			{
+				switch (this.PrimaryTermModifier)
+				{
+				case Localize.TermModification.ToUpper:
+					Localize.MainTranslation = Localize.MainTranslation.ToUpper();
+					break;
+				case Localize.TermModification.ToLower:
+					Localize.MainTranslation = Localize.MainTranslation.ToLower();
+					break;
+				case Localize.TermModification.ToUpperFirst:
+					Localize.MainTranslation = GoogleTranslation.UppercaseFirst(Localize.MainTranslation);
+					break;
+				case Localize.TermModification.ToTitle:
+					Localize.MainTranslation = GoogleTranslation.TitleCase(Localize.MainTranslation);
+					break;
+				}
+				if (!string.IsNullOrEmpty(this.TermPrefix))
+				{
+					Localize.MainTranslation = ((!flag2) ? (this.TermPrefix + Localize.MainTranslation) : (Localize.MainTranslation + this.TermPrefix));
+				}
+				if (!string.IsNullOrEmpty(this.TermSuffix))
+				{
+					Localize.MainTranslation = ((!flag2) ? (Localize.MainTranslation + this.TermSuffix) : (this.TermSuffix + Localize.MainTranslation));
+				}
+				if (this.AddSpacesToJoinedLanguages && LocalizationManager.HasJoinedWords && !string.IsNullOrEmpty(Localize.MainTranslation))
+				{
+					StringBuilder stringBuilder = new StringBuilder();
+					stringBuilder.Append(Localize.MainTranslation[0]);
+					int i = 1;
+					int length = Localize.MainTranslation.Length;
+					while (i < length)
+					{
+						stringBuilder.Append(' ');
+						stringBuilder.Append(Localize.MainTranslation[i]);
+						i++;
+					}
+					Localize.MainTranslation = stringBuilder.ToString();
+				}
+				if (flag2 && this.mLocalizeTarget.AllowMainTermToBeRTL() && !string.IsNullOrEmpty(Localize.MainTranslation))
+				{
+					Localize.MainTranslation = LocalizationManager.ApplyRTLfix(Localize.MainTranslation, this.MaxCharactersInRTL, this.IgnoreNumbersInRTL);
+				}
+			}
+			if (Localize.SecondaryTranslation != null)
+			{
+				switch (this.SecondaryTermModifier)
+				{
+				case Localize.TermModification.ToUpper:
+					Localize.SecondaryTranslation = Localize.SecondaryTranslation.ToUpper();
+					break;
+				case Localize.TermModification.ToLower:
+					Localize.SecondaryTranslation = Localize.SecondaryTranslation.ToLower();
+					break;
+				case Localize.TermModification.ToUpperFirst:
+					Localize.SecondaryTranslation = GoogleTranslation.UppercaseFirst(Localize.SecondaryTranslation);
+					break;
+				case Localize.TermModification.ToTitle:
+					Localize.SecondaryTranslation = GoogleTranslation.TitleCase(Localize.SecondaryTranslation);
+					break;
+				}
+				if (flag2 && this.mLocalizeTarget.AllowSecondTermToBeRTL() && !string.IsNullOrEmpty(Localize.SecondaryTranslation))
+				{
+					Localize.SecondaryTranslation = LocalizationManager.ApplyRTLfix(Localize.SecondaryTranslation);
+				}
+			}
+			if (LocalizationManager.HighlightLocalizedTargets)
+			{
+				Localize.MainTranslation = "LOC:" + this.FinalTerm;
+			}
+			this.mLocalizeTarget.DoLocalize(this, Localize.MainTranslation, Localize.SecondaryTranslation);
+			Localize.CurrentLocalizeComponent = null;
+		}
+
+		public bool FindTarget()
+		{
+			if (this.mLocalizeTarget != null && this.mLocalizeTarget.IsValid(this))
+			{
+				return true;
+			}
+			if (this.mLocalizeTarget != null)
+			{
+				UnityEngine.Object.DestroyImmediate(this.mLocalizeTarget);
+				this.mLocalizeTarget = null;
+				this.mLocalizeTargetName = null;
+			}
+			if (!string.IsNullOrEmpty(this.mLocalizeTargetName))
+			{
+				foreach (ILocalizeTargetDescriptor localizeTargetDescriptor in LocalizationManager.mLocalizeTargets)
+				{
+					if (this.mLocalizeTargetName == localizeTargetDescriptor.GetTargetType().ToString())
+					{
+						if (localizeTargetDescriptor.CanLocalize(this))
+						{
+							this.mLocalizeTarget = localizeTargetDescriptor.CreateTarget(this);
+						}
+						if (this.mLocalizeTarget != null)
+						{
+							return true;
+						}
+					}
+				}
+			}
+			foreach (ILocalizeTargetDescriptor localizeTargetDescriptor2 in LocalizationManager.mLocalizeTargets)
+			{
+				if (localizeTargetDescriptor2.CanLocalize(this))
+				{
+					this.mLocalizeTarget = localizeTargetDescriptor2.CreateTarget(this);
+					this.mLocalizeTargetName = localizeTargetDescriptor2.GetTargetType().ToString();
+					if (this.mLocalizeTarget != null)
+					{
+						return true;
+					}
+				}
+			}
+			return false;
+		}
+
+		public void GetFinalTerms(out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = string.Empty;
+			secondaryTerm = string.Empty;
+			if (!this.FindTarget())
+			{
+				return;
+			}
+			if (this.mLocalizeTarget != null)
+			{
+				this.mLocalizeTarget.GetFinalTerms(this, this.mTerm, this.mTermSecondary, out primaryTerm, out secondaryTerm);
+				primaryTerm = I2Utils.RemoveNonASCII(primaryTerm, false);
+			}
+			if (!string.IsNullOrEmpty(this.mTerm))
+			{
+				primaryTerm = this.mTerm;
+			}
+			if (!string.IsNullOrEmpty(this.mTermSecondary))
+			{
+				secondaryTerm = this.mTermSecondary;
+			}
+			if (primaryTerm != null)
+			{
+				primaryTerm = primaryTerm.Trim();
+			}
+			if (secondaryTerm != null)
+			{
+				secondaryTerm = secondaryTerm.Trim();
+			}
+		}
+
+		public string GetMainTargetsText()
+		{
+			string text = null;
+			string text2 = null;
+			if (this.mLocalizeTarget != null)
+			{
+				this.mLocalizeTarget.GetFinalTerms(this, null, null, out text, out text2);
+			}
+			return (!string.IsNullOrEmpty(text)) ? text : this.mTerm;
+		}
+
+		public void SetFinalTerms(string Main, string Secondary, out string primaryTerm, out string secondaryTerm, bool RemoveNonASCII)
+		{
+			primaryTerm = ((!RemoveNonASCII) ? Main : I2Utils.RemoveNonASCII(Main, false));
+			secondaryTerm = Secondary;
+		}
+
+		public void SetTerm(string primary)
+		{
+			if (!string.IsNullOrEmpty(primary))
+			{
+				this.mTerm = primary;
+				this.FinalTerm = primary;
+			}
+			this.OnLocalize(true);
+		}
+
+		public void SetTerm(string primary, string secondary)
+		{
+			if (!string.IsNullOrEmpty(primary))
+			{
+				this.mTerm = primary;
+				this.FinalTerm = primary;
+			}
+			this.mTermSecondary = secondary;
+			this.FinalSecondaryTerm = secondary;
+			this.OnLocalize(true);
+		}
+
+		internal T GetSecondaryTranslatedObj<T>(ref string mainTranslation, ref string secondaryTranslation) where T : UnityEngine.Object
+		{
+			string text;
+			string text2;
+			this.DeserializeTranslation(mainTranslation, out text, out text2);
+			T t = (T)((object)null);
+			if (!string.IsNullOrEmpty(text2))
+			{
+				t = this.GetObject<T>(text2);
+				if (t != null)
+				{
+					mainTranslation = text;
+					secondaryTranslation = text2;
+				}
+			}
+			if (t == null)
+			{
+				t = this.GetObject<T>(secondaryTranslation);
+			}
+			return t;
+		}
+
+		public void UpdateAssetDictionary()
+		{
+			this.TranslatedObjects.RemoveAll((UnityEngine.Object x) => x == null);
+			this.mAssetDictionary = this.TranslatedObjects.Distinct<UnityEngine.Object>().ToDictionary((UnityEngine.Object o) => o.name);
+		}
+
+		internal T GetObject<T>(string Translation) where T : UnityEngine.Object
+		{
+			if (string.IsNullOrEmpty(Translation))
+			{
+				return (T)((object)null);
+			}
+			T translatedObject = this.GetTranslatedObject<T>(Translation);
+			if (translatedObject == null)
+			{
+				translatedObject = this.GetTranslatedObject<T>(Translation);
+			}
+			return translatedObject;
+		}
+
+		private T GetTranslatedObject<T>(string Translation) where T : UnityEngine.Object
+		{
+			return this.FindTranslatedObject<T>(Translation);
+		}
+
+		private void DeserializeTranslation(string translation, out string value, out string secondary)
+		{
+			if (!string.IsNullOrEmpty(translation) && translation.Length > 1 && translation[0] == '[')
+			{
+				int num = translation.IndexOf(']');
+				if (num > 0)
+				{
+					secondary = translation.Substring(1, num - 1);
+					value = translation.Substring(num + 1);
+					return;
+				}
+			}
+			value = translation;
+			secondary = string.Empty;
+		}
+
+		public T FindTranslatedObject<T>(string value) where T : UnityEngine.Object
+		{
+			if (string.IsNullOrEmpty(value))
+			{
+				return (T)((object)null);
+			}
+			if (this.mAssetDictionary == null || this.mAssetDictionary.Count != this.TranslatedObjects.Count)
+			{
+				this.UpdateAssetDictionary();
+			}
+			foreach (KeyValuePair<string, UnityEngine.Object> keyValuePair in this.mAssetDictionary)
+			{
+				if (keyValuePair.Value is T && value.EndsWith(keyValuePair.Key, StringComparison.OrdinalIgnoreCase) && string.Compare(value, keyValuePair.Key, StringComparison.OrdinalIgnoreCase) == 0)
+				{
+					return (T)((object)keyValuePair.Value);
+				}
+			}
+			T t = LocalizationManager.FindAsset(value) as T;
+			if (t)
+			{
+				return t;
+			}
+			return ResourceManager.pInstance.GetAsset<T>(value);
+		}
+
+		public bool HasTranslatedObject(UnityEngine.Object Obj)
+		{
+			return this.TranslatedObjects.Contains(Obj) || ResourceManager.pInstance.HasAsset(Obj);
+		}
+
+		public void AddTranslatedObject(UnityEngine.Object Obj)
+		{
+			if (this.TranslatedObjects.Contains(Obj))
+			{
+				return;
+			}
+			this.TranslatedObjects.Add(Obj);
+			this.UpdateAssetDictionary();
+		}
+
+		public void SetGlobalLanguage(string Language)
+		{
+			LocalizationManager.CurrentLanguage = Language;
+		}
+
+		public string mTerm = string.Empty;
+
+		public string mTermSecondary = string.Empty;
+
+		[NonSerialized]
+		public string FinalTerm;
+
+		[NonSerialized]
+		public string FinalSecondaryTerm;
+
+		public Localize.TermModification PrimaryTermModifier;
+
+		public Localize.TermModification SecondaryTermModifier;
+
+		public string TermPrefix;
+
+		public string TermSuffix;
+
+		public bool LocalizeOnAwake = true;
+
+		private string LastLocalizedLanguage;
+
+		public bool IgnoreRTL;
+
+		public int MaxCharactersInRTL;
+
+		public bool IgnoreNumbersInRTL = true;
+
+		public bool CorrectAlignmentForRTL = true;
+
+		public bool AddSpacesToJoinedLanguages;
+
+		public List<UnityEngine.Object> TranslatedObjects = new List<UnityEngine.Object>();
+
+		[NonSerialized]
+		public Dictionary<string, UnityEngine.Object> mAssetDictionary = new Dictionary<string, UnityEngine.Object>(StringComparer.Ordinal);
+
+		public UnityEvent LocalizeEvent = new UnityEvent();
+
+		public static string MainTranslation;
+
+		public static string SecondaryTranslation;
+
+		public static string CallBackTerm;
+
+		public static string CallBackSecondaryTerm;
+
+		public static Localize CurrentLocalizeComponent;
+
+		public bool AlwaysForceLocalize;
+
+		[SerializeField]
+		public EventCallback LocalizeCallBack = new EventCallback();
+
+		public bool mGUI_ShowReferences;
+
+		public bool mGUI_ShowTems = true;
+
+		public bool mGUI_ShowCallback;
+
+		public ILocalizeTarget mLocalizeTarget;
+
+		public string mLocalizeTargetName;
+
+		public enum TermModification
+		{
+			DontModify,
+			ToUpper,
+			ToLower,
+			ToUpperFirst,
+			ToTitle
+		}
+	}
+}

+ 75 - 0
Assembly-CSharp/I2/Loc/LocalizeDropdown.cs

@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace I2.Loc
+{
+	[AddComponentMenu("I2/Localization/Localize Dropdown")]
+	public class LocalizeDropdown : MonoBehaviour
+	{
+		public void Start()
+		{
+			LocalizationManager.OnLocalizeEvent += this.OnLocalize;
+			this.OnLocalize();
+		}
+
+		public void OnDestroy()
+		{
+			LocalizationManager.OnLocalizeEvent -= this.OnLocalize;
+		}
+
+		private void OnEnable()
+		{
+			if (this._Terms.Count == 0)
+			{
+				this.FillValues();
+			}
+			this.OnLocalize();
+		}
+
+		public void OnLocalize()
+		{
+			if (!base.enabled || base.gameObject == null || !base.gameObject.activeInHierarchy)
+			{
+				return;
+			}
+			if (string.IsNullOrEmpty(LocalizationManager.CurrentLanguage))
+			{
+				return;
+			}
+			this.UpdateLocalization();
+		}
+
+		private void FillValues()
+		{
+			Dropdown component = base.GetComponent<Dropdown>();
+			if (component == null && I2Utils.IsPlaying())
+			{
+				return;
+			}
+			foreach (Dropdown.OptionData optionData in component.options)
+			{
+				this._Terms.Add(optionData.text);
+			}
+		}
+
+		public void UpdateLocalization()
+		{
+			Dropdown component = base.GetComponent<Dropdown>();
+			if (component == null)
+			{
+				return;
+			}
+			component.options.Clear();
+			foreach (string term in this._Terms)
+			{
+				string translation = LocalizationManager.GetTranslation(term, true, 0, true, false, null, null);
+				component.options.Add(new Dropdown.OptionData(translation));
+			}
+			component.RefreshShownValue();
+		}
+
+		public List<string> _Terms = new List<string>();
+	}
+}

+ 27 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget.cs

@@ -0,0 +1,27 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public abstract class LocalizeTarget<T> : ILocalizeTarget where T : UnityEngine.Object
+	{
+		public override bool IsValid(Localize cmp)
+		{
+			if (this.mTarget != null)
+			{
+				Component component = this.mTarget as Component;
+				if (component != null && component.gameObject != cmp.gameObject)
+				{
+					this.mTarget = (T)((object)null);
+				}
+			}
+			if (this.mTarget == null)
+			{
+				this.mTarget = cmp.GetComponent<T>();
+			}
+			return this.mTarget != null;
+		}
+
+		public T mTarget;
+	}
+}

+ 18 - 0
Assembly-CSharp/I2/Loc/LocalizeTargetDesc.cs

@@ -0,0 +1,18 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public abstract class LocalizeTargetDesc<T> : ILocalizeTargetDescriptor where T : ILocalizeTarget
+	{
+		public override ILocalizeTarget CreateTarget(Localize cmp)
+		{
+			return ScriptableObject.CreateInstance<T>();
+		}
+
+		public override Type GetTargetType()
+		{
+			return typeof(T);
+		}
+	}
+}

+ 12 - 0
Assembly-CSharp/I2/Loc/LocalizeTargetDesc_Child.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace I2.Loc
+{
+	public class LocalizeTargetDesc_Child : LocalizeTargetDesc<LocalizeTarget_UnityStandard_Child>
+	{
+		public override bool CanLocalize(Localize cmp)
+		{
+			return cmp.transform.childCount > 1;
+		}
+	}
+}

+ 12 - 0
Assembly-CSharp/I2/Loc/LocalizeTargetDesc_Prefab.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace I2.Loc
+{
+	public class LocalizeTargetDesc_Prefab : LocalizeTargetDesc<LocalizeTarget_UnityStandard_Prefab>
+	{
+		public override bool CanLocalize(Localize cmp)
+		{
+			return true;
+		}
+	}
+}

+ 25 - 0
Assembly-CSharp/I2/Loc/LocalizeTargetDesc_Type.cs

@@ -0,0 +1,25 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTargetDesc_Type<T, G> : LocalizeTargetDesc<G> where T : UnityEngine.Object where G : LocalizeTarget<T>
+	{
+		public override bool CanLocalize(Localize cmp)
+		{
+			return cmp.GetComponent<T>() != null;
+		}
+
+		public override ILocalizeTarget CreateTarget(Localize cmp)
+		{
+			T component = cmp.GetComponent<T>();
+			if (component == null)
+			{
+				return null;
+			}
+			G g = ScriptableObject.CreateInstance<G>();
+			g.mTarget = component;
+			return g;
+		}
+	}
+}

+ 115 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_NGUI_Label.cs

@@ -0,0 +1,115 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_NGUI_Label : LocalizeTarget<UILabel>
+	{
+		static LocalizeTarget_NGUI_Label()
+		{
+			LocalizeTarget_NGUI_Label.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<UILabel, LocalizeTarget_NGUI_Label>
+			{
+				Name = "NGUI Label",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.UIFont;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return true;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return true;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget) ? null : this.mTarget.text);
+			secondaryTerm = ((!(this.mTarget.ambigiousFont != null)) ? string.Empty : this.mTarget.ambigiousFont.name);
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Font secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Font>(ref mainTranslation, ref secondaryTranslation);
+			if (secondaryTranslatedObj != null)
+			{
+				if (secondaryTranslatedObj != this.mTarget.ambigiousFont)
+				{
+					this.mTarget.ambigiousFont = secondaryTranslatedObj;
+				}
+			}
+			else
+			{
+				UIFont secondaryTranslatedObj2 = cmp.GetSecondaryTranslatedObj<UIFont>(ref mainTranslation, ref secondaryTranslation);
+				if (secondaryTranslatedObj2 != null && this.mTarget.ambigiousFont != secondaryTranslatedObj2)
+				{
+					this.mTarget.ambigiousFont = secondaryTranslatedObj2;
+				}
+			}
+			if (this.mInitializeAlignment)
+			{
+				this.mInitializeAlignment = false;
+				this.mAlignment_LTR = (this.mAlignment_RTL = this.mTarget.alignment);
+				if (LocalizationManager.IsRight2Left && this.mAlignment_RTL == NGUIText.Alignment.Right)
+				{
+					this.mAlignment_LTR = NGUIText.Alignment.Left;
+				}
+				if (!LocalizationManager.IsRight2Left && this.mAlignment_LTR == NGUIText.Alignment.Left)
+				{
+					this.mAlignment_RTL = NGUIText.Alignment.Right;
+				}
+			}
+			UIInput uiinput = NGUITools.FindInParents<UIInput>(this.mTarget.gameObject);
+			if (uiinput != null && uiinput.label == this.mTarget)
+			{
+				if (mainTranslation != null && uiinput.defaultText != mainTranslation)
+				{
+					if (cmp.CorrectAlignmentForRTL && (uiinput.label.alignment == NGUIText.Alignment.Left || uiinput.label.alignment == NGUIText.Alignment.Right))
+					{
+						uiinput.label.alignment = ((!LocalizationManager.IsRight2Left) ? this.mAlignment_LTR : this.mAlignment_RTL);
+					}
+					uiinput.defaultText = mainTranslation;
+				}
+			}
+			else if (mainTranslation != null && this.mTarget.text != mainTranslation)
+			{
+				if (cmp.CorrectAlignmentForRTL && (this.mTarget.alignment == NGUIText.Alignment.Left || this.mTarget.alignment == NGUIText.Alignment.Right))
+				{
+					this.mTarget.alignment = ((!LocalizationManager.IsRight2Left) ? this.mAlignment_LTR : this.mAlignment_RTL);
+				}
+				this.mTarget.text = mainTranslation;
+			}
+		}
+
+		private NGUIText.Alignment mAlignment_RTL = NGUIText.Alignment.Right;
+
+		private NGUIText.Alignment mAlignment_LTR = NGUIText.Alignment.Left;
+
+		private bool mAlignmentWasRTL;
+
+		private bool mInitializeAlignment = true;
+	}
+}

+ 78 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_NGUI_Sprite.cs

@@ -0,0 +1,78 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_NGUI_Sprite : LocalizeTarget<UISprite>
+	{
+		static LocalizeTarget_NGUI_Sprite()
+		{
+			LocalizeTarget_NGUI_Sprite.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<UISprite, LocalizeTarget_NGUI_Sprite>
+			{
+				Name = "NGUI UISprite",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Sprite;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.UIAtlas;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return true;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget) ? null : this.mTarget.spriteName);
+			secondaryTerm = ((!(this.mTarget.atlas != null)) ? string.Empty : this.mTarget.atlas.name);
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			if (this.mTarget.spriteName == mainTranslation)
+			{
+				return;
+			}
+			UIAtlas secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<UIAtlas>(ref mainTranslation, ref secondaryTranslation);
+			bool flag = false;
+			if (secondaryTranslatedObj != null && this.mTarget.atlas != secondaryTranslatedObj)
+			{
+				this.mTarget.atlas = secondaryTranslatedObj;
+				flag = true;
+			}
+			if (this.mTarget.spriteName != mainTranslation && this.mTarget.atlas.GetSprite(mainTranslation) != null)
+			{
+				this.mTarget.spriteName = mainTranslation;
+				flag = true;
+			}
+			if (flag)
+			{
+				this.mTarget.MakePixelPerfect();
+			}
+		}
+	}
+}

+ 64 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_NGUI_Texture.cs

@@ -0,0 +1,64 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_NGUI_Texture : LocalizeTarget<UITexture>
+	{
+		static LocalizeTarget_NGUI_Texture()
+		{
+			LocalizeTarget_NGUI_Texture.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<UITexture, LocalizeTarget_NGUI_Texture>
+			{
+				Name = "NGUI UITexture",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Texture;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!(this.mTarget != null) || !(this.mTarget.mainTexture != null)) ? null : this.mTarget.mainTexture.name);
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Texture mainTexture = this.mTarget.mainTexture;
+			if (mainTexture == null || mainTexture.name != mainTranslation)
+			{
+				this.mTarget.mainTexture = cmp.FindTranslatedObject<Texture>(mainTranslation);
+				this.mTarget.MakePixelPerfect();
+			}
+		}
+	}
+}

+ 69 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_AudioSource.cs

@@ -0,0 +1,69 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_AudioSource : LocalizeTarget<AudioSource>
+	{
+		static LocalizeTarget_UnityStandard_AudioSource()
+		{
+			LocalizeTarget_UnityStandard_AudioSource.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<AudioSource, LocalizeTarget_UnityStandard_AudioSource>
+			{
+				Name = "AudioSource",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.AudioClip;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget.clip) ? string.Empty : this.mTarget.clip.name);
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			bool flag = (this.mTarget.isPlaying || this.mTarget.loop) && Application.isPlaying;
+			AudioClip clip = this.mTarget.clip;
+			AudioClip audioClip = cmp.FindTranslatedObject<AudioClip>(mainTranslation);
+			if (clip != audioClip)
+			{
+				this.mTarget.clip = audioClip;
+			}
+			if (flag && this.mTarget.clip)
+			{
+				this.mTarget.Play();
+			}
+		}
+	}
+}

+ 79 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_Child.cs

@@ -0,0 +1,79 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_Child : LocalizeTarget<GameObject>
+	{
+		static LocalizeTarget_UnityStandard_Child()
+		{
+			LocalizeTarget_UnityStandard_Child.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Child
+			{
+				Name = "Child",
+				Priority = 200
+			});
+		}
+
+		public override bool IsValid(Localize cmp)
+		{
+			return cmp.transform.childCount > 1;
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.GameObject;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = cmp.name;
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			if (string.IsNullOrEmpty(mainTranslation))
+			{
+				return;
+			}
+			Transform transform = cmp.transform;
+			string text = mainTranslation;
+			int num = mainTranslation.LastIndexOfAny(LanguageSource.CategorySeparators);
+			if (num >= 0)
+			{
+				text = text.Substring(num + 1);
+			}
+			for (int i = 0; i < transform.childCount; i++)
+			{
+				Transform child = transform.GetChild(i);
+				child.gameObject.SetActive(child.name == text);
+			}
+		}
+	}
+}

+ 92 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_GUIText.cs

@@ -0,0 +1,92 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_GUIText : LocalizeTarget<GUIText>
+	{
+		static LocalizeTarget_UnityStandard_GUIText()
+		{
+			LocalizeTarget_UnityStandard_GUIText.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<GUIText, LocalizeTarget_UnityStandard_GUIText>
+			{
+				Name = "GUIText",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Font;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return true;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return true;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget) ? null : this.mTarget.text);
+			secondaryTerm = ((!string.IsNullOrEmpty(Secondary) || !(this.mTarget.font != null)) ? null : this.mTarget.font.name);
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Font secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Font>(ref mainTranslation, ref secondaryTranslation);
+			if (secondaryTranslatedObj != null && this.mTarget.font != secondaryTranslatedObj)
+			{
+				this.mTarget.font = secondaryTranslatedObj;
+			}
+			if (this.mInitializeAlignment)
+			{
+				this.mInitializeAlignment = false;
+				this.mAlignment_LTR = (this.mAlignment_RTL = this.mTarget.alignment);
+				if (LocalizationManager.IsRight2Left && this.mAlignment_RTL == TextAlignment.Right)
+				{
+					this.mAlignment_LTR = TextAlignment.Left;
+				}
+				if (!LocalizationManager.IsRight2Left && this.mAlignment_LTR == TextAlignment.Left)
+				{
+					this.mAlignment_RTL = TextAlignment.Right;
+				}
+			}
+			if (mainTranslation != null && this.mTarget.text != mainTranslation)
+			{
+				if (cmp.CorrectAlignmentForRTL && this.mTarget.alignment != TextAlignment.Center)
+				{
+					this.mTarget.alignment = ((!LocalizationManager.IsRight2Left) ? this.mAlignment_LTR : this.mAlignment_RTL);
+				}
+				this.mTarget.text = mainTranslation;
+			}
+		}
+
+		private TextAlignment mAlignment_RTL = TextAlignment.Right;
+
+		private TextAlignment mAlignment_LTR;
+
+		private bool mAlignmentWasRTL;
+
+		private bool mInitializeAlignment = true;
+	}
+}

+ 63 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_GUITexture.cs

@@ -0,0 +1,63 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_GUITexture : LocalizeTarget<GUITexture>
+	{
+		static LocalizeTarget_UnityStandard_GUITexture()
+		{
+			LocalizeTarget_UnityStandard_GUITexture.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<GUITexture, LocalizeTarget_UnityStandard_GUITexture>
+			{
+				Name = "GUITexture",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Texture;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget.texture) ? string.Empty : this.mTarget.texture.name);
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Texture texture = this.mTarget.texture;
+			if (texture == null || texture.name != mainTranslation)
+			{
+				this.mTarget.texture = cmp.FindTranslatedObject<Texture>(mainTranslation);
+			}
+		}
+	}
+}

+ 114 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_Prefab.cs

@@ -0,0 +1,114 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_Prefab : LocalizeTarget<GameObject>
+	{
+		static LocalizeTarget_UnityStandard_Prefab()
+		{
+			LocalizeTarget_UnityStandard_Prefab.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Prefab
+			{
+				Name = "Prefab",
+				Priority = 250
+			});
+		}
+
+		public override bool IsValid(Localize cmp)
+		{
+			return true;
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.GameObject;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = cmp.name;
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			if (string.IsNullOrEmpty(mainTranslation))
+			{
+				return;
+			}
+			if (this.mTarget && this.mTarget.name == mainTranslation)
+			{
+				return;
+			}
+			Transform transform = cmp.transform;
+			string text = mainTranslation;
+			int num = mainTranslation.LastIndexOfAny(LanguageSource.CategorySeparators);
+			if (num >= 0)
+			{
+				text = text.Substring(num + 1);
+			}
+			Transform transform2 = this.InstantiateNewPrefab(cmp, mainTranslation);
+			if (transform2 == null)
+			{
+				return;
+			}
+			transform2.name = text;
+			for (int i = transform.childCount - 1; i >= 0; i--)
+			{
+				Transform child = transform.GetChild(i);
+				if (child != transform2)
+				{
+					UnityEngine.Object.Destroy(child.gameObject);
+				}
+			}
+		}
+
+		private Transform InstantiateNewPrefab(Localize cmp, string mainTranslation)
+		{
+			GameObject gameObject = cmp.FindTranslatedObject<GameObject>(mainTranslation);
+			if (gameObject == null)
+			{
+				return null;
+			}
+			GameObject mTarget = this.mTarget;
+			this.mTarget = UnityEngine.Object.Instantiate<GameObject>(gameObject);
+			if (this.mTarget == null)
+			{
+				return null;
+			}
+			Transform transform = cmp.transform;
+			Transform transform2 = this.mTarget.transform;
+			transform2.SetParent(transform);
+			Transform transform3 = (!mTarget) ? transform : mTarget.transform;
+			transform2.rotation = transform3.rotation;
+			transform2.position = transform3.position;
+			return transform2;
+		}
+	}
+}

+ 63 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_SpriteRenderer.cs

@@ -0,0 +1,63 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_SpriteRenderer : LocalizeTarget<SpriteRenderer>
+	{
+		static LocalizeTarget_UnityStandard_SpriteRenderer()
+		{
+			LocalizeTarget_UnityStandard_SpriteRenderer.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<SpriteRenderer, LocalizeTarget_UnityStandard_SpriteRenderer>
+			{
+				Name = "SpriteRenderer",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Sprite;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!(this.mTarget.sprite != null)) ? string.Empty : this.mTarget.sprite.name);
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Sprite sprite = this.mTarget.sprite;
+			if (sprite == null || sprite.name != mainTranslation)
+			{
+				this.mTarget.sprite = cmp.FindTranslatedObject<Sprite>(mainTranslation);
+			}
+		}
+	}
+}

+ 93 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityStandard_TextMesh.cs

@@ -0,0 +1,93 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityStandard_TextMesh : LocalizeTarget<TextMesh>
+	{
+		static LocalizeTarget_UnityStandard_TextMesh()
+		{
+			LocalizeTarget_UnityStandard_TextMesh.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<TextMesh, LocalizeTarget_UnityStandard_TextMesh>
+			{
+				Name = "TextMesh",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Font;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return true;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return true;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget) ? null : this.mTarget.text);
+			secondaryTerm = ((!string.IsNullOrEmpty(Secondary) || !(this.mTarget.font != null)) ? null : this.mTarget.font.name);
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Font secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Font>(ref mainTranslation, ref secondaryTranslation);
+			if (secondaryTranslatedObj != null && this.mTarget.font != secondaryTranslatedObj)
+			{
+				this.mTarget.font = secondaryTranslatedObj;
+			}
+			if (this.mInitializeAlignment)
+			{
+				this.mInitializeAlignment = false;
+				this.mAlignment_LTR = (this.mAlignment_RTL = this.mTarget.alignment);
+				if (LocalizationManager.IsRight2Left && this.mAlignment_RTL == TextAlignment.Right)
+				{
+					this.mAlignment_LTR = TextAlignment.Left;
+				}
+				if (!LocalizationManager.IsRight2Left && this.mAlignment_LTR == TextAlignment.Left)
+				{
+					this.mAlignment_RTL = TextAlignment.Right;
+				}
+			}
+			if (mainTranslation != null && this.mTarget.text != mainTranslation)
+			{
+				if (cmp.CorrectAlignmentForRTL && this.mTarget.alignment != TextAlignment.Center)
+				{
+					this.mTarget.alignment = ((!LocalizationManager.IsRight2Left) ? this.mAlignment_LTR : this.mAlignment_RTL);
+				}
+				this.mTarget.font.RequestCharactersInTexture(mainTranslation);
+				this.mTarget.text = mainTranslation;
+			}
+		}
+
+		private TextAlignment mAlignment_RTL = TextAlignment.Right;
+
+		private TextAlignment mAlignment_LTR;
+
+		private bool mAlignmentWasRTL;
+
+		private bool mInitializeAlignment = true;
+	}
+}

+ 68 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityUI_Image.cs

@@ -0,0 +1,68 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityUI_Image : LocalizeTarget<Image>
+	{
+		static LocalizeTarget_UnityUI_Image()
+		{
+			LocalizeTarget_UnityUI_Image.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<Image, LocalizeTarget_UnityUI_Image>
+			{
+				Name = "Image",
+				Priority = 100
+			});
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return (!(this.mTarget.sprite == null)) ? eTermType.Sprite : eTermType.Texture;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget.mainTexture) ? string.Empty : this.mTarget.mainTexture.name);
+			if (this.mTarget.sprite != null && this.mTarget.sprite.name != primaryTerm)
+			{
+				primaryTerm = primaryTerm + "." + this.mTarget.sprite.name;
+			}
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Sprite sprite = this.mTarget.sprite;
+			if (sprite == null || sprite.name != mainTranslation)
+			{
+				this.mTarget.sprite = cmp.FindTranslatedObject<Sprite>(mainTranslation);
+			}
+		}
+	}
+}

+ 64 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityUI_RawImage.cs

@@ -0,0 +1,64 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityUI_RawImage : LocalizeTarget<RawImage>
+	{
+		static LocalizeTarget_UnityUI_RawImage()
+		{
+			LocalizeTarget_UnityUI_RawImage.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<RawImage, LocalizeTarget_UnityUI_RawImage>
+			{
+				Name = "RawImage",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Texture;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return false;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget.mainTexture) ? string.Empty : this.mTarget.mainTexture.name);
+			secondaryTerm = null;
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Texture texture = this.mTarget.texture;
+			if (texture == null || texture.name != mainTranslation)
+			{
+				this.mTarget.texture = cmp.FindTranslatedObject<Texture>(mainTranslation);
+			}
+		}
+	}
+}

+ 153 - 0
Assembly-CSharp/I2/Loc/LocalizeTarget_UnityUI_Text.cs

@@ -0,0 +1,153 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace I2.Loc
+{
+	public class LocalizeTarget_UnityUI_Text : LocalizeTarget<Text>
+	{
+		static LocalizeTarget_UnityUI_Text()
+		{
+			LocalizeTarget_UnityUI_Text.AutoRegister();
+		}
+
+		[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+		private static void AutoRegister()
+		{
+			LocalizationManager.RegisterTarget(new LocalizeTargetDesc_Type<Text, LocalizeTarget_UnityUI_Text>
+			{
+				Name = "Text",
+				Priority = 100
+			});
+		}
+
+		public override eTermType GetPrimaryTermType(Localize cmp)
+		{
+			return eTermType.Text;
+		}
+
+		public override eTermType GetSecondaryTermType(Localize cmp)
+		{
+			return eTermType.Font;
+		}
+
+		public override bool CanUseSecondaryTerm()
+		{
+			return true;
+		}
+
+		public override bool AllowMainTermToBeRTL()
+		{
+			return true;
+		}
+
+		public override bool AllowSecondTermToBeRTL()
+		{
+			return false;
+		}
+
+		public override void GetFinalTerms(Localize cmp, string Main, string Secondary, out string primaryTerm, out string secondaryTerm)
+		{
+			primaryTerm = ((!this.mTarget) ? null : this.mTarget.text);
+			secondaryTerm = ((!(this.mTarget.font != null)) ? string.Empty : this.mTarget.font.name);
+		}
+
+		public override void DoLocalize(Localize cmp, string mainTranslation, string secondaryTranslation)
+		{
+			Font secondaryTranslatedObj = cmp.GetSecondaryTranslatedObj<Font>(ref mainTranslation, ref secondaryTranslation);
+			if (secondaryTranslatedObj != null && secondaryTranslatedObj != this.mTarget.font)
+			{
+				this.mTarget.font = secondaryTranslatedObj;
+			}
+			if (this.mInitializeAlignment)
+			{
+				this.mInitializeAlignment = false;
+				this.mAlignmentWasRTL = LocalizationManager.IsRight2Left;
+				this.InitAlignment(this.mAlignmentWasRTL, this.mTarget.alignment, out this.mAlignment_LTR, out this.mAlignment_RTL);
+			}
+			else
+			{
+				TextAnchor textAnchor;
+				TextAnchor textAnchor2;
+				this.InitAlignment(this.mAlignmentWasRTL, this.mTarget.alignment, out textAnchor, out textAnchor2);
+				if ((this.mAlignmentWasRTL && this.mAlignment_RTL != textAnchor2) || (!this.mAlignmentWasRTL && this.mAlignment_LTR != textAnchor))
+				{
+					this.mAlignment_LTR = textAnchor;
+					this.mAlignment_RTL = textAnchor2;
+				}
+				this.mAlignmentWasRTL = LocalizationManager.IsRight2Left;
+			}
+			if (mainTranslation != null && this.mTarget.text != mainTranslation)
+			{
+				if (cmp.CorrectAlignmentForRTL)
+				{
+					this.mTarget.alignment = ((!LocalizationManager.IsRight2Left) ? this.mAlignment_LTR : this.mAlignment_RTL);
+				}
+				this.mTarget.text = mainTranslation;
+				this.mTarget.SetVerticesDirty();
+			}
+		}
+
+		private void InitAlignment(bool isRTL, TextAnchor alignment, out TextAnchor alignLTR, out TextAnchor alignRTL)
+		{
+			alignRTL = alignment;
+			alignLTR = alignment;
+			if (isRTL)
+			{
+				switch (alignment)
+				{
+				case TextAnchor.UpperLeft:
+					alignLTR = TextAnchor.UpperRight;
+					break;
+				case TextAnchor.UpperRight:
+					alignLTR = TextAnchor.UpperLeft;
+					break;
+				case TextAnchor.MiddleLeft:
+					alignLTR = TextAnchor.MiddleRight;
+					break;
+				case TextAnchor.MiddleRight:
+					alignLTR = TextAnchor.MiddleLeft;
+					break;
+				case TextAnchor.LowerLeft:
+					alignLTR = TextAnchor.LowerRight;
+					break;
+				case TextAnchor.LowerRight:
+					alignLTR = TextAnchor.LowerLeft;
+					break;
+				}
+			}
+			else
+			{
+				switch (alignment)
+				{
+				case TextAnchor.UpperLeft:
+					alignRTL = TextAnchor.UpperRight;
+					break;
+				case TextAnchor.UpperRight:
+					alignRTL = TextAnchor.UpperLeft;
+					break;
+				case TextAnchor.MiddleLeft:
+					alignRTL = TextAnchor.MiddleRight;
+					break;
+				case TextAnchor.MiddleRight:
+					alignRTL = TextAnchor.MiddleLeft;
+					break;
+				case TextAnchor.LowerLeft:
+					alignRTL = TextAnchor.LowerRight;
+					break;
+				case TextAnchor.LowerRight:
+					alignRTL = TextAnchor.LowerLeft;
+					break;
+				}
+			}
+		}
+
+		private TextAnchor mAlignment_RTL = TextAnchor.UpperRight;
+
+		private TextAnchor mAlignment_LTR;
+
+		private bool mAlignmentWasRTL;
+
+		private bool mInitializeAlignment = true;
+	}
+}

+ 44 - 0
Assembly-CSharp/I2/Loc/LocalizedString.cs

@@ -0,0 +1,44 @@
+using System;
+
+namespace I2.Loc
+{
+	[Serializable]
+	public struct LocalizedString
+	{
+		public LocalizedString(LocalizedString str)
+		{
+			this.mTerm = str.mTerm;
+			this.mRTL_IgnoreArabicFix = str.mRTL_IgnoreArabicFix;
+			this.mRTL_MaxLineLength = str.mRTL_MaxLineLength;
+			this.mRTL_ConvertNumbers = str.mRTL_ConvertNumbers;
+		}
+
+		public static implicit operator string(LocalizedString s)
+		{
+			return s.ToString();
+		}
+
+		public static implicit operator LocalizedString(string term)
+		{
+			return new LocalizedString
+			{
+				mTerm = term
+			};
+		}
+
+		public override string ToString()
+		{
+			string translation = LocalizationManager.GetTranslation(this.mTerm, !this.mRTL_IgnoreArabicFix, this.mRTL_MaxLineLength, !this.mRTL_ConvertNumbers, true, null, null);
+			LocalizationManager.ApplyLocalizationParams(ref translation);
+			return translation;
+		}
+
+		public string mTerm;
+
+		public bool mRTL_IgnoreArabicFix;
+
+		public int mRTL_MaxLineLength;
+
+		public bool mRTL_ConvertNumbers;
+	}
+}

+ 24 - 0
Assembly-CSharp/I2/Loc/NGUI_LanguagePopup.cs

@@ -0,0 +1,24 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class NGUI_LanguagePopup : MonoBehaviour
+	{
+		private void Start()
+		{
+			UIPopupList component = base.GetComponent<UIPopupList>();
+			component.items = this.Source.GetLanguages(true);
+			EventDelegate.Add(component.onChange, new EventDelegate.Callback(this.OnValueChange));
+			int num = component.items.IndexOf(LocalizationManager.CurrentLanguage);
+			component.value = component.items[(num < 0) ? 0 : num];
+		}
+
+		public void OnValueChange()
+		{
+			LocalizationManager.CurrentLanguage = UIPopupList.current.value;
+		}
+
+		public LanguageSource Source;
+	}
+}

+ 107 - 0
Assembly-CSharp/I2/Loc/PersistentStorage.cs

@@ -0,0 +1,107 @@
+using System;
+
+namespace I2.Loc
+{
+	public static class PersistentStorage
+	{
+		public static void SetSetting_String(string key, string value)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			PersistentStorage.mStorage.SetSetting_String(key, value);
+		}
+
+		public static string GetSetting_String(string key, string defaultValue)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.GetSetting_String(key, defaultValue);
+		}
+
+		public static void DeleteSetting(string key)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			PersistentStorage.mStorage.DeleteSetting(key);
+		}
+
+		public static bool HasSetting(string key)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.HasSetting(key);
+		}
+
+		public static void ForceSaveSettings()
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			PersistentStorage.mStorage.ForceSaveSettings();
+		}
+
+		public static bool CanAccessFiles()
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.CanAccessFiles();
+		}
+
+		public static bool SaveFile(PersistentStorage.eFileType fileType, string fileName, string data, bool logExceptions = true)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.SaveFile(fileType, fileName, data, logExceptions);
+		}
+
+		public static string LoadFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.LoadFile(fileType, fileName, logExceptions);
+		}
+
+		public static bool DeleteFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.DeleteFile(fileType, fileName, logExceptions);
+		}
+
+		public static bool HasFile(PersistentStorage.eFileType fileType, string fileName, bool logExceptions = true)
+		{
+			if (PersistentStorage.mStorage == null)
+			{
+				PersistentStorage.mStorage = new I2CustomPersistentStorage();
+			}
+			return PersistentStorage.mStorage.HasFile(fileType, fileName, logExceptions);
+		}
+
+		private static I2CustomPersistentStorage mStorage;
+
+		public enum eFileType
+		{
+			Raw,
+			Persistent,
+			Temporal,
+			Streaming
+		}
+	}
+}

+ 86 - 0
Assembly-CSharp/I2/Loc/RTLFixer.cs

@@ -0,0 +1,86 @@
+using System;
+
+namespace I2.Loc
+{
+	public class RTLFixer
+	{
+		public static string Fix(string str)
+		{
+			return RTLFixer.Fix(str, false, true);
+		}
+
+		public static string Fix(string str, bool rtl)
+		{
+			if (rtl)
+			{
+				return RTLFixer.Fix(str);
+			}
+			string[] array = str.Split(new char[]
+			{
+				' '
+			});
+			string text = string.Empty;
+			string text2 = string.Empty;
+			foreach (string text3 in array)
+			{
+				if (char.IsLower(text3.ToLower()[text3.Length / 2]))
+				{
+					text = text + RTLFixer.Fix(text2) + text3 + " ";
+					text2 = string.Empty;
+				}
+				else
+				{
+					text2 = text2 + text3 + " ";
+				}
+			}
+			if (text2 != string.Empty)
+			{
+				text += RTLFixer.Fix(text2);
+			}
+			return text;
+		}
+
+		public static string Fix(string str, bool showTashkeel, bool useHinduNumbers)
+		{
+			string text = HindiFixer.Fix(str);
+			if (text != str)
+			{
+				return text;
+			}
+			RTLFixerTool.showTashkeel = showTashkeel;
+			RTLFixerTool.useHinduNumbers = useHinduNumbers;
+			if (str.Contains("\n"))
+			{
+				str = str.Replace("\n", Environment.NewLine);
+			}
+			if (!str.Contains(Environment.NewLine))
+			{
+				return RTLFixerTool.FixLine(str);
+			}
+			string[] separator = new string[]
+			{
+				Environment.NewLine
+			};
+			string[] array = str.Split(separator, StringSplitOptions.None);
+			if (array.Length == 0)
+			{
+				return RTLFixerTool.FixLine(str);
+			}
+			if (array.Length == 1)
+			{
+				return RTLFixerTool.FixLine(str);
+			}
+			string text2 = RTLFixerTool.FixLine(array[0]);
+			int i = 1;
+			if (array.Length > 1)
+			{
+				while (i < array.Length)
+				{
+					text2 = text2 + Environment.NewLine + RTLFixerTool.FixLine(array[i]);
+					i++;
+				}
+			}
+			return text2;
+		}
+	}
+}

File diff suppressed because it is too large
+ 415 - 0
Assembly-CSharp/I2/Loc/RTLFixerTool.cs


+ 136 - 0
Assembly-CSharp/I2/Loc/RealTimeTranslation.cs

@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class RealTimeTranslation : MonoBehaviour
+	{
+		public void OnGUI()
+		{
+			GUILayout.Label("Translate:", new GUILayoutOption[0]);
+			this.OriginalText = GUILayout.TextArea(this.OriginalText, new GUILayoutOption[]
+			{
+				GUILayout.Width((float)Screen.width)
+			});
+			GUILayout.Space(10f);
+			GUILayout.BeginHorizontal(new GUILayoutOption[0]);
+			if (GUILayout.Button("English -> Español", new GUILayoutOption[]
+			{
+				GUILayout.Height(100f)
+			}))
+			{
+				this.StartTranslating("en", "es");
+			}
+			if (GUILayout.Button("Español -> English", new GUILayoutOption[]
+			{
+				GUILayout.Height(100f)
+			}))
+			{
+				this.StartTranslating("es", "en");
+			}
+			GUILayout.EndHorizontal();
+			GUILayout.Space(10f);
+			GUILayout.BeginHorizontal(new GUILayoutOption[0]);
+			GUILayout.TextArea("Multiple Translation with 1 call:\n'This is an example' -> en,zh\n'Hola' -> en", new GUILayoutOption[0]);
+			if (GUILayout.Button("Multi Translate", new GUILayoutOption[]
+			{
+				GUILayout.ExpandHeight(true)
+			}))
+			{
+				this.ExampleMultiTranslations_Async();
+			}
+			GUILayout.EndHorizontal();
+			GUILayout.TextArea(this.TranslatedText, new GUILayoutOption[]
+			{
+				GUILayout.Width((float)Screen.width)
+			});
+			GUILayout.Space(10f);
+			if (this.IsTranslating)
+			{
+				GUILayout.Label("Contacting Google....", new GUILayoutOption[0]);
+			}
+		}
+
+		public void StartTranslating(string fromCode, string toCode)
+		{
+			this.IsTranslating = true;
+			GoogleTranslation.Translate(this.OriginalText, fromCode, toCode, new Action<string, string>(this.OnTranslationReady));
+		}
+
+		private void OnTranslationReady(string Translation, string errorMsg)
+		{
+			this.IsTranslating = false;
+			if (errorMsg != null)
+			{
+				Debug.LogError(errorMsg);
+			}
+			else
+			{
+				this.TranslatedText = Translation;
+			}
+		}
+
+		public void ExampleMultiTranslations_Blocking()
+		{
+			Dictionary<string, TranslationQuery> dictionary = new Dictionary<string, TranslationQuery>();
+			GoogleTranslation.AddQuery("This is an example", "en", "es", dictionary);
+			GoogleTranslation.AddQuery("This is an example", "auto", "zh", dictionary);
+			GoogleTranslation.AddQuery("Hola", "es", "en", dictionary);
+			if (!GoogleTranslation.ForceTranslate(dictionary, true))
+			{
+				return;
+			}
+			Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "en", dictionary));
+			Debug.Log(GoogleTranslation.GetQueryResult("This is an example", "zh", dictionary));
+			Debug.Log(GoogleTranslation.GetQueryResult("This is an example", string.Empty, dictionary));
+			Debug.Log(dictionary["Hola"].Results[0]);
+		}
+
+		public void ExampleMultiTranslations_Async()
+		{
+			this.IsTranslating = true;
+			Dictionary<string, TranslationQuery> dictionary = new Dictionary<string, TranslationQuery>();
+			GoogleTranslation.AddQuery("This is an example", "en", "es", dictionary);
+			GoogleTranslation.AddQuery("This is an example", "auto", "zh", dictionary);
+			GoogleTranslation.AddQuery("Hola", "es", "en", dictionary);
+			GoogleTranslation.Translate(dictionary, new Action<Dictionary<string, TranslationQuery>, string>(this.OnMultitranslationReady), true);
+		}
+
+		private void OnMultitranslationReady(Dictionary<string, TranslationQuery> dict, string errorMsg)
+		{
+			if (!string.IsNullOrEmpty(errorMsg))
+			{
+				Debug.LogError(errorMsg);
+				return;
+			}
+			this.IsTranslating = false;
+			this.TranslatedText = string.Empty;
+			this.TranslatedText = this.TranslatedText + GoogleTranslation.GetQueryResult("This is an example", "es", dict) + "\n";
+			this.TranslatedText = this.TranslatedText + GoogleTranslation.GetQueryResult("This is an example", "zh", dict) + "\n";
+			this.TranslatedText = this.TranslatedText + GoogleTranslation.GetQueryResult("This is an example", string.Empty, dict) + "\n";
+			this.TranslatedText += dict["Hola"].Results[0];
+		}
+
+		public bool IsWaitingForTranslation()
+		{
+			return this.IsTranslating;
+		}
+
+		public string GetTranslatedText()
+		{
+			return this.TranslatedText;
+		}
+
+		public void SetOriginalText(string text)
+		{
+			this.OriginalText = text;
+		}
+
+		private string OriginalText = "This is an example showing how to use the google translator to translate chat messages within the game.\nIt also supports multiline translations.";
+
+		private string TranslatedText = string.Empty;
+
+		private bool IsTranslating;
+	}
+}

+ 26 - 0
Assembly-CSharp/I2/Loc/RegisterBundlesManager.cs

@@ -0,0 +1,26 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class RegisterBundlesManager : MonoBehaviour, IResourceManager_Bundles
+	{
+		public void OnEnable()
+		{
+			if (!ResourceManager.pInstance.mBundleManagers.Contains(this))
+			{
+				ResourceManager.pInstance.mBundleManagers.Add(this);
+			}
+		}
+
+		public void OnDisable()
+		{
+			ResourceManager.pInstance.mBundleManagers.Remove(this);
+		}
+
+		public virtual UnityEngine.Object LoadFromBundle(string path, Type assetType)
+		{
+			return null;
+		}
+	}
+}

+ 27 - 0
Assembly-CSharp/I2/Loc/RegisterGlobalParameters.cs

@@ -0,0 +1,27 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class RegisterGlobalParameters : MonoBehaviour, ILocalizationParamsManager
+	{
+		public virtual void OnEnable()
+		{
+			if (!LocalizationManager.ParamManagers.Contains(this))
+			{
+				LocalizationManager.ParamManagers.Add(this);
+				LocalizationManager.LocalizeAll(true);
+			}
+		}
+
+		public virtual void OnDisable()
+		{
+			LocalizationManager.ParamManagers.Remove(this);
+		}
+
+		public virtual string GetParameterValue(string ParamName)
+		{
+			return null;
+		}
+	}
+}

+ 183 - 0
Assembly-CSharp/I2/Loc/ResourceManager.cs

@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using UnityEngine;
+using UnityEngine.Events;
+using UnityEngine.SceneManagement;
+
+namespace I2.Loc
+{
+	public class ResourceManager : MonoBehaviour
+	{
+		public static ResourceManager pInstance
+		{
+			get
+			{
+				bool flag = ResourceManager.mInstance == null;
+				if (ResourceManager.mInstance == null)
+				{
+					ResourceManager.mInstance = (ResourceManager)UnityEngine.Object.FindObjectOfType(typeof(ResourceManager));
+				}
+				if (ResourceManager.mInstance == null)
+				{
+					GameObject gameObject = new GameObject("I2ResourceManager", new Type[]
+					{
+						typeof(ResourceManager)
+					});
+					gameObject.hideFlags |= HideFlags.HideAndDontSave;
+					ResourceManager.mInstance = gameObject.GetComponent<ResourceManager>();
+					if (ResourceManager.<>f__mg$cache0 == null)
+					{
+						ResourceManager.<>f__mg$cache0 = new UnityAction<Scene, LoadSceneMode>(ResourceManager.MyOnLevelWasLoaded);
+					}
+					SceneManager.sceneLoaded += ResourceManager.<>f__mg$cache0;
+				}
+				if (flag && Application.isPlaying)
+				{
+					UnityEngine.Object.DontDestroyOnLoad(ResourceManager.mInstance.gameObject);
+				}
+				return ResourceManager.mInstance;
+			}
+		}
+
+		public static void MyOnLevelWasLoaded(Scene scene, LoadSceneMode mode)
+		{
+			ResourceManager.pInstance.CleanResourceCache();
+			LocalizationManager.UpdateSources();
+		}
+
+		public T GetAsset<T>(string Name) where T : UnityEngine.Object
+		{
+			T t = this.FindAsset(Name) as T;
+			if (t != null)
+			{
+				return t;
+			}
+			return this.LoadFromResources<T>(Name);
+		}
+
+		private UnityEngine.Object FindAsset(string Name)
+		{
+			if (this.Assets != null)
+			{
+				int i = 0;
+				int num = this.Assets.Length;
+				while (i < num)
+				{
+					if (this.Assets[i] != null && this.Assets[i].name == Name)
+					{
+						return this.Assets[i];
+					}
+					i++;
+				}
+			}
+			return null;
+		}
+
+		public bool HasAsset(UnityEngine.Object Obj)
+		{
+			return this.Assets != null && Array.IndexOf<UnityEngine.Object>(this.Assets, Obj) >= 0;
+		}
+
+		public T LoadFromResources<T>(string Path) where T : UnityEngine.Object
+		{
+			T result;
+			try
+			{
+				UnityEngine.Object @object;
+				if (string.IsNullOrEmpty(Path))
+				{
+					result = (T)((object)null);
+				}
+				else if (this.mResourcesCache.TryGetValue(Path, out @object) && @object != null)
+				{
+					result = (@object as T);
+				}
+				else
+				{
+					T t = (T)((object)null);
+					if (Path.EndsWith("]", StringComparison.OrdinalIgnoreCase))
+					{
+						int num = Path.LastIndexOf("[", StringComparison.OrdinalIgnoreCase);
+						int length = Path.Length - num - 2;
+						string value = Path.Substring(num + 1, length);
+						Path = Path.Substring(0, num);
+						T[] array = Resources.LoadAll<T>(Path);
+						int i = 0;
+						int num2 = array.Length;
+						while (i < num2)
+						{
+							if (array[i].name.Equals(value))
+							{
+								t = array[i];
+								break;
+							}
+							i++;
+						}
+					}
+					else
+					{
+						t = (Resources.Load(Path, typeof(T)) as T);
+					}
+					if (t == null)
+					{
+						t = this.LoadFromBundle<T>(Path);
+					}
+					if (t != null)
+					{
+						this.mResourcesCache[Path] = t;
+					}
+					result = t;
+				}
+			}
+			catch (Exception ex)
+			{
+				Debug.LogErrorFormat("Unable to load {0} '{1}'\nERROR: {2}", new object[]
+				{
+					typeof(T),
+					Path,
+					ex.ToString()
+				});
+				result = (T)((object)null);
+			}
+			return result;
+		}
+
+		public T LoadFromBundle<T>(string path) where T : UnityEngine.Object
+		{
+			int i = 0;
+			int count = this.mBundleManagers.Count;
+			while (i < count)
+			{
+				if (this.mBundleManagers[i] != null)
+				{
+					T t = this.mBundleManagers[i].LoadFromBundle(path, typeof(T)) as T;
+					if (t != null)
+					{
+						return t;
+					}
+				}
+				i++;
+			}
+			return (T)((object)null);
+		}
+
+		public void CleanResourceCache()
+		{
+			this.mResourcesCache.Clear();
+			Resources.UnloadUnusedAssets();
+			base.CancelInvoke();
+		}
+
+		private static ResourceManager mInstance;
+
+		public List<IResourceManager_Bundles> mBundleManagers = new List<IResourceManager_Bundles>();
+
+		public UnityEngine.Object[] Assets;
+
+		private readonly Dictionary<string, UnityEngine.Object> mResourcesCache = new Dictionary<string, UnityEngine.Object>(StringComparer.Ordinal);
+
+		[CompilerGenerated]
+		private static UnityAction<Scene, LoadSceneMode> <>f__mg$cache0;
+	}
+}

+ 24 - 0
Assembly-CSharp/I2/Loc/SetLanguage.cs

@@ -0,0 +1,24 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	[AddComponentMenu("I2/Localization/SetLanguage Button")]
+	public class SetLanguage : MonoBehaviour
+	{
+		private void OnClick()
+		{
+			this.ApplyLanguage();
+		}
+
+		public void ApplyLanguage()
+		{
+			if (LocalizationManager.HasLanguage(this._Language, true, true, true))
+			{
+				LocalizationManager.CurrentLanguage = this._Language;
+			}
+		}
+
+		public string _Language;
+	}
+}

+ 43 - 0
Assembly-CSharp/I2/Loc/SetLanguageDropdown.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Events;
+using UnityEngine.UI;
+
+namespace I2.Loc
+{
+	[AddComponentMenu("I2/Localization/SetLanguage Dropdown")]
+	public class SetLanguageDropdown : MonoBehaviour
+	{
+		private void OnEnable()
+		{
+			Dropdown component = base.GetComponent<Dropdown>();
+			if (component == null)
+			{
+				return;
+			}
+			string currentLanguage = LocalizationManager.CurrentLanguage;
+			if (LocalizationManager.Sources.Count == 0)
+			{
+				LocalizationManager.UpdateSources();
+			}
+			List<string> allLanguages = LocalizationManager.GetAllLanguages(true);
+			component.ClearOptions();
+			component.AddOptions(allLanguages);
+			component.value = allLanguages.IndexOf(currentLanguage);
+			component.onValueChanged.RemoveListener(new UnityAction<int>(this.OnValueChanged));
+			component.onValueChanged.AddListener(new UnityAction<int>(this.OnValueChanged));
+		}
+
+		private void OnValueChanged(int index)
+		{
+			Dropdown component = base.GetComponent<Dropdown>();
+			if (index < 0)
+			{
+				index = 0;
+				component.value = index;
+			}
+			LocalizationManager.CurrentLanguage = component.options[index].text;
+		}
+	}
+}

+ 12 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSON.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace I2.Loc.SimpleJSON
+{
+	public static class JSON
+	{
+		public static JSONNode Parse(string aJSON)
+		{
+			return JSONNode.Parse(aJSON);
+		}
+	}
+}

+ 139 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSONArray.cs

@@ -0,0 +1,139 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+
+namespace I2.Loc.SimpleJSON
+{
+	public class JSONArray : JSONNode, IEnumerable
+	{
+		public override JSONNode this[int aIndex]
+		{
+			get
+			{
+				if (aIndex < 0 || aIndex >= this.m_List.Count)
+				{
+					return new JSONLazyCreator(this);
+				}
+				return this.m_List[aIndex];
+			}
+			set
+			{
+				if (aIndex < 0 || aIndex >= this.m_List.Count)
+				{
+					this.m_List.Add(value);
+				}
+				else
+				{
+					this.m_List[aIndex] = value;
+				}
+			}
+		}
+
+		public override JSONNode this[string aKey]
+		{
+			get
+			{
+				return new JSONLazyCreator(this);
+			}
+			set
+			{
+				this.m_List.Add(value);
+			}
+		}
+
+		public override int Count
+		{
+			get
+			{
+				return this.m_List.Count;
+			}
+		}
+
+		public override void Add(string aKey, JSONNode aItem)
+		{
+			this.m_List.Add(aItem);
+		}
+
+		public override JSONNode Remove(int aIndex)
+		{
+			if (aIndex < 0 || aIndex >= this.m_List.Count)
+			{
+				return null;
+			}
+			JSONNode result = this.m_List[aIndex];
+			this.m_List.RemoveAt(aIndex);
+			return result;
+		}
+
+		public override JSONNode Remove(JSONNode aNode)
+		{
+			this.m_List.Remove(aNode);
+			return aNode;
+		}
+
+		public override IEnumerable<JSONNode> Childs
+		{
+			get
+			{
+				foreach (JSONNode N in this.m_List)
+				{
+					yield return N;
+				}
+				yield break;
+			}
+		}
+
+		public IEnumerator GetEnumerator()
+		{
+			foreach (JSONNode N in this.m_List)
+			{
+				yield return N;
+			}
+			yield break;
+		}
+
+		public override string ToString()
+		{
+			string text = "[ ";
+			foreach (JSONNode jsonnode in this.m_List)
+			{
+				if (text.Length > 2)
+				{
+					text += ", ";
+				}
+				text += jsonnode.ToString();
+			}
+			text += " ]";
+			return text;
+		}
+
+		public override string ToString(string aPrefix)
+		{
+			string text = "[ ";
+			foreach (JSONNode jsonnode in this.m_List)
+			{
+				if (text.Length > 3)
+				{
+					text += ", ";
+				}
+				text = text + "\n" + aPrefix + "   ";
+				text += jsonnode.ToString(aPrefix + "   ");
+			}
+			text = text + "\n" + aPrefix + "]";
+			return text;
+		}
+
+		public override void Serialize(BinaryWriter aWriter)
+		{
+			aWriter.Write(1);
+			aWriter.Write(this.m_List.Count);
+			for (int i = 0; i < this.m_List.Count; i++)
+			{
+				this.m_List[i].Serialize(aWriter);
+			}
+		}
+
+		private List<JSONNode> m_List = new List<JSONNode>();
+	}
+}

+ 15 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSONBinaryTag.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace I2.Loc.SimpleJSON
+{
+	public enum JSONBinaryTag
+	{
+		Array = 1,
+		Class,
+		Value,
+		IntValue,
+		DoubleValue,
+		BoolValue,
+		FloatValue
+	}
+}

+ 203 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSONClass.cs

@@ -0,0 +1,203 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace I2.Loc.SimpleJSON
+{
+	public class JSONClass : JSONNode, IEnumerable
+	{
+		public override JSONNode this[string aKey]
+		{
+			get
+			{
+				if (this.m_Dict.ContainsKey(aKey))
+				{
+					return this.m_Dict[aKey];
+				}
+				return new JSONLazyCreator(this, aKey);
+			}
+			set
+			{
+				if (this.m_Dict.ContainsKey(aKey))
+				{
+					this.m_Dict[aKey] = value;
+				}
+				else
+				{
+					this.m_Dict.Add(aKey, value);
+				}
+			}
+		}
+
+		public override JSONNode this[int aIndex]
+		{
+			get
+			{
+				if (aIndex < 0 || aIndex >= this.m_Dict.Count)
+				{
+					return null;
+				}
+				return this.m_Dict.ElementAt(aIndex).Value;
+			}
+			set
+			{
+				if (aIndex < 0 || aIndex >= this.m_Dict.Count)
+				{
+					return;
+				}
+				string key = this.m_Dict.ElementAt(aIndex).Key;
+				this.m_Dict[key] = value;
+			}
+		}
+
+		public override int Count
+		{
+			get
+			{
+				return this.m_Dict.Count;
+			}
+		}
+
+		public override void Add(string aKey, JSONNode aItem)
+		{
+			if (!string.IsNullOrEmpty(aKey))
+			{
+				if (this.m_Dict.ContainsKey(aKey))
+				{
+					this.m_Dict[aKey] = aItem;
+				}
+				else
+				{
+					this.m_Dict.Add(aKey, aItem);
+				}
+			}
+			else
+			{
+				this.m_Dict.Add(Guid.NewGuid().ToString(), aItem);
+			}
+		}
+
+		public override JSONNode Remove(string aKey)
+		{
+			if (!this.m_Dict.ContainsKey(aKey))
+			{
+				return null;
+			}
+			JSONNode result = this.m_Dict[aKey];
+			this.m_Dict.Remove(aKey);
+			return result;
+		}
+
+		public override JSONNode Remove(int aIndex)
+		{
+			if (aIndex < 0 || aIndex >= this.m_Dict.Count)
+			{
+				return null;
+			}
+			KeyValuePair<string, JSONNode> keyValuePair = this.m_Dict.ElementAt(aIndex);
+			this.m_Dict.Remove(keyValuePair.Key);
+			return keyValuePair.Value;
+		}
+
+		public override JSONNode Remove(JSONNode aNode)
+		{
+			JSONNode result;
+			try
+			{
+				KeyValuePair<string, JSONNode> keyValuePair = (from k in this.m_Dict
+				where k.Value == aNode
+				select k).First<KeyValuePair<string, JSONNode>>();
+				this.m_Dict.Remove(keyValuePair.Key);
+				result = aNode;
+			}
+			catch
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public override IEnumerable<JSONNode> Childs
+		{
+			get
+			{
+				foreach (KeyValuePair<string, JSONNode> N in this.m_Dict)
+				{
+					yield return N.Value;
+				}
+				yield break;
+			}
+		}
+
+		public IEnumerator GetEnumerator()
+		{
+			foreach (KeyValuePair<string, JSONNode> N in this.m_Dict)
+			{
+				yield return N;
+			}
+			yield break;
+		}
+
+		public override string ToString()
+		{
+			string text = "{";
+			foreach (KeyValuePair<string, JSONNode> keyValuePair in this.m_Dict)
+			{
+				if (text.Length > 2)
+				{
+					text += ", ";
+				}
+				string text2 = text;
+				text = string.Concat(new string[]
+				{
+					text2,
+					"\"",
+					JSONNode.Escape(keyValuePair.Key),
+					"\":",
+					keyValuePair.Value.ToString()
+				});
+			}
+			text += "}";
+			return text;
+		}
+
+		public override string ToString(string aPrefix)
+		{
+			string text = "{ ";
+			foreach (KeyValuePair<string, JSONNode> keyValuePair in this.m_Dict)
+			{
+				if (text.Length > 3)
+				{
+					text += ", ";
+				}
+				text = text + "\n" + aPrefix + "   ";
+				string text2 = text;
+				text = string.Concat(new string[]
+				{
+					text2,
+					"\"",
+					JSONNode.Escape(keyValuePair.Key),
+					"\" : ",
+					keyValuePair.Value.ToString(aPrefix + "   ")
+				});
+			}
+			text = text + "\n" + aPrefix + "}";
+			return text;
+		}
+
+		public override void Serialize(BinaryWriter aWriter)
+		{
+			aWriter.Write(2);
+			aWriter.Write(this.m_Dict.Count);
+			foreach (string text in this.m_Dict.Keys)
+			{
+				aWriter.Write(text);
+				this.m_Dict[text].Serialize(aWriter);
+			}
+		}
+
+		private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>(StringComparer.Ordinal);
+	}
+}

+ 92 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSONData.cs

@@ -0,0 +1,92 @@
+using System;
+using System.IO;
+
+namespace I2.Loc.SimpleJSON
+{
+	public class JSONData : JSONNode
+	{
+		public JSONData(string aData)
+		{
+			this.m_Data = aData;
+		}
+
+		public JSONData(float aData)
+		{
+			this.AsFloat = aData;
+		}
+
+		public JSONData(double aData)
+		{
+			this.AsDouble = aData;
+		}
+
+		public JSONData(bool aData)
+		{
+			this.AsBool = aData;
+		}
+
+		public JSONData(int aData)
+		{
+			this.AsInt = aData;
+		}
+
+		public override string Value
+		{
+			get
+			{
+				return this.m_Data;
+			}
+			set
+			{
+				this.m_Data = value;
+			}
+		}
+
+		public override string ToString()
+		{
+			return "\"" + JSONNode.Escape(this.m_Data) + "\"";
+		}
+
+		public override string ToString(string aPrefix)
+		{
+			return "\"" + JSONNode.Escape(this.m_Data) + "\"";
+		}
+
+		public override void Serialize(BinaryWriter aWriter)
+		{
+			JSONData jsondata = new JSONData(string.Empty);
+			jsondata.AsInt = this.AsInt;
+			if (jsondata.m_Data == this.m_Data)
+			{
+				aWriter.Write(4);
+				aWriter.Write(this.AsInt);
+				return;
+			}
+			jsondata.AsFloat = this.AsFloat;
+			if (jsondata.m_Data == this.m_Data)
+			{
+				aWriter.Write(7);
+				aWriter.Write(this.AsFloat);
+				return;
+			}
+			jsondata.AsDouble = this.AsDouble;
+			if (jsondata.m_Data == this.m_Data)
+			{
+				aWriter.Write(5);
+				aWriter.Write(this.AsDouble);
+				return;
+			}
+			jsondata.AsBool = this.AsBool;
+			if (jsondata.m_Data == this.m_Data)
+			{
+				aWriter.Write(6);
+				aWriter.Write(this.AsBool);
+				return;
+			}
+			aWriter.Write(3);
+			aWriter.Write(this.m_Data);
+		}
+
+		private string m_Data;
+	}
+}

+ 198 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSONLazyCreator.cs

@@ -0,0 +1,198 @@
+using System;
+
+namespace I2.Loc.SimpleJSON
+{
+	internal class JSONLazyCreator : JSONNode
+	{
+		public JSONLazyCreator(JSONNode aNode)
+		{
+			this.m_Node = aNode;
+			this.m_Key = null;
+		}
+
+		public JSONLazyCreator(JSONNode aNode, string aKey)
+		{
+			this.m_Node = aNode;
+			this.m_Key = aKey;
+		}
+
+		private void Set(JSONNode aVal)
+		{
+			if (this.m_Key == null)
+			{
+				this.m_Node.Add(aVal);
+			}
+			else
+			{
+				this.m_Node.Add(this.m_Key, aVal);
+			}
+			this.m_Node = null;
+		}
+
+		public override JSONNode this[int aIndex]
+		{
+			get
+			{
+				return new JSONLazyCreator(this);
+			}
+			set
+			{
+				this.Set(new JSONArray
+				{
+					value
+				});
+			}
+		}
+
+		public override JSONNode this[string aKey]
+		{
+			get
+			{
+				return new JSONLazyCreator(this, aKey);
+			}
+			set
+			{
+				this.Set(new JSONClass
+				{
+					{
+						aKey,
+						value
+					}
+				});
+			}
+		}
+
+		public override void Add(JSONNode aItem)
+		{
+			this.Set(new JSONArray
+			{
+				aItem
+			});
+		}
+
+		public override void Add(string aKey, JSONNode aItem)
+		{
+			this.Set(new JSONClass
+			{
+				{
+					aKey,
+					aItem
+				}
+			});
+		}
+
+		public static bool operator ==(JSONLazyCreator a, object b)
+		{
+			return b == null || object.ReferenceEquals(a, b);
+		}
+
+		public static bool operator !=(JSONLazyCreator a, object b)
+		{
+			return !(a == b);
+		}
+
+		public override bool Equals(object obj)
+		{
+			return obj == null || object.ReferenceEquals(this, obj);
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+
+		public override string ToString()
+		{
+			return string.Empty;
+		}
+
+		public override string ToString(string aPrefix)
+		{
+			return string.Empty;
+		}
+
+		public override int AsInt
+		{
+			get
+			{
+				JSONData aVal = new JSONData(0);
+				this.Set(aVal);
+				return 0;
+			}
+			set
+			{
+				JSONData aVal = new JSONData(value);
+				this.Set(aVal);
+			}
+		}
+
+		public override float AsFloat
+		{
+			get
+			{
+				JSONData aVal = new JSONData(0f);
+				this.Set(aVal);
+				return 0f;
+			}
+			set
+			{
+				JSONData aVal = new JSONData(value);
+				this.Set(aVal);
+			}
+		}
+
+		public override double AsDouble
+		{
+			get
+			{
+				JSONData aVal = new JSONData(0.0);
+				this.Set(aVal);
+				return 0.0;
+			}
+			set
+			{
+				JSONData aVal = new JSONData(value);
+				this.Set(aVal);
+			}
+		}
+
+		public override bool AsBool
+		{
+			get
+			{
+				JSONData aVal = new JSONData(false);
+				this.Set(aVal);
+				return false;
+			}
+			set
+			{
+				JSONData aVal = new JSONData(value);
+				this.Set(aVal);
+			}
+		}
+
+		public override JSONArray AsArray
+		{
+			get
+			{
+				JSONArray jsonarray = new JSONArray();
+				this.Set(jsonarray);
+				return jsonarray;
+			}
+		}
+
+		public override JSONClass AsObject
+		{
+			get
+			{
+				JSONClass jsonclass = new JSONClass();
+				this.Set(jsonclass);
+				return jsonclass;
+			}
+		}
+
+		private JSONNode m_Node;
+
+		private string m_Key;
+	}
+}

+ 621 - 0
Assembly-CSharp/I2/Loc/SimpleJSON/JSONNode.cs

@@ -0,0 +1,621 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+
+namespace I2.Loc.SimpleJSON
+{
+	public class JSONNode
+	{
+		public virtual void Add(string aKey, JSONNode aItem)
+		{
+		}
+
+		public virtual JSONNode this[int aIndex]
+		{
+			get
+			{
+				return null;
+			}
+			set
+			{
+			}
+		}
+
+		public virtual JSONNode this[string aKey]
+		{
+			get
+			{
+				return null;
+			}
+			set
+			{
+			}
+		}
+
+		public virtual string Value
+		{
+			get
+			{
+				return string.Empty;
+			}
+			set
+			{
+			}
+		}
+
+		public virtual int Count
+		{
+			get
+			{
+				return 0;
+			}
+		}
+
+		public virtual void Add(JSONNode aItem)
+		{
+			this.Add(string.Empty, aItem);
+		}
+
+		public virtual JSONNode Remove(string aKey)
+		{
+			return null;
+		}
+
+		public virtual JSONNode Remove(int aIndex)
+		{
+			return null;
+		}
+
+		public virtual JSONNode Remove(JSONNode aNode)
+		{
+			return aNode;
+		}
+
+		public virtual IEnumerable<JSONNode> Childs
+		{
+			get
+			{
+				yield break;
+			}
+		}
+
+		public IEnumerable<JSONNode> DeepChilds
+		{
+			get
+			{
+				foreach (JSONNode C in this.Childs)
+				{
+					foreach (JSONNode D in C.DeepChilds)
+					{
+						yield return D;
+					}
+				}
+				yield break;
+			}
+		}
+
+		public override string ToString()
+		{
+			return "JSONNode";
+		}
+
+		public virtual string ToString(string aPrefix)
+		{
+			return "JSONNode";
+		}
+
+		public virtual int AsInt
+		{
+			get
+			{
+				int result = 0;
+				if (int.TryParse(this.Value, out result))
+				{
+					return result;
+				}
+				return 0;
+			}
+			set
+			{
+				this.Value = value.ToString();
+			}
+		}
+
+		public virtual float AsFloat
+		{
+			get
+			{
+				float result = 0f;
+				if (float.TryParse(this.Value, out result))
+				{
+					return result;
+				}
+				return 0f;
+			}
+			set
+			{
+				this.Value = value.ToString();
+			}
+		}
+
+		public virtual double AsDouble
+		{
+			get
+			{
+				double result = 0.0;
+				if (double.TryParse(this.Value, out result))
+				{
+					return result;
+				}
+				return 0.0;
+			}
+			set
+			{
+				this.Value = value.ToString();
+			}
+		}
+
+		public virtual bool AsBool
+		{
+			get
+			{
+				bool result = false;
+				if (bool.TryParse(this.Value, out result))
+				{
+					return result;
+				}
+				return !string.IsNullOrEmpty(this.Value);
+			}
+			set
+			{
+				this.Value = ((!value) ? "false" : "true");
+			}
+		}
+
+		public virtual JSONArray AsArray
+		{
+			get
+			{
+				return this as JSONArray;
+			}
+		}
+
+		public virtual JSONClass AsObject
+		{
+			get
+			{
+				return this as JSONClass;
+			}
+		}
+
+		public static implicit operator JSONNode(string s)
+		{
+			return new JSONData(s);
+		}
+
+		public static implicit operator string(JSONNode d)
+		{
+			return (!(d == null)) ? d.Value : null;
+		}
+
+		public static bool operator ==(JSONNode a, object b)
+		{
+			return (b == null && a is JSONLazyCreator) || object.ReferenceEquals(a, b);
+		}
+
+		public static bool operator !=(JSONNode a, object b)
+		{
+			return !(a == b);
+		}
+
+		public override bool Equals(object obj)
+		{
+			return object.ReferenceEquals(this, obj);
+		}
+
+		public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+
+		internal static string Escape(string aText)
+		{
+			string text = string.Empty;
+			foreach (char c in aText)
+			{
+				switch (c)
+				{
+				case '\b':
+					text += "\\b";
+					break;
+				case '\t':
+					text += "\\t";
+					break;
+				case '\n':
+					text += "\\n";
+					break;
+				default:
+					if (c != '"')
+					{
+						if (c != '\\')
+						{
+							text += c;
+						}
+						else
+						{
+							text += "\\\\";
+						}
+					}
+					else
+					{
+						text += "\\\"";
+					}
+					break;
+				case '\f':
+					text += "\\f";
+					break;
+				case '\r':
+					text += "\\r";
+					break;
+				}
+			}
+			return text;
+		}
+
+		public static JSONNode Parse(string aJSON)
+		{
+			Stack<JSONNode> stack = new Stack<JSONNode>();
+			JSONNode jsonnode = null;
+			int i = 0;
+			string text = string.Empty;
+			string text2 = string.Empty;
+			bool flag = false;
+			while (i < aJSON.Length)
+			{
+				char c = aJSON[i];
+				switch (c)
+				{
+				case '\t':
+					goto IL_333;
+				case '\n':
+				case '\r':
+					break;
+				default:
+					switch (c)
+					{
+					case '[':
+						if (flag)
+						{
+							text += aJSON[i];
+							goto IL_45C;
+						}
+						stack.Push(new JSONArray());
+						if (jsonnode != null)
+						{
+							text2 = text2.Trim();
+							if (jsonnode is JSONArray)
+							{
+								jsonnode.Add(stack.Peek());
+							}
+							else if (text2 != string.Empty)
+							{
+								jsonnode.Add(text2, stack.Peek());
+							}
+						}
+						text2 = string.Empty;
+						text = string.Empty;
+						jsonnode = stack.Peek();
+						goto IL_45C;
+					case '\\':
+						i++;
+						if (flag)
+						{
+							char c2 = aJSON[i];
+							switch (c2)
+							{
+							case 'r':
+								text += '\r';
+								break;
+							default:
+								if (c2 != 'b')
+								{
+									if (c2 != 'f')
+									{
+										if (c2 != 'n')
+										{
+											text += c2;
+										}
+										else
+										{
+											text += '\n';
+										}
+									}
+									else
+									{
+										text += '\f';
+									}
+								}
+								else
+								{
+									text += '\b';
+								}
+								break;
+							case 't':
+								text += '\t';
+								break;
+							case 'u':
+							{
+								string s = aJSON.Substring(i + 1, 4);
+								text += (char)int.Parse(s, NumberStyles.AllowHexSpecifier);
+								i += 4;
+								break;
+							}
+							}
+						}
+						goto IL_45C;
+					case ']':
+						break;
+					default:
+						switch (c)
+						{
+						case ' ':
+							goto IL_333;
+						default:
+							switch (c)
+							{
+							case '{':
+								if (flag)
+								{
+									text += aJSON[i];
+									goto IL_45C;
+								}
+								stack.Push(new JSONClass());
+								if (jsonnode != null)
+								{
+									text2 = text2.Trim();
+									if (jsonnode is JSONArray)
+									{
+										jsonnode.Add(stack.Peek());
+									}
+									else if (text2 != string.Empty)
+									{
+										jsonnode.Add(text2, stack.Peek());
+									}
+								}
+								text2 = string.Empty;
+								text = string.Empty;
+								jsonnode = stack.Peek();
+								goto IL_45C;
+							default:
+								if (c != ',')
+								{
+									if (c != ':')
+									{
+										text += aJSON[i];
+										goto IL_45C;
+									}
+									if (flag)
+									{
+										text += aJSON[i];
+										goto IL_45C;
+									}
+									text2 = text;
+									text = string.Empty;
+									goto IL_45C;
+								}
+								else
+								{
+									if (flag)
+									{
+										text += aJSON[i];
+										goto IL_45C;
+									}
+									if (text != string.Empty)
+									{
+										if (jsonnode is JSONArray)
+										{
+											jsonnode.Add(text);
+										}
+										else if (text2 != string.Empty)
+										{
+											jsonnode.Add(text2, text);
+										}
+									}
+									text2 = string.Empty;
+									text = string.Empty;
+									goto IL_45C;
+								}
+								break;
+							case '}':
+								break;
+							}
+							break;
+						case '"':
+							flag ^= true;
+							goto IL_45C;
+						}
+						break;
+					}
+					if (flag)
+					{
+						text += aJSON[i];
+					}
+					else
+					{
+						if (stack.Count == 0)
+						{
+							throw new Exception("JSON Parse: Too many closing brackets");
+						}
+						stack.Pop();
+						if (text != string.Empty)
+						{
+							text2 = text2.Trim();
+							if (jsonnode is JSONArray)
+							{
+								jsonnode.Add(text);
+							}
+							else if (text2 != string.Empty)
+							{
+								jsonnode.Add(text2, text);
+							}
+						}
+						text2 = string.Empty;
+						text = string.Empty;
+						if (stack.Count > 0)
+						{
+							jsonnode = stack.Peek();
+						}
+					}
+					break;
+				}
+				IL_45C:
+				i++;
+				continue;
+				IL_333:
+				if (flag)
+				{
+					text += aJSON[i];
+				}
+				goto IL_45C;
+			}
+			if (flag)
+			{
+				throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
+			}
+			return jsonnode;
+		}
+
+		public virtual void Serialize(BinaryWriter aWriter)
+		{
+		}
+
+		public void SaveToStream(Stream aData)
+		{
+			BinaryWriter aWriter = new BinaryWriter(aData);
+			this.Serialize(aWriter);
+		}
+
+		public void SaveToCompressedStream(Stream aData)
+		{
+			throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
+		}
+
+		public void SaveToCompressedFile(string aFileName)
+		{
+			throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
+		}
+
+		public string SaveToCompressedBase64()
+		{
+			throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
+		}
+
+		public void SaveToFile(string aFileName)
+		{
+			Directory.CreateDirectory(new FileInfo(aFileName).Directory.FullName);
+			using (FileStream fileStream = File.OpenWrite(aFileName))
+			{
+				this.SaveToStream(fileStream);
+			}
+		}
+
+		public string SaveToBase64()
+		{
+			string result;
+			using (MemoryStream memoryStream = new MemoryStream())
+			{
+				this.SaveToStream(memoryStream);
+				memoryStream.Position = 0L;
+				result = Convert.ToBase64String(memoryStream.ToArray());
+			}
+			return result;
+		}
+
+		public static JSONNode Deserialize(BinaryReader aReader)
+		{
+			JSONBinaryTag jsonbinaryTag = (JSONBinaryTag)aReader.ReadByte();
+			switch (jsonbinaryTag)
+			{
+			case JSONBinaryTag.Array:
+			{
+				int num = aReader.ReadInt32();
+				JSONArray jsonarray = new JSONArray();
+				for (int i = 0; i < num; i++)
+				{
+					jsonarray.Add(JSONNode.Deserialize(aReader));
+				}
+				return jsonarray;
+			}
+			case JSONBinaryTag.Class:
+			{
+				int num2 = aReader.ReadInt32();
+				JSONClass jsonclass = new JSONClass();
+				for (int j = 0; j < num2; j++)
+				{
+					string aKey = aReader.ReadString();
+					JSONNode aItem = JSONNode.Deserialize(aReader);
+					jsonclass.Add(aKey, aItem);
+				}
+				return jsonclass;
+			}
+			case JSONBinaryTag.Value:
+				return new JSONData(aReader.ReadString());
+			case JSONBinaryTag.IntValue:
+				return new JSONData(aReader.ReadInt32());
+			case JSONBinaryTag.DoubleValue:
+				return new JSONData(aReader.ReadDouble());
+			case JSONBinaryTag.BoolValue:
+				return new JSONData(aReader.ReadBoolean());
+			case JSONBinaryTag.FloatValue:
+				return new JSONData(aReader.ReadSingle());
+			default:
+				throw new Exception("Error deserializing JSON. Unknown tag: " + jsonbinaryTag);
+			}
+		}
+
+		public static JSONNode LoadFromCompressedFile(string aFileName)
+		{
+			throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
+		}
+
+		public static JSONNode LoadFromCompressedStream(Stream aData)
+		{
+			throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
+		}
+
+		public static JSONNode LoadFromCompressedBase64(string aBase64)
+		{
+			throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
+		}
+
+		public static JSONNode LoadFromStream(Stream aData)
+		{
+			JSONNode result;
+			using (BinaryReader binaryReader = new BinaryReader(aData))
+			{
+				result = JSONNode.Deserialize(binaryReader);
+			}
+			return result;
+		}
+
+		public static JSONNode LoadFromFile(string aFileName)
+		{
+			JSONNode result;
+			using (FileStream fileStream = File.OpenRead(aFileName))
+			{
+				result = JSONNode.LoadFromStream(fileStream);
+			}
+			return result;
+		}
+
+		public static JSONNode LoadFromBase64(string aBase64)
+		{
+			byte[] buffer = Convert.FromBase64String(aBase64);
+			return JSONNode.LoadFromStream(new MemoryStream(buffer)
+			{
+				Position = 0L
+			});
+		}
+	}
+}

+ 163 - 0
Assembly-CSharp/I2/Loc/SpecializationManager.cs

@@ -0,0 +1,163 @@
+using System;
+using System.Collections.Generic;
+
+namespace I2.Loc
+{
+	public class SpecializationManager : BaseSpecializationManager
+	{
+		private SpecializationManager()
+		{
+			this.InitializeSpecializations();
+		}
+
+		public static string GetSpecializedText(string text, string specialization = null)
+		{
+			int num = text.IndexOf("[i2s_");
+			if (num < 0)
+			{
+				return text;
+			}
+			if (string.IsNullOrEmpty(specialization))
+			{
+				specialization = SpecializationManager.Singleton.GetCurrentSpecialization();
+			}
+			while (!string.IsNullOrEmpty(specialization) && specialization != "Any")
+			{
+				string text2 = "[i2s_" + specialization + "]";
+				int num2 = text.IndexOf(text2);
+				if (num2 >= 0)
+				{
+					num2 += text2.Length;
+					int num3 = text.IndexOf("[i2s_", num2);
+					if (num3 < 0)
+					{
+						num3 = text.Length;
+					}
+					return text.Substring(num2, num3 - num2);
+				}
+				specialization = SpecializationManager.Singleton.GetFallbackSpecialization(specialization);
+			}
+			return text.Substring(0, num);
+		}
+
+		public static string SetSpecializedText(string text, string newText, string specialization)
+		{
+			if (string.IsNullOrEmpty(specialization))
+			{
+				specialization = "Any";
+			}
+			if ((text == null || !text.Contains("[i2s_")) && specialization == "Any")
+			{
+				return newText;
+			}
+			Dictionary<string, string> specializations = SpecializationManager.GetSpecializations(text, null);
+			specializations[specialization] = newText;
+			return SpecializationManager.SetSpecializedText(specializations);
+		}
+
+		public static string SetSpecializedText(Dictionary<string, string> specializations)
+		{
+			string text;
+			if (!specializations.TryGetValue("Any", out text))
+			{
+				text = string.Empty;
+			}
+			foreach (KeyValuePair<string, string> keyValuePair in specializations)
+			{
+				if (keyValuePair.Key != "Any" && !string.IsNullOrEmpty(keyValuePair.Value))
+				{
+					string text2 = text;
+					text = string.Concat(new string[]
+					{
+						text2,
+						"[i2s_",
+						keyValuePair.Key,
+						"]",
+						keyValuePair.Value
+					});
+				}
+			}
+			return text;
+		}
+
+		public static Dictionary<string, string> GetSpecializations(string text, Dictionary<string, string> buffer = null)
+		{
+			if (buffer == null)
+			{
+				buffer = new Dictionary<string, string>();
+			}
+			else
+			{
+				buffer.Clear();
+			}
+			if (text == null)
+			{
+				buffer["Any"] = string.Empty;
+				return buffer;
+			}
+			int num = text.IndexOf("[i2s_");
+			if (num < 0)
+			{
+				num = text.Length;
+			}
+			buffer["Any"] = text.Substring(0, num);
+			for (int i = num; i < text.Length; i = num)
+			{
+				i += "[i2s_".Length;
+				int num2 = text.IndexOf(']', i);
+				if (num2 < 0)
+				{
+					break;
+				}
+				string key = text.Substring(i, num2 - i);
+				i = num2 + 1;
+				num = text.IndexOf("[i2s_", i);
+				if (num < 0)
+				{
+					num = text.Length;
+				}
+				string value = text.Substring(i, num - i);
+				buffer[key] = value;
+			}
+			return buffer;
+		}
+
+		public static void AppendSpecializations(string text, List<string> list = null)
+		{
+			if (text == null)
+			{
+				return;
+			}
+			if (list == null)
+			{
+				list = new List<string>();
+			}
+			if (!list.Contains("Any"))
+			{
+				list.Add("Any");
+			}
+			int i = 0;
+			while (i < text.Length)
+			{
+				i = text.IndexOf("[i2s_", i);
+				if (i < 0)
+				{
+					break;
+				}
+				i += "[i2s_".Length;
+				int num = text.IndexOf(']', i);
+				if (num < 0)
+				{
+					break;
+				}
+				string item = text.Substring(i, num - i);
+				if (!list.Contains(item))
+				{
+					list.Add(item);
+				}
+			}
+		}
+
+		public static SpecializationManager Singleton = new SpecializationManager();
+	}
+}

File diff suppressed because it is too large
+ 76 - 0
Assembly-CSharp/I2/Loc/StringObfucator.cs


+ 17 - 0
Assembly-CSharp/I2/Loc/TashkeelLocation.cs

@@ -0,0 +1,17 @@
+using System;
+
+namespace I2.Loc
+{
+	internal class TashkeelLocation
+	{
+		public TashkeelLocation(char tashkeel, int position)
+		{
+			this.tashkeel = tashkeel;
+			this.position = position;
+		}
+
+		public char tashkeel;
+
+		public int position;
+	}
+}

+ 120 - 0
Assembly-CSharp/I2/Loc/TermData.cs

@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	[Serializable]
+	public class TermData
+	{
+		public string GetTranslation(int idx, string specialization = null)
+		{
+			string text = this.Languages[idx];
+			if (text != null)
+			{
+				text = SpecializationManager.GetSpecializedText(text, specialization);
+				text = text.Replace("[i2nt]", string.Empty).Replace("[/i2nt]", string.Empty);
+			}
+			return text;
+		}
+
+		public void SetTranslation(int idx, string translation, string specialization = null)
+		{
+			this.Languages[idx] = SpecializationManager.SetSpecializedText(this.Languages[idx], translation, specialization);
+		}
+
+		public void RemoveSpecialization(string specialization)
+		{
+			for (int i = 0; i < this.Languages.Length; i++)
+			{
+				this.RemoveSpecialization(i, specialization);
+			}
+		}
+
+		public void RemoveSpecialization(int idx, string specialization)
+		{
+			string text = this.Languages[idx];
+			if (specialization == "Any" || !text.Contains("[i2s_" + specialization + "]"))
+			{
+				return;
+			}
+			Dictionary<string, string> specializations = SpecializationManager.GetSpecializations(text, null);
+			specializations.Remove(specialization);
+			this.Languages[idx] = SpecializationManager.SetSpecializedText(specializations);
+		}
+
+		public bool IsAutoTranslated(int idx, bool IsTouch)
+		{
+			return (this.Flags[idx] & 2) > 0;
+		}
+
+		public void Validate()
+		{
+			int num = Mathf.Max(this.Languages.Length, this.Flags.Length);
+			if (this.Languages.Length != num)
+			{
+				Array.Resize<string>(ref this.Languages, num);
+			}
+			if (this.Flags.Length != num)
+			{
+				Array.Resize<byte>(ref this.Flags, num);
+			}
+			if (this.Languages_Touch != null)
+			{
+				for (int i = 0; i < Mathf.Min(this.Languages_Touch.Length, num); i++)
+				{
+					if (string.IsNullOrEmpty(this.Languages[i]) && !string.IsNullOrEmpty(this.Languages_Touch[i]))
+					{
+						this.Languages[i] = this.Languages_Touch[i];
+						this.Languages_Touch[i] = null;
+					}
+				}
+				this.Languages_Touch = null;
+			}
+		}
+
+		public bool IsTerm(string name, bool allowCategoryMistmatch)
+		{
+			if (!allowCategoryMistmatch)
+			{
+				return name == this.Term;
+			}
+			return name == LanguageSource.GetKeyFromFullTerm(this.Term, false);
+		}
+
+		public bool HasSpecializations()
+		{
+			for (int i = 0; i < this.Languages.Length; i++)
+			{
+				if (!string.IsNullOrEmpty(this.Languages[i]) && this.Languages[i].Contains("[i2s_"))
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public List<string> GetAllSpecializations()
+		{
+			List<string> list = new List<string>();
+			for (int i = 0; i < this.Languages.Length; i++)
+			{
+				SpecializationManager.AppendSpecializations(this.Languages[i], list);
+			}
+			return list;
+		}
+
+		public string Term = string.Empty;
+
+		public eTermType TermType;
+
+		public string Description;
+
+		public string[] Languages = new string[0];
+
+		public byte[] Flags = new byte[0];
+
+		[SerializeField]
+		private string[] Languages_Touch;
+	}
+}

+ 15 - 0
Assembly-CSharp/I2/Loc/TermsPopup.cs

@@ -0,0 +1,15 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class TermsPopup : PropertyAttribute
+	{
+		public TermsPopup(string filter = "")
+		{
+			this.Filter = filter;
+		}
+
+		public string Filter { get; private set; }
+	}
+}

+ 25 - 0
Assembly-CSharp/I2/Loc/ToggleLanguage.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class ToggleLanguage : MonoBehaviour
+	{
+		private void Start()
+		{
+			base.Invoke("test", 3f);
+		}
+
+		private void test()
+		{
+			List<string> allLanguages = LocalizationManager.GetAllLanguages(true);
+			int num = allLanguages.IndexOf(LocalizationManager.CurrentLanguage);
+			if (num >= 0)
+			{
+				num = (num + 1) % allLanguages.Count;
+			}
+			base.Invoke("test", 3f);
+		}
+	}
+}

+ 10 - 0
Assembly-CSharp/I2/Loc/TranslationFlag.cs

@@ -0,0 +1,10 @@
+using System;
+
+namespace I2.Loc
+{
+	public enum TranslationFlag : byte
+	{
+		Normal = 1,
+		AutoTranslated
+	}
+}

+ 25 - 0
Assembly-CSharp/I2/Loc/TranslationJob.cs

@@ -0,0 +1,25 @@
+using System;
+
+namespace I2.Loc
+{
+	public class TranslationJob : IDisposable
+	{
+		public virtual TranslationJob.eJobState GetState()
+		{
+			return this.mJobState;
+		}
+
+		public virtual void Dispose()
+		{
+		}
+
+		public TranslationJob.eJobState mJobState;
+
+		public enum eJobState
+		{
+			Running,
+			Succeeded,
+			Failed
+		}
+	}
+}

+ 74 - 0
Assembly-CSharp/I2/Loc/TranslationJob_GET.cs

@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class TranslationJob_GET : TranslationJob_WWW
+	{
+		public TranslationJob_GET(Dictionary<string, TranslationQuery> requests, Action<Dictionary<string, TranslationQuery>, string> OnTranslationReady)
+		{
+			this._requests = requests;
+			this._OnTranslationReady = OnTranslationReady;
+			this.mQueries = GoogleTranslation.ConvertTranslationRequest(requests, true);
+			this.GetState();
+		}
+
+		private void ExecuteNextQuery()
+		{
+			if (this.mQueries.Count == 0)
+			{
+				this.mJobState = TranslationJob.eJobState.Succeeded;
+				return;
+			}
+			int index = this.mQueries.Count - 1;
+			string arg = this.mQueries[index];
+			this.mQueries.RemoveAt(index);
+			string url = string.Format("{0}?action=Translate&list={1}", LocalizationManager.GetWebServiceURL(null), arg);
+			this.www = new WWW(url);
+		}
+
+		public override TranslationJob.eJobState GetState()
+		{
+			if (this.www != null && this.www.isDone)
+			{
+				this.ProcessResult(this.www.bytes, this.www.error);
+				this.www.Dispose();
+				this.www = null;
+			}
+			if (this.www == null)
+			{
+				this.ExecuteNextQuery();
+			}
+			return this.mJobState;
+		}
+
+		public void ProcessResult(byte[] bytes, string errorMsg)
+		{
+			if (string.IsNullOrEmpty(errorMsg))
+			{
+				string @string = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+				errorMsg = GoogleTranslation.ParseTranslationResult(@string, this._requests);
+				if (string.IsNullOrEmpty(errorMsg))
+				{
+					if (this._OnTranslationReady != null)
+					{
+						this._OnTranslationReady(this._requests, null);
+					}
+					return;
+				}
+			}
+			this.mJobState = TranslationJob.eJobState.Failed;
+			this.mErrorMessage = errorMsg;
+		}
+
+		private Dictionary<string, TranslationQuery> _requests;
+
+		private Action<Dictionary<string, TranslationQuery>, string> _OnTranslationReady;
+
+		private List<string> mQueries;
+
+		public string mErrorMessage;
+	}
+}

+ 113 - 0
Assembly-CSharp/I2/Loc/TranslationJob_Main.cs

@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+
+namespace I2.Loc
+{
+	public class TranslationJob_Main : TranslationJob
+	{
+		public TranslationJob_Main(Dictionary<string, TranslationQuery> requests, Action<Dictionary<string, TranslationQuery>, string> OnTranslationReady)
+		{
+			this._requests = requests;
+			this._OnTranslationReady = OnTranslationReady;
+			this.mPost = new TranslationJob_POST(requests, OnTranslationReady);
+		}
+
+		public override TranslationJob.eJobState GetState()
+		{
+			if (this.mWeb != null)
+			{
+				TranslationJob.eJobState state = this.mWeb.GetState();
+				if (state == TranslationJob.eJobState.Running)
+				{
+					return TranslationJob.eJobState.Running;
+				}
+				if (state != TranslationJob.eJobState.Succeeded)
+				{
+					if (state == TranslationJob.eJobState.Failed)
+					{
+						this.mWeb.Dispose();
+						this.mWeb = null;
+						this.mPost = new TranslationJob_POST(this._requests, this._OnTranslationReady);
+					}
+				}
+				else
+				{
+					this.mJobState = TranslationJob.eJobState.Succeeded;
+				}
+			}
+			if (this.mPost != null)
+			{
+				TranslationJob.eJobState state2 = this.mPost.GetState();
+				if (state2 == TranslationJob.eJobState.Running)
+				{
+					return TranslationJob.eJobState.Running;
+				}
+				if (state2 != TranslationJob.eJobState.Succeeded)
+				{
+					if (state2 == TranslationJob.eJobState.Failed)
+					{
+						this.mPost.Dispose();
+						this.mPost = null;
+						this.mGet = new TranslationJob_GET(this._requests, this._OnTranslationReady);
+					}
+				}
+				else
+				{
+					this.mJobState = TranslationJob.eJobState.Succeeded;
+				}
+			}
+			if (this.mGet != null)
+			{
+				TranslationJob.eJobState state3 = this.mGet.GetState();
+				if (state3 == TranslationJob.eJobState.Running)
+				{
+					return TranslationJob.eJobState.Running;
+				}
+				if (state3 != TranslationJob.eJobState.Succeeded)
+				{
+					if (state3 == TranslationJob.eJobState.Failed)
+					{
+						this.mErrorMessage = this.mGet.mErrorMessage;
+						if (this._OnTranslationReady != null)
+						{
+							this._OnTranslationReady(this._requests, this.mErrorMessage);
+						}
+						this.mGet.Dispose();
+						this.mGet = null;
+					}
+				}
+				else
+				{
+					this.mJobState = TranslationJob.eJobState.Succeeded;
+				}
+			}
+			return this.mJobState;
+		}
+
+		public override void Dispose()
+		{
+			if (this.mPost != null)
+			{
+				this.mPost.Dispose();
+			}
+			if (this.mGet != null)
+			{
+				this.mGet.Dispose();
+			}
+			this.mPost = null;
+			this.mGet = null;
+		}
+
+		private TranslationJob_WEB mWeb;
+
+		private TranslationJob_POST mPost;
+
+		private TranslationJob_GET mGet;
+
+		private Dictionary<string, TranslationQuery> _requests;
+
+		private Action<Dictionary<string, TranslationQuery>, string> _OnTranslationReady;
+
+		public string mErrorMessage;
+	}
+}

+ 54 - 0
Assembly-CSharp/I2/Loc/TranslationJob_POST.cs

@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class TranslationJob_POST : TranslationJob_WWW
+	{
+		public TranslationJob_POST(Dictionary<string, TranslationQuery> requests, Action<Dictionary<string, TranslationQuery>, string> OnTranslationReady)
+		{
+			this._requests = requests;
+			this._OnTranslationReady = OnTranslationReady;
+			List<string> list = GoogleTranslation.ConvertTranslationRequest(requests, false);
+			WWWForm wwwform = new WWWForm();
+			wwwform.AddField("action", "Translate");
+			wwwform.AddField("list", list[0]);
+			this.www = new WWW(LocalizationManager.GetWebServiceURL(null), wwwform);
+		}
+
+		public override TranslationJob.eJobState GetState()
+		{
+			if (this.www != null && this.www.isDone)
+			{
+				this.ProcessResult(this.www.bytes, this.www.error);
+				this.www.Dispose();
+				this.www = null;
+			}
+			return this.mJobState;
+		}
+
+		public void ProcessResult(byte[] bytes, string errorMsg)
+		{
+			if (!string.IsNullOrEmpty(errorMsg))
+			{
+				this.mJobState = TranslationJob.eJobState.Failed;
+			}
+			else
+			{
+				string @string = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+				errorMsg = GoogleTranslation.ParseTranslationResult(@string, this._requests);
+				if (this._OnTranslationReady != null)
+				{
+					this._OnTranslationReady(this._requests, errorMsg);
+				}
+				this.mJobState = TranslationJob.eJobState.Succeeded;
+			}
+		}
+
+		private Dictionary<string, TranslationQuery> _requests;
+
+		private Action<Dictionary<string, TranslationQuery>, string> _OnTranslationReady;
+	}
+}

+ 158 - 0
Assembly-CSharp/I2/Loc/TranslationJob_WEB.cs

@@ -0,0 +1,158 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using System.Text.RegularExpressions;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class TranslationJob_WEB : TranslationJob_WWW
+	{
+		public TranslationJob_WEB(Dictionary<string, TranslationQuery> requests, Action<Dictionary<string, TranslationQuery>, string> OnTranslationReady)
+		{
+			this._requests = requests;
+			this._OnTranslationReady = OnTranslationReady;
+			this.FindAllQueries();
+			this.ExecuteNextBatch();
+		}
+
+		private void FindAllQueries()
+		{
+			this.mQueries = new List<KeyValuePair<string, string>>();
+			foreach (KeyValuePair<string, TranslationQuery> keyValuePair in this._requests)
+			{
+				foreach (string str in keyValuePair.Value.TargetLanguagesCode)
+				{
+					this.mQueries.Add(new KeyValuePair<string, string>(keyValuePair.Value.OrigText, keyValuePair.Value.LanguageCode + ":" + str));
+				}
+			}
+			this.mQueries.Sort((KeyValuePair<string, string> a, KeyValuePair<string, string> b) => a.Value.CompareTo(b.Value));
+		}
+
+		private void ExecuteNextBatch()
+		{
+			if (this.mQueries.Count == 0)
+			{
+				this.mJobState = TranslationJob.eJobState.Succeeded;
+				return;
+			}
+			this.mCurrentBatch_Text = new List<string>();
+			string text = null;
+			int num = 200;
+			StringBuilder stringBuilder = new StringBuilder();
+			int i;
+			for (i = 0; i < this.mQueries.Count; i++)
+			{
+				string key = this.mQueries[i].Key;
+				string value = this.mQueries[i].Value;
+				if (text == null || value == text)
+				{
+					if (i != 0)
+					{
+						stringBuilder.Append("|||");
+					}
+					stringBuilder.Append(key);
+					this.mCurrentBatch_Text.Add(key);
+					text = value;
+				}
+				if (stringBuilder.Length > num)
+				{
+					break;
+				}
+			}
+			this.mQueries.RemoveRange(0, i);
+			string[] array = text.Split(new char[]
+			{
+				':'
+			});
+			this.mCurrentBatch_FromLanguageCode = array[0];
+			this.mCurrentBatch_ToLanguageCode = array[1];
+			string text2 = string.Format("http://www.google.com/translate_t?hl=en&vi=c&ie=UTF8&oe=UTF8&submit=Translate&langpair={0}|{1}&text={2}", this.mCurrentBatch_FromLanguageCode, this.mCurrentBatch_ToLanguageCode, Uri.EscapeUriString(stringBuilder.ToString()));
+			Debug.Log(text2);
+			this.www = new WWW(text2);
+		}
+
+		public override TranslationJob.eJobState GetState()
+		{
+			if (this.www != null && this.www.isDone)
+			{
+				this.ProcessResult(this.www.bytes, this.www.error);
+				this.www.Dispose();
+				this.www = null;
+			}
+			if (this.www == null)
+			{
+				this.ExecuteNextBatch();
+			}
+			return this.mJobState;
+		}
+
+		public void ProcessResult(byte[] bytes, string errorMsg)
+		{
+			if (string.IsNullOrEmpty(errorMsg))
+			{
+				string @string = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+				string message = this.ParseTranslationResult(@string, "aab");
+				Debug.Log(message);
+				if (string.IsNullOrEmpty(errorMsg))
+				{
+					if (this._OnTranslationReady != null)
+					{
+						this._OnTranslationReady(this._requests, null);
+					}
+					return;
+				}
+			}
+			this.mJobState = TranslationJob.eJobState.Failed;
+			this.mErrorMessage = errorMsg;
+		}
+
+		private string ParseTranslationResult(string html, string OriginalText)
+		{
+			string result;
+			try
+			{
+				int num = html.IndexOf("TRANSLATED_TEXT='") + "TRANSLATED_TEXT='".Length;
+				int num2 = html.IndexOf("';var", num);
+				string text = html.Substring(num, num2 - num);
+				text = Regex.Replace(text, "\\\\x([a-fA-F0-9]{2})", (Match match) => char.ConvertFromUtf32(int.Parse(match.Groups[1].Value, NumberStyles.HexNumber)));
+				text = Regex.Replace(text, "&#(\\d+);", (Match match) => char.ConvertFromUtf32(int.Parse(match.Groups[1].Value)));
+				text = text.Replace("<br>", "\n");
+				if (OriginalText.ToUpper() == OriginalText)
+				{
+					text = text.ToUpper();
+				}
+				else if (GoogleTranslation.UppercaseFirst(OriginalText) == OriginalText)
+				{
+					text = GoogleTranslation.UppercaseFirst(text);
+				}
+				else if (GoogleTranslation.TitleCase(OriginalText) == OriginalText)
+				{
+					text = GoogleTranslation.TitleCase(text);
+				}
+				result = text;
+			}
+			catch (Exception ex)
+			{
+				Debug.LogError(ex.Message);
+				result = string.Empty;
+			}
+			return result;
+		}
+
+		private Dictionary<string, TranslationQuery> _requests;
+
+		private Action<Dictionary<string, TranslationQuery>, string> _OnTranslationReady;
+
+		public string mErrorMessage;
+
+		private string mCurrentBatch_ToLanguageCode;
+
+		private string mCurrentBatch_FromLanguageCode;
+
+		private List<string> mCurrentBatch_Text;
+
+		private List<KeyValuePair<string, string>> mQueries;
+	}
+}

+ 19 - 0
Assembly-CSharp/I2/Loc/TranslationJob_WWW.cs

@@ -0,0 +1,19 @@
+using System;
+using UnityEngine;
+
+namespace I2.Loc
+{
+	public class TranslationJob_WWW : TranslationJob
+	{
+		public override void Dispose()
+		{
+			if (this.www != null)
+			{
+				this.www.Dispose();
+			}
+			this.www = null;
+		}
+
+		public WWW www;
+	}
+}

+ 19 - 0
Assembly-CSharp/I2/Loc/TranslationQuery.cs

@@ -0,0 +1,19 @@
+using System;
+
+namespace I2.Loc
+{
+	public struct TranslationQuery
+	{
+		public string OrigText;
+
+		public string Text;
+
+		public string LanguageCode;
+
+		public string[] TargetLanguagesCode;
+
+		public string[] Results;
+
+		public string[] Tags;
+	}
+}

+ 11 - 0
Assembly-CSharp/I2/Loc/eLanguageDataFlags.cs

@@ -0,0 +1,11 @@
+using System;
+
+namespace I2.Loc
+{
+	public enum eLanguageDataFlags
+	{
+		DISABLED = 1,
+		KEEP_LOADED,
+		NOT_LOADED = 4
+	}
+}

+ 14 - 0
Assembly-CSharp/I2/Loc/ePluralType.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace I2.Loc
+{
+	public enum ePluralType
+	{
+		Zero,
+		One,
+		Two,
+		Few,
+		Many,
+		Plural
+	}
+}

+ 12 - 0
Assembly-CSharp/I2/Loc/eSpreadsheetUpdateMode.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace I2.Loc
+{
+	public enum eSpreadsheetUpdateMode
+	{
+		None,
+		Replace,
+		Merge,
+		AddNewTerms
+	}
+}

+ 19 - 0
Assembly-CSharp/I2/Loc/eTermType.cs

@@ -0,0 +1,19 @@
+using System;
+
+namespace I2.Loc
+{
+	public enum eTermType
+	{
+		Text,
+		Font,
+		Texture,
+		AudioClip,
+		GameObject,
+		Sprite,
+		Material,
+		Child,
+		UIAtlas,
+		UIFont,
+		Object
+	}
+}

+ 11 - 0
Assembly-CSharp/IOnaholeNodeButton.cs

@@ -0,0 +1,11 @@
+using System;
+using UnityEngine;
+
+public interface IOnaholeNodeButton
+{
+	GameObject gameObject { get; }
+
+	string uniqueName { get; set; }
+
+	OnaholeNodeButton.SelectType selectType { get; set; }
+}

+ 1 - 1
Assembly-CSharp/Kasizuki/KasizukiManager.cs

@@ -788,7 +788,7 @@ namespace Kasizuki
 		public void Serialize(BinaryWriter bw)
 		{
 			bw.Write("COM3D2_KASIZUKI");
-			bw.Write(1150);
+			bw.Write(1160);
 			this.SerializeOriginHeader(bw);
 			foreach (KeyValuePair<int, KasizukiManager.SaveData> keyValuePair in this.m_SaveDataArray)
 			{

+ 3 - 3
Assembly-CSharp/Maid.cs

@@ -1205,7 +1205,7 @@ public class Maid : MonoBehaviour
 	public bool SerializeProp(BinaryWriter f_bwWrite)
 	{
 		f_bwWrite.Write("CM3D2_MPROP_LIST");
-		f_bwWrite.Write(1150);
+		f_bwWrite.Write(1160);
 		f_bwWrite.Write(this.m_dicMaidProp.Count);
 		foreach (KeyValuePair<string, MaidProp> keyValuePair in this.m_dicMaidProp)
 		{
@@ -1237,7 +1237,7 @@ public class Maid : MonoBehaviour
 	public bool SerializeMisc(BinaryWriter f_bwWrite)
 	{
 		f_bwWrite.Write("CM3D2_MAID_MISC");
-		f_bwWrite.Write(1150);
+		f_bwWrite.Write(1160);
 		f_bwWrite.Write(this.m_nActiveSlotNo);
 		if (this.m_texIcon != null)
 		{
@@ -1262,7 +1262,7 @@ public class Maid : MonoBehaviour
 	public bool SerializeBody(BinaryWriter f_bwWrite)
 	{
 		f_bwWrite.Write("CM3D2_MAID_BODY");
-		f_bwWrite.Write(1150);
+		f_bwWrite.Write(1160);
 		return true;
 	}
 

+ 1 - 1
Assembly-CSharp/MaidParts.cs

@@ -35,7 +35,7 @@ public class MaidParts : MonoBehaviour
 	public unsafe bool Serialize(BinaryWriter f_bwWrite)
 	{
 		f_bwWrite.Write("CM3D2_MULTI_COL");
-		f_bwWrite.Write(1150);
+		f_bwWrite.Write(1160);
 		f_bwWrite.Write(this.m_aryPartsColor.Length);
 		for (int i = 0; i < this.m_aryPartsColor.Length; i++)
 		{

+ 1 - 1
Assembly-CSharp/MaidProp.cs

@@ -8,7 +8,7 @@ public class MaidProp
 	public bool Serialize(BinaryWriter f_bwWrite)
 	{
 		f_bwWrite.Write("CM3D2_MPROP");
-		f_bwWrite.Write(1150);
+		f_bwWrite.Write(1160);
 		f_bwWrite.Write(this.idx);
 		f_bwWrite.Write(this.name);
 		f_bwWrite.Write(this.type);

+ 1 - 1
Assembly-CSharp/MaidStatus/Status.cs

@@ -1207,7 +1207,7 @@ namespace MaidStatus
 		public void Serialize(BinaryWriter binary)
 		{
 			binary.Write("CM3D2_MAID_STATUS");
-			binary.Write(1150);
+			binary.Write(1160);
 			binary.Write(this.guid);
 			binary.Write(this.creationTime);
 			binary.Write((short)this.heroineType);

+ 66 - 60
Assembly-CSharp/Menu.cs

@@ -148,12 +148,12 @@ public class Menu : MonoBehaviour
 				}
 				if (stringCom == "name")
 				{
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "アイテム")
 				{
 					Menu.SetMaidItemTemp(maid, stringList[1], f_bTemp);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "アイテム条件")
 				{
@@ -252,7 +252,7 @@ public class Menu : MonoBehaviour
 					NDebug.Assert("アイテム条件が不正です。「なら」が必要です。\n" + text5, false);
 					goto IL_36D;
 					IL_36D:
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "アイテムパラメータ")
 				{
@@ -272,7 +272,7 @@ public class Menu : MonoBehaviour
 					Debug.LogError("アイテムパラメータ 命令の引数が不正です。SlotNameを明示的に指定しする必要があります。アイテムパラメータ <スロット名> <変数名> <値> の順です。" + text5);
 					goto IL_3E2;
 					IL_3E2:
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "半脱ぎ" || stringCom == "リソース参照")
 				{
@@ -308,22 +308,22 @@ public class Menu : MonoBehaviour
 					Menu.m_dicResourceRef.Add(hashCode, sortedDictionary);
 					goto IL_4B9;
 					IL_4B9:
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "set")
 				{
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "setname")
 				{
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "setslotitem")
 				{
 					string tag = stringList[1];
 					uint val = uint.Parse(stringList[2]);
 					maid.SetProp(tag, (int)val, false);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "additem")
 				{
@@ -364,17 +364,23 @@ public class Menu : MonoBehaviour
 					}
 					body.AddItem((MPN)Enum.Parse(typeof(MPN), text7, true), text11, stringList[1], attachSlot, attachName, f_bTemp);
 					body.SetVisibleNodeSlot(text11, true, "_ALL_");
-					goto IL_1013;
+					goto IL_1057;
+				}
+				if (stringCom == "nofloory")
+				{
+					TBody.SlotID index = (TBody.SlotID)Enum.Parse(typeof(TBody.SlotID), stringList[1], true);
+					body.goSlot[(int)index].m_bHitFloorY = false;
+					goto IL_1057;
 				}
 				if (stringCom == "saveitem")
 				{
 					text3 = stringList[1];
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "category")
 				{
 					text7 = stringList[1];
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "maskitem")
 				{
@@ -382,11 +388,11 @@ public class Menu : MonoBehaviour
 					{
 						string maskslot = stringList[1];
 						body.AddMask(text7, maskslot);
-						goto IL_6A3;
+						goto IL_6E7;
 					}
-					goto IL_6A3;
-					IL_6A3:
-					goto IL_1013;
+					goto IL_6E7;
+					IL_6E7:
+					goto IL_1057;
 				}
 				if (stringCom == "delitem")
 				{
@@ -396,27 +402,27 @@ public class Menu : MonoBehaviour
 						slotname3 = stringList[1];
 					}
 					body.DelItem((MPN)Enum.Parse(typeof(MPN), text7, true), slotname3);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "node消去")
 				{
 					body.SetVisibleNodeSlot(text7, false, stringList[1]);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "node表示")
 				{
 					body.SetVisibleNodeSlot(text7, true, stringList[1]);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "パーツnode消去")
 				{
 					body.SetVisibleNodeSlotParts(text7, stringList[1], false, stringList[2]);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "パーツnode表示")
 				{
 					body.SetVisibleNodeSlotParts(text7, stringList[1], true, stringList[2]);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "color")
 				{
@@ -425,14 +431,14 @@ public class Menu : MonoBehaviour
 					string prop_name = stringList[3];
 					Color col = new Color(float.Parse(stringList[4]) / 255f, float.Parse(stringList[5]) / 255f, float.Parse(stringList[6]) / 255f, float.Parse(stringList[7]) / 255f);
 					body.ChangeCol(name, matno, prop_name, col);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "mancolor")
 				{
 					Color manColor = new Color(float.Parse(stringList[1]) / 255f, float.Parse(stringList[2]) / 255f, float.Parse(stringList[3]) / 255f, 1f);
 					maid.ManColor = manColor;
 					maid.ManColorUpdate();
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "tex" || stringCom == "テクスチャ変更")
 				{
@@ -461,22 +467,22 @@ public class Menu : MonoBehaviour
 					if ((text7 == "skin" || text7 == "haircolor") && !flag)
 					{
 						body.RestoreShader(text12);
-						goto IL_950;
+						goto IL_994;
 					}
-					goto IL_950;
-					IL_950:
-					goto IL_1013;
+					goto IL_994;
+					IL_994:
+					goto IL_1057;
 				}
 				if (stringCom == "prop")
 				{
 					string tag2 = stringList[1];
 					string s = stringList[2];
 					maid.SetProp(tag2, int.Parse(s), false);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "テクスチャ乗算")
 				{
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "テクスチャ合成")
 				{
@@ -487,12 +493,12 @@ public class Menu : MonoBehaviour
 					if ((text7 == "accTatoo" || text7 == "hokuro") && !filename.Contains("_del"))
 					{
 						body.MulTexSet(stringList[1], int.Parse(stringList[2]), stringList[3], int.Parse(stringList[4]), stringList[5], (GameUty.SystemMaterial)Enum.Parse(typeof(GameUty.SystemMaterial), stringList[6]), true, 0, 0, 0f, 0f, true, f_SubProp, 1f, 1024);
-						goto IL_AB3;
+						goto IL_AF7;
 					}
 					body.MulTexSet(stringList[1], int.Parse(stringList[2]), stringList[3], int.Parse(stringList[4]), stringList[5], (GameUty.SystemMaterial)Enum.Parse(typeof(GameUty.SystemMaterial), stringList[6]), false, 0, 0, 0f, 0f, false, null, 1f, 1024);
-					goto IL_AB3;
-					IL_AB3:
-					goto IL_1013;
+					goto IL_AF7;
+					IL_AF7:
+					goto IL_1057;
 				}
 				if (stringCom == "テクスチャセット合成")
 				{
@@ -501,7 +507,7 @@ public class Menu : MonoBehaviour
 						NDebug.Assert("テクスチャセット合成 の引数が不正です。" + stringList.Length, false);
 					}
 					body.MulTexSet(stringList[1], int.Parse(stringList[2]), stringList[3], int.Parse(stringList[4]), stringList[5], (GameUty.SystemMaterial)Enum.Parse(typeof(GameUty.SystemMaterial), stringList[6]), true, 0, 0, 0f, 0f, true, null, 1f, 1024);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "マテリアル変更")
 				{
@@ -509,7 +515,7 @@ public class Menu : MonoBehaviour
 					int f_nMatNo = int.Parse(stringList[2]);
 					string f_strFileName = stringList[3];
 					body.ChangeMaterial(f_strSlotName, f_nMatNo, f_strFileName);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "shader")
 				{
@@ -518,14 +524,14 @@ public class Menu : MonoBehaviour
 					string f_strShaderFileName = stringList[3];
 					body.ChangeShader(f_strSlotName2, f_nMatNo2, f_strShaderFileName);
 					flag = true;
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "アタッチポイントの設定")
 				{
 					if (stringList.Length < 5)
 					{
 						Debug.LogError("アタッチポイントの設定引数の数が不正です。 " + text5 + " " + str);
-						goto IL_C76;
+						goto IL_CBA;
 					}
 					Vector3 v = new Vector3(float.Parse(stringList[2]), float.Parse(stringList[3]), float.Parse(stringList[4]));
 					Quaternion q = Quaternion.identity;
@@ -538,9 +544,9 @@ public class Menu : MonoBehaviour
 						Debug.LogError("アタッチポイントの設定引数に角度指定がありません。 " + text5 + "  " + str);
 					}
 					body.SetAttachPoint(slotname, stringList[1], v, q, f_bTemp);
-					goto IL_C76;
-					IL_C76:
-					goto IL_1013;
+					goto IL_CBA;
+					IL_CBA:
+					goto IL_1057;
 				}
 				if (stringCom == "blendset")
 				{
@@ -553,12 +559,12 @@ public class Menu : MonoBehaviour
 						float val2 = float.Parse(stringList[3 + j * 2]);
 						body.Face.morph.SetValueBlendSet(blendSetName, tag3, val2);
 					}
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "paramset")
 				{
 					body.Face.NewParamSet(text5);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "commenttype")
 				{
@@ -567,18 +573,18 @@ public class Menu : MonoBehaviour
 						maid.status.partsDic.Add(stringList[1], string.Empty);
 					}
 					maid.status.partsDic[stringList[1]] = stringList[2];
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "useredit")
 				{
 					if (stringList[2].ToLower() == "material")
 					{
 						body.SetMaterialProperty(text7, stringList[3], int.Parse(stringList[4]), stringList[5], stringList[6], stringList[7], false);
-						goto IL_DCE;
+						goto IL_E12;
 					}
-					goto IL_DCE;
-					IL_DCE:
-					goto IL_1013;
+					goto IL_E12;
+					IL_E12:
+					goto IL_1057;
 				}
 				if (stringCom == "bonemorph")
 				{
@@ -587,7 +593,7 @@ public class Menu : MonoBehaviour
 						Debug.LogError("BoneMorpの設定引数の数が不正です。 " + text5 + " " + str);
 					}
 					body.bonemorph.ChangeMorphPosValue(stringList[1], stringList[2], new Vector3(float.Parse(stringList[3]), float.Parse(stringList[4]), float.Parse(stringList[5])), new Vector3(float.Parse(stringList[6]), float.Parse(stringList[7]), float.Parse(stringList[8])));
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "length")
 				{
@@ -596,7 +602,7 @@ public class Menu : MonoBehaviour
 						Debug.LogError("lengthの設定引数の数が不正です。 " + text5 + " " + str);
 					}
 					body.SetHairLengthDataList(stringList[1], stringList[2], stringList[3], stringList[4], new Vector3(float.Parse(stringList[5]), float.Parse(stringList[6]), float.Parse(stringList[7])), new Vector3(float.Parse(stringList[8]), float.Parse(stringList[9]), float.Parse(stringList[10])));
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "anime")
 				{
@@ -612,7 +618,7 @@ public class Menu : MonoBehaviour
 						f_bLoop = (stringList[3] == "loop");
 					}
 					body.ItemAnimationPlay(f_slot, stringList[2], f_bLoop);
-					goto IL_1013;
+					goto IL_1057;
 				}
 				if (stringCom == "param2")
 				{
@@ -620,23 +626,23 @@ public class Menu : MonoBehaviour
 					{
 						string slotname4 = stringList[1];
 						body.GetSlot(slotname4).SetParam2(stringList[2], stringList[3]);
-						goto IL_FCD;
+						goto IL_1011;
 					}
 					Debug.LogError("param2の設定引数の数が不正です。 " + text5 + " " + str);
-					goto IL_FCD;
-					IL_FCD:
-					goto IL_1013;
+					goto IL_1011;
+					IL_1011:
+					goto IL_1057;
 				}
 				if (stringCom == "animematerial")
 				{
 					TBody.SlotID f_slot2 = (TBody.SlotID)Enum.Parse(typeof(TBody.SlotID), stringList[1], true);
 					string s2 = stringList[2];
 					body.MaterialAnimatorAdd(f_slot2, int.Parse(s2));
-					goto IL_1013;
+					goto IL_1057;
 				}
-				goto IL_1013;
-				IL_1013:
-				goto IL_1096;
+				goto IL_1057;
+				IL_1057:
+				goto IL_10DA;
 			}
 			catch (Exception ex)
 			{
@@ -654,9 +660,9 @@ public class Menu : MonoBehaviour
 					ex.StackTrace
 				}));
 				NDebug.Assert("メニューファイル処理中にエラーが発生しました。" + Path.GetFileName(filename), true);
-				goto IL_1096;
+				goto IL_10DA;
 			}
-			IL_1096:
+			IL_10DA:
 			goto IL_90;
 		}
 		list.Sort((Menu.LastParam a, Menu.LastParam b) => a.nOrder - a.nOrder);
@@ -747,7 +753,7 @@ public class Menu : MonoBehaviour
 			Directory.CreateDirectory(text);
 		}
 		StreamWriter streamWriter = new StreamWriter(text + "\\" + text2 + ".txt", false, Encoding.UTF8);
-		streamWriter.WriteLine("出力バージョン\t" + 1150);
+		streamWriter.WriteLine("出力バージョン\t" + 1160);
 		streamWriter.WriteLine("基本アイテム\t" + filename.Replace(" ", ":"));
 		try
 		{

+ 2 - 0
Assembly-CSharp/MessageWindowCtrl.cs

@@ -171,6 +171,8 @@ public class MessageWindowCtrl : MonoBehaviour
 
 	private const string BACKLOG_UNIT_PREFAB_PATH = "SystemUI/MessageWindow/Backlog/Prefabs/BacklogUnit";
 
+	private const string BACKLOG_UNIT_PREFAB_SUBTITLE_PATH = "SystemUI/MessageWindow/Backlog/Prefabs/BacklogSubtitleUnit";
+
 	private const int MIN_VALUE = 0;
 
 	private const int MAX_VALUE = 1;

+ 6 - 0
Assembly-CSharp/MessageWindowMgr.cs

@@ -316,9 +316,15 @@ public class MessageWindowMgr : BaseMgr<MessageWindowMgr>
 
 	public void AddBackLog(string name, string text, string voice_file, int pitch)
 	{
+		this.AddBackLog(name, text, string.Empty, voice_file, pitch);
+	}
+
+	public void AddBackLog(string name, string text, string subtitle_text, string voice_file, int pitch)
+	{
 		BacklogCtrl.BacklogUnit backlogUnit = new BacklogCtrl.BacklogUnit();
 		backlogUnit.m_speakerName = name;
 		backlogUnit.m_msg = text;
+		backlogUnit.m_subtitlemsg = subtitle_text;
 		backlogUnit.m_voiceId = voice_file;
 		backlogUnit.m_voicePitch = pitch;
 		this.m_listBacklogUnit.Add(backlogUnit);

+ 1 - 1
Assembly-CSharp/Misc.cs

@@ -2,7 +2,7 @@
 
 public class Misc
 {
-	public const int GAME_VERSION = 1150;
+	public const int GAME_VERSION = 1160;
 
 	public const string GAME_DATA_PATH = "GameData";
 

+ 1 - 1
Assembly-CSharp/ModCompile.cs

@@ -604,7 +604,7 @@ public class ModCompile : MonoBehaviour
 		MemoryStream memoryStream = new MemoryStream();
 		BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 		binaryWriter.Write("CM3D2_MESH");
-		binaryWriter.Write(1150);
+		binaryWriter.Write(1160);
 		string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(f_strMqoFile);
 		binaryWriter.Write(fileNameWithoutExtension);
 		binaryWriter.Write(exObjIn2.strName);

+ 48 - 0
Assembly-CSharp/Monitor.cs

@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+
+public class Monitor
+{
+	public static List<Monitor.InfoData> info_data_list
+	{
+		get
+		{
+			if (Monitor.data_ == null || Monitor.data_.Count == 0)
+			{
+				Monitor.<>c__AnonStorey0 <>c__AnonStorey = new Monitor.<>c__AnonStorey0();
+				Monitor.data_ = new List<Monitor.InfoData>();
+				<>c__AnonStorey.class_pointer = DLLMonitorData.CreateMonitorData();
+				int monitorCount = DLLMonitorData.GetMonitorCount(<>c__AnonStorey.class_pointer);
+				int i;
+				for (i = 0; i < monitorCount; i++)
+				{
+					DllBase.NativeWriteStringFunction func = delegate(IntPtr p, int buff_size)
+					{
+						DLLMonitorData.GetMonitorName(<>c__AnonStorey.class_pointer, i, p, buff_size);
+					};
+					Monitor.InfoData item;
+					item.name = DllBase.GetNativeStringToUtf8(func);
+					item.width = DLLMonitorData.GetMonitorWidth(<>c__AnonStorey.class_pointer, i);
+					item.height = DLLMonitorData.GetMonitorHeight(<>c__AnonStorey.class_pointer, i);
+					item.is_primary = DLLMonitorData.IsMonitorPrimary(<>c__AnonStorey.class_pointer, i);
+					Monitor.data_.Add(item);
+				}
+				DLLMonitorData.DeleteMonitorData(<>c__AnonStorey.class_pointer);
+			}
+			return Monitor.data_;
+		}
+	}
+
+	private static List<Monitor.InfoData> data_;
+
+	public struct InfoData
+	{
+		public string name;
+
+		public int width;
+
+		public int height;
+
+		public bool is_primary;
+	}
+}

+ 30 - 0
Assembly-CSharp/NodeButtonData.cs

@@ -0,0 +1,30 @@
+using System;
+
+public class NodeButtonData
+{
+	public NodeButtonData(IOnaholeNodeButton button, Action enterEvent)
+	{
+		this.button = button;
+		this.enterEvent = enterEvent;
+	}
+
+	public NodeButtonData()
+	{
+	}
+
+	public OnaholeNodeButton.SelectType selectType
+	{
+		get
+		{
+			return this.button.selectType;
+		}
+		set
+		{
+			this.button.selectType = value;
+		}
+	}
+
+	public IOnaholeNodeButton button;
+
+	public Action enterEvent;
+}

+ 12 - 3
Assembly-CSharp/OnHoverTaskIcon.cs

@@ -74,7 +74,10 @@ public class OnHoverTaskIcon : MonoBehaviour
 	{
 		if (isOver)
 		{
-			this.m_goNamePlate.SetActive(true);
+			if (this.m_goNamePlate != null)
+			{
+				this.m_goNamePlate.SetActive(true);
+			}
 			if (this.workData != null && this.workData.id != ScheduleCSVData.faclilityPowerUpWorkId)
 			{
 				this.CheckFacilityState();
@@ -82,8 +85,14 @@ public class OnHoverTaskIcon : MonoBehaviour
 		}
 		else
 		{
-			this.m_goNamePlate.SetActive(false);
-			this.WariningFacilty.gameObject.SetActive(false);
+			if (this.m_goNamePlate != null)
+			{
+				this.m_goNamePlate.SetActive(false);
+			}
+			if (this.WariningFacilty != null)
+			{
+				this.WariningFacilty.gameObject.SetActive(false);
+			}
 		}
 	}
 

+ 390 - 0
Assembly-CSharp/OnaholeBaseNodeMenuManager.cs

@@ -0,0 +1,390 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using wf;
+
+public class OnaholeBaseNodeMenuManager : MonoBehaviour
+{
+	public static OnaholeNodeButton CreateBasicNodeButton(GameObject parent, string text, string uniqueName, bool sizeSmall, bool drawNextMark)
+	{
+		GameObject gameObject = Utility.CreatePrefab(parent, "SceneYotogi/CBL/BasicNodeMenu", true);
+		OnaholeNodeButton component = gameObject.GetComponent<OnaholeNodeButton>();
+		component.selectType = OnaholeNodeButton.SelectType.None;
+		component.text = text;
+		component.uniqueName = uniqueName;
+		component.visibleNextMarker = drawNextMark;
+		component.sizeModeBig = !sizeSmall;
+		return component;
+	}
+
+	public static OnaholeNodeSlider CreateNodeSlider(GameObject parent, OnaholeNodeSlider.SliderType type, string uniqueName)
+	{
+		GameObject gameObject = Utility.CreatePrefab(parent, "SceneYotogi/CBL/NodeSliderMenu", true);
+		OnaholeNodeSlider component = gameObject.GetComponent<OnaholeNodeSlider>();
+		component.selectType = OnaholeNodeButton.SelectType.None;
+		component.uniqueName = uniqueName;
+		component.SetSliderType(type);
+		return component;
+	}
+
+	public OnaholeNodeIconButton CreateNodeIconMenu(GameObject parent, string uniqueName)
+	{
+		GameObject gameObject = Utility.CreatePrefab(parent, "SceneYotogi/CBL/NodeIconMenu", true);
+		OnaholeNodeIconButton component = gameObject.GetComponent<OnaholeNodeIconButton>();
+		component.selectType = OnaholeNodeButton.SelectType.None;
+		component.uniqueName = uniqueName;
+		return component;
+	}
+
+	public bool inputUpKey
+	{
+		get
+		{
+			return this.isInputEnabled && base.gameObject.activeInHierarchy && YotogiManager.instans.inputCBLUpKey;
+		}
+	}
+
+	public bool inputDownKey
+	{
+		get
+		{
+			return this.isInputEnabled && base.gameObject.activeInHierarchy && YotogiManager.instans.inputCBLDownKey;
+		}
+	}
+
+	public bool inputRightKye
+	{
+		get
+		{
+			return this.isInputEnabled && base.gameObject.activeInHierarchy && YotogiManager.instans.inputCBLRightKey;
+		}
+	}
+
+	public bool inputLeftKey
+	{
+		get
+		{
+			return this.isInputEnabled && base.gameObject.activeInHierarchy && YotogiManager.instans.inputCBLLeftKey;
+		}
+	}
+
+	public bool inputEnterKey
+	{
+		get
+		{
+			return this.isInputEnabled && base.gameObject.activeInHierarchy && YotogiManager.instans.inputCBLEnterKey;
+		}
+	}
+
+	public bool inputCancelKey
+	{
+		get
+		{
+			return this.isInputEnabled && base.gameObject.activeInHierarchy && YotogiManager.instans.inputCBLCancelKey;
+		}
+	}
+
+	public NodeButtonData selectedNodeButton
+	{
+		get
+		{
+			foreach (NodeButtonData nodeButtonData in this.menuButtons)
+			{
+				if (nodeButtonData.selectType == OnaholeNodeButton.SelectType.Select || nodeButtonData.selectType == OnaholeNodeButton.SelectType.Focus)
+				{
+					return nodeButtonData;
+				}
+			}
+			return null;
+		}
+	}
+
+	public void NextItem()
+	{
+		List<NodeButtonData> list = this.menuButtons;
+		if (this.operationMap != null && 0 < this.operationMap.Count)
+		{
+			foreach (List<NodeButtonData> list2 in this.operationMap)
+			{
+				foreach (NodeButtonData nodeButtonData in list2)
+				{
+					if (nodeButtonData.selectType == OnaholeNodeButton.SelectType.Select || nodeButtonData.selectType == OnaholeNodeButton.SelectType.Focus)
+					{
+						list = list2;
+						break;
+					}
+				}
+			}
+		}
+		NodeButtonData nodeButtonData2 = null;
+		for (int i = 0; i < list.Count; i++)
+		{
+			if (list[i].selectType == OnaholeNodeButton.SelectType.Select || list[i].selectType == OnaholeNodeButton.SelectType.Focus)
+			{
+				nodeButtonData2 = list[i];
+				int num = i;
+				for (;;)
+				{
+					num++;
+					if (list.Count <= num)
+					{
+						num = -1;
+					}
+					else if (list[num].selectType != OnaholeNodeButton.SelectType.Disable)
+					{
+						break;
+					}
+				}
+				nodeButtonData2 = list[num];
+				break;
+			}
+		}
+		if (nodeButtonData2 != null)
+		{
+			this.SetFocusButton(nodeButtonData2);
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Hover);
+		}
+	}
+
+	public void PrevItem()
+	{
+		List<NodeButtonData> list = this.menuButtons;
+		if (this.operationMap != null && 0 < this.operationMap.Count)
+		{
+			foreach (List<NodeButtonData> list2 in this.operationMap)
+			{
+				foreach (NodeButtonData nodeButtonData in list2)
+				{
+					if (nodeButtonData.selectType == OnaholeNodeButton.SelectType.Select || nodeButtonData.selectType == OnaholeNodeButton.SelectType.Focus)
+					{
+						list = list2;
+						break;
+					}
+				}
+			}
+		}
+		NodeButtonData nodeButtonData2 = null;
+		for (int i = 0; i < list.Count; i++)
+		{
+			if (list[i].selectType == OnaholeNodeButton.SelectType.Select || list[i].selectType == OnaholeNodeButton.SelectType.Focus)
+			{
+				nodeButtonData2 = list[i];
+				int num = i;
+				for (;;)
+				{
+					num--;
+					if (num < 0)
+					{
+						num = list.Count;
+					}
+					else if (list[num].selectType != OnaholeNodeButton.SelectType.Disable)
+					{
+						break;
+					}
+				}
+				nodeButtonData2 = list[num];
+				break;
+			}
+		}
+		if (nodeButtonData2 != null)
+		{
+			this.SetFocusButton(nodeButtonData2);
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Hover);
+		}
+	}
+
+	public void RightItem()
+	{
+		if (this.operationMap == null || this.operationMap.Count <= 1)
+		{
+			return;
+		}
+		List<NodeButtonData> list = null;
+		for (int i = 0; i < this.operationMap.Count; i++)
+		{
+			for (int j = 0; j < this.operationMap[i].Count; j++)
+			{
+				NodeButtonData nodeButtonData = this.operationMap[i][j];
+				if (nodeButtonData.selectType == OnaholeNodeButton.SelectType.Select || nodeButtonData.selectType == OnaholeNodeButton.SelectType.Focus)
+				{
+					list = new List<NodeButtonData>();
+					for (int k = 0; k < this.operationMap.Count; k++)
+					{
+						list.Add(this.operationMap[k][j]);
+					}
+					break;
+				}
+			}
+			if (list != null)
+			{
+				break;
+			}
+		}
+		if (list == null)
+		{
+			return;
+		}
+		NodeButtonData nodeButtonData2 = null;
+		for (int l = 0; l < list.Count; l++)
+		{
+			if (list[l].selectType == OnaholeNodeButton.SelectType.Select || list[l].selectType == OnaholeNodeButton.SelectType.Focus)
+			{
+				nodeButtonData2 = list[l];
+				int num = l;
+				for (;;)
+				{
+					num++;
+					if (list.Count <= num)
+					{
+						num = -1;
+					}
+					else if (list[num].selectType != OnaholeNodeButton.SelectType.Disable)
+					{
+						break;
+					}
+				}
+				nodeButtonData2 = list[num];
+				break;
+			}
+		}
+		if (nodeButtonData2 != null)
+		{
+			this.SetFocusButton(nodeButtonData2);
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Hover);
+		}
+	}
+
+	public void LeftItem()
+	{
+		if (this.operationMap == null || this.operationMap.Count <= 1)
+		{
+			return;
+		}
+		List<NodeButtonData> list = null;
+		for (int i = 0; i < this.operationMap.Count; i++)
+		{
+			for (int j = 0; j < this.operationMap[i].Count; j++)
+			{
+				NodeButtonData nodeButtonData = this.operationMap[i][j];
+				if (nodeButtonData.selectType == OnaholeNodeButton.SelectType.Select || nodeButtonData.selectType == OnaholeNodeButton.SelectType.Focus)
+				{
+					list = new List<NodeButtonData>();
+					for (int k = 0; k < this.operationMap.Count; k++)
+					{
+						list.Add(this.operationMap[k][j]);
+					}
+					break;
+				}
+			}
+			if (list != null)
+			{
+				break;
+			}
+		}
+		if (list == null)
+		{
+			return;
+		}
+		NodeButtonData nodeButtonData2 = null;
+		for (int l = 0; l < list.Count; l++)
+		{
+			if (list[l].selectType == OnaholeNodeButton.SelectType.Select || list[l].selectType == OnaholeNodeButton.SelectType.Focus)
+			{
+				nodeButtonData2 = list[l];
+				int num = l;
+				for (;;)
+				{
+					num--;
+					if (num < 0)
+					{
+						num = list.Count;
+					}
+					else if (list[num].selectType != OnaholeNodeButton.SelectType.Disable)
+					{
+						break;
+					}
+				}
+				nodeButtonData2 = list[num];
+				break;
+			}
+		}
+		if (nodeButtonData2 != null)
+		{
+			this.SetFocusButton(nodeButtonData2);
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Hover);
+		}
+	}
+
+	protected virtual void OnEnterMenu()
+	{
+		GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+	}
+
+	protected virtual void OnCancelMenu()
+	{
+		GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+	}
+
+	protected virtual void Update()
+	{
+		if (this.inputDownKey)
+		{
+			this.NextItem();
+		}
+		else if (this.inputUpKey)
+		{
+			this.PrevItem();
+		}
+	}
+
+	protected NodeButtonData GetNodeButtonData(string uniquName)
+	{
+		foreach (NodeButtonData nodeButtonData in this.menuButtons)
+		{
+			if (nodeButtonData.button.uniqueName == uniquName)
+			{
+				return nodeButtonData;
+			}
+		}
+		return null;
+	}
+
+	protected void SetFocusButton(NodeButtonData buttonData)
+	{
+		if (buttonData == null)
+		{
+			return;
+		}
+		foreach (NodeButtonData nodeButtonData in this.menuButtons)
+		{
+			if (nodeButtonData.button.selectType != OnaholeNodeButton.SelectType.Disable)
+			{
+				nodeButtonData.button.selectType = ((buttonData.button != nodeButtonData.button) ? OnaholeNodeButton.SelectType.None : OnaholeNodeButton.SelectType.Focus);
+			}
+		}
+	}
+
+	protected void SetSelectedButton(NodeButtonData buttonData)
+	{
+		if (buttonData == null)
+		{
+			return;
+		}
+		foreach (NodeButtonData nodeButtonData in this.menuButtons)
+		{
+			if (nodeButtonData.button.selectType != OnaholeNodeButton.SelectType.Disable)
+			{
+				nodeButtonData.button.selectType = ((buttonData.button != nodeButtonData.button) ? OnaholeNodeButton.SelectType.None : OnaholeNodeButton.SelectType.Select);
+			}
+		}
+	}
+
+	[SerializeField]
+	protected UIGrid menuButtonGrid;
+
+	protected List<NodeButtonData> menuButtons = new List<NodeButtonData>();
+
+	protected List<List<NodeButtonData>> operationMap = new List<List<NodeButtonData>>();
+
+	public bool isInputEnabled;
+}

+ 94 - 0
Assembly-CSharp/OnaholeChuBlipDevice.cs

@@ -4,6 +4,86 @@ using UnityEngine;
 
 public class OnaholeChuBlipDevice : MonoBehaviour
 {
+	public long rawArrowUp { get; private set; }
+
+	public long rawArrowDown { get; private set; }
+
+	public long rawArrowRight { get; private set; }
+
+	public long rawArrowLeft { get; private set; }
+
+	public float arrowUp
+	{
+		get
+		{
+			return (float)this.rawArrowUp * 1.52590219E-05f;
+		}
+	}
+
+	public float arrowDown
+	{
+		get
+		{
+			return (float)this.rawArrowDown * 1.52590219E-05f;
+		}
+	}
+
+	public float arrowRight
+	{
+		get
+		{
+			return (float)this.rawArrowRight * 1.52590219E-05f;
+		}
+	}
+
+	public float arrowLeft
+	{
+		get
+		{
+			return (float)this.rawArrowLeft * 1.52590219E-05f;
+		}
+	}
+
+	public long rawVertical
+	{
+		get
+		{
+			return this.rawArrowUp - this.rawArrowDown;
+		}
+	}
+
+	public long rawHorizontal
+	{
+		get
+		{
+			return this.rawArrowRight - this.rawArrowLeft;
+		}
+	}
+
+	public float vertical
+	{
+		get
+		{
+			return (float)this.rawVertical * 1.52590219E-05f;
+		}
+	}
+
+	public float horizontal
+	{
+		get
+		{
+			return (float)this.rawHorizontal * 1.52590219E-05f;
+		}
+	}
+
+	public Vector2 inputVec
+	{
+		get
+		{
+			return new Vector2(this.vertical, this.horizontal);
+		}
+	}
+
 	private Dictionary<string, float> data_dic_ = new Dictionary<string, float>();
 
 	private float insertDepth;
@@ -29,4 +109,18 @@ public class OnaholeChuBlipDevice : MonoBehaviour
 	private float decisionInsertDepth;
 
 	private float testDepth;
+
+	private bool buttonA;
+
+	private bool buttonB;
+
+	private bool buttonC;
+
+	private bool beforeButtonA;
+
+	private bool beforeButtonB;
+
+	private bool beforeButtonC;
+
+	public const float RECIPROCAL_ARROW_VALUE = 1.52590219E-05f;
 }

+ 2 - 2
Assembly-CSharp/OnaholeEstrusMode.cs

@@ -3,6 +3,8 @@ using UnityEngine;
 
 public class OnaholeEstrusMode : MonoBehaviour
 {
+	public OnaholeEstrusMode.Mode mode { get; private set; }
+
 	public float KP
 	{
 		get
@@ -39,8 +41,6 @@ public class OnaholeEstrusMode : MonoBehaviour
 		}
 	}
 
-	private OnaholeEstrusMode.Mode mode;
-
 	[SerializeField]
 	private bool permissionEstrus;
 

+ 123 - 0
Assembly-CSharp/OnaholeNodeButton.cs

@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class OnaholeNodeButton : MonoBehaviour, IOnaholeNodeButton
+{
+	public string text
+	{
+		get
+		{
+			return this.textLabel.text;
+		}
+		set
+		{
+			this.textLabel.text = ((!string.IsNullOrEmpty(value)) ? value : string.Empty);
+		}
+	}
+
+	public bool visibleNextMarker
+	{
+		get
+		{
+			return this.nextMarker.activeSelf;
+		}
+		set
+		{
+			this.nextMarker.SetActive(value);
+			this.textLabel.rightAnchor.absolute = ((!value) ? 0 : -30);
+			UIRect.AnchorUpdate updateAnchors = this.textLabel.updateAnchors;
+			this.textLabel.updateAnchors = UIRect.AnchorUpdate.OnUpdate;
+			this.textLabel.UpdateAnchors();
+			this.textLabel.updateAnchors = updateAnchors;
+		}
+	}
+
+	public bool sizeModeBig
+	{
+		set
+		{
+			this.bg.width = ((!value) ? 250 : 380);
+			List<UIRect> list = new List<UIRect>();
+			list.Add(this.textLabel);
+			if (this.nextMarker.GetComponent<UIRect>() != null)
+			{
+				list.Add(this.nextMarker.GetComponent<UIRect>());
+			}
+			foreach (UIRect uirect in list)
+			{
+				UIRect.AnchorUpdate updateAnchors = uirect.updateAnchors;
+				uirect.updateAnchors = UIRect.AnchorUpdate.OnUpdate;
+				uirect.UpdateAnchors();
+				uirect.updateAnchors = updateAnchors;
+			}
+		}
+	}
+
+	public string uniqueName { get; set; }
+
+	public OnaholeNodeButton.SelectType selectType
+	{
+		get
+		{
+			return this.selectType_;
+		}
+		set
+		{
+			this.selectType_ = value;
+			if (value == OnaholeNodeButton.SelectType.None)
+			{
+				this.bg.alpha = this.defaultBGAlpha;
+				this.textLabel.color = Color.white;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Focus)
+			{
+				this.bg.alpha = 1f;
+				this.textLabel.color = Color.white;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Select)
+			{
+				this.bg.alpha = 1f;
+				this.textLabel.color = Color.yellow;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Disable)
+			{
+				this.bg.alpha = 0.2f;
+				this.textLabel.color = Color.gray;
+			}
+		}
+	}
+
+	public void Awake()
+	{
+		this.defaultBGAlpha = this.bg.alpha;
+		this.selectType = OnaholeNodeButton.SelectType.None;
+		this.sizeModeBig = false;
+	}
+
+	GameObject IOnaholeNodeButton.get_gameObject()
+	{
+		return base.gameObject;
+	}
+
+	[SerializeField]
+	private UIWidget bg;
+
+	[SerializeField]
+	private UILabel textLabel;
+
+	[SerializeField]
+	private GameObject nextMarker;
+
+	private float defaultBGAlpha;
+
+	private OnaholeNodeButton.SelectType selectType_;
+
+	public enum SelectType
+	{
+		None,
+		Focus,
+		Select,
+		Disable
+	}
+}

+ 82 - 0
Assembly-CSharp/OnaholeNodeIconButton.cs

@@ -0,0 +1,82 @@
+using System;
+using UnityEngine;
+
+public class OnaholeNodeIconButton : MonoBehaviour, IOnaholeNodeButton
+{
+	public string uniqueName { get; set; }
+
+	public OnaholeNodeButton.SelectType selectType
+	{
+		get
+		{
+			return this.selectType_;
+		}
+		set
+		{
+			this.selectType_ = value;
+			if (value == OnaholeNodeButton.SelectType.None)
+			{
+				this.bg.alpha = this.defaultBGAlpha;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Focus)
+			{
+				this.bg.alpha = 1f;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Select)
+			{
+				this.bg.alpha = 1f;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Disable)
+			{
+				this.bg.alpha = 0.2f;
+			}
+		}
+	}
+
+	private void Awake()
+	{
+		this.defaultBGAlpha = this.bg.alpha;
+		this.selectType = OnaholeNodeButton.SelectType.None;
+		this.SetCopyTargetSprite(this.copyTargetSprite);
+	}
+
+	public void SetCopyTargetSprite(UISprite sprite)
+	{
+		if (sprite == null || this.iconSprite == null)
+		{
+			return;
+		}
+		this.copyTargetSprite = sprite;
+		this.iconSprite.atlas = this.copyTargetSprite.atlas;
+		this.iconSprite.spriteName = this.copyTargetSprite.spriteName;
+		this.iconSprite.SetDimensions(this.copyTargetSprite.width, this.copyTargetSprite.height);
+		this.iconSprite.SetDirty();
+		this.Update();
+	}
+
+	private void Update()
+	{
+		if (this.iconSprite != null && this.copyTargetSprite != null)
+		{
+			this.iconSprite.color = this.copyTargetSprite.color;
+		}
+	}
+
+	GameObject IOnaholeNodeButton.get_gameObject()
+	{
+		return base.gameObject;
+	}
+
+	[SerializeField]
+	private UIWidget bg;
+
+	[SerializeField]
+	private UISprite iconSprite;
+
+	[SerializeField]
+	private UISprite copyTargetSprite;
+
+	private float defaultBGAlpha;
+
+	private OnaholeNodeButton.SelectType selectType_;
+}

+ 384 - 0
Assembly-CSharp/OnaholeNodeMenuChildSecondRow.cs

@@ -0,0 +1,384 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class OnaholeNodeMenuChildSecondRow : OnaholeBaseNodeMenuManager
+{
+	private void Awake()
+	{
+		this.Clear();
+	}
+
+	public void Clear()
+	{
+		this.isInputEnabled = (this.sliderInputMode = false);
+		this.changeInput = -1;
+		this.ClearButtonObject();
+		this.mode = OnaholeNodeMenuChildSecondRow.Mode.SkillCategorySelect;
+	}
+
+	public void CallMenu(OnaholeNodeMenuChildSecondRow.Mode mode)
+	{
+		this.mode = mode;
+		this.ClearButtonObject();
+		if (mode == OnaholeNodeMenuChildSecondRow.Mode.StageSelect)
+		{
+			this.CallStageSlect();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.SkillCategorySelect)
+		{
+			this.CallSkillCategorySelect();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.Costume)
+		{
+			this.CallCostumeSetting();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.DeviceSetting)
+		{
+			this.CallChuBLipSetting();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.MaidSensitivity)
+		{
+			this.CallMaidSensitivitySetting();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.PistonSetting)
+		{
+			this.CallPistonSetting();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.ManAlpha)
+		{
+			this.CallManAlphaSetting();
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.AutoMode)
+		{
+			this.CallGeneralBoolControl(this.nodeMenuManager.autoPistonEnabled);
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.AutoFinish)
+		{
+			this.CallGeneralBoolControl(this.nodeMenuManager.autoFinishEnabled);
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.AutoReaction)
+		{
+			this.CallGeneralBoolControl(this.nodeMenuManager.autoReaction);
+		}
+		else if (mode == OnaholeNodeMenuChildSecondRow.Mode.YotogiEnd)
+		{
+			this.CallYotogiEnd();
+		}
+		if (mode != OnaholeNodeMenuChildSecondRow.Mode.Costume)
+		{
+			this.menuButtonGrid.Reposition();
+		}
+		this.changeInput = 1;
+	}
+
+	private void CallStageSlect()
+	{
+	}
+
+	public void CallSkillCategorySelect()
+	{
+	}
+
+	private void CallCostumeSetting()
+	{
+		Action enterEvent = delegate
+		{
+			UndressingManager.UndressingData undressingData = this.nodeMenuManager.undressingManager.GetUndressingData((UndressingManager.UnitType)Enum.Parse(typeof(UndressingManager.UnitType), base.selectedNodeButton.button.uniqueName));
+			this.nodeMenuManager.undressingManager.OnClickButton(undressingData);
+		};
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		foreach (UndressingManager.UnitData unitData in this.nodeMenuManager.undressingManager.UnitDataList)
+		{
+			OnaholeNodeIconButton onaholeNodeIconButton = base.CreateNodeIconMenu(gameObject, unitData.UnitType.ToString());
+			onaholeNodeIconButton.SetCopyTargetSprite(unitData.ButtonObject.GetComponent<UISprite>());
+			onaholeNodeIconButton.selectType = ((!unitData.ButtonObject.isEnabled) ? OnaholeNodeButton.SelectType.Disable : OnaholeNodeButton.SelectType.Focus);
+			this.menuButtons.Add(new NodeButtonData(onaholeNodeIconButton, enterEvent));
+		}
+		base.SetFocusButton(this.menuButtons[0]);
+		this.menuButtonGrid.arrangement = UIGrid.Arrangement.Horizontal;
+		this.menuButtonGrid.cellWidth = (this.menuButtonGrid.cellHeight = 115f);
+		this.menuButtonGrid.maxPerLine = 3;
+		this.menuButtonGrid.Reposition();
+		this.operationMap = new List<List<NodeButtonData>>();
+		for (int i = 0; i < this.menuButtonGrid.maxPerLine; i++)
+		{
+			this.operationMap.Add(new List<NodeButtonData>());
+		}
+		int num = 0;
+		foreach (NodeButtonData item in this.menuButtons)
+		{
+			List<NodeButtonData> list = this.operationMap[num];
+			list.Add(item);
+			num++;
+			if (this.operationMap.Count <= num)
+			{
+				num = 0;
+			}
+		}
+		this.menuButtonGrid.cellWidth = 0f;
+		this.menuButtonGrid.arrangement = UIGrid.Arrangement.Vertical;
+		this.menuButtonGrid.maxPerLine = 0;
+	}
+
+	private void CallChuBLipSetting()
+	{
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.Sensitivity, "Sensitivity"), new Action(this.StartSliderInputMode)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.HoleSync, "HoleSync"), new Action(this.StartSliderInputMode)));
+		base.SetFocusButton(this.menuButtons[0]);
+		this.menuButtonGrid.cellHeight = (float)this.kGridCellHeightSliderItem;
+	}
+
+	private void CallMaidSensitivitySetting()
+	{
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.MaidSensitivity, "MaidSensitivity"), new Action(this.StartSliderInputMode)));
+		base.SetFocusButton(this.menuButtons[0]);
+		this.menuButtonGrid.cellHeight = (float)this.kGridCellHeightSliderItem;
+	}
+
+	private void CallPistonSetting()
+	{
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.HoleAutoSpeed, "HoleAutoSpeed"), new Action(this.StartSliderInputMode)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.HoleAutoInsertStartPos, "HoleAutoInsertStartPos"), new Action(this.StartSliderInputMode)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.HoleAutoInsertEndPos, "HoleAutoInsertEndPos"), new Action(this.StartSliderInputMode)));
+		base.SetFocusButton(this.menuButtons[0]);
+		this.menuButtonGrid.cellHeight = (float)this.kGridCellHeightSliderItem;
+	}
+
+	private void CallManAlphaSetting()
+	{
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateNodeSlider(gameObject, OnaholeNodeSlider.SliderType.ManAlpha, "ManAlpha"), new Action(this.StartSliderInputMode)));
+		base.SetFocusButton(this.menuButtons[0]);
+		this.menuButtonGrid.cellHeight = (float)this.kGridCellHeightSliderItem;
+	}
+
+	private void CallGeneralBoolControl(bool currentValue)
+	{
+		Action enterEvent = delegate
+		{
+			this.OnCancelMenu();
+		};
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "ON", "true", true, false), enterEvent));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "OFF", "false", true, false), enterEvent));
+		base.SetFocusButton((!currentValue) ? this.menuButtons[1] : this.menuButtons[0]);
+		this.menuButtonGrid.cellHeight = (float)this.kGridCellHeightButtonItem;
+	}
+
+	private void CallYotogiEnd()
+	{
+		Action enterEvent = delegate
+		{
+			if (bool.Parse(base.selectedNodeButton.button.uniqueName))
+			{
+				this.nodeMenuManager.EndYotogi();
+			}
+			else
+			{
+				this.OnCancelMenu();
+			}
+			this.isInputEnabled = false;
+		};
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "OK", "true", true, false), enterEvent));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "CANCEL", "false", true, false), enterEvent));
+		base.SetFocusButton(this.menuButtons[1]);
+		this.menuButtonGrid.cellHeight = (float)this.kGridCellHeightButtonItem;
+	}
+
+	private void StartSliderInputMode()
+	{
+		NodeButtonData selectedNodeButton = base.selectedNodeButton;
+		base.SetSelectedButton(selectedNodeButton);
+		this.sliderInputMode = true;
+	}
+
+	public void ReturnMenu()
+	{
+		if (base.selectedNodeButton != null)
+		{
+			base.selectedNodeButton.button.selectType = OnaholeNodeButton.SelectType.Focus;
+		}
+		this.changeInput = 1;
+	}
+
+	protected override void OnEnterMenu()
+	{
+		base.OnEnterMenu();
+		if (base.selectedNodeButton != null)
+		{
+			base.selectedNodeButton.enterEvent();
+		}
+	}
+
+	protected override void OnCancelMenu()
+	{
+		base.OnCancelMenu();
+		string uniqueName = base.selectedNodeButton.button.uniqueName;
+		if (this.mode == OnaholeNodeMenuChildSecondRow.Mode.AutoMode)
+		{
+			this.nodeMenuManager.autoPistonEnabled = bool.Parse(uniqueName);
+		}
+		else if (this.mode == OnaholeNodeMenuChildSecondRow.Mode.AutoFinish)
+		{
+			this.nodeMenuManager.autoFinishEnabled = bool.Parse(uniqueName);
+		}
+		else if (this.mode == OnaholeNodeMenuChildSecondRow.Mode.AutoReaction)
+		{
+			this.nodeMenuManager.autoReaction = bool.Parse(uniqueName);
+		}
+		this.isInputEnabled = false;
+		this.ClearButtonObject();
+		this.nodeMenuManager.ReturnMenu();
+	}
+
+	private void ClearButtonObject()
+	{
+		Transform transform = this.menuButtonGrid.transform;
+		GameObject[] array = new GameObject[transform.childCount];
+		for (int i = 0; i < transform.childCount; i++)
+		{
+			array[i] = transform.GetChild(i).gameObject;
+		}
+		for (int j = 0; j < array.Length; j++)
+		{
+			UnityEngine.Object.DestroyImmediate(array[j]);
+		}
+		transform.DetachChildren();
+		this.menuButtons.Clear();
+		this.operationMap.Clear();
+	}
+
+	protected override void Update()
+	{
+		if (this.sliderInputMode)
+		{
+			NodeButtonData selectedNodeButton = base.selectedNodeButton;
+			OnaholeNodeSlider onaholeNodeSlider = selectedNodeButton.button as OnaholeNodeSlider;
+			if (onaholeNodeSlider != null)
+			{
+				if (base.inputRightKye)
+				{
+					onaholeNodeSlider.sliderValue += 0.1f;
+				}
+				else if (base.inputLeftKey)
+				{
+					onaholeNodeSlider.sliderValue -= 0.1f;
+				}
+				else if (base.inputCancelKey)
+				{
+					base.SetFocusButton(selectedNodeButton);
+					this.sliderInputMode = false;
+					base.OnCancelMenu();
+				}
+				else if (base.inputEnterKey)
+				{
+					base.SetFocusButton(selectedNodeButton);
+					this.sliderInputMode = false;
+					base.OnEnterMenu();
+				}
+			}
+		}
+		else if (this.mode != OnaholeNodeMenuChildSecondRow.Mode.Costume)
+		{
+			if (base.inputDownKey)
+			{
+				base.NextItem();
+			}
+			else if (base.inputUpKey)
+			{
+				base.PrevItem();
+			}
+			else if (base.inputEnterKey || base.inputRightKye)
+			{
+				this.OnEnterMenu();
+			}
+			else if (base.inputCancelKey || base.inputLeftKey)
+			{
+				this.OnCancelMenu();
+			}
+		}
+		else if (base.inputDownKey)
+		{
+			base.NextItem();
+		}
+		else if (base.inputUpKey)
+		{
+			base.PrevItem();
+		}
+		else if (base.inputRightKye)
+		{
+			base.RightItem();
+		}
+		else if (base.inputLeftKey)
+		{
+			bool flag = false;
+			int num = 0;
+			while (num < this.operationMap[0].Count && !flag)
+			{
+				NodeButtonData nodeButtonData = this.operationMap[0][num];
+				if (nodeButtonData.button.selectType == OnaholeNodeButton.SelectType.Focus || nodeButtonData.button.selectType == OnaholeNodeButton.SelectType.Select)
+				{
+					flag = true;
+				}
+				num++;
+			}
+			if (flag)
+			{
+				this.OnCancelMenu();
+			}
+			else
+			{
+				base.LeftItem();
+			}
+		}
+		else if (base.inputEnterKey)
+		{
+			this.OnEnterMenu();
+		}
+		else if (base.inputCancelKey)
+		{
+			this.OnCancelMenu();
+		}
+		if (this.changeInput != -1)
+		{
+			this.isInputEnabled = (this.changeInput == 1);
+		}
+		this.changeInput = -1;
+	}
+
+	private readonly int kGridCellHeightButtonItem = 45;
+
+	private readonly int kGridCellHeightSliderItem = 100;
+
+	[SerializeField]
+	public OnaholeNodeMenuManager nodeMenuManager;
+
+	[SerializeField]
+	private OnaholeNodeMenuChildThirdRow thirdRow;
+
+	private OnaholeNodeMenuChildSecondRow.Mode mode;
+
+	private int changeInput;
+
+	private bool sliderInputMode;
+
+	public enum Mode
+	{
+		StageSelect,
+		SkillCategorySelect,
+		Costume,
+		DeviceSetting,
+		MaidSensitivity,
+		PistonSetting,
+		ManAlpha,
+		AutoMode,
+		AutoFinish,
+		AutoReaction,
+		YotogiEnd
+	}
+}

+ 80 - 0
Assembly-CSharp/OnaholeNodeMenuChildThirdRow.cs

@@ -0,0 +1,80 @@
+using System;
+using UnityEngine;
+
+public class OnaholeNodeMenuChildThirdRow : OnaholeBaseNodeMenuManager
+{
+	private void Awake()
+	{
+		this.Clear();
+	}
+
+	public void Clear()
+	{
+		this.isInputEnabled = false;
+		this.ClearButtonObject();
+	}
+
+	public void CallSkillSelect(string categoryName)
+	{
+	}
+
+	public void OnEnterSkill()
+	{
+	}
+
+	protected override void OnEnterMenu()
+	{
+		base.OnEnterMenu();
+		if (base.selectedNodeButton != null)
+		{
+			base.selectedNodeButton.enterEvent();
+		}
+	}
+
+	protected override void OnCancelMenu()
+	{
+		base.OnCancelMenu();
+		this.isInputEnabled = false;
+		this.ClearButtonObject();
+		this.secondRow.ReturnMenu();
+	}
+
+	private void ClearButtonObject()
+	{
+		Transform transform = this.menuButtonGrid.transform;
+		GameObject[] array = new GameObject[transform.childCount];
+		for (int i = 0; i < transform.childCount; i++)
+		{
+			array[i] = transform.GetChild(i).gameObject;
+		}
+		for (int j = 0; j < array.Length; j++)
+		{
+			UnityEngine.Object.DestroyImmediate(array[j]);
+		}
+		transform.DetachChildren();
+		this.menuButtons.Clear();
+	}
+
+	protected override void Update()
+	{
+		if (base.inputDownKey)
+		{
+			base.NextItem();
+		}
+		else if (base.inputUpKey)
+		{
+			base.PrevItem();
+		}
+		else if (base.inputEnterKey || base.inputRightKye)
+		{
+			this.OnEnterMenu();
+		}
+		else if (base.inputCancelKey || base.inputLeftKey)
+		{
+			this.OnCancelMenu();
+		}
+	}
+
+	[SerializeField]
+	private OnaholeNodeMenuChildSecondRow secondRow;
+}

+ 238 - 0
Assembly-CSharp/OnaholeNodeMenuManager.cs

@@ -0,0 +1,238 @@
+using System;
+using UnityEngine;
+
+public class OnaholeNodeMenuManager : OnaholeBaseNodeMenuManager
+{
+	public bool isOpen
+	{
+		get
+		{
+			return base.gameObject.activeSelf;
+		}
+	}
+
+	private void Awake()
+	{
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "ステージ選択", OnaholeNodeMenuChildSecondRow.Mode.StageSelect.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "夜伽スキル", OnaholeNodeMenuChildSecondRow.Mode.SkillCategorySelect.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "コスチューム", OnaholeNodeMenuChildSecondRow.Mode.Costume.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "Chu-B Lip S2設定", OnaholeNodeMenuChildSecondRow.Mode.DeviceSetting.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "メイド感度", OnaholeNodeMenuChildSecondRow.Mode.MaidSensitivity.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "ピストン設定", OnaholeNodeMenuChildSecondRow.Mode.PistonSetting.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "男の透明度", OnaholeNodeMenuChildSecondRow.Mode.ManAlpha.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "オートモード", OnaholeNodeMenuChildSecondRow.Mode.AutoMode.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "オートフィニッシュ", OnaholeNodeMenuChildSecondRow.Mode.AutoFinish.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "オートリアクション", OnaholeNodeMenuChildSecondRow.Mode.AutoReaction.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "リアクションLevelUp", "reactionlevelup", true, false), new Action(this.ClickEmulate)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "エディット", "edit", true, false), new Action(this.ClickEmulate)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "液体を拭く", "releaseseieki", true, false), new Action(this.ClickEmulate)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "カメラリセット", "camerareset", true, false), new Action(this.ClickEmulate)));
+		this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, "夜伽終了", OnaholeNodeMenuChildSecondRow.Mode.YotogiEnd.ToString(), true, true), new Action(this.CallSubMenu)));
+		this.reactionLevelUpButtonData = base.GetNodeButtonData("reactionlevelup");
+		this.menuButtonGrid.Reposition();
+		base.SetFocusButton(this.menuButtons[0]);
+		this.isInputEnabled = false;
+		this.changeInput = -1;
+	}
+
+	public void Open()
+	{
+		this.Close();
+		this.changeInput = 1;
+		if (!this.editButton.isEnabled)
+		{
+			base.GetNodeButtonData("edit").selectType = OnaholeNodeButton.SelectType.Disable;
+		}
+		base.SetFocusButton(this.menuButtons[0]);
+		base.gameObject.SetActive(true);
+		GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+	}
+
+	public void Close()
+	{
+		this.isInputEnabled = false;
+		this.changeInput = -1;
+		this.secondRow.Clear();
+		this.thirdRow.Clear();
+		base.gameObject.SetActive(false);
+	}
+
+	private void CallSubMenu()
+	{
+		if (base.selectedNodeButton == null)
+		{
+			return;
+		}
+		base.SetSelectedButton(base.selectedNodeButton);
+		this.secondRow.CallMenu((OnaholeNodeMenuChildSecondRow.Mode)Enum.Parse(typeof(OnaholeNodeMenuChildSecondRow.Mode), base.selectedNodeButton.button.uniqueName));
+		this.isInputEnabled = false;
+	}
+
+	private void ClickEmulate()
+	{
+		if (base.selectedNodeButton == null)
+		{
+			return;
+		}
+		UIButton uibutton = null;
+		if (base.selectedNodeButton.button.uniqueName == "edit")
+		{
+			uibutton = this.editButton;
+		}
+		else if (base.selectedNodeButton.button.uniqueName == "releaseseieki")
+		{
+			uibutton = this.releaseSeiekiButton;
+		}
+		else if (base.selectedNodeButton.button.uniqueName == "camerareset")
+		{
+			uibutton = this.cameraResetButton;
+		}
+		else if (base.selectedNodeButton.button.uniqueName == "reactionlevelup")
+		{
+			uibutton = this.reactionLevelUpButton;
+		}
+		if (uibutton != null)
+		{
+			EventDelegate.Execute(uibutton.onClick);
+		}
+	}
+
+	public void ReturnMenu()
+	{
+		if (base.selectedNodeButton != null)
+		{
+			base.selectedNodeButton.button.selectType = OnaholeNodeButton.SelectType.Focus;
+		}
+		this.changeInput = 1;
+	}
+
+	public void EndYotogi()
+	{
+		EventDelegate.Execute(this.yotogiEndButton.onClick);
+	}
+
+	protected override void OnEnterMenu()
+	{
+		base.OnEnterMenu();
+		if (base.selectedNodeButton != null)
+		{
+			base.selectedNodeButton.enterEvent();
+		}
+	}
+
+	protected override void OnCancelMenu()
+	{
+	}
+
+	private void UpdateUIText()
+	{
+		NodeButtonData nodeButtonData = base.GetNodeButtonData(OnaholeNodeMenuChildSecondRow.Mode.AutoMode.ToString());
+		OnaholeNodeButton onaholeNodeButton = nodeButtonData.button as OnaholeNodeButton;
+		onaholeNodeButton.text = "オートモード:" + ((!this.autoPistonEnabled) ? "OFF" : "ON");
+		nodeButtonData = base.GetNodeButtonData(OnaholeNodeMenuChildSecondRow.Mode.AutoFinish.ToString());
+		onaholeNodeButton = (nodeButtonData.button as OnaholeNodeButton);
+		onaholeNodeButton.text = "オートフィニッシュ:" + ((!this.autoFinishEnabled) ? "OFF" : "ON");
+		nodeButtonData = base.GetNodeButtonData(OnaholeNodeMenuChildSecondRow.Mode.AutoReaction.ToString());
+		onaholeNodeButton = (nodeButtonData.button as OnaholeNodeButton);
+		onaholeNodeButton.text = "オートリアクション:" + ((!this.autoReaction) ? "OFF" : "ON");
+		bool flag = false;
+		if ((this.autoReaction && this.reactionLevelUpButtonData.button.selectType != OnaholeNodeButton.SelectType.Disable) || (this.reactionLevel == 2 && this.reactionLevelUpButtonData.button.selectType != OnaholeNodeButton.SelectType.Disable))
+		{
+			flag = true;
+		}
+		if (flag)
+		{
+			if (base.selectedNodeButton.button.uniqueName == this.reactionLevelUpButtonData.button.uniqueName)
+			{
+				for (int i = 0; i < this.menuButtons.Count; i++)
+				{
+					if (this.menuButtons[i].button.uniqueName == base.selectedNodeButton.button.uniqueName)
+					{
+						int num = i + 1;
+						if (this.menuButtons.Count <= num)
+						{
+							num = 0;
+						}
+						base.SetFocusButton(this.menuButtons[num]);
+						break;
+					}
+				}
+			}
+			this.reactionLevelUpButtonData.button.selectType = OnaholeNodeButton.SelectType.Disable;
+		}
+		else if (!this.autoReaction && this.reactionLevel != 2 && this.reactionLevelUpButtonData.button.selectType == OnaholeNodeButton.SelectType.Disable)
+		{
+			this.reactionLevelUpButtonData.button.selectType = OnaholeNodeButton.SelectType.None;
+		}
+	}
+
+	protected override void Update()
+	{
+		if (base.inputDownKey)
+		{
+			base.NextItem();
+		}
+		else if (base.inputUpKey)
+		{
+			base.PrevItem();
+		}
+		else if (base.inputEnterKey || base.inputRightKye)
+		{
+			this.OnEnterMenu();
+		}
+		else if (base.inputCancelKey || base.inputLeftKey)
+		{
+			this.OnCancelMenu();
+		}
+		if (this.changeInput != -1)
+		{
+			this.isInputEnabled = (this.changeInput == 1);
+		}
+		this.changeInput = -1;
+		this.UpdateUIText();
+	}
+
+	[SerializeField]
+	private OnaholeNodeMenuChildSecondRow secondRow;
+
+	[SerializeField]
+	private OnaholeNodeMenuChildThirdRow thirdRow;
+
+	[SerializeField]
+	[Header("夜伽から貰ってくるコンポーネント群")]
+	public YotogiPlayManagerWithChubLip playManager;
+
+	[SerializeField]
+	public YotogiAppearanceWithChubLip appearanceData;
+
+	[SerializeField]
+	public UndressingManager undressingManager;
+
+	[SerializeField]
+	private UIButton reactionLevelUpButton;
+
+	[SerializeField]
+	private UIButton editButton;
+
+	[SerializeField]
+	private UIButton releaseSeiekiButton;
+
+	[SerializeField]
+	private UIButton cameraResetButton;
+
+	[SerializeField]
+	private UIButton yotogiEndButton;
+
+	private int changeInput;
+
+	private NodeButtonData reactionLevelUpButtonData;
+
+	public bool autoPistonEnabled;
+
+	public bool autoFinishEnabled;
+
+	public bool autoReaction;
+
+	public int reactionLevel;
+}

+ 111 - 0
Assembly-CSharp/OnaholeNodeSlider.cs

@@ -0,0 +1,111 @@
+using System;
+using UnityEngine;
+
+public class OnaholeNodeSlider : MonoBehaviour, IOnaholeNodeButton
+{
+	public string text
+	{
+		get
+		{
+			return this.textLabel.text;
+		}
+		set
+		{
+			this.textLabel.text = ((!string.IsNullOrEmpty(value)) ? value : string.Empty);
+		}
+	}
+
+	public string uniqueName { get; set; }
+
+	public OnaholeNodeButton.SelectType selectType
+	{
+		get
+		{
+			return this.selectType_;
+		}
+		set
+		{
+			this.selectType_ = value;
+			if (value == OnaholeNodeButton.SelectType.None)
+			{
+				this.bg.alpha = this.defaultBGAlpha;
+				this.textLabel.color = Color.white;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Focus)
+			{
+				this.bg.alpha = 1f;
+				this.textLabel.color = Color.white;
+			}
+			else if (value == OnaholeNodeButton.SelectType.Select)
+			{
+				this.bg.alpha = 1f;
+				this.textLabel.color = Color.yellow;
+			}
+		}
+	}
+
+	public float sliderValue
+	{
+		get
+		{
+			return (this.sliderData == null) ? 0f : this.sliderData.slider.value;
+		}
+		set
+		{
+			if (this.sliderData != null)
+			{
+				this.sliderData.slider.value = value;
+			}
+		}
+	}
+
+	public void Awake()
+	{
+		this.defaultBGAlpha = this.bg.alpha;
+		this.selectType = OnaholeNodeButton.SelectType.None;
+	}
+
+	public void SetSliderType(OnaholeNodeSlider.SliderType type)
+	{
+	}
+
+	private void Update()
+	{
+	}
+
+	private void OnChangeSliderValue(AbstractSliderData obj)
+	{
+		obj.ChangeSliderValue();
+	}
+
+	GameObject IOnaholeNodeButton.get_gameObject()
+	{
+		return base.gameObject;
+	}
+
+	[SerializeField]
+	private UIWidget bg;
+
+	[SerializeField]
+	private UILabel textLabel;
+
+	[SerializeField]
+	private UISlider valueSlider;
+
+	private float defaultBGAlpha;
+
+	private OnaholeNodeButton.SelectType selectType_;
+
+	private AbstractSliderData sliderData;
+
+	public enum SliderType
+	{
+		Sensitivity,
+		HoleSync,
+		HoleAutoSpeed,
+		HoleAutoInsertStartPos,
+		HoleAutoInsertEndPos,
+		MaidSensitivity,
+		ManAlpha
+	}
+}

+ 202 - 0
Assembly-CSharp/OnaholeNodeTouchMenuManager.cs

@@ -0,0 +1,202 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class OnaholeNodeTouchMenuManager : OnaholeBaseNodeMenuManager
+{
+	public bool isOpen
+	{
+		get
+		{
+			return base.gameObject.activeSelf;
+		}
+	}
+
+	private OnaholeNodeTouchMenuManager.UIMode uiMode
+	{
+		get
+		{
+			return (!this.menuButtonGrid.gameObject.activeSelf) ? OnaholeNodeTouchMenuManager.UIMode.Play : OnaholeNodeTouchMenuManager.UIMode.Menu;
+		}
+		set
+		{
+			if (value == OnaholeNodeTouchMenuManager.UIMode.Menu)
+			{
+				this.menuButtonGrid.gameObject.SetActive(true);
+				this.playImageWidget.gameObject.SetActive(false);
+				this.playImageWidget.alpha = 1f;
+			}
+			else
+			{
+				this.menuButtonGrid.gameObject.SetActive(false);
+				this.playImageWidget.gameObject.SetActive(true);
+				this.playImageWidget.alpha = 1f;
+			}
+		}
+	}
+
+	public void AddMenu(string menuText, Action<OnaholeNodeTouchMenuManager> onClickEvent)
+	{
+		GameObject gameObject = this.menuButtonGrid.gameObject;
+		if (!this.onClickEventDic.ContainsKey(menuText))
+		{
+			this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(gameObject, menuText, menuText, true, false), new Action(this.OnClickStartToucMode)));
+			this.onClickEventDic.Add(menuText, onClickEvent);
+		}
+	}
+
+	public void ClearMenu()
+	{
+		foreach (NodeButtonData nodeButtonData in this.menuButtons)
+		{
+			UnityEngine.Object.DestroyImmediate(nodeButtonData.button.gameObject);
+		}
+		this.menuButtons.Clear();
+		this.menuButtonGrid.Reposition();
+		this.onClickEventDic.Clear();
+		this.Close();
+	}
+
+	public void Open()
+	{
+		this.Close();
+		if (this.menuButtons.Count == 0 || this.menuButtons[this.menuButtons.Count - 1].button.uniqueName != "close")
+		{
+			this.menuButtons.Add(new NodeButtonData(OnaholeBaseNodeMenuManager.CreateBasicNodeButton(this.menuButtonGrid.gameObject, "弄りモードを終了", "close", true, false), new Action(this.OnCancelMenu)));
+		}
+		this.changeInput = 1;
+		base.SetFocusButton(this.menuButtons[0]);
+		base.gameObject.SetActive(true);
+		this.menuButtonGrid.Reposition();
+		this.uiMode = OnaholeNodeTouchMenuManager.UIMode.Menu;
+		GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+	}
+
+	public void Close()
+	{
+		this.reservCallMenu = false;
+		this.isInputEnabled = false;
+		this.changeInput = -1;
+		base.gameObject.SetActive(false);
+	}
+
+	public void SelectMenu(string menuText)
+	{
+		this.Close();
+		if (this.menuButtons.Count == 0)
+		{
+			return;
+		}
+		foreach (NodeButtonData nodeButtonData in this.menuButtons)
+		{
+			if (menuText == nodeButtonData.button.uniqueName)
+			{
+				this.changeInput = 1;
+				base.gameObject.SetActive(true);
+				base.SetFocusButton(nodeButtonData);
+				this.OnClickStartToucMode();
+				break;
+			}
+		}
+	}
+
+	public void ChangeMenuMode()
+	{
+		this.reservCallMenu = true;
+	}
+
+	private void OnClickStartToucMode()
+	{
+		if (base.selectedNodeButton == null)
+		{
+			return;
+		}
+		string uniqueName = base.selectedNodeButton.button.uniqueName;
+		if (this.onClickEventDic.ContainsKey(uniqueName) && this.onClickEventDic[uniqueName] != null)
+		{
+			this.onClickEventDic[uniqueName](this);
+		}
+		this.uiMode = OnaholeNodeTouchMenuManager.UIMode.Play;
+	}
+
+	protected override void OnEnterMenu()
+	{
+		if (base.selectedNodeButton != null)
+		{
+			if (base.selectedNodeButton.button.uniqueName != "close")
+			{
+				base.OnEnterMenu();
+			}
+			base.selectedNodeButton.enterEvent();
+		}
+	}
+
+	protected override void OnCancelMenu()
+	{
+	}
+
+	protected override void Update()
+	{
+		if (this.uiMode == OnaholeNodeTouchMenuManager.UIMode.Menu)
+		{
+			if (base.inputDownKey)
+			{
+				base.NextItem();
+			}
+			else if (base.inputUpKey)
+			{
+				base.PrevItem();
+			}
+			else if (base.inputEnterKey || base.inputRightKye)
+			{
+				this.OnEnterMenu();
+			}
+			else if (base.inputCancelKey || base.inputLeftKey)
+			{
+				this.OnCancelMenu();
+			}
+		}
+		else if (base.inputEnterKey)
+		{
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+			this.uiMode = OnaholeNodeTouchMenuManager.UIMode.Menu;
+		}
+		else if (base.inputCancelKey)
+		{
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+			this.playImageWidget.alpha = (float)((!Mathf.Approximately(1f, this.playImageWidget.alpha)) ? 1 : 0);
+		}
+		if (this.changeInput != -1)
+		{
+			this.isInputEnabled = (this.changeInput == 1);
+		}
+		this.changeInput = -1;
+		if (this.reservCallMenu)
+		{
+			this.uiMode = OnaholeNodeTouchMenuManager.UIMode.Menu;
+			GameMain.Instance.SoundMgr.PlaySystem(SoundMgr.SeType.Click);
+		}
+		this.reservCallMenu = false;
+	}
+
+	[SerializeField]
+	private UIWidget playImageWidget;
+
+	[SerializeField]
+	[Header("夜伽から貰ってくるコンポーネント群")]
+	private YotogiPlayManagerWithChubLip playManager;
+
+	public Action onCallModeEnd;
+
+	private int changeInput;
+
+	private Dictionary<string, Action<OnaholeNodeTouchMenuManager>> onClickEventDic = new Dictionary<string, Action<OnaholeNodeTouchMenuManager>>();
+
+	private bool reservCallMenu;
+
+	public enum UIMode
+	{
+		Menu,
+		Play
+	}
+}

+ 4 - 0
Assembly-CSharp/OvrGrabObj.cs

@@ -5,6 +5,10 @@ public class OvrGrabObj : MonoBehaviour
 {
 	private void Awake()
 	{
+		if (!GameMain.Instance.VRMode || GameMain.Instance.VRFamily == GameMain.VRFamilyType.NON)
+		{
+			base.enabled = false;
+		}
 		this.m_nOvrGrabHandLayerNo = LayerMask.NameToLayer("OvrGrabHand");
 	}
 

+ 2 - 2
Assembly-CSharp/OvrIK.cs

@@ -1403,7 +1403,7 @@ public class OvrIK : MonoBehaviour
 	{
 		public void OnBeforeSerialize()
 		{
-			this.m_nVersion = 1150;
+			this.m_nVersion = 1160;
 		}
 
 		public void OnAfterDeserialize()
@@ -1463,7 +1463,7 @@ public class OvrIK : MonoBehaviour
 		private const string CONF_NAME = "OvrIK.json";
 
 		[SerializeField]
-		private int m_nVersion = 1150;
+		private int m_nVersion = 1160;
 
 		[SerializeField]
 		private float solver_locomotion_weight = 1f;

+ 1 - 1
Assembly-CSharp/PhotoModeSaveAndLoad.cs

@@ -450,7 +450,7 @@ public class PhotoModeSaveAndLoad : MonoBehaviour
 	private XElement CreateCommonData(string title, string comment)
 	{
 		string value = DateTime.ParseExact(DateTime.Now.ToString("yyyyMMddHHmmss"), "yyyyMMddHHmmss", null).ToString("yyyy.MM.dd HH:mm");
-		XElement xelement = new XElement("GameVersion", 1150);
+		XElement xelement = new XElement("GameVersion", 1160);
 		XElement xelement2 = new XElement("SaveTime", value);
 		XElement xelement3 = new XElement("Title", title);
 		XElement xelement4 = new XElement("Comment", comment);

+ 1 - 1
Assembly-CSharp/PlayerStatus/Status.cs

@@ -827,7 +827,7 @@ namespace PlayerStatus
 		public void Serialize(BinaryWriter binary)
 		{
 			binary.Write("CM3D2_PLAYER_STATUS");
-			binary.Write(1150);
+			binary.Write(1160);
 			binary.Write(this.playerName_);
 			binary.Write(this.days_);
 			binary.Write(this.totalPurchasePrice_);

+ 9 - 2
Assembly-CSharp/SceneCasino.cs

@@ -132,7 +132,7 @@ public class SceneCasino : KasaSceneMgr<SceneCasino>
 		ExChangeUI instance2 = ExChangeUI.Instance;
 		instance2.FadeInStartAction = (Action)Delegate.Combine(instance2.FadeInStartAction, new Action(delegate
 		{
-			this.m_NguiCam.enabled = false;
+			this.m_NguiEnable = false;
 		}));
 		ExChangeUI instance3 = ExChangeUI.Instance;
 		instance3.FadeOutStartAction = (Action)Delegate.Combine(instance3.FadeOutStartAction, new Action(delegate
@@ -142,7 +142,7 @@ public class SceneCasino : KasaSceneMgr<SceneCasino>
 		ExChangeUI instance4 = ExChangeUI.Instance;
 		instance4.FadeOutStartAction = (Action)Delegate.Combine(instance4.FadeOutStartAction, new Action(delegate
 		{
-			this.m_NguiCam.enabled = true;
+			this.m_NguiEnable = true;
 		}));
 		ExChangeUI instance5 = ExChangeUI.Instance;
 		instance5.FadeOutStartAction = (Action)Delegate.Combine(instance5.FadeOutStartAction, new Action(delegate
@@ -151,6 +151,11 @@ public class SceneCasino : KasaSceneMgr<SceneCasino>
 		}));
 	}
 
+	private void LateUpdate()
+	{
+		this.m_NguiCam.EnableProcess &= this.m_NguiEnable;
+	}
+
 	private void WearMaidInit()
 	{
 		CasinoDataMgr.Instance.DealerMaid.FaceBlend("無し");
@@ -397,6 +402,8 @@ public class SceneCasino : KasaSceneMgr<SceneCasino>
 	[SerializeField]
 	private UICamera m_NguiCam;
 
+	private bool m_NguiEnable = true;
+
 	public enum CasinoMenu
 	{
 		Blackjack,

+ 9 - 2
Assembly-CSharp/SceneCasinoShop.cs

@@ -64,17 +64,22 @@ public class SceneCasinoShop : KasaSceneMgr<SceneCasinoShop>
 		ExChangeUI instance2 = ExChangeUI.Instance;
 		instance2.FadeInStartAction = (Action)Delegate.Combine(instance2.FadeInStartAction, new Action(delegate
 		{
-			this.m_NguiCam.enabled = false;
+			this.m_NguiEnable = false;
 		}));
 		ExChangeUI instance3 = ExChangeUI.Instance;
 		instance3.FadeOutStartAction = (Action)Delegate.Combine(instance3.FadeOutStartAction, new Action(delegate
 		{
-			this.m_NguiCam.enabled = true;
+			this.m_NguiEnable = true;
 		}));
 		this.UpdateUIState();
 		base.StartCoroutine(this.ScrollRecet());
 	}
 
+	private void LateUpdate()
+	{
+		this.m_NguiCam.EnableProcess &= this.m_NguiEnable;
+	}
+
 	private IEnumerator ScrollRecet()
 	{
 		for (int i = 0; i < 5; i++)
@@ -426,6 +431,8 @@ public class SceneCasinoShop : KasaSceneMgr<SceneCasinoShop>
 
 	private UIPanel m_ScrollPanel;
 
+	private bool m_NguiEnable = true;
+
 	[Serializable]
 	private class ScrollUIData
 	{

+ 8 - 4
Assembly-CSharp/Schedule/ScheduleAPI.cs

@@ -520,16 +520,20 @@ namespace Schedule
 				Maid scheduleSlot = GameMain.Instance.CharacterMgr.status.GetScheduleSlot(i);
 				if (scheduleSlot != null)
 				{
-					int key;
+					int num;
 					if (isDaytime)
 					{
-						key = scheduleSlot.status.noonWorkId;
+						num = scheduleSlot.status.noonWorkId;
 					}
 					else
 					{
-						key = scheduleSlot.status.nightWorkId;
+						num = scheduleSlot.status.nightWorkId;
 					}
-					ScheduleCSVData.ScheduleBase scheduleBase = ScheduleCSVData.AllData[key];
+					if (!ScheduleCSVData.AllData.ContainsKey(num))
+					{
+						Debug.LogError("ScheduleAPI:タスクID[" + num + "]のデータが見つかりませんでした");
+					}
+					ScheduleCSVData.ScheduleBase scheduleBase = ScheduleCSVData.AllData[num];
 					if (scheduleBase.type == ScheduleTaskCtrl.TaskType.Yotogi)
 					{
 						ScheduleCSVData.Yotogi yotogi = (ScheduleCSVData.Yotogi)scheduleBase;

+ 28 - 2
Assembly-CSharp/ScheduleCtrl.cs

@@ -117,6 +117,32 @@ public class ScheduleCtrl : BaseCreateViewerCtrl
 				else
 				{
 					ScheduleCtrl.SetMaidStatus(UTY.GetChildObject(gameObject, "MaidStatus", false), maidStatusAndTaskUnit);
+					int num = int.Parse(maidStatusAndTaskUnit.daytimeTaskId);
+					if (!ScheduleCSVData.AllData.ContainsKey(num))
+					{
+						Debug.LogWarning(string.Concat(new object[]
+						{
+							"昼スロットNo[",
+							maidStatusAndTaskUnit.slotNo,
+							"]に存在するタスクID[",
+							num,
+							"]のデータが見つけられませんでした"
+						}));
+						maidStatusAndTaskUnit.daytimeTaskId = 2001.ToString();
+					}
+					num = int.Parse(maidStatusAndTaskUnit.nightTaskId);
+					if (!ScheduleCSVData.AllData.ContainsKey(num))
+					{
+						Debug.LogWarning(string.Concat(new object[]
+						{
+							"夜スロットNo[",
+							maidStatusAndTaskUnit.slotNo,
+							"]に存在するタスクID[",
+							num,
+							"]のデータが見つけられませんでした"
+						}));
+						maidStatusAndTaskUnit.nightTaskId = 10000.ToString();
+					}
 				}
 			}
 			else
@@ -203,8 +229,8 @@ public class ScheduleCtrl : BaseCreateViewerCtrl
 			scheduleSlot.status.nightCommu = false;
 			return null;
 		}
-		ScheduleCSVData.ScheduleBase scheduleBase = ScheduleCSVData.AllData[key];
-		if (!scheduleBase.isCommu)
+		ScheduleCSVData.ScheduleBase scheduleBase = (!ScheduleCSVData.AllData.ContainsKey(key)) ? null : ScheduleCSVData.AllData[key];
+		if (scheduleBase == null || !scheduleBase.isCommu)
 		{
 			if (time == ScheduleMgr.ScheduleTime.DayTime)
 			{

+ 2 - 1
Assembly-CSharp/ScriptManager.cs

@@ -2920,7 +2920,7 @@ public class ScriptManager : IDisposable
 	public void Serialize(BinaryWriter binary)
 	{
 		binary.Write("CM3D2_SCRIPT");
-		binary.Write(1150);
+		binary.Write(1160);
 		this.adv_kag_.Serialize(binary);
 	}
 
@@ -2944,6 +2944,7 @@ public class ScriptManager : IDisposable
 		motionKagManager.SetSloatNo(0);
 		this.kag_mot_dic_.Add(0, motionKagManager);
 		this.ExecScript("global.tf = new Dictionary();");
+		SubtitleMovieManager.DestroyGlobalInstance();
 	}
 
 	public bool compatibilityMode

+ 2 - 2
Assembly-CSharp/SoundMgr.cs

@@ -7,6 +7,8 @@ using wf;
 
 public class SoundMgr : MonoBehaviour
 {
+	public AudioSourceMgr m_AudioDummyVoice { get; private set; }
+
 	public AudioMixerMgr mix_mgr { get; private set; }
 
 	public static float ConvertToAudioSourcePitch(int pitch)
@@ -364,8 +366,6 @@ public class SoundMgr : MonoBehaviour
 
 	private bool[] m_bThreeD = new bool[5];
 
-	private AudioSourceMgr m_AudioDummyVoice;
-
 	public bool compatibilityMode;
 
 	private string[] m_arySeFileName = new string[]

+ 49 - 29
Assembly-CSharp/SubtitleDisplayManager.cs

@@ -4,6 +4,26 @@ using UnityEngine;
 
 public class SubtitleDisplayManager : MonoBehaviour
 {
+	public static float configMessageAlpha
+	{
+		get
+		{
+			return (float)(100 - GameMain.Instance.CMSystem.MsgWndAlpha) / 100f;
+		}
+	}
+
+	public static SubtitleDisplayManager.DisplayType configDisplayType
+	{
+		get
+		{
+			return GameMain.Instance.CMSystem.SubtitleType;
+		}
+		set
+		{
+			GameMain.Instance.CMSystem.SubtitleType = value;
+		}
+	}
+
 	public string charaNameText
 	{
 		get
@@ -101,6 +121,10 @@ public class SubtitleDisplayManager : MonoBehaviour
 					{
 						this.singleTextAreaObject.SetActive(true);
 						this.singleUILabel.text = ((this.hideTypeOverRide != SubtitleDisplayManager.DisplayType.Subtitle) ? this.originalText_ : this.subtitlesText_);
+						UILabel uilabel = (this.hideTypeOverRide != SubtitleDisplayManager.DisplayType.Original) ? this.subtitlesUILabel : this.originalUILabel;
+						this.singleUILabel.effectDistance = uilabel.effectDistance;
+						this.singleUILabel.spacingX = uilabel.spacingX;
+						this.singleUILabel.spacingY = uilabel.spacingY;
 					}
 				}
 			}
@@ -108,6 +132,10 @@ public class SubtitleDisplayManager : MonoBehaviour
 			{
 				this.singleTextAreaObject.SetActive(true);
 				this.singleUILabel.text = ((this.displayType_ != SubtitleDisplayManager.DisplayType.Subtitle) ? this.originalText_ : this.subtitlesText_);
+				UILabel uilabel2 = (this.displayType_ != SubtitleDisplayManager.DisplayType.Subtitle) ? this.originalUILabel : this.subtitlesUILabel;
+				this.singleUILabel.effectDistance = uilabel2.effectDistance;
+				this.singleUILabel.spacingX = uilabel2.spacingX;
+				this.singleUILabel.spacingY = uilabel2.spacingY;
 			}
 		}
 	}
@@ -128,43 +156,25 @@ public class SubtitleDisplayManager : MonoBehaviour
 	{
 		get
 		{
-			return (this.messageBgAlphaLinkWidgets == null || 0 >= this.messageBgAlphaLinkWidgets.Length) ? 0f : this.messageBgAlphaLinkWidgets[0].alpha;
+			return this.setAlpha;
 		}
 		set
 		{
+			this.setAlpha = value;
 			if (this.messageBgAlphaLinkWidgets != null)
 			{
 				foreach (UIWidget uiwidget in this.messageBgAlphaLinkWidgets)
 				{
-					if (uiwidget != null && !Mathf.Approximately(uiwidget.alpha, value))
+					float num = 0.7f * this.setAlpha;
+					if (uiwidget != null && !Mathf.Approximately(uiwidget.alpha, num))
 					{
-						uiwidget.alpha = value;
+						uiwidget.alpha = num;
 					}
 				}
 			}
 		}
 	}
 
-	private float configMessageAlpha
-	{
-		get
-		{
-			return (float)(100 - GameMain.Instance.CMSystem.MsgWndAlpha) / 100f;
-		}
-	}
-
-	private SubtitleDisplayManager.DisplayType configDisplayType
-	{
-		get
-		{
-			return GameMain.Instance.CMSystem.SubtitleType;
-		}
-		set
-		{
-			GameMain.Instance.CMSystem.SubtitleType = value;
-		}
-	}
-
 	private void Awake()
 	{
 		if (this.callAwake)
@@ -177,8 +187,8 @@ public class SubtitleDisplayManager : MonoBehaviour
 		text = text;
 		this.subtitlesText = text;
 		this.originalText = text;
-		this.displayType = this.configDisplayType;
-		this.messageBgAlpha = this.configMessageAlpha;
+		this.displayType = SubtitleDisplayManager.configDisplayType;
+		this.messageBgAlpha = SubtitleDisplayManager.configMessageAlpha;
 	}
 
 	public void SetTextFromScriptStyle(string text)
@@ -197,13 +207,17 @@ public class SubtitleDisplayManager : MonoBehaviour
 
 	public void Update()
 	{
-		if (this.messageBgAlpha != this.configMessageAlpha)
+		if (!this.autoDisplayTypeChange)
+		{
+			return;
+		}
+		if (this.messageBgAlpha != SubtitleDisplayManager.configMessageAlpha)
 		{
-			this.messageBgAlpha = this.configMessageAlpha;
+			this.messageBgAlpha = SubtitleDisplayManager.configMessageAlpha;
 		}
-		if (this.displayType != this.configDisplayType)
+		if (this.displayType != SubtitleDisplayManager.configDisplayType)
 		{
-			this.displayType = this.configDisplayType;
+			this.displayType = SubtitleDisplayManager.configDisplayType;
 		}
 	}
 
@@ -238,6 +252,10 @@ public class SubtitleDisplayManager : MonoBehaviour
 	[SerializeField]
 	private SubtitleDisplayManager.DisplayType hideTypeOverRide;
 
+	[Header("コンフィグの内容を読み取って表示タイプを自動更新する")]
+	[SerializeField]
+	private bool autoDisplayTypeChange = true;
+
 	private bool callAwake;
 
 	private string charaNameText_;
@@ -248,6 +266,8 @@ public class SubtitleDisplayManager : MonoBehaviour
 
 	private SubtitleDisplayManager.DisplayType displayType_;
 
+	private float setAlpha = -1f;
+
 	public enum DisplayType
 	{
 		None,

+ 37 - 9
Assembly-CSharp/SubtitleMovieManager.cs

@@ -7,13 +7,29 @@ public class SubtitleMovieManager : MonoBehaviour
 {
 	public bool isPlaying { get; private set; }
 
-	public static SubtitleMovieManager GetGlobalInstance()
+	public static SubtitleMovieManager GetGlobalInstance(bool casinoType)
 	{
 		GameObject childObject = UTY.GetChildObject(GameObject.Find("__GameMain__"), "SystemUI Root", false);
-		GameObject gameObject = UTY.GetChildObject(childObject, "SubtitleMovieManager", true);
-		if (gameObject != null)
+		GameObject gameObject;
+		if (!casinoType)
 		{
-			gameObject = Utility.CreatePrefab(childObject, "SubtitleMovieManager", true);
+			gameObject = UTY.GetChildObject(childObject, "GlobalSubtitleMovieManager", true);
+			if (gameObject == null)
+			{
+				gameObject = Utility.CreatePrefab(childObject, "System/Prefab/SubtitleMovieManager", true);
+				gameObject.name = "GlobalSubtitleMovieManager";
+			}
+			gameObject.transform.localPosition = new Vector3(-459f, -247f, 0f);
+		}
+		else
+		{
+			gameObject = UTY.GetChildObject(childObject, "GlobalSubtitleMovieManagerCasinoType", true);
+			if (gameObject == null)
+			{
+				gameObject = Utility.CreatePrefab(childObject, "System/Prefab/SubtitleMovieManagerCasino", true);
+				gameObject.name = "GlobalSubtitleMovieManagerCasinoType";
+			}
+			gameObject.transform.localPosition = new Vector3(228f, 375f, 0f);
 		}
 		return gameObject.GetComponent<SubtitleMovieManager>();
 	}
@@ -21,7 +37,12 @@ public class SubtitleMovieManager : MonoBehaviour
 	public static void DestroyGlobalInstance()
 	{
 		GameObject childObject = UTY.GetChildObject(GameObject.Find("__GameMain__"), "SystemUI Root", false);
-		GameObject childObject2 = UTY.GetChildObject(childObject, "SubtitleMovieManager", true);
+		GameObject childObject2 = UTY.GetChildObject(childObject, "GlobalSubtitleMovieManager", true);
+		if (childObject2 != null)
+		{
+			UnityEngine.Object.DestroyImmediate(childObject2);
+		}
+		childObject2 = UTY.GetChildObject(childObject, "GlobalSubtitleMovieManagerCasinoType", true);
 		if (childObject2 != null)
 		{
 			UnityEngine.Object.DestroyImmediate(childObject2);
@@ -34,7 +55,7 @@ public class SubtitleMovieManager : MonoBehaviour
 		this.isPlaying = false;
 	}
 
-	public bool AddData(int displayStartTime, int displayTime, string text)
+	public bool AddData(string text, int displayStartTime, int displayTime)
 	{
 		if (this.isPlaying)
 		{
@@ -101,7 +122,7 @@ public class SubtitleMovieManager : MonoBehaviour
 			}
 			else if (text2.IndexOf("@hitret") == 0)
 			{
-				this.AddData(num, num2 - num, text);
+				this.AddData(text, num, num2 - num);
 				flag = false;
 			}
 			else if (flag)
@@ -111,10 +132,10 @@ public class SubtitleMovieManager : MonoBehaviour
 		}
 	}
 
-	public void Play(int displayTime, string text)
+	public void Play(string text, int displayTime)
 	{
 		this.Clear();
-		this.AddData(0, displayTime, text);
+		this.AddData(text, 0, displayTime);
 		this.Play();
 	}
 
@@ -122,6 +143,7 @@ public class SubtitleMovieManager : MonoBehaviour
 	{
 		this.timeElapsed = 0;
 		this.isPlaying = true;
+		this.subtitleMgr.visible = false;
 	}
 
 	public void Stop()
@@ -168,11 +190,17 @@ public class SubtitleMovieManager : MonoBehaviour
 				}
 			}
 		}
+		if (this.displayDatas.Count == 0 && this.autoDestroy)
+		{
+			UnityEngine.Object.DestroyImmediate(base.gameObject);
+		}
 	}
 
 	[SerializeField]
 	private SubtitleDisplayManager subtitleMgr;
 
+	public bool autoDestroy;
+
 	private int timeElapsed;
 
 	private List<SubtitleMovieManager.DisplayData> displayDatas = new List<SubtitleMovieManager.DisplayData>();

+ 52 - 0
Assembly-CSharp/TBodySkin.cs

@@ -80,6 +80,7 @@ public class TBodySkin
 		this.m_OriVert.Clear();
 		this.m_ParentMPN = MPN.null_mpn;
 		this.m_mp = null;
+		this.m_bHitFloorY = true;
 	}
 
 	public void NewParamSet(string A)
@@ -436,6 +437,10 @@ public class TBodySkin
 	public void Load(MPN mpn, Transform srcbody, Transform body1, Dictionary<string, Transform> trans, string bonename, string filename, string slotname, string AttachSlot, int layer, bool f_bTemp)
 	{
 		this.DeleteObj();
+		if (mpn == MPN.accashi || mpn == MPN.shoes)
+		{
+			this.m_bHitFloorY = false;
+		}
 		this.m_ParentMPN = mpn;
 		if (this.m_ParentMPN != MPN.null_mpn)
 		{
@@ -704,6 +709,32 @@ public class TBodySkin
 		{
 			this.listTrsScr[j].localScale = this.listTrsScr[j + 1].localScale;
 		}
+		this.TightSkirt();
+	}
+
+	public void TightSkirt()
+	{
+	}
+
+	private void LookAtAxis(Transform f_trSrc, Vector3 f_vTargetPosWorld, TBodySkin.Axis f_axis, Vector3 f_vForwardWorld)
+	{
+		Vector3 position = f_trSrc.InverseTransformPoint(f_vTargetPosWorld);
+		if (f_axis == TBodySkin.Axis.X)
+		{
+			position.x = 0f;
+		}
+		else if (f_axis == TBodySkin.Axis.Y)
+		{
+			position.y = 0f;
+		}
+		else
+		{
+			position.z = 0f;
+		}
+		Vector3 vector = f_trSrc.TransformPoint(position);
+		Debug.DrawLine(vector, f_trSrc.position, Color.cyan);
+		Quaternion lhs = Quaternion.FromToRotation(f_vForwardWorld, (vector - f_trSrc.position).normalized);
+		f_trSrc.rotation = lhs * f_trSrc.rotation;
 	}
 
 	public void OnChangeScreenSizeOrAA()
@@ -990,6 +1021,8 @@ public class TBodySkin
 
 	public Dictionary<string, TMorph.TempAttachPos> m_dicTempAttachPoint = new Dictionary<string, TMorph.TempAttachPos>();
 
+	public bool m_bHitFloorY = true;
+
 	private Transform m_trMaid;
 
 	private Transform m_trMaidOffs;
@@ -998,6 +1031,18 @@ public class TBodySkin
 
 	private bool m_bTemp;
 
+	private Transform m_trThigh_L;
+
+	private Transform m_trThigh_R;
+
+	private Transform m_trCalf_L;
+
+	private Transform m_trCalf_R;
+
+	private Transform m_trFoot_L;
+
+	private Transform m_trFoot_R;
+
 	public TBodySkin.OriVert m_OriVert = new TBodySkin.OriVert();
 
 	public TBodySkin.HairLengthCtrl m_HairLengthCtrl;
@@ -1217,4 +1262,11 @@ public class TBodySkin
 
 		public BoneWeight[] bwWeight;
 	}
+
+	private enum Axis
+	{
+		X,
+		Y,
+		Z
+	}
 }

+ 3 - 3
Assembly-CSharp/THair1.cs

@@ -258,7 +258,7 @@ public class THair1
 					this.hplist[j - 1].v = thp2.v + b;
 					this.hplist[j - 1].g -= a * 0.01f;
 				}
-				if (thp2.v.y < this.HitHeightY)
+				if (this.bonehair.bodyskin.m_bHitFloorY && thp2.v.y < this.HitHeightY)
 				{
 					thp2.v.y = this.HitHeightY;
 					thp2.g *= 0.9f;
@@ -276,7 +276,7 @@ public class THair1
 					thp3.g -= a2 * 0.01f;
 				}
 				thp3.Secchi = bh.SphereMove_hair2(ref thp3.v, ref thp3.g, thp3.v_old);
-				if (thp3.v.y < this.HitHeightY)
+				if (this.bonehair.bodyskin.m_bHitFloorY && thp3.v.y < this.HitHeightY)
 				{
 					thp3.v.y = this.HitHeightY;
 					thp3.g *= 0.9f;
@@ -312,7 +312,7 @@ public class THair1
 				thp5.v = vector2;
 			}
 			thp5.Secchi = bh.SphereMove_hair2(ref thp5.v, ref thp5.g, thp5.v_old);
-			if (thp5.v.y < this.HitHeightY)
+			if (this.bonehair.bodyskin.m_bHitFloorY && thp5.v.y < this.HitHeightY)
 			{
 				thp5.v.y = this.HitHeightY;
 				thp5.g *= 0.9f;

+ 8 - 2
Assembly-CSharp/UndressingManager.cs

@@ -130,7 +130,12 @@ public class UndressingManager : MonoBehaviour
 		}
 	}
 
-	private void OnClickButton(UndressingManager.UndressingData unit_data)
+	public UndressingManager.UndressingData GetUndressingData(UndressingManager.UnitType unitType)
+	{
+		return (!this.unit_dic_.ContainsKey(unitType)) ? null : this.unit_dic_[unitType];
+	}
+
+	public void OnClickButton(UndressingManager.UndressingData unit_data)
 	{
 		UndressingManager.MaskStatus status = (unit_data.mask_mode != UndressingManager.MaskStatus.On) ? UndressingManager.MaskStatus.On : UndressingManager.MaskStatus.Off;
 		this.SetMaskMode(unit_data.unit_type, status);
@@ -225,7 +230,7 @@ public class UndressingManager : MonoBehaviour
 
 	public delegate void OnClickEventDelegate(string call_file);
 
-	private class UndressingData
+	public class UndressingData
 	{
 		public UndressingManager.MaskStatus mask_mode
 		{
@@ -274,6 +279,7 @@ public class UndressingManager : MonoBehaviour
 			}
 			if (!flag)
 			{
+				this.button_object.defaultColor = this.button_object.disabledColor;
 				this.button_object.isEnabled = false;
 				return;
 			}

+ 1 - 1
Assembly-CSharp/WindowPartsFingerPreset.cs

@@ -182,7 +182,7 @@ public class WindowPartsFingerPreset : MonoBehaviour
 	{
 		WindowPartsFingerBlend.Type blendType = tareget_blend.BlendType;
 		FingerBlend.BaseFinger baseFingerClass = tareget_blend.GetBaseFingerClass(tareget_blend.mgr.select_maid, blendType);
-		XElement xelement = new XElement("GameVersion", 1150);
+		XElement xelement = new XElement("GameVersion", 1160);
 		XElement xelement2 = new XElement("RightData", blendType == WindowPartsFingerBlend.Type.RightArm || blendType == WindowPartsFingerBlend.Type.RightLeg);
 		XElement xelement3 = new XElement("BinaryData", Convert.ToBase64String(baseFingerClass.GetBinary()));
 		XNode[] contents = new XNode[]

+ 54 - 0
Assembly-CSharp/YotogiManager.cs

@@ -551,6 +551,60 @@ public class YotogiManager : WfScreenManager
 		return 1 < num;
 	}
 
+	public bool inputCBLUpKey
+	{
+		get
+		{
+			GameMain.Instance.MainCamera.IsFadeOut();
+			return false;
+		}
+	}
+
+	public bool inputCBLDownKey
+	{
+		get
+		{
+			GameMain.Instance.MainCamera.IsFadeOut();
+			return false;
+		}
+	}
+
+	public bool inputCBLRightKey
+	{
+		get
+		{
+			GameMain.Instance.MainCamera.IsFadeOut();
+			return false;
+		}
+	}
+
+	public bool inputCBLLeftKey
+	{
+		get
+		{
+			GameMain.Instance.MainCamera.IsFadeOut();
+			return false;
+		}
+	}
+
+	public bool inputCBLEnterKey
+	{
+		get
+		{
+			GameMain.Instance.MainCamera.IsFadeOut();
+			return false;
+		}
+	}
+
+	public bool inputCBLCancelKey
+	{
+		get
+		{
+			GameMain.Instance.MainCamera.IsFadeOut();
+			return false;
+		}
+	}
+
 	public int GetPlayPossibleMaidCount()
 	{
 		CharacterMgr characterMgr = GameMain.Instance.CharacterMgr;

+ 56 - 0
Assembly-CSharp/Yotogis/Skill.cs

@@ -549,6 +549,32 @@ namespace Yotogis
 								num += 2;
 							}
 							this.getcondition_data.marriage = (csv_acq.GetCellAsString(num++, y) == "○");
+							this.getcondition_data.requestPersonals = new MaidStatus.Old.Personal[0];
+							string cellAsString5 = csv_acq.GetCellAsString(num++, y);
+							if (!string.IsNullOrEmpty(cellAsString5))
+							{
+								string[] array4 = cellAsString5.Split(new char[]
+								{
+									','
+								});
+								List<MaidStatus.Old.Personal> list = new List<MaidStatus.Old.Personal>();
+								foreach (string text in array4)
+								{
+									try
+									{
+										MaidStatus.Old.Personal item = (MaidStatus.Old.Personal)Enum.Parse(typeof(MaidStatus.Old.Personal), text);
+										list.Add(item);
+									}
+									catch (Exception)
+									{
+										Debug.LogWarning("Yotogi.SkillData::token_textのenum変換に失敗しました:" + text);
+									}
+								}
+								if (0 < list.Count)
+								{
+									this.getcondition_data.requestPersonals = list.ToArray();
+								}
+							}
 							return;
 						}
 						if (cellAsString4 == "○")
@@ -622,6 +648,22 @@ namespace Yotogis
 					return this.exec_seikeiken.ContainsKey(check_seikeiken);
 				}
 
+				public bool IsExecPersonal(MaidStatus.Old.Personal personal)
+				{
+					if (this.getcondition_data.requestPersonals.Length == 0)
+					{
+						return true;
+					}
+					foreach (MaidStatus.Old.Personal personal2 in this.getcondition_data.requestPersonals)
+					{
+						if (personal2 == personal)
+						{
+							return true;
+						}
+					}
+					return false;
+				}
+
 				public bool IsCheckGetSkill(MaidStatus.Status status, bool is_seikeiken_check)
 				{
 					if (is_seikeiken_check && !this.getcondition_data.seikeiken[(int)status.seikeiken])
@@ -660,6 +702,18 @@ namespace Yotogis
 					{
 						return false;
 					}
+					if (this.getcondition_data.requestPersonals.Length != 0)
+					{
+						bool flag = false;
+						foreach (MaidStatus.Old.Personal personal in this.getcondition_data.requestPersonals)
+						{
+							flag |= (personal.ToString() == status.personal.uniqueName);
+						}
+						if (!flag)
+						{
+							return false;
+						}
+					}
 					if (0 < this.getcondition_data.yotogi_class_level)
 					{
 						if (!status.yotogiClass.Contains(this.getcondition_data.yotogi_class.id))
@@ -1039,6 +1093,8 @@ namespace Yotogis
 					}
 
 					public bool marriage;
+
+					public MaidStatus.Old.Personal[] requestPersonals;
 				}
 			}
 		}