ConstantData.cs 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Media;
  5. using System.Reflection;
  6. using System.Text;
  7. using NTERA.Core;
  8. using NTERA.EmuEra.Game.EraEmu.GameData.Variable;
  9. using NTERA.EmuEra.Game.EraEmu.Sub;
  10. namespace NTERA.EmuEra.Game.EraEmu.GameData
  11. {
  12. //難読化用属性。enum.ToString()やenum.Parse()を行うなら(Exclude=true)にすること。
  13. [Obfuscation(Exclude = false)]
  14. internal enum CharacterStrData
  15. {
  16. NAME = 0,
  17. CALLNAME = 1,
  18. NICKNAME = 2,
  19. MASTERNAME = 3,
  20. CSTR = 4
  21. }
  22. //難読化用属性。enum.ToString()やenum.Parse()を行うなら(Exclude=true)にすること。
  23. [Obfuscation(Exclude = false)]
  24. internal enum CharacterIntData
  25. {
  26. BASE = 0,
  27. ABL = 1,
  28. TALENT = 2,
  29. MARK = 3,
  30. EXP = 4,
  31. RELATION = 5,
  32. CFLAG = 6,
  33. EQUIP = 7,
  34. JUEL = 8
  35. }
  36. internal sealed class ConstantData
  37. {
  38. private const int ablIndex = (int)(VariableCode.ABLNAME & VariableCode.__LOWERCASE__);
  39. private const int expIndex = (int)(VariableCode.EXPNAME & VariableCode.__LOWERCASE__);
  40. private const int talentIndex = (int)(VariableCode.TALENTNAME & VariableCode.__LOWERCASE__);
  41. private const int paramIndex = (int)(VariableCode.PALAMNAME & VariableCode.__LOWERCASE__);
  42. private const int trainIndex = (int)(VariableCode.TRAINNAME & VariableCode.__LOWERCASE__);
  43. private const int markIndex = (int)(VariableCode.MARKNAME & VariableCode.__LOWERCASE__);
  44. private const int itemIndex = (int)(VariableCode.ITEMNAME & VariableCode.__LOWERCASE__);
  45. private const int baseIndex = (int)(VariableCode.BASENAME & VariableCode.__LOWERCASE__);
  46. private const int sourceIndex = (int)(VariableCode.SOURCENAME & VariableCode.__LOWERCASE__);
  47. private const int exIndex = (int)(VariableCode.EXNAME & VariableCode.__LOWERCASE__);
  48. private const int strIndex = (int)(VariableCode.__DUMMY_STR__ & VariableCode.__LOWERCASE__);
  49. private const int equipIndex = (int)(VariableCode.EQUIPNAME & VariableCode.__LOWERCASE__);
  50. private const int tequipIndex = (int)(VariableCode.TEQUIPNAME & VariableCode.__LOWERCASE__);
  51. private const int flagIndex = (int)(VariableCode.FLAGNAME & VariableCode.__LOWERCASE__);
  52. private const int tflagIndex = (int)(VariableCode.TFLAGNAME & VariableCode.__LOWERCASE__);
  53. private const int cflagIndex = (int)(VariableCode.CFLAGNAME & VariableCode.__LOWERCASE__);
  54. private const int tcvarIndex = (int)(VariableCode.TCVARNAME & VariableCode.__LOWERCASE__);
  55. private const int cstrIndex = (int)(VariableCode.CSTRNAME & VariableCode.__LOWERCASE__);
  56. private const int stainIndex = (int)(VariableCode.STAINNAME & VariableCode.__LOWERCASE__);
  57. private const int cdflag1Index = (int)(VariableCode.CDFLAGNAME1 & VariableCode.__LOWERCASE__);
  58. private const int cdflag2Index = (int)(VariableCode.CDFLAGNAME2 & VariableCode.__LOWERCASE__);
  59. private const int strnameIndex = (int)(VariableCode.STRNAME & VariableCode.__LOWERCASE__);
  60. private const int tstrnameIndex = (int)(VariableCode.TSTRNAME & VariableCode.__LOWERCASE__);
  61. private const int savestrnameIndex = (int)(VariableCode.SAVESTRNAME & VariableCode.__LOWERCASE__);
  62. private const int globalIndex = (int)(VariableCode.GLOBALNAME & VariableCode.__LOWERCASE__);
  63. private const int globalsIndex = (int)(VariableCode.GLOBALSNAME & VariableCode.__LOWERCASE__);
  64. private const int countNameCsv = (int)VariableCode.__COUNT_CSV_STRING_ARRAY_1D__;
  65. public int[] MaxDataList = new int[countNameCsv];
  66. List<VariableCode> changedCode = new List<VariableCode>();
  67. public int[] VariableIntArrayLength;
  68. public int[] VariableStrArrayLength;
  69. public Int64[] VariableIntArray2DLength;
  70. public Int64[] VariableStrArray2DLength;
  71. public Int64[] VariableIntArray3DLength;
  72. public Int64[] VariableStrArray3DLength;
  73. public int[] CharacterIntArrayLength;
  74. public int[] CharacterStrArrayLength;
  75. public Int64[] CharacterIntArray2DLength;
  76. public Int64[] CharacterStrArray2DLength;
  77. public Translation tranls;
  78. // JVN: Keep track if loading PARAM or PALAM.CSV
  79. private static bool canLoadParam;
  80. private readonly GameBase gamebase;
  81. private string[][] names = new string[(int)VariableCode.__COUNT_CSV_STRING_ARRAY_1D__][];
  82. private Dictionary<string, int>[] nameToIntDics = new Dictionary<string, int>[(int)VariableCode.__COUNT_CSV_STRING_ARRAY_1D__];
  83. private Dictionary<string, int> relationDic = new Dictionary<string, int>();
  84. public string[] GetCsvNameList(VariableCode code)
  85. {
  86. return names[(int)(code & VariableCode.__LOWERCASE__)];
  87. }
  88. public Int64[] ItemPrice;
  89. private readonly List<CharacterTemplate> CharacterTmplList;
  90. private IConsole output;
  91. public ConstantData(GameBase gamebase)
  92. {
  93. this.gamebase = gamebase;
  94. setDefaultArrayLength();
  95. CharacterTmplList = new List<CharacterTemplate>();
  96. useCompatiName = Config.Config.CompatiCALLNAME;
  97. }
  98. readonly bool useCompatiName;
  99. private void setDefaultArrayLength()
  100. {
  101. MaxDataList[ablIndex] = 100;
  102. MaxDataList[talentIndex] = 1000;
  103. MaxDataList[expIndex] = 100;
  104. MaxDataList[markIndex] = 100;
  105. MaxDataList[trainIndex] = 1000;
  106. MaxDataList[paramIndex] = 200;
  107. MaxDataList[itemIndex] = 1000;
  108. MaxDataList[baseIndex] = 100;
  109. MaxDataList[sourceIndex] = 1000;
  110. MaxDataList[exIndex] = 100;
  111. MaxDataList[equipIndex] = 100;
  112. MaxDataList[tequipIndex] = 100;
  113. MaxDataList[flagIndex] = 10000;
  114. MaxDataList[tflagIndex] = 1000;
  115. MaxDataList[cflagIndex] = 1000;
  116. MaxDataList[tcvarIndex] = 100;
  117. MaxDataList[cstrIndex] = 100;
  118. MaxDataList[stainIndex] = 1000;
  119. MaxDataList[strIndex] = 20000;
  120. MaxDataList[cdflag1Index] = 1;
  121. MaxDataList[cdflag2Index] = 1;
  122. MaxDataList[strnameIndex] = 20000;
  123. MaxDataList[tstrnameIndex] = 100;
  124. MaxDataList[savestrnameIndex] = 100;
  125. MaxDataList[globalIndex] = 1000;
  126. MaxDataList[globalsIndex] = 100;
  127. VariableIntArrayLength = new int[(int)VariableCode.__COUNT_INTEGER_ARRAY__];
  128. VariableStrArrayLength = new int[(int)VariableCode.__COUNT_STRING_ARRAY__];
  129. VariableIntArray2DLength = new Int64[(int)VariableCode.__COUNT_INTEGER_ARRAY_2D__];
  130. VariableStrArray2DLength = new Int64[(int)VariableCode.__COUNT_STRING_ARRAY_2D__];
  131. VariableIntArray3DLength = new Int64[(int)VariableCode.__COUNT_INTEGER_ARRAY_3D__];
  132. VariableStrArray3DLength = new Int64[(int)VariableCode.__COUNT_STRING_ARRAY_3D__];
  133. CharacterIntArrayLength = new int[(int)VariableCode.__COUNT_CHARACTER_INTEGER_ARRAY__];
  134. CharacterStrArrayLength = new int[(int)VariableCode.__COUNT_CHARACTER_STRING_ARRAY__];
  135. CharacterIntArray2DLength = new Int64[(int)VariableCode.__COUNT_CHARACTER_INTEGER_ARRAY_2D__];
  136. CharacterStrArray2DLength = new Int64[(int)VariableCode.__COUNT_CHARACTER_STRING_ARRAY_2D__];
  137. for (int i = 0; i < VariableIntArrayLength.Length; i++)
  138. VariableIntArrayLength[i] = 1000;
  139. VariableIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.FLAG)] = 10000;
  140. VariableIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.ITEMPRICE)] = MaxDataList[itemIndex];
  141. VariableIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.RANDDATA)] = 625;
  142. for (int i = 0; i < VariableStrArrayLength.Length; i++)
  143. VariableStrArrayLength[i] = 100;
  144. VariableStrArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.STR)] = MaxDataList[strIndex];
  145. for (int i = 0; i < VariableIntArray2DLength.Length; i++)
  146. VariableIntArray2DLength[i] = (100L << 32) + 100L;
  147. for (int i = 0; i < VariableStrArray2DLength.Length; i++)
  148. VariableStrArray2DLength[i] = (100L << 32) + 100L;
  149. for (int i = 0; i < VariableIntArray3DLength.Length; i++)
  150. VariableIntArray3DLength[i] = (100L << 40) + (100L << 20) + 100L;
  151. for (int i = 0; i < VariableStrArray3DLength.Length; i++)
  152. VariableStrArray3DLength[i] = (100L << 40) + (100L << 20) + 100L;
  153. for (int i = 0; i < CharacterIntArrayLength.Length; i++)
  154. CharacterIntArrayLength[i] = 100;
  155. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.TALENT)] = 1000;
  156. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.CFLAG)] = 1000;
  157. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)] = 200;
  158. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.GOTJUEL)] = 200;
  159. for (int i = 0; i < CharacterStrArrayLength.Length; i++)
  160. CharacterStrArrayLength[i] = 100;
  161. for (int i = 0; i < CharacterIntArray2DLength.Length; i++)
  162. CharacterIntArray2DLength[i] = (1L << 32) + 1L;
  163. for (int i = 0; i < CharacterStrArray2DLength.Length; i++)
  164. CharacterStrArray2DLength[i] = (1L << 32) + 1L;
  165. }
  166. private void loadVariableSizeData(string csvPath, bool disp)
  167. {
  168. if (!File.Exists(csvPath))
  169. return;
  170. EraStreamReader eReader = new EraStreamReader(false);
  171. if (!eReader.Open(csvPath))
  172. {
  173. output.PrintError("Failed to open " + eReader.Filename);
  174. return;
  175. }
  176. ScriptPosition position = null;
  177. if (disp)
  178. output.PrintSystemLine("Loading " + eReader.Filename + "...");
  179. try
  180. {
  181. StringStream st = null;
  182. while ((st = eReader.ReadEnabledLine()) != null)
  183. {
  184. position = new ScriptPosition(eReader.Filename, eReader.LineNo, st.RowString);
  185. changeVariableSizeData(st.Substring(), position);
  186. }
  187. position = new ScriptPosition(eReader.Filename, -1, null);
  188. }
  189. catch
  190. {
  191. ShowParserError("An unexpected error has occured", position, 3);
  192. }
  193. finally
  194. {
  195. eReader.Close();
  196. }
  197. decideActualArraySize(position);
  198. }
  199. private void changeVariableSizeData(string line, ScriptPosition position)
  200. {
  201. string[] tokens = line.Split(',');
  202. if (tokens.Length < 2)
  203. {
  204. ParserMediator.Warn("\",\" is required", position, 1);
  205. return;
  206. }
  207. string idtoken = tokens[0].Trim();
  208. VariableIdentifier id = VariableIdentifier.GetVariableId(idtoken);
  209. if (id == null)
  210. {
  211. ParserMediator.Warn("The first value cannot be recognized as a variable name", position, 1);
  212. return;
  213. }
  214. if ((!id.IsArray1D) && (!id.IsArray2D) && (!id.IsArray3D))
  215. {
  216. ParserMediator.Warn("Cannot change the size of a " + id + " variable that is not an array variable", position, 1);
  217. return;
  218. }
  219. if ((id.IsCalc) || (id.Code == VariableCode.RANDDATA))
  220. {
  221. ParserMediator.Warn("Cannot change the size of a " + id + " variable", position, 1);
  222. return;
  223. }
  224. int length = 0;
  225. int length2 = 0;
  226. int length3 = 0;
  227. if (!int.TryParse(tokens[1], out length))
  228. {
  229. ParserMediator.Warn("The second value cannot be recognized as an integer value", position, 1);
  230. return;
  231. }
  232. //1820a16 変数禁止指定 負の値を指定する
  233. if (length <= 0)
  234. {
  235. if (length == 0)
  236. {
  237. ParserMediator.Warn("配列長に0は指定できません(変数を使用禁止にするには配列長に負の値を指定してください)", position, 2);
  238. return;
  239. }
  240. if(!id.CanForbid)
  241. {
  242. ParserMediator.Warn("使用禁止にできない変数に対して負の配列長が指定されています", position, 2);
  243. return;
  244. }
  245. if (tokens.Length > 2 && tokens[2].Length > 0 && tokens[2].Trim().Length > 0 && char.IsDigit((tokens[2].Trim())[0]))
  246. {
  247. ParserMediator.Warn("一次元配列のサイズ指定に不必要なデータは無視されます", position, 0);
  248. }
  249. length = 0;
  250. goto check1break;
  251. }
  252. if (id.IsArray1D)
  253. {
  254. if (tokens.Length > 2 && tokens[2].Length > 0 && tokens[2].Trim().Length > 0 && char.IsDigit((tokens[2].Trim())[0]))
  255. {
  256. ParserMediator.Warn("一次元配列のサイズ指定に不必要なデータは無視されます", position, 0);
  257. }
  258. if (id.IsLocal && length < 1)
  259. {
  260. ParserMediator.Warn("ローカル変数のサイズを1未満にはできません", position, 1);
  261. return;
  262. }
  263. if (!id.IsLocal && length < 100)
  264. {
  265. ParserMediator.Warn("ローカル変数でない一次元配列のサイズを100未満にはできません", position, 1);
  266. return;
  267. }
  268. if (length > 1000000)
  269. {
  270. ParserMediator.Warn("一次元配列のサイズを1000000より大きくすることはできません", position, 1);
  271. return;
  272. }
  273. }
  274. else if (id.IsArray2D)
  275. {
  276. if (tokens.Length < 3)
  277. {
  278. ParserMediator.Warn("二次元配列のサイズ指定には2つの数値が必要です", position, 1);
  279. return;
  280. }
  281. if (tokens.Length > 3 && tokens[3].Length > 0 && tokens[3].Trim().Length > 0 && char.IsDigit((tokens[3].Trim())[0]))
  282. {
  283. ParserMediator.Warn("二次元配列のサイズ指定に不必要なデータは無視されます", position, 0);
  284. }
  285. if (!int.TryParse(tokens[2], out length2))
  286. {
  287. ParserMediator.Warn("三つ目の値を整数値として認識できません", position, 1);
  288. return;
  289. }
  290. if ((length < 1) || (length2 < 1))
  291. {
  292. ParserMediator.Warn("配列サイズを1未満にはできません", position, 1);
  293. return;
  294. }
  295. if ((length > 1000000) || (length2 > 1000000))
  296. {
  297. ParserMediator.Warn("配列サイズを1000000より大きくすることはできません", position, 1);
  298. return;
  299. }
  300. if (length * length2 > 1000000)
  301. {
  302. ParserMediator.Warn("二次元配列の要素数は最大で100万個までです", position, 1);
  303. return;
  304. }
  305. }
  306. else if (id.IsArray3D)
  307. {
  308. if (tokens.Length < 4)
  309. {
  310. ParserMediator.Warn("三次元配列のサイズ指定には3つの数値が必要です", position, 1);
  311. return;
  312. }
  313. if (tokens.Length > 4 && tokens[4].Length > 0 && tokens[4].Trim().Length > 0 && char.IsDigit((tokens[4].Trim())[0]))
  314. {
  315. ParserMediator.Warn("三次元配列のサイズ指定に不必要なデータは無視されます", position, 0);
  316. }
  317. if (!int.TryParse(tokens[2], out length2))
  318. {
  319. ParserMediator.Warn("三つ目の値を整数値として認識できません", position, 1);
  320. return;
  321. }
  322. if (!int.TryParse(tokens[3], out length3))
  323. {
  324. ParserMediator.Warn("四つ目の値を整数値として認識できません", position, 1);
  325. return;
  326. }
  327. if ((length < 1) || (length2 < 1) || (length3 < 1))
  328. {
  329. ParserMediator.Warn("配列サイズを1未満にはできません", position, 1);
  330. return;
  331. }
  332. //1802 サイズ保存の都合上、2^20超えるとバグる
  333. if ((length > 1000000) || (length2 > 1000000) || (length3 > 1000000))
  334. {
  335. ParserMediator.Warn("配列サイズを1000000より大きくすることはできません", position, 1);
  336. return;
  337. }
  338. if (length * length2 * length3 > 10000000)
  339. {
  340. ParserMediator.Warn("三次元配列の要素数は最大で1000万個までです", position, 1);
  341. return;
  342. }
  343. }
  344. check1break:
  345. switch (id.Code)
  346. {
  347. //1753a PALAMだけ仕様が違うのはかえって問題なので、変数と要素文字列配列数の同期は全部バックアウト
  348. //基本的には旧来の処理に戻しただけ
  349. case VariableCode.ITEMNAME:
  350. case VariableCode.ITEMPRICE:
  351. VariableIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.ITEMPRICE)] = length;
  352. MaxDataList[itemIndex] = length;
  353. break;
  354. case VariableCode.STR:
  355. VariableStrArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.STR)] = length;
  356. MaxDataList[strIndex] = length;
  357. break;
  358. case VariableCode.ABLNAME:
  359. case VariableCode.TALENTNAME:
  360. case VariableCode.EXPNAME:
  361. case VariableCode.MARKNAME:
  362. case VariableCode.PALAMNAME:
  363. case VariableCode.TRAINNAME:
  364. case VariableCode.BASENAME:
  365. case VariableCode.SOURCENAME:
  366. case VariableCode.EXNAME:
  367. case VariableCode.EQUIPNAME:
  368. case VariableCode.TEQUIPNAME:
  369. case VariableCode.FLAGNAME:
  370. case VariableCode.TFLAGNAME:
  371. case VariableCode.CFLAGNAME:
  372. case VariableCode.TCVARNAME:
  373. case VariableCode.CSTRNAME:
  374. case VariableCode.STAINNAME:
  375. case VariableCode.CDFLAGNAME1:
  376. case VariableCode.CDFLAGNAME2:
  377. case VariableCode.TSTRNAME:
  378. case VariableCode.SAVESTRNAME:
  379. case VariableCode.STRNAME:
  380. case VariableCode.GLOBALNAME:
  381. case VariableCode.GLOBALSNAME:
  382. MaxDataList[(int)(id.Code & VariableCode.__LOWERCASE__)] = length;
  383. break;
  384. default:
  385. {
  386. if (id.IsCharacterData)
  387. {
  388. if (id.IsArray2D)
  389. {
  390. Int64 length64 = (((Int64)length) << 32) + length2;
  391. if (id.IsInteger)
  392. CharacterIntArray2DLength[id.CodeInt] = length64;
  393. else if (id.IsString)
  394. CharacterStrArray2DLength[id.CodeInt] = length64;
  395. }
  396. else
  397. {
  398. if (id.IsInteger)
  399. CharacterIntArrayLength[id.CodeInt] = length;
  400. else if (id.IsString)
  401. CharacterStrArrayLength[id.CodeInt] = length;
  402. }
  403. }
  404. else if (id.IsArray2D)
  405. {
  406. Int64 length64 = (((Int64)length) << 32) + length2;
  407. if (id.IsInteger)
  408. VariableIntArray2DLength[id.CodeInt] = length64;
  409. else if (id.IsString)
  410. VariableStrArray2DLength[id.CodeInt] = length64;
  411. }
  412. else if (id.IsArray3D)
  413. {
  414. //Int64 length3d = ((Int64)length << 32) + ((Int64)length2 << 16) + (Int64)length3;
  415. Int64 length3d = ((Int64)length << 40) + ((Int64)length2 << 20) + length3;
  416. if (id.IsInteger)
  417. VariableIntArray3DLength[id.CodeInt] = length3d;
  418. else
  419. VariableStrArray3DLength[id.CodeInt] = length3d;
  420. }
  421. else
  422. {
  423. if (id.IsInteger)
  424. VariableIntArrayLength[id.CodeInt] = length;
  425. else if (id.IsString)
  426. VariableStrArrayLength[id.CodeInt] = length;
  427. }
  428. }
  429. break;
  430. }
  431. //1803beta004 二重定義を警告対象に
  432. if (changedCode.Contains(id.Code))
  433. ParserMediator.Warn(id.Code + "の要素数は既に定義されています(上書きします)", position, 1);
  434. else
  435. changedCode.Add(id.Code);
  436. }
  437. private void _decideActualArraySize_sub(VariableCode mainCode, VariableCode nameCode, int[] arraylength, ScriptPosition position)
  438. {
  439. int nameIndex = (int)(nameCode & VariableCode.__LOWERCASE__);
  440. int mainLengthIndex = (int)(mainCode & VariableCode.__LOWERCASE__);
  441. if (changedCode.Contains(nameCode) && changedCode.Contains(mainCode))
  442. {
  443. if (MaxDataList[nameIndex] != arraylength[mainLengthIndex])
  444. {
  445. int i = Math.Max(MaxDataList[nameIndex], arraylength[mainLengthIndex]);
  446. arraylength[mainLengthIndex] = i;
  447. MaxDataList[nameIndex] = i;
  448. //1803beta004 不適切な指定として警告Lv1の対象にする
  449. if (MaxDataList[nameIndex] == 0 || arraylength[mainLengthIndex] == 0)
  450. ParserMediator.Warn(mainCode +"と" + nameCode + "の禁止設定が異なります(使用禁止を解除します)", position, 1);
  451. else
  452. ParserMediator.Warn(mainCode +"と" + nameCode + "の要素数が異なります(大きい方に合わせます)", position, 1);
  453. }
  454. }
  455. else if (changedCode.Contains(nameCode) && !changedCode.Contains(mainCode))
  456. arraylength[mainLengthIndex] = MaxDataList[nameIndex];
  457. else if (!changedCode.Contains(nameCode) && changedCode.Contains(mainCode))
  458. MaxDataList[nameIndex] = arraylength[mainLengthIndex];
  459. }
  460. private void decideActualArraySize(ScriptPosition position)
  461. {
  462. _decideActualArraySize_sub(VariableCode.ABL, VariableCode.ABLNAME, CharacterIntArrayLength, position);
  463. _decideActualArraySize_sub(VariableCode.TALENT, VariableCode.TALENTNAME, CharacterIntArrayLength, position);
  464. _decideActualArraySize_sub(VariableCode.EXP, VariableCode.EXPNAME, CharacterIntArrayLength, position);
  465. _decideActualArraySize_sub(VariableCode.MARK, VariableCode.MARKNAME, CharacterIntArrayLength, position);
  466. _decideActualArraySize_sub(VariableCode.BASE, VariableCode.BASENAME, CharacterIntArrayLength, position);
  467. _decideActualArraySize_sub(VariableCode.SOURCE, VariableCode.SOURCENAME, CharacterIntArrayLength, position);
  468. _decideActualArraySize_sub(VariableCode.EX, VariableCode.EXNAME, CharacterIntArrayLength, position);
  469. _decideActualArraySize_sub(VariableCode.EQUIP, VariableCode.EQUIPNAME, CharacterIntArrayLength, position);
  470. _decideActualArraySize_sub(VariableCode.TEQUIP, VariableCode.TEQUIPNAME, CharacterIntArrayLength, position);
  471. _decideActualArraySize_sub(VariableCode.FLAG, VariableCode.FLAGNAME, VariableIntArrayLength, position);
  472. _decideActualArraySize_sub(VariableCode.TFLAG, VariableCode.TFLAGNAME, VariableIntArrayLength, position);
  473. _decideActualArraySize_sub(VariableCode.CFLAG, VariableCode.CFLAGNAME, CharacterIntArrayLength, position);
  474. _decideActualArraySize_sub(VariableCode.TCVAR, VariableCode.TCVARNAME, CharacterIntArrayLength, position);
  475. _decideActualArraySize_sub(VariableCode.CSTR, VariableCode.CSTRNAME, CharacterStrArrayLength, position);
  476. _decideActualArraySize_sub(VariableCode.STAIN, VariableCode.STAINNAME, CharacterIntArrayLength, position);
  477. _decideActualArraySize_sub(VariableCode.STR, VariableCode.STRNAME, VariableStrArrayLength, position);
  478. _decideActualArraySize_sub(VariableCode.TSTR, VariableCode.TSTRNAME, VariableStrArrayLength, position);
  479. _decideActualArraySize_sub(VariableCode.SAVESTR, VariableCode.SAVESTRNAME, VariableStrArrayLength, position);
  480. _decideActualArraySize_sub(VariableCode.GLOBAL, VariableCode.GLOBALNAME, VariableIntArrayLength, position);
  481. _decideActualArraySize_sub(VariableCode.GLOBALS, VariableCode.GLOBALSNAME, VariableStrArrayLength, position);
  482. //PALAM(JUEL込み)
  483. //PALAMNAMEが変わっていてかつPALAMかJUELが変わっているとき、
  484. if ((changedCode.Contains(VariableCode.PALAMNAME)) && (changedCode.Contains(VariableCode.PALAM) || changedCode.Contains(VariableCode.JUEL)))
  485. {
  486. int palamJuelMax = Math.Max(CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.PALAM)]
  487. , CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)]);
  488. }
  489. //PALAMかJUELが変わっていれば、そのうち大きい方にPALAMNAMEをあわせる
  490. if (changedCode.Contains(VariableCode.PALAM) || changedCode.Contains(VariableCode.JUEL))
  491. {
  492. int palamJuelMax = Math.Max(CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.PALAM)]
  493. , CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)]);
  494. //PALAMNAMEが変わっている
  495. if(changedCode.Contains(VariableCode.PALAMNAME))
  496. {
  497. if (MaxDataList[paramIndex] != palamJuelMax)
  498. {
  499. int i = Math.Max(MaxDataList[paramIndex], palamJuelMax);
  500. MaxDataList[paramIndex] = i;
  501. if(CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.PALAM)] == palamJuelMax)
  502. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.PALAM)] = i;
  503. if(CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)] == palamJuelMax)
  504. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)] = i;
  505. //1803beta004 不適切な指定として警告Lv1の対象にする
  506. ParserMediator.Warn("PALAMとJUELとPALAMNAMEの要素数が不適切です", position, 1);
  507. }
  508. }
  509. else//PALAMNAMEの指定がないなら大きい方にPALAMNAMEをあわせる
  510. MaxDataList[paramIndex] = palamJuelMax;
  511. }
  512. //PALAMとJUEL不変でPALAMNAMEが変わっている場合
  513. else if (changedCode.Contains(VariableCode.PALAMNAME))
  514. {
  515. //PALAMを指定のPALAMNAMEにあわせる
  516. CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.PALAM)] = MaxDataList[paramIndex];
  517. //指定のPALAMNAMEがJUELより小さければ警告出してJUELにあわせる
  518. if (MaxDataList[paramIndex] < CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)])
  519. {
  520. ParserMediator.Warn("PALAMNAMEの要素数がJUELより少なくなっています(JUELに合わせます)", position, 1);
  521. MaxDataList[paramIndex] = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)];
  522. }
  523. }
  524. //CDFLAG
  525. //一部変更されたら双方変更されたと扱う
  526. bool cdflagNameLengthChanged = changedCode.Contains(VariableCode.CDFLAGNAME1) || changedCode.Contains(VariableCode.CDFLAGNAME2);
  527. int mainLengthIndex = (int)(VariableCode.__LOWERCASE__ & VariableCode.CDFLAG);
  528. Int64 length64 = CharacterIntArray2DLength[mainLengthIndex];
  529. int length1 = (int)(length64 >> 32);
  530. int length2 = (int)(length64 & 0x7FFFFFFF);
  531. if (changedCode.Contains(VariableCode.CDFLAG) && cdflagNameLengthChanged)
  532. {
  533. //調整が面倒なので投げる
  534. if ((length1 != MaxDataList[cdflag1Index]) || (length2 != MaxDataList[cdflag2Index]))
  535. throw new CodeEE("The number of elements of CDFLAG does not match the number of elements of CDFLAGNAME 1 and CDFLAGNAME 2", position);
  536. }
  537. else if (cdflagNameLengthChanged && !changedCode.Contains(VariableCode.CDFLAG))
  538. {
  539. length1 = MaxDataList[cdflag1Index];
  540. length2 = MaxDataList[cdflag2Index];
  541. if (length1 * length2 > 1000000)
  542. {
  543. //調整が面倒なので投げる
  544. throw new CodeEE("CDFLAG has too many elements (product of CDFLAGNAME 1 and CDFLAGNAME 2 number of elements exceeds 1 million)", position);
  545. }
  546. CharacterIntArray2DLength[mainLengthIndex] = (((Int64)length1) << 32) + length2;
  547. }
  548. else if (!cdflagNameLengthChanged && changedCode.Contains(VariableCode.CDFLAG))
  549. {
  550. MaxDataList[cdflag1Index] = length1;
  551. MaxDataList[cdflag2Index] = length2;
  552. }
  553. //もう使わないのでデータ破棄
  554. changedCode.Clear();
  555. }
  556. public void LoadData(string csvDir, IConsole console, bool disp)
  557. {
  558. output = console;
  559. loadVariableSizeData(csvDir + "VariableSize.CSV", disp);
  560. for(int i = 0; i< countNameCsv;i++)
  561. {
  562. names[i] = new string[MaxDataList[i]];
  563. nameToIntDics[i] = new Dictionary<string, int>();
  564. }
  565. // JVN: Check if file exist, keep result in canLoadParam
  566. canLoadParam = File.Exists(csvDir + "PARAM.CSV");
  567. tranls = new Translation(csvDir, ref output, canLoadParam);
  568. ItemPrice = new Int64[MaxDataList[itemIndex]];
  569. loadDataTo(csvDir + "ABL.CSV", ablIndex, null, disp);
  570. loadDataTo(csvDir + "EXP.CSV", expIndex, null, disp);
  571. loadDataTo(csvDir + "TALENT.CSV", talentIndex, null, disp);
  572. loadDataTo(csvDir + (canLoadParam ? "PARAM.CSV" : "PALAM.CSV"), paramIndex, null, disp); // JVN: Change file name depending on boolean
  573. loadDataTo(csvDir + "TRAIN.CSV", trainIndex, null, disp);
  574. loadDataTo(csvDir + "MARK.CSV", markIndex, null, disp);
  575. loadDataTo(csvDir + "ITEM.CSV", itemIndex, ItemPrice, disp);
  576. loadDataTo(csvDir + "BASE.CSV", baseIndex, null, disp);
  577. loadDataTo(csvDir + "SOURCE.CSV", sourceIndex, null, disp);
  578. loadDataTo(csvDir + "EX.CSV", exIndex, null, disp);
  579. loadDataTo(csvDir + "STR.CSV", strIndex, null, disp);
  580. loadDataTo(csvDir + "EQUIP.CSV", equipIndex, null, disp);
  581. loadDataTo(csvDir + "TEQUIP.CSV", tequipIndex, null, disp);
  582. loadDataTo(csvDir + "FLAG.CSV", flagIndex, null, disp);
  583. loadDataTo(csvDir + "TFLAG.CSV", tflagIndex, null, disp);
  584. loadDataTo(csvDir + "CFLAG.CSV", cflagIndex, null, disp);
  585. loadDataTo(csvDir + "TCVAR.CSV", tcvarIndex, null, disp);
  586. loadDataTo(csvDir + "CSTR.CSV", cstrIndex, null, disp);
  587. loadDataTo(csvDir + "STAIN.CSV", stainIndex, null, disp);
  588. loadDataTo(csvDir + "CDFLAG1.CSV", cdflag1Index, null, disp);
  589. loadDataTo(csvDir + "CDFLAG2.CSV", cdflag2Index, null, disp);
  590. loadDataTo(csvDir + "STRNAME.CSV", strnameIndex, null, disp);
  591. loadDataTo(csvDir + "TSTR.CSV", tstrnameIndex, null, disp);
  592. loadDataTo(csvDir + "SAVESTR.CSV", savestrnameIndex, null, disp);
  593. loadDataTo(csvDir + "GLOBAL.CSV", globalIndex, null, disp);
  594. loadDataTo(csvDir + "GLOBALS.CSV", globalsIndex, null, disp);
  595. //逆引き辞書を作成
  596. for (int i = 0; i < names.Length; i++)
  597. {
  598. if (i == 10)//Strは逆引き無用
  599. continue;
  600. string[] nameArray = names[i];
  601. for (int j = 0; j < nameArray.Length; j++)
  602. {
  603. if (!string.IsNullOrEmpty(nameArray[j]) && !nameToIntDics[i].ContainsKey(nameArray[j]))
  604. nameToIntDics[i].Add(nameArray[j], j);
  605. }
  606. }
  607. //if (!Program.AnalysisMode)
  608. loadCharacterData(csvDir, disp);
  609. //逆引き辞書を作成2 (RELATION)
  610. for (int i = 0; i < CharacterTmplList.Count; i++)
  611. {
  612. CharacterTemplate tmpl = CharacterTmplList[i];
  613. if (!string.IsNullOrEmpty(tmpl.Name) && !relationDic.ContainsKey(tmpl.Name))
  614. relationDic.Add(tmpl.Name, (int)tmpl.No);
  615. if (!string.IsNullOrEmpty(tmpl.Callname) && !relationDic.ContainsKey(tmpl.Callname))
  616. relationDic.Add(tmpl.Callname, (int)tmpl.No);
  617. if (!string.IsNullOrEmpty(tmpl.Nickname) && !relationDic.ContainsKey(tmpl.Nickname))
  618. relationDic.Add(tmpl.Nickname, (int)tmpl.No);
  619. }
  620. }
  621. public bool isDefined(VariableCode varCode, string str)
  622. {
  623. if (string.IsNullOrEmpty(str))
  624. return false;
  625. string errPos = null;
  626. Dictionary<string, int> dic = null;
  627. if (varCode == VariableCode.CDFLAG)
  628. {
  629. dic = GetKeywordDictionary(out errPos, VariableCode.CDFLAGNAME1, -1);
  630. if ((dic == null)||(!dic.ContainsKey(str)))
  631. dic = GetKeywordDictionary(out errPos, VariableCode.CDFLAGNAME2, -1);
  632. if (dic == null)
  633. return false;
  634. return dic.ContainsKey(str);
  635. }
  636. dic = GetKeywordDictionary(out errPos, varCode, -1);
  637. if (dic == null)
  638. return false;
  639. return dic.ContainsKey(str);
  640. }
  641. public bool TryKeywordToInteger(out int ret, VariableCode code, string key, int index)
  642. {
  643. ret = 0;
  644. if (string.IsNullOrEmpty(key))
  645. return false;
  646. Dictionary<string, int> dic = null;
  647. try
  648. {
  649. dic = GetKeywordDictionary(out _, code, index);
  650. if (dic == null)
  651. return false;
  652. }
  653. catch { return false; }
  654. return (dic.TryGetValue(key, out ret));
  655. }
  656. public int KeywordToInteger(VariableCode code, string key, int index)
  657. {
  658. if (string.IsNullOrEmpty(key))
  659. throw new CodeEE("Keywords cannot be empty");
  660. var dic = GetKeywordDictionary(out var errPos, code, index);
  661. if (dic.TryGetValue(key, out var ret))
  662. return ret;
  663. if (errPos == null)
  664. throw new CodeEE("Array variable" + code + "elements can not be specified as a string");
  665. throw new CodeEE("There is no definition of\"" + key + "\" at " + errPos);
  666. }
  667. public Dictionary<string, int> GetKeywordDictionary(out string errPos, VariableCode code, int index)
  668. {
  669. errPos = null;
  670. int allowIndex = -1;
  671. Dictionary<string, int> ret = null;
  672. switch (code)
  673. {
  674. case VariableCode.ABL:
  675. ret = nameToIntDics[ablIndex];//AblName;
  676. errPos = "abl.csv";
  677. allowIndex = 1;
  678. break;
  679. case VariableCode.EXP:
  680. ret = nameToIntDics[expIndex];//ExpName;
  681. errPos = "exp.csv";
  682. allowIndex = 1;
  683. break;
  684. case VariableCode.TALENT:
  685. ret = nameToIntDics[talentIndex];//TalentName;
  686. errPos = "talent.csv";
  687. allowIndex = 1;
  688. break;
  689. case VariableCode.UP:
  690. case VariableCode.DOWN:
  691. ret = nameToIntDics[paramIndex];//ParamName 1;
  692. errPos = (canLoadParam ? "param.csv" : "palam.csv"); // JVN: For error output & debugging
  693. allowIndex = 0;
  694. break;
  695. case VariableCode.PALAM:
  696. case VariableCode.JUEL:
  697. case VariableCode.GOTJUEL:
  698. case VariableCode.CUP:
  699. case VariableCode.CDOWN:
  700. ret = nameToIntDics[paramIndex];//ParamName 2;
  701. errPos = (canLoadParam ? "param.csv" : "palam.csv"); // JVN: For error output & debugging
  702. allowIndex = 1;
  703. break;
  704. case VariableCode.TRAINNAME:
  705. ret = nameToIntDics[trainIndex];//TrainName;
  706. errPos = "train.csv";
  707. allowIndex = 0;
  708. break;
  709. case VariableCode.MARK:
  710. ret = nameToIntDics[markIndex];//MarkName;
  711. errPos = "mark.csv";
  712. allowIndex = 1;
  713. break;
  714. case VariableCode.ITEM:
  715. case VariableCode.ITEMSALES:
  716. case VariableCode.ITEMPRICE:
  717. ret = nameToIntDics[itemIndex];//ItemName;
  718. errPos = "Item.csv";
  719. allowIndex = 0;
  720. break;
  721. case VariableCode.LOSEBASE:
  722. ret = nameToIntDics[baseIndex];//BaseName;
  723. errPos = "base.csv";
  724. allowIndex = 0;
  725. break;
  726. case VariableCode.BASE:
  727. case VariableCode.MAXBASE:
  728. case VariableCode.DOWNBASE:
  729. ret = nameToIntDics[baseIndex];//BaseName;
  730. errPos = "base.csv";
  731. allowIndex = 1;
  732. break;
  733. case VariableCode.SOURCE:
  734. ret = nameToIntDics[sourceIndex];//SourceName;
  735. errPos = "source.csv";
  736. allowIndex = 1;
  737. break;
  738. case VariableCode.EX:
  739. case VariableCode.NOWEX:
  740. ret = nameToIntDics[exIndex];//ExName;
  741. errPos = "ex.csv";
  742. allowIndex = 1;
  743. break;
  744. case VariableCode.EQUIP:
  745. ret = nameToIntDics[equipIndex];//EquipName;
  746. errPos = "equip.csv";
  747. allowIndex = 1;
  748. break;
  749. case VariableCode.TEQUIP:
  750. ret = nameToIntDics[tequipIndex];//TequipName;
  751. errPos = "tequip.csv";
  752. allowIndex = 1;
  753. break;
  754. case VariableCode.FLAG:
  755. ret = nameToIntDics[flagIndex];//FlagName;
  756. errPos = "flag.csv";
  757. allowIndex = 0;
  758. break;
  759. case VariableCode.TFLAG:
  760. ret = nameToIntDics[tflagIndex];//TFlagName;
  761. errPos = "tflag.csv";
  762. allowIndex = 0;
  763. break;
  764. case VariableCode.CFLAG:
  765. ret = nameToIntDics[cflagIndex];//CFlagName;
  766. errPos = "cflag.csv";
  767. allowIndex = 1;
  768. break;
  769. case VariableCode.TCVAR:
  770. ret = nameToIntDics[tcvarIndex];//TCVarName;
  771. errPos = "tcvar.csv";
  772. allowIndex = 1;
  773. break;
  774. case VariableCode.CSTR:
  775. ret = nameToIntDics[cstrIndex];//CStrName;
  776. errPos = "cstr.csv";
  777. allowIndex = 1;
  778. break;
  779. case VariableCode.STAIN:
  780. ret = nameToIntDics[stainIndex];//StainName;
  781. errPos = "stain.csv";
  782. allowIndex = 1;
  783. break;
  784. case VariableCode.CDFLAGNAME1:
  785. ret = nameToIntDics[cdflag1Index];
  786. errPos = "cdflag1.csv";
  787. allowIndex = 0;
  788. break;
  789. case VariableCode.CDFLAGNAME2:
  790. ret = nameToIntDics[cdflag2Index];
  791. errPos = "cdflag2.csv";
  792. allowIndex = 0;
  793. break;
  794. case VariableCode.CDFLAG:
  795. {
  796. if (index == 1)
  797. {
  798. ret = nameToIntDics[cdflag1Index];//CDFlagName1
  799. errPos = "cdflag1.csv";
  800. }
  801. else if (index == 2)
  802. {
  803. ret = nameToIntDics[cdflag2Index];//CDFlagName2
  804. errPos = "cdflag2.csv";
  805. }
  806. else if (index >= 0)
  807. throw new CodeEE("配列変数" + code + "の" + (index + 1) + "番目の要素を文字列で指定することはできません");
  808. else
  809. throw new CodeEE("CDFLAGの要素の取得にはCDFLAGNAME1又はCDFLAGNAME2を使用します");
  810. return ret;
  811. }
  812. case VariableCode.STR:
  813. ret = nameToIntDics[strnameIndex];
  814. errPos = "strname.csv";
  815. allowIndex = 0;
  816. break;
  817. case VariableCode.TSTR:
  818. ret = nameToIntDics[tstrnameIndex];
  819. errPos = "tstr.csv";
  820. allowIndex = 0;
  821. break;
  822. case VariableCode.SAVESTR:
  823. ret = nameToIntDics[savestrnameIndex];
  824. errPos = "savestr.csv";
  825. allowIndex = 0;
  826. break;
  827. case VariableCode.GLOBAL:
  828. ret = nameToIntDics[globalIndex];
  829. errPos = "global.csv";
  830. allowIndex = 0;
  831. break;
  832. case VariableCode.GLOBALS:
  833. ret = nameToIntDics[globalsIndex];
  834. errPos = "globals.csv";
  835. allowIndex = 0;
  836. break;
  837. case VariableCode.RELATION:
  838. ret = relationDic;
  839. errPos = "chara*.csv";
  840. allowIndex = 1;
  841. break;
  842. case VariableCode.NAME:
  843. ret = relationDic;
  844. errPos = "chara*.csv";
  845. allowIndex = -1;
  846. break;
  847. }
  848. if (index < 0)
  849. return ret;
  850. if (ret == null)
  851. throw new CodeEE("配列変数" + code + "の要素を文字列で指定することはできません");
  852. if ((index != allowIndex))
  853. {
  854. if (allowIndex < 0)//GETNUM専用
  855. throw new CodeEE("配列変数" + code + "の要素を文字列で指定することはできません");
  856. throw new CodeEE("配列変数" + code + "の" + (index + 1) + "番目の要素を文字列で指定することはできません");
  857. }
  858. return ret;
  859. }
  860. public CharacterTemplate GetCharacterTemplate(Int64 index)
  861. {
  862. foreach (CharacterTemplate chara in CharacterTmplList)
  863. {
  864. if (chara.No == index)
  865. return chara;
  866. }
  867. return null;
  868. }
  869. public CharacterTemplate GetCharacterTemplate_UseSp(Int64 index, bool sp)
  870. {
  871. foreach (CharacterTemplate chara in CharacterTmplList)
  872. {
  873. if (chara.No != index)
  874. continue;
  875. if (Config.Config.CompatiSPChara && sp != chara.IsSpchara)
  876. continue;
  877. return chara;
  878. }
  879. return null;
  880. }
  881. public CharacterTemplate GetCharacterTemplateFromCsvNo(Int64 index)
  882. {
  883. foreach (CharacterTemplate chara in CharacterTmplList)
  884. {
  885. if (chara.csvNo != index)
  886. continue;
  887. return chara;
  888. }
  889. return null;
  890. }
  891. public CharacterTemplate GetPseudoChara()
  892. {
  893. return new CharacterTemplate(0, this);
  894. }
  895. //private CharacterData dummyChara = null;
  896. //public CharacterData DummyChara
  897. //{
  898. // get { if (dummyChara == null) dummyChara = new CharacterData(GlobalStatic.VEvaluator.Constant, GetPseudoChara(),varData); return dummyChara; }
  899. // set { dummyChara = value; }
  900. //}
  901. private void loadCharacterData(string csvDir, bool disp)
  902. {
  903. if (!Directory.Exists(csvDir))
  904. return;
  905. List<KeyValuePair<string, string>> csvPaths = Config.Config.GetFiles(csvDir, "CHARA*.CSV");
  906. for (int i = 0; i < csvPaths.Count; i++)
  907. loadCharacterDataFile(csvPaths[i].Value, csvPaths[i].Key, disp);
  908. if (useCompatiName)
  909. {
  910. foreach (CharacterTemplate tmpl in CharacterTmplList)
  911. if (string.IsNullOrEmpty(tmpl.Callname))
  912. tmpl.Callname = tmpl.Name;
  913. }
  914. foreach (CharacterTemplate tmpl in CharacterTmplList)
  915. tmpl.SetSpFlag();
  916. Dictionary<Int64, CharacterTemplate> nList = new Dictionary<Int64, CharacterTemplate>();
  917. Dictionary<Int64, CharacterTemplate> spList = new Dictionary<Int64, CharacterTemplate>();
  918. foreach (CharacterTemplate tmpl in CharacterTmplList)
  919. {
  920. Dictionary<Int64, CharacterTemplate> targetList = nList;
  921. if(Config.Config.CompatiSPChara && tmpl.IsSpchara)
  922. {
  923. targetList = spList;
  924. }
  925. if (targetList.ContainsKey(tmpl.No))
  926. {
  927. if (!Config.Config.CompatiSPChara && (tmpl.IsSpchara!= targetList[tmpl.No].IsSpchara))
  928. ParserMediator.Warn("Character number " + tmpl.No + " was defined more than once\n" + "(To define it as an SP character please turn on compatibility option ”Allow SP characters”)", null, 1);
  929. else
  930. ParserMediator.Warn("Character number " + tmpl.No + " was defined more than once", null, 1);
  931. }
  932. else
  933. targetList.Add(tmpl.No, tmpl);
  934. }
  935. }
  936. private void loadCharacterDataFile(string csvPath, string csvName, bool disp)
  937. {
  938. CharacterTemplate tmpl = null;
  939. EraStreamReader eReader = new EraStreamReader(false);
  940. if (!eReader.Open(csvPath, csvName))
  941. {
  942. output.PrintError("Failed to open " + eReader.Filename);
  943. return;
  944. }
  945. ScriptPosition position = null;
  946. if (disp)
  947. output.PrintSystemLine("Loading " + eReader.Filename + "...");
  948. try
  949. {
  950. Int64 index = -1;
  951. StringStream st = null;
  952. while ((st = eReader.ReadEnabledLine()) != null)
  953. {
  954. position = new ScriptPosition(eReader.Filename, eReader.LineNo, st.RowString);
  955. string[] tokens = st.Substring().Split(',');
  956. if (tokens.Length < 2)
  957. {
  958. ParserMediator.Warn("\",\" is required", position, 1);
  959. continue;
  960. }
  961. if (tokens[0].Length == 0)
  962. {
  963. ParserMediator.Warn("\",\"で始まっています", position, 1);
  964. continue;
  965. }
  966. if ((tokens[0].Equals("NO", Config.Config.SCVariable))
  967. || (tokens[0].Equals("番号", Config.Config.SCVariable)))
  968. {
  969. if (tmpl != null)
  970. {
  971. ParserMediator.Warn("番号が二重に定義されました", position, 1);
  972. continue;
  973. }
  974. if (!Int64.TryParse(tokens[1].TrimEnd(), out index))
  975. {
  976. ParserMediator.Warn(tokens[1] + "を整数値に変換できません", position, 1);
  977. continue;
  978. }
  979. tmpl = new CharacterTemplate(index, this);
  980. string no = eReader.Filename.ToUpper();
  981. no = no.Substring(no.IndexOf("CHARA") + 5);
  982. StringBuilder sb = new StringBuilder();
  983. StringStream ss = new StringStream(no);
  984. while (!ss.EOS && char.IsDigit(ss.Current))
  985. {
  986. sb.Append(ss.Current);
  987. ss.ShiftNext();
  988. }
  989. if (sb.Length > 0)
  990. tmpl.csvNo = Convert.ToInt64(sb.ToString());
  991. else
  992. tmpl.csvNo = 0;
  993. //tmpl.csvNo = index;
  994. CharacterTmplList.Add(tmpl);
  995. continue;
  996. }
  997. if (tmpl == null)
  998. {
  999. ParserMediator.Warn("番号が定義される前に他のデータが始まりました", position, 1);
  1000. continue;
  1001. }
  1002. toCharacterTemplate(gamebase, position, tmpl, tokens);
  1003. }
  1004. }
  1005. catch
  1006. {
  1007. ShowParserError("An unexpected error has occurred", position, 3);
  1008. }
  1009. finally
  1010. {
  1011. eReader.Dispose();
  1012. }
  1013. }
  1014. private void ShowParserError(string errDescription, ScriptPosition position = null, int level = 3)
  1015. {
  1016. SystemSounds.Hand.Play();
  1017. if (position != null)
  1018. ParserMediator.Warn(errDescription, position, level);
  1019. else
  1020. output.PrintError(errDescription);
  1021. }
  1022. private bool tryToInt64(string str, out Int64 p)
  1023. {
  1024. p = -1;
  1025. if (string.IsNullOrEmpty(str))
  1026. return false;
  1027. StringStream st = new StringStream(str);
  1028. int sign = 1;
  1029. if (st.Current == '+')
  1030. st.ShiftNext();
  1031. else if (st.Current == '-')
  1032. {
  1033. sign = -1;
  1034. st.ShiftNext();
  1035. }
  1036. //1803beta005 char.IsDigitは全角数字とかまでひろってしまうので・・・
  1037. //if (!char.IsDigit(st.Current))
  1038. // return false;
  1039. switch (st.Current)
  1040. {
  1041. case '0':
  1042. case '1':
  1043. case '2':
  1044. case '3':
  1045. case '4':
  1046. case '5':
  1047. case '6':
  1048. case '7':
  1049. case '8':
  1050. case '9':
  1051. break;
  1052. default:
  1053. return false;
  1054. }
  1055. try
  1056. {
  1057. p = LexicalAnalyzer.ReadInt64(st, false);
  1058. p = p * sign;
  1059. }
  1060. catch
  1061. {
  1062. return false;
  1063. }
  1064. return true;
  1065. }
  1066. private void toCharacterTemplate(GameBase gamebase, ScriptPosition position, CharacterTemplate chara, string[] tokens)
  1067. {
  1068. if (chara == null)
  1069. return;
  1070. int length = -1;
  1071. Int64 p1 = -1;
  1072. Int64 p2 = -1;
  1073. Dictionary<int, Int64> intArray = null;
  1074. Dictionary<int, string> strArray = null;
  1075. Dictionary<string, int> namearray = null;
  1076. string errPos = null;
  1077. string varname = tokens[0].ToUpper();
  1078. switch (varname)
  1079. {
  1080. case "NAME":
  1081. case "名前":
  1082. chara.Name = Translation.translateChara(chara.No, Translation.CharaData.Name, tokens[1]); // JVN: This will translate the name of the character
  1083. return;
  1084. case "CALLNAME":
  1085. case "呼び名":
  1086. chara.Callname = Translation.translateChara(chara.No, Translation.CharaData.Callname, tokens[1]); // JVN: Translate Callname
  1087. return;
  1088. case "NICKNAME":
  1089. case "あだ名":
  1090. chara.Nickname = Translation.translateChara(chara.No, Translation.CharaData.Nickname, tokens[1]); // JVN: Translate Nickname
  1091. return;
  1092. case "MASTERNAME":
  1093. case "主人の呼び方":
  1094. chara.Mastername = Translation.translateChara(chara.No, Translation.CharaData.Mastername, tokens[1]); // JNV: Translate Mastername
  1095. return;
  1096. case "MARK":
  1097. case "刻印":
  1098. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.MARK)];
  1099. intArray = chara.Mark;
  1100. namearray = nameToIntDics[markIndex];
  1101. errPos = "mark.csv";
  1102. break;
  1103. case "EXP":
  1104. case "経験":
  1105. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.EXP)];
  1106. intArray = chara.Exp;
  1107. namearray = nameToIntDics[expIndex];//ExpName;
  1108. errPos = "exp.csv";
  1109. break;
  1110. case "ABL":
  1111. case "能力":
  1112. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.ABL)];
  1113. intArray = chara.Abl;
  1114. namearray = nameToIntDics[ablIndex];//AblName;
  1115. errPos = "abl.csv";
  1116. break;
  1117. case "BASE":
  1118. case "基礎":
  1119. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.MAXBASE)];
  1120. intArray = chara.Maxbase;
  1121. namearray = nameToIntDics[baseIndex];//BaseName;
  1122. errPos = "base.csv";
  1123. break;
  1124. case "TALENT":
  1125. case "素質":
  1126. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.TALENT)];
  1127. intArray = chara.Talent;
  1128. namearray = nameToIntDics[talentIndex];//TalentName;
  1129. errPos = "talent.csv";
  1130. break;
  1131. case "RELATION":
  1132. case "相性":
  1133. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.RELATION)];
  1134. intArray = chara.Relation;
  1135. namearray = null;
  1136. break;
  1137. case "CFLAG":
  1138. case "フラグ":
  1139. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.CFLAG)];
  1140. intArray = chara.CFlag;
  1141. namearray = nameToIntDics[cflagIndex];//CFlagName;
  1142. errPos = "cflag.csv";
  1143. break;
  1144. case "EQUIP":
  1145. case "装着物":
  1146. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.EQUIP)];
  1147. intArray = chara.Equip;
  1148. namearray = nameToIntDics[equipIndex];//EquipName;
  1149. errPos = "equip.csv";
  1150. break;
  1151. case "JUEL":
  1152. case "珠":
  1153. length = CharacterIntArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)];
  1154. intArray = chara.Juel;
  1155. namearray = nameToIntDics[paramIndex];//ParamName;
  1156. errPos = (canLoadParam ? "param.csv" : "palam.csv"); // JVN: For error output & debugging
  1157. break;
  1158. case "CSTR":
  1159. length = CharacterStrArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.CSTR)];
  1160. strArray = chara.CStr;
  1161. namearray = nameToIntDics[cstrIndex];//CStrName;
  1162. errPos = "cstr.csv";
  1163. break;
  1164. default:
  1165. ParserMediator.Warn("\"" + tokens[0] + "\" cannot be interpreted", position, 1);
  1166. return;
  1167. }
  1168. if (length < 0)
  1169. {
  1170. ParserMediator.Warn("Program error", position, 3);
  1171. return;
  1172. }
  1173. if (length == 0)
  1174. {
  1175. ParserMediator.Warn(varname + " is a prohibited set variable", position, 2);
  1176. return;
  1177. }
  1178. bool p1isNumeric = tryToInt64(tokens[1].TrimEnd(), out p1);
  1179. if (p1isNumeric && ((p1 < 0) || (p1 >= length)))
  1180. {
  1181. ParserMediator.Warn(p1 + " is out of the range of the array", position, 1);
  1182. return;
  1183. }
  1184. int index = (int)p1;
  1185. if ((!p1isNumeric) && (namearray != null))
  1186. {
  1187. if (!namearray.TryGetValue(tokens[1], out index))
  1188. {
  1189. ParserMediator.Warn(errPos + "に\"" + tokens[1] + "\"の定義がありません", position, 1);
  1190. //ParserMediator.Warn("\"" + tokens[1] + "\" cannot be interpreted", position, 1);
  1191. return;
  1192. }
  1193. if (index >= length)
  1194. {
  1195. ParserMediator.Warn("\"" + tokens[1] + "\"は配列の範囲外です", position, 1);
  1196. return;
  1197. }
  1198. }
  1199. if ((index < 0) || (index >= length))
  1200. {
  1201. if (p1isNumeric)
  1202. ParserMediator.Warn(index + "は配列の範囲外です", position, 1);
  1203. else if (tokens[1].Length == 0)
  1204. ParserMediator.Warn("二つ目の識別子がありません", position, 1);
  1205. else
  1206. ParserMediator.Warn("\"" + tokens[1] + "\" cannot be interpreted", position, 1);
  1207. return;
  1208. }
  1209. if (strArray != null)
  1210. {
  1211. if (tokens.Length < 3)
  1212. ParserMediator.Warn("三つ目の識別子がありません", position, 1);
  1213. if (strArray.ContainsKey(index))
  1214. ParserMediator.Warn(varname + "の" + index + "番目の要素は既に定義されています(上書きします)", position, 1);
  1215. strArray[index] = Translation.translateChara(chara.No, Translation.CharaData.CSTR, tokens[2], index); // JVN: Finally, this translates CSTRs
  1216. }
  1217. else
  1218. {
  1219. if ((tokens.Length < 3) || !tryToInt64(tokens[2], out p2))
  1220. p2 = 1;
  1221. if (intArray.ContainsKey(index))
  1222. ParserMediator.Warn(varname + "の" + index + "番目の要素は既に定義されています(上書きします)", position, 1);
  1223. intArray[index] = p2;
  1224. }
  1225. }
  1226. private void loadDataTo(string csvPath, int targetIndex, Int64[] targetI, bool disp)
  1227. {
  1228. if (!File.Exists(csvPath))
  1229. return;
  1230. string[] target = names[targetIndex];
  1231. List<int> defined = new List<int>();
  1232. EraStreamReader eReader = new EraStreamReader(false);
  1233. if (!eReader.Open(csvPath))
  1234. {
  1235. output.PrintError("Failed to open " + eReader.Filename);
  1236. return;
  1237. }
  1238. ScriptPosition position = null;
  1239. if (disp || Program.AnalysisMode)
  1240. output.PrintSystemLine("Loading " + eReader.Filename + "...");
  1241. try
  1242. {
  1243. StringStream st = null;
  1244. while ((st = eReader.ReadEnabledLine()) != null)
  1245. {
  1246. position = new ScriptPosition(eReader.Filename, eReader.LineNo, st.RowString);
  1247. string[] tokens = st.Substring().Split(',');
  1248. if (tokens.Length < 2)
  1249. {
  1250. ParserMediator.Warn("\",\" is required", position, 1);
  1251. continue;
  1252. }
  1253. int index = 0;
  1254. if (!Int32.TryParse(tokens[0], out index))
  1255. {
  1256. ParserMediator.Warn("The first value cannot be converted to an integer value", position, 1);
  1257. continue;
  1258. }
  1259. if (target.Length == 0)
  1260. {
  1261. ParserMediator.Warn("Prohibited set name array", position, 2);
  1262. break;
  1263. }
  1264. if ((index < 0) || (target.Length <= index))
  1265. {
  1266. ParserMediator.Warn(index + "は配列の範囲外です", position, 1);
  1267. continue;
  1268. }
  1269. if (defined.Contains(index))
  1270. ParserMediator.Warn(index + "番目の要素はすでに定義されています(新しい値で上書きします)", position, 1);
  1271. else
  1272. defined.Add(index);
  1273. target[index] = tokens[1];
  1274. if ((targetI != null) && (tokens.Length >= 3))
  1275. {
  1276. Int64 price;
  1277. if (!Int64.TryParse(tokens[2].TrimEnd(), out price))
  1278. {
  1279. ParserMediator.Warn("Couldn\'t read amount of money", position, 1);
  1280. continue;
  1281. }
  1282. targetI[index] = price;
  1283. }
  1284. }
  1285. }
  1286. catch
  1287. {
  1288. ShowParserError("An unexpected error has occurred", position, 3);
  1289. }
  1290. finally
  1291. {
  1292. eReader.Close();
  1293. }
  1294. }
  1295. }
  1296. internal sealed class CharacterTemplate
  1297. {
  1298. int[] arraySize;
  1299. int cstrSize;
  1300. public string Name;
  1301. public string Callname;
  1302. public string Nickname;
  1303. public string Mastername;
  1304. public readonly Int64 No;
  1305. public readonly Dictionary<Int32, Int64> Maxbase = new Dictionary<Int32, Int64>();
  1306. public readonly Dictionary<Int32, Int64> Mark = new Dictionary<Int32, Int64>();
  1307. public readonly Dictionary<Int32, Int64> Exp = new Dictionary<Int32, Int64>();
  1308. public readonly Dictionary<Int32, Int64> Abl = new Dictionary<Int32, Int64>();
  1309. public readonly Dictionary<Int32, Int64> Talent = new Dictionary<Int32, Int64>();
  1310. public readonly Dictionary<Int32, Int64> Relation = new Dictionary<Int32, Int64>();
  1311. public readonly Dictionary<Int32, Int64> CFlag = new Dictionary<Int32, Int64>();
  1312. public readonly Dictionary<Int32, Int64> Equip = new Dictionary<Int32, Int64>();
  1313. public readonly Dictionary<Int32, Int64> Juel = new Dictionary<Int32, Int64>();
  1314. public readonly Dictionary<Int32, string> CStr = new Dictionary<Int32, string>();
  1315. public Int64 csvNo;
  1316. public bool IsSpchara { get; private set; }
  1317. public CharacterTemplate(Int64 index, ConstantData constant)
  1318. {
  1319. arraySize = constant.CharacterIntArrayLength;
  1320. cstrSize = constant.CharacterStrArrayLength[(int)(VariableCode.__LOWERCASE__ & VariableCode.CSTR)];
  1321. No = index;
  1322. }
  1323. public int ArrayStrLength(CharacterStrData type)
  1324. {
  1325. switch (type)
  1326. {
  1327. case CharacterStrData.CSTR:
  1328. return cstrSize;
  1329. default:
  1330. throw new CodeEE("Attempted to refer to a key that does not exist");
  1331. }
  1332. }
  1333. public int ArrayLength(CharacterIntData type)
  1334. {
  1335. switch (type)
  1336. {
  1337. case CharacterIntData.BASE:
  1338. {
  1339. int size = arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.BASE)];
  1340. int maxSize = arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.MAXBASE)];
  1341. return size > maxSize ? size : maxSize;
  1342. }
  1343. case CharacterIntData.MARK:
  1344. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.MARK)];
  1345. case CharacterIntData.ABL:
  1346. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.ABL)];
  1347. case CharacterIntData.EXP:
  1348. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.EXP)];
  1349. case CharacterIntData.RELATION:
  1350. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.RELATION)];
  1351. case CharacterIntData.TALENT:
  1352. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.TALENT)];
  1353. case CharacterIntData.CFLAG:
  1354. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.CFLAG)];
  1355. case CharacterIntData.EQUIP:
  1356. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.EQUIP)];
  1357. case CharacterIntData.JUEL:
  1358. return arraySize[(int)(VariableCode.__LOWERCASE__ & VariableCode.JUEL)];
  1359. default:
  1360. throw new CodeEE("Attempted to refer to a key that does not exist");
  1361. }
  1362. }
  1363. internal void SetSpFlag()
  1364. {
  1365. if (CFlag.ContainsKey(0) && CFlag[0] != 0L)
  1366. IsSpchara = true;
  1367. }
  1368. }
  1369. }