ContinuousController.cs 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631
  1. using Photon.Pun;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Security.Cryptography;
  8. using System.Threading.Tasks;
  9. using UnityEngine;
  10. using UnityEngine.Events;
  11. using UnityEngine.EventSystems;
  12. using UnityEngine.SceneManagement;
  13. using Hashtable = ExitGames.Client.Photon.Hashtable;
  14. public class ContinuousController : MonoBehaviour
  15. {
  16. [Header("game language")]
  17. // public Language language;
  18. [Header("Game version")]
  19. public float GameVer;
  20. [Header("ignore updates")]
  21. public bool IgnoreUpdate;
  22. [Header("card list")]
  23. public CEntity_Base[] CardList = new CEntity_Base[] { };
  24. [Header("Card list sorted by card ID")]
  25. public CEntity_Base[] SortedCardList = new CEntity_Base[] { };
  26. [Header("Card back image")]
  27. public Sprite ReverseCard;
  28. public Sprite ReverseCard_Digitama;
  29. [Header("SE prefab")]
  30. public SoundObject soundObject;
  31. [Header("deck code encryption")]
  32. public ShuffleDeckCode ShuffleDeckCode;
  33. DeckData _battleDeckData = null;
  34. public DeckData BattleDeckData
  35. {
  36. get
  37. {
  38. return _battleDeckData;
  39. }
  40. set
  41. {
  42. _battleDeckData = value;
  43. if (value != null)
  44. {
  45. LastBattleDeckData = value;
  46. }
  47. }
  48. }
  49. public DeckData LastBattleDeckData { get; private set; } = null;
  50. public bool NeedUpdate { get; set; }
  51. public bool isRandomMatch { get; set; }
  52. [HideInInspector] public List<SkillInfo> nullSkillInfos = null;
  53. public String GameVerString => Application.version;//GameVer.ToString(CultureInfo.InvariantCulture);
  54. #region Key for property to save deck data for battle
  55. public static string DeckDataPropertyKey => "BattleDeckData";
  56. #endregion
  57. #region Key for the property that stores the player name data
  58. public static string PlayerNameKey => "PlayerNameKey";
  59. #endregion
  60. #region Key for the property that stores the win count data
  61. public static string WinCountKey => "WinCountKey";
  62. #endregion
  63. [Header("Player name character limit")]
  64. public int PlayerNameMaxLength;
  65. #region Call up a scene for data storage
  66. public static IEnumerator LoadCoroutine()
  67. {
  68. if (instance == null)
  69. {
  70. SceneManager.LoadSceneAsync("ContinuousControllerScene", LoadSceneMode.Additive);
  71. while (instance == null)
  72. {
  73. yield return null;
  74. }
  75. instance.Init();
  76. }
  77. }
  78. #endregion
  79. #region List of Deck Recipes
  80. public List<DeckData> DeckDatas { get; set; } = new List<DeckData>();
  81. #endregion
  82. #region Deck Recipe Key
  83. public string DeckDatasPlayerPrefsKey { get { return "DeckDatas3"; } }
  84. #endregion
  85. public CEntity_Base DiaboromonToken { get; private set; }
  86. public CEntity_Base AmonToken { get; private set; }
  87. public CEntity_Base UmonToken { get; private set; }
  88. public CEntity_Base FujitsumonToken { get; private set; }
  89. public CEntity_Base GyuukimonToken { get; private set; }
  90. public CEntity_Base KoHagurumonToken { get; private set; }
  91. public CEntity_Base FamiliarToken { get; private set; }
  92. public CEntity_Base SelfDeleteFamiliarToken { get; private set; }
  93. public CEntity_Base VoleeZerdruckenToken { get; private set; }
  94. public CEntity_Base UkaNoMitamaToken { get; private set; }
  95. public CEntity_Base WarGrowlmonToken { get; private set; }
  96. public CEntity_Base TaomonToken { get; private set; }
  97. public CEntity_Base RapidmonToken { get; private set; }
  98. public CEntity_Base PipeFoxToken { get; private set; }
  99. public CEntity_Base AthoRenePorToken { get; private set; }
  100. public CEntity_Base HinukamuyToken { get; private set; }
  101. public CEntity_Base PetrificationToken { get; private set; }
  102. public CardRestriction BanList { get; private set; } = new CardRestriction(new List<CardLimitCount>(), new List<BannedPair>());
  103. void LoadBanList()
  104. {
  105. BanList = DataBase.ENGBanList;
  106. }
  107. async Task CreateTokenData()
  108. {
  109. DiaboromonToken = new CEntity_Base()
  110. {
  111. cardColors = new List<CardColor>() { CardColor.White },
  112. PlayCost = 14,
  113. Level = 6,
  114. CardName_JPN = "ディアボロモン",
  115. CardName_ENG = "Diaboromon",
  116. Form_JPN = new List<string>() { "究極体" },
  117. Form_ENG = new List<string>() { "Mega" },
  118. Attribute_JPN = new List<string>() { "不明" },
  119. Attribute_ENG = new List<string>() { "Unknown" },
  120. Type_JPN = new List<string>() { "種族不明" },
  121. Type_ENG = new List<string>() { "Unidentified" },
  122. CardSpriteName = "BT2-082-token",
  123. cardKind = new List<CardKind> { CardKind.Digimon },
  124. DP = 3000,
  125. };
  126. await DiaboromonToken.GetCardSprite();
  127. AmonToken = new CEntity_Base()
  128. {
  129. cardColors = new List<CardColor>() { CardColor.Red },
  130. PlayCost = -1,
  131. Level = 0,
  132. CardName_JPN = "紅炎のアモン",
  133. CardName_ENG = "Amon of Crimson Flame",
  134. Form_JPN = new List<string>(),
  135. Form_ENG = new List<string>(),
  136. Attribute_JPN = new List<string>(),
  137. Attribute_ENG = new List<string>(),
  138. Type_JPN = new List<string>(),
  139. Type_ENG = new List<string>(),
  140. CardSpriteName = "BT14-018-token-red",
  141. cardKind = new List<CardKind> { CardKind.Digimon },
  142. DP = 6000,
  143. CardEffectClassName = "BT4_038"
  144. };
  145. await AmonToken.GetCardSprite();
  146. UmonToken = new CEntity_Base()
  147. {
  148. cardColors = new List<CardColor>() { CardColor.Yellow },
  149. PlayCost = -1,
  150. Level = 0,
  151. CardName_JPN = "蒼雷のウモン",
  152. CardName_ENG = "Umon of Blue Thunder",
  153. Form_JPN = new List<string>(),
  154. Form_ENG = new List<string>(),
  155. Attribute_JPN = new List<string>(),
  156. Attribute_ENG = new List<string>(),
  157. Type_JPN = new List<string>(),
  158. Type_ENG = new List<string>(),
  159. CardSpriteName = "BT14-018-token-yellow",
  160. cardKind = new List<CardKind> { CardKind.Digimon },
  161. DP = 6000,
  162. CardEffectClassName = "BT1_031"
  163. };
  164. await UmonToken.GetCardSprite();
  165. FujitsumonToken = new CEntity_Base()
  166. {
  167. cardColors = new List<CardColor>() { CardColor.Purple },
  168. PlayCost = -1,
  169. Level = 0,
  170. CardName_JPN = "フジツモン",
  171. CardName_ENG = "Fujitsumon",
  172. Form_JPN = new List<string>(),
  173. Form_ENG = new List<string>(),
  174. Attribute_JPN = new List<string>(),
  175. Attribute_ENG = new List<string>(),
  176. Type_JPN = new List<string>(),
  177. Type_ENG = new List<string>(),
  178. CardSpriteName = "EX5-058-token",
  179. cardKind = new List<CardKind> { CardKind.Digimon },
  180. DP = 3000,
  181. CardEffectClassName = "EX5_058_token"
  182. };
  183. await FujitsumonToken.GetCardSprite();
  184. GyuukimonToken = new CEntity_Base()
  185. {
  186. cardColors = new List<CardColor>() { CardColor.Purple },
  187. PlayCost = 7,
  188. Level = 5,
  189. CardName_JPN = "ギュウキモン",
  190. CardName_ENG = "Gyuukimon",
  191. Form_JPN = new List<string>() { "究極の" },
  192. Form_ENG = new List<string>() { "Ultimate" },
  193. Attribute_JPN = new List<string>() { "ウイルス" },
  194. Attribute_ENG = new List<string>() { "Virus" },
  195. Type_JPN = new List<string>() { "ダークアニマル" },
  196. Type_ENG = new List<string>() { "Dark Animal" },
  197. CardSpriteName = "LM-018-token",
  198. cardKind = new List<CardKind> { CardKind.Digimon },
  199. DP = 3000,
  200. };
  201. await GyuukimonToken.GetCardSprite();
  202. KoHagurumonToken = new CEntity_Base()
  203. {
  204. cardColors = new List<CardColor>() { CardColor.Black },
  205. PlayCost = -1,
  206. Level = 0,
  207. CardName_JPN = "",
  208. CardName_ENG = "KoHagurumon",
  209. Form_JPN = new List<string>(),
  210. Form_ENG = new List<string>(),
  211. Attribute_JPN = new List<string>(),
  212. Attribute_ENG = new List<string>(),
  213. Type_JPN = new List<string>(),
  214. Type_ENG = new List<string>(),
  215. CardSpriteName = "BT16-052-token",
  216. cardKind = new List<CardKind> { CardKind.Digimon },
  217. DP = 1000,
  218. CardEffectClassName = "BT16_052_token"
  219. };
  220. await KoHagurumonToken.GetCardSprite();
  221. FamiliarToken = new CEntity_Base()
  222. {
  223. cardColors = new List<CardColor>() { CardColor.Yellow },
  224. PlayCost = -1,
  225. Level = 0,
  226. CardName_JPN = "",
  227. CardName_ENG = "Familiar",
  228. Form_JPN = new List<string>(),
  229. Form_ENG = new List<string>(),
  230. Attribute_JPN = new List<string>(),
  231. Attribute_ENG = new List<string>(),
  232. Type_JPN = new List<string>(),
  233. Type_ENG = new List<string>(),
  234. CardSpriteName = "EX7-030-token",
  235. cardKind = new List<CardKind> { CardKind.Digimon },
  236. DP = 3000,
  237. CardEffectClassName = "EX7_030_token"
  238. };
  239. await FamiliarToken.GetCardSprite();
  240. SelfDeleteFamiliarToken = new CEntity_Base()
  241. {
  242. cardColors = new List<CardColor>() { CardColor.Yellow },
  243. PlayCost = -1,
  244. Level = 0,
  245. CardName_JPN = "",
  246. CardName_ENG = "Familiar",
  247. Form_JPN = new List<string>(),
  248. Form_ENG = new List<string>(),
  249. Attribute_JPN = new List<string>(),
  250. Attribute_ENG = new List<string>(),
  251. Type_JPN = new List<string>(),
  252. Type_ENG = new List<string>(),
  253. CardSpriteName = "EX7-030-token",
  254. cardKind = new List<CardKind> { CardKind.Digimon },
  255. DP = 3000,
  256. CardEffectClassName = "P_165_token"
  257. };
  258. await SelfDeleteFamiliarToken.GetCardSprite();
  259. VoleeZerdruckenToken = new CEntity_Base()
  260. {
  261. cardColors = new List<CardColor>() { CardColor.Purple },
  262. PlayCost = -1,
  263. Level = 4,
  264. CardName_JPN = "",
  265. CardName_ENG = "Volée & Zerdrücken",
  266. Form_JPN = new List<string>(),
  267. Form_ENG = new List<string>(),
  268. Attribute_JPN = new List<string>(),
  269. Attribute_ENG = new List<string>(),
  270. Type_JPN = new List<string>(),
  271. Type_ENG = new List<string>(),
  272. CardSpriteName = "EX7-058-token",
  273. cardKind = new List<CardKind> { CardKind.Digimon },
  274. DP = 5000,
  275. CardEffectClassName = "EX7_058_token"
  276. };
  277. await VoleeZerdruckenToken.GetCardSprite();
  278. UkaNoMitamaToken = new CEntity_Base()
  279. {
  280. cardColors = new List<CardColor>() { CardColor.Yellow },
  281. PlayCost = -1,
  282. Level = 0,
  283. CardName_JPN = "",
  284. CardName_ENG = "Uka-no-Mitama",
  285. Form_JPN = new List<string>(),
  286. Form_ENG = new List<string>(),
  287. Attribute_JPN = new List<string>(),
  288. Attribute_ENG = new List<string>(),
  289. Type_JPN = new List<string>(),
  290. Type_ENG = new List<string>(),
  291. CardSpriteName = "EX8-037-token",
  292. cardKind = new List<CardKind> { CardKind.Digimon },
  293. DP = 9000,
  294. CardEffectClassName = "EX8_037_token"
  295. };
  296. await UkaNoMitamaToken.GetCardSprite();
  297. WarGrowlmonToken = new CEntity_Base()
  298. {
  299. cardColors = new List<CardColor>() { CardColor.Red },
  300. PlayCost = -1,
  301. Level = 0,
  302. CardName_JPN = "",
  303. CardName_ENG = "WarGrowlmon",
  304. Form_JPN = new List<string>(),
  305. Form_ENG = new List<string>(),
  306. Attribute_JPN = new List<string>(),
  307. Attribute_ENG = new List<string>(),
  308. Type_JPN = new List<string>(),
  309. Type_ENG = new List<string>(),
  310. CardSpriteName = "BT19-091-token-red",
  311. cardKind = new List<CardKind> { CardKind.Digimon },
  312. DP = 6000
  313. };
  314. await WarGrowlmonToken.GetCardSprite();
  315. TaomonToken = new CEntity_Base()
  316. {
  317. cardColors = new List<CardColor>() { CardColor.Yellow },
  318. PlayCost = -1,
  319. Level = 0,
  320. CardName_JPN = "",
  321. CardName_ENG = "Taomon",
  322. Form_JPN = new List<string>(),
  323. Form_ENG = new List<string>(),
  324. Attribute_JPN = new List<string>(),
  325. Attribute_ENG = new List<string>(),
  326. Type_JPN = new List<string>(),
  327. Type_ENG = new List<string>(),
  328. CardSpriteName = "BT19-091-token-yellow",
  329. cardKind = new List<CardKind> { CardKind.Digimon },
  330. DP = 6000
  331. };
  332. await TaomonToken.GetCardSprite();
  333. RapidmonToken = new CEntity_Base()
  334. {
  335. cardColors = new List<CardColor>() { CardColor.Green },
  336. PlayCost = -1,
  337. Level = 0,
  338. CardName_JPN = "",
  339. CardName_ENG = "Rapidmon",
  340. Form_JPN = new List<string>(),
  341. Form_ENG = new List<string>(),
  342. Attribute_JPN = new List<string>(),
  343. Attribute_ENG = new List<string>(),
  344. Type_JPN = new List<string>(),
  345. Type_ENG = new List<string>(),
  346. CardSpriteName = "BT19-091-token-green",
  347. cardKind = new List<CardKind> { CardKind.Digimon },
  348. DP = 6000
  349. };
  350. await RapidmonToken.GetCardSprite();
  351. PipeFoxToken = new CEntity_Base()
  352. {
  353. cardColors = new List<CardColor>() { CardColor.Yellow },
  354. PlayCost = -1,
  355. Level = 0,
  356. CardName_JPN = "",
  357. CardName_ENG = "Pipe-Fox",
  358. Form_JPN = new List<string>(),
  359. Form_ENG = new List<string>(),
  360. Attribute_JPN = new List<string>(),
  361. Attribute_ENG = new List<string>(),
  362. Type_JPN = new List<string>(),
  363. Type_ENG = new List<string>(),
  364. CardSpriteName = "BT19-040-token",
  365. cardKind = new List<CardKind> { CardKind.Digimon },
  366. DP = 6000,
  367. CardEffectClassName = "BT19_040_token"
  368. };
  369. await PipeFoxToken.GetCardSprite();
  370. AthoRenePorToken = new CEntity_Base()
  371. {
  372. cardColors = new List<CardColor>() { CardColor.White },
  373. PlayCost = -1,
  374. Level = 0,
  375. CardName_JPN = "",
  376. CardName_ENG = "Atho, René & Por",
  377. Form_JPN = new List<string>(),
  378. Form_ENG = new List<string>(),
  379. Attribute_JPN = new List<string>(),
  380. Attribute_ENG = new List<string>(),
  381. Type_JPN = new List<string>(),
  382. Type_ENG = new List<string>(),
  383. CardSpriteName = "BT20-017-token",
  384. cardKind = new List<CardKind> { CardKind.Digimon },
  385. DP = 6000,
  386. CardEffectClassName = "BT20_017_token"
  387. };
  388. await AthoRenePorToken.GetCardSprite();
  389. HinukamuyToken = new CEntity_Base()
  390. {
  391. cardColors = new List<CardColor>() { CardColor.White },
  392. PlayCost = -1,
  393. Level = 0,
  394. CardName_JPN = "",
  395. CardName_ENG = "HinukamuyToken",
  396. Form_JPN = new List<string>(),
  397. Form_ENG = new List<string>(),
  398. Attribute_JPN = new List<string>(),
  399. Attribute_ENG = new List<string>(),
  400. Type_JPN = new List<string>(),
  401. Type_ENG = new List<string>(),
  402. CardSpriteName = "BT23-057-token",
  403. cardKind = new List<CardKind> { CardKind.Digimon },
  404. DP = 6000,
  405. CardEffectClassName = "BT23_057_token"
  406. };
  407. await HinukamuyToken.GetCardSprite();
  408. PetrificationToken = new CEntity_Base()
  409. {
  410. cardColors = new List<CardColor>() { CardColor.White },
  411. PlayCost = -1,
  412. Level = 0,
  413. CardName_JPN = "",
  414. CardName_ENG = "Petrification",
  415. Form_JPN = new List<string>(),
  416. Form_ENG = new List<string>(),
  417. Attribute_JPN = new List<string>(),
  418. Attribute_ENG = new List<string>(),
  419. Type_JPN = new List<string>(),
  420. Type_ENG = new List<string>(),
  421. CardSpriteName = "BT21-029-token",
  422. cardKind = new List<CardKind> { CardKind.Digimon },
  423. DP = 3000,
  424. CardEffectClassName = "BT21_029_token"
  425. };
  426. await PetrificationToken.GetCardSprite();
  427. }
  428. public static ContinuousController instance = null;
  429. private void Awake()
  430. {
  431. instance = this;
  432. }
  433. public async void Init()
  434. {
  435. Application.targetFrameRate = 60;
  436. long random = RandomUtility.GetSecureRandom();
  437. GameRandom.Seed(random);
  438. Debug.Log($"Game Initialize - random number sequence initialization, GameRandom.Seed:{random}");
  439. Sprite reverseCardSprite = await StreamingAssetsUtility.GetSprite("card_back_main");
  440. if (reverseCardSprite != null)
  441. {
  442. ReverseCard = reverseCardSprite;
  443. }
  444. Sprite reverseDigieggCardSprite = await StreamingAssetsUtility.GetSprite("card_back_sub");
  445. if (reverseDigieggCardSprite != null)
  446. {
  447. ReverseCard_Digitama = reverseDigieggCardSprite;
  448. }
  449. LoadBanList();
  450. // deck data
  451. //DeckDatas = PlayerPrefsUtil.LoadList<DeckData>(DeckDatasPlayerPrefsKey);
  452. LoadDeckLists();
  453. GetComponent<StarterDeck>().SetStarterDecks();
  454. // player data
  455. LoadPlayerName();
  456. LoadWinCount();
  457. // game play
  458. LoadAutoEffectOrder();
  459. LoadAutoDeckBottomOrder();
  460. LoadAutoDeckTopOrder();
  461. LoadAutoMinDigivolutionCost();
  462. LoadAutoMaxCardCount();
  463. LoadAutoHatch();
  464. LoadShowCutInAnimation();
  465. LoadReverseOpponentsCards();
  466. LoadTurnSuspendedCards();
  467. LoadCheckBeforeEndingSelection();
  468. LoadSuspendedCardsDirectionIsLeft();
  469. //Graphics
  470. LoadShowBackgroundParticle();
  471. // Sound
  472. LoadVolume();
  473. // ServerRegion
  474. LoadServerRegion();
  475. // Language
  476. LoadLanguage();
  477. await CreateTokenData();
  478. DontDestroyOnLoad(gameObject);
  479. }
  480. [Obsolete("This is obsolete, switching to save files")]
  481. public void ModifyAllDeckDatas()
  482. {
  483. List<DeckData> tempDeckDatas = new List<DeckData>();
  484. foreach (DeckData deckData in DeckDatas)
  485. {
  486. tempDeckDatas.Add(deckData);
  487. }
  488. foreach (DeckData deckData in tempDeckDatas)
  489. {
  490. if (deckData.AllDeckCards().Count == 0)
  491. {
  492. DeckDatas.Remove(deckData);
  493. }
  494. }
  495. for (int i = 0; i < DeckDatas.Count; i++)
  496. {
  497. //DeckData deckData = new DeckData(DeckData.GetDeckCode(DeckDatas[i].DeckName, DeckData.SortedDeckCardsList(DeckDatas[i].DeckCards()), DeckData.SortedDeckCardsList(DeckDatas[i].DigitamaDeckCards()), DeckDatas[i].KeyCard));
  498. DeckData deckData = DeckDatas[i];
  499. DeckDatas[i] = deckData.ModifiedDeckData();
  500. }
  501. SaveDeckDatas();
  502. }
  503. [Obsolete("This is obsolete, switching to save files")]
  504. public void SaveDeckDatas()
  505. {
  506. PlayerPrefsUtil.SaveList(DeckDatasPlayerPrefsKey, DeckDatas);
  507. PlayerPrefs.Save();
  508. }
  509. public void SaveDeckData(DeckData data)
  510. {
  511. string savePath = StreamingAssetsUtility.GetStreamingAssetPath("Decks", false);
  512. File.WriteAllText($"{savePath}/{data.DeckName}_{data.DeckID}.txt", DeckCodeUtility.GetDeckBuilderFile(data));
  513. }
  514. public void RenameDeck(DeckData data, string newName)
  515. {
  516. string savePath = StreamingAssetsUtility.GetStreamingAssetPath("Decks", false);
  517. if (File.Exists($"{savePath}/{data.DeckName}_{data.DeckID}.txt"))
  518. {
  519. File.Move($"{savePath}/{data.DeckName}_{data.DeckID}.txt", $"{savePath}/{newName}_{data.DeckID}.txt");
  520. data.DeckName = newName;
  521. SaveDeckData(data);
  522. }
  523. else
  524. data.DeckName = newName;
  525. }
  526. public void DeleteDeck(DeckData data)
  527. {
  528. string filePath = StreamingAssetsUtility.GetStreamingAssetPath("Decks", false);
  529. if (!Directory.Exists(filePath))
  530. return;
  531. if (!File.Exists($"{filePath}/{data.DeckName}_{data.DeckID}.txt"))
  532. return;
  533. File.Delete($"{filePath}/{data.DeckName}_{data.DeckID}.txt");
  534. }
  535. public void DeleteAllDecks()
  536. {
  537. foreach(DeckData data in DeckDatas)
  538. {
  539. DeleteDeck(data);
  540. }
  541. }
  542. public void LoadDeckLists()
  543. {
  544. string loadPath = StreamingAssetsUtility.GetStreamingAssetPath("Decks", false);
  545. if (!Directory.Exists(loadPath))
  546. return;
  547. string[] deckLists = Directory.GetFiles(loadPath);
  548. foreach(string deckPath in deckLists)
  549. {
  550. string fileName = Path.GetFileNameWithoutExtension(deckPath);
  551. if (!fileName.Contains("_"))
  552. continue;
  553. string deckList = File.ReadAllText(deckPath);
  554. StreamReader sr = new StreamReader(deckPath);
  555. string deckName = sr.ReadLine().Replace("Name: ", "");
  556. int KeyCard = int.Parse(sr.ReadLine().Replace("Key Card: ", ""));
  557. int SortValue = int.Parse(sr.ReadLine().Replace("Sort Index: ", ""));
  558. sr.Close();
  559. string deck = deckList.Substring(deckList.IndexOf("//"));
  560. //Debug.Log(deckName);
  561. if(SortValue < 0)
  562. SortValue = 0;
  563. CreateDeckFromFile(fileName.Split("_")[1], deckName, KeyCard, deck, SortValue);
  564. }
  565. DeckDatas = DeckDatas.OrderBy(x => x.DeckName).ToList();
  566. }
  567. private void CreateDeckFromFile(string id, string name, int keyID, string deckCode, int index = 0)
  568. {
  569. List<CEntity_Base> AllDeckCards = DeckCodeUtility.GetAllDeckCardsFromDeckBuilderDeckCode(deckCode);
  570. if (AllDeckCards.Count == 0)
  571. {
  572. AllDeckCards = DeckCodeUtility.GetAllDeckCardsFromTTSDeckCode(deckCode);
  573. }
  574. List<CEntity_Base> deckCards = new List<CEntity_Base>();
  575. List<CEntity_Base> digitamaDeckCards = new List<CEntity_Base>();
  576. foreach (CEntity_Base cEntity_Base in AllDeckCards)
  577. {
  578. if (cEntity_Base.cardKind.Contains(CardKind.DigiEgg))
  579. {
  580. digitamaDeckCards.Add(cEntity_Base);
  581. }
  582. else
  583. {
  584. deckCards.Add(cEntity_Base);
  585. }
  586. }
  587. Debug.Log($"Create Deck From File: {name}");
  588. DeckData deckData = (new DeckData(DeckData.GetDeckCode(name, deckCards, digitamaDeckCards, null),id)).ModifiedDeckData();
  589. deckData.KeyCardId = keyID;
  590. deckData.DeckName = name;
  591. deckData.SortValue = index;
  592. DeckDatas.Insert(index, deckData);
  593. }
  594. #region Player Name
  595. string _playerName;
  596. string _playerNameKey = "PlayerName";
  597. public string PlayerName
  598. {
  599. get
  600. {
  601. if (string.IsNullOrEmpty(_playerName))
  602. {
  603. return "Player";
  604. }
  605. return _playerName;
  606. }
  607. set
  608. {
  609. _playerName = DeckData.ValidateDeckName(value);
  610. }
  611. }
  612. public void SavePlayerName(string playerName)
  613. {
  614. PlayerName = playerName;
  615. PlayerPrefs.SetString(_playerNameKey, playerName);
  616. PlayerPrefs.Save();
  617. }
  618. public void LoadPlayerName()
  619. {
  620. if (PlayerPrefs.HasKey(_playerNameKey))
  621. {
  622. PlayerName = PlayerPrefs.GetString(_playerNameKey);
  623. }
  624. if (string.IsNullOrEmpty(PlayerName))
  625. {
  626. PlayerName = "Player";
  627. }
  628. }
  629. #endregion
  630. #region number of victories
  631. public int WinCount { get; set; }
  632. string _winCountKey = "WinCount";
  633. public void SaveWinCount()
  634. {
  635. PlayerPrefs.SetInt(_winCountKey, WinCount);
  636. PlayerPrefs.Save();
  637. }
  638. public void LoadWinCount()
  639. {
  640. if (PlayerPrefs.HasKey(_winCountKey))
  641. {
  642. WinCount = PlayerPrefs.GetInt(_winCountKey);
  643. }
  644. }
  645. #endregion
  646. #region Auto effect order
  647. [HideInInspector] public bool autoEffectOrder = false;
  648. string _autoEffectOrderKey = "AutoEffectOrder";
  649. public void SaveAutoEffectOrder()
  650. {
  651. PlayerPrefsUtil.SetBool(_autoEffectOrderKey, autoEffectOrder);
  652. PlayerPrefs.Save();
  653. }
  654. public void LoadAutoEffectOrder()
  655. {
  656. autoEffectOrder = PlayerPrefsUtil.GetBool(_autoEffectOrderKey, false);
  657. }
  658. #endregion
  659. #region Auto deck bottom order
  660. [HideInInspector] public bool autoDeckBottomOrder = false;
  661. string _autoDeckBottomOrderKey = "AutoDeckBottomOrder";
  662. public void SaveAutoDeckBottomOrder()
  663. {
  664. PlayerPrefsUtil.SetBool(_autoDeckBottomOrderKey, autoDeckBottomOrder);
  665. PlayerPrefs.Save();
  666. }
  667. public void LoadAutoDeckBottomOrder()
  668. {
  669. autoDeckBottomOrder = PlayerPrefsUtil.GetBool(_autoDeckBottomOrderKey, false);
  670. }
  671. #endregion
  672. #region Auto deck top order
  673. [HideInInspector] public bool autoDeckTopOrder = false;
  674. string _autoDeckTopOrderKey = "AutoDeckTopOrder";
  675. public void SaveAutoDeckTopOrder()
  676. {
  677. PlayerPrefsUtil.SetBool(_autoDeckTopOrderKey, autoDeckTopOrder);
  678. PlayerPrefs.Save();
  679. }
  680. public void LoadAutoDeckTopOrder()
  681. {
  682. autoDeckTopOrder = PlayerPrefsUtil.GetBool(_autoDeckTopOrderKey, false);
  683. }
  684. #endregion
  685. #region Auto min digivolution cost
  686. [HideInInspector] public bool autoMinDigivolutionCost = false;
  687. string _autoMinDigivolutionCostKey = "AutoMinDigivolutionCost";
  688. public void SaveAutoMinDigivolutionCost()
  689. {
  690. PlayerPrefsUtil.SetBool(_autoMinDigivolutionCostKey, autoMinDigivolutionCost);
  691. PlayerPrefs.Save();
  692. }
  693. public void LoadAutoMinDigivolutionCost()
  694. {
  695. autoMinDigivolutionCost = PlayerPrefsUtil.GetBool(_autoMinDigivolutionCostKey, false);
  696. }
  697. #endregion
  698. #region Auto max card count
  699. [HideInInspector] public bool autoMaxCardCount = false;
  700. string _autoMaxCardCountKey = "AutoMaxCardCount";
  701. public void SaveAutoMaxCardCount()
  702. {
  703. PlayerPrefsUtil.SetBool(_autoMaxCardCountKey, autoMaxCardCount);
  704. PlayerPrefs.Save();
  705. }
  706. public void LoadAutoMaxCardCount()
  707. {
  708. autoMaxCardCount = PlayerPrefsUtil.GetBool(_autoMaxCardCountKey, false);
  709. }
  710. #endregion
  711. #region Auto hatch
  712. [HideInInspector] public bool autoHatch = false;
  713. string _autoHatchKey = "AutoHatch";
  714. public void SaveAutoHatch()
  715. {
  716. PlayerPrefsUtil.SetBool(_autoHatchKey, autoHatch);
  717. PlayerPrefs.Save();
  718. }
  719. public void LoadAutoHatch()
  720. {
  721. autoHatch = PlayerPrefsUtil.GetBool(_autoHatchKey, false);
  722. }
  723. #endregion
  724. #region Show CutIn Animation
  725. [HideInInspector] public bool showCutInAnimation = false;
  726. string _showCutInAnimationKey = "ShowCutInAnimation";
  727. public void SaveShowCutInAnimation()
  728. {
  729. PlayerPrefsUtil.SetBool(_showCutInAnimationKey, showCutInAnimation);
  730. PlayerPrefs.Save();
  731. }
  732. public void LoadShowCutInAnimation()
  733. {
  734. //TODO: Setting default to false, to fix animation syncing bug, MB
  735. showCutInAnimation = false;
  736. //showCutInAnimation = PlayerPrefsUtil.GetBool(_showCutInAnimationKey, true);
  737. }
  738. #endregion
  739. #region Reverse opponents' cards
  740. [HideInInspector] public bool reverseOpponentsCards = false;
  741. string _reverseOpponentsCardsKey = "ReverseOpponentsCards";
  742. public void SaveReverseOpponentsCards()
  743. {
  744. PlayerPrefsUtil.SetBool(_reverseOpponentsCardsKey, reverseOpponentsCards);
  745. PlayerPrefs.Save();
  746. }
  747. public void LoadReverseOpponentsCards()
  748. {
  749. reverseOpponentsCards = PlayerPrefsUtil.GetBool(_reverseOpponentsCardsKey, false);
  750. }
  751. #endregion
  752. #region Turn suspended cards
  753. [HideInInspector] public bool turnSuspendedCards = false;
  754. string _turnSuspendedCardsKey = "TurnSuspendedCards";
  755. public void SaveTurnSuspendedCards()
  756. {
  757. PlayerPrefsUtil.SetBool(_turnSuspendedCardsKey, turnSuspendedCards);
  758. PlayerPrefs.Save();
  759. }
  760. public void LoadTurnSuspendedCards()
  761. {
  762. turnSuspendedCards = PlayerPrefsUtil.GetBool(_turnSuspendedCardsKey, true);
  763. }
  764. #endregion
  765. #region Check before ending selection
  766. [HideInInspector] public bool checkBeforeEndingSelection = false;
  767. string _checkBeforeEndingSelectionKey = "CheckBeforeEndingSelection";
  768. public void SaveCheckBeforeEndingSelection()
  769. {
  770. PlayerPrefsUtil.SetBool(_checkBeforeEndingSelectionKey, checkBeforeEndingSelection);
  771. PlayerPrefs.Save();
  772. }
  773. public void LoadCheckBeforeEndingSelection()
  774. {
  775. checkBeforeEndingSelection = PlayerPrefsUtil.GetBool(_checkBeforeEndingSelectionKey, true);
  776. }
  777. #endregion
  778. #region Suspended cards' direction is left
  779. [HideInInspector] public bool suspendedCardsDirectionIsLeft = false;
  780. string _suspendedCardsDirectionIsLeftKey = "SuspendedCardsDirectionIsLeft";
  781. public void SaveSuspendedCardsDirectionIsLeft()
  782. {
  783. PlayerPrefsUtil.SetBool(_suspendedCardsDirectionIsLeftKey, suspendedCardsDirectionIsLeft);
  784. PlayerPrefs.Save();
  785. }
  786. public void LoadSuspendedCardsDirectionIsLeft()
  787. {
  788. suspendedCardsDirectionIsLeft = PlayerPrefsUtil.GetBool(_suspendedCardsDirectionIsLeftKey, true);
  789. }
  790. #endregion
  791. #region Show background particle
  792. [HideInInspector] public bool showBackgroundParticle = false;
  793. string _showBackgroundParticleKey = "ShowBackgroundParticle";
  794. public void SaveShowBackgroundParticle()
  795. {
  796. PlayerPrefsUtil.SetBool(_showBackgroundParticleKey, showBackgroundParticle);
  797. PlayerPrefs.Save();
  798. }
  799. public void LoadShowBackgroundParticle()
  800. {
  801. showBackgroundParticle = PlayerPrefsUtil.GetBool(_showBackgroundParticleKey, true);
  802. }
  803. #endregion
  804. #region Sound volume
  805. public float BGMVolume { get; set; }
  806. public float SEVolume { get; set; }
  807. public void SetBGMVolume(float BGMVolume)
  808. {
  809. this.BGMVolume = BGMVolume;
  810. PlayerPrefs.SetFloat("BGMVolume", BGMVolume);
  811. PlayerPrefs.Save();
  812. }
  813. public void SetSEVolume(float SEVolume)
  814. {
  815. this.SEVolume = SEVolume;
  816. PlayerPrefs.SetFloat("SEVolume", SEVolume);
  817. PlayerPrefs.Save();
  818. }
  819. public void ChangeBGMVolume(AudioSource audioSource)
  820. {
  821. audioSource.volume = BGMVolume * 0.25f * 0.8f;
  822. }
  823. public void ChangeSEVolume(AudioSource audioSource)
  824. {
  825. audioSource.volume = SEVolume * 0.5f * 0.8f;
  826. }
  827. void LoadVolume()
  828. {
  829. BGMVolume = 0.5f;
  830. SEVolume = 0.5f;
  831. if (PlayerPrefs.HasKey("BGMVolume"))
  832. {
  833. BGMVolume = PlayerPrefs.GetFloat("BGMVolume");
  834. }
  835. if (PlayerPrefs.HasKey("SEVolume"))
  836. {
  837. SEVolume = PlayerPrefs.GetFloat("SEVolume");
  838. }
  839. }
  840. #endregion
  841. #region Server region
  842. [HideInInspector] public string serverRegion = "us";
  843. string _serverRegionKey = "ServerRegion";
  844. public void SaveServerRegion()
  845. {
  846. PlayerPrefs.SetString(_serverRegionKey, serverRegion);
  847. PlayerPrefs.Save();
  848. }
  849. public void LoadServerRegion()
  850. {
  851. //serverRegion = PlayerPrefs.GetString(_serverRegionKey, "us");
  852. }
  853. public string LastConnectServerRegion = "";
  854. #endregion
  855. #region Language
  856. [HideInInspector] public Language language = Language.ENG;
  857. string _languageKey = "Language";
  858. public void SaveLanguage()
  859. {
  860. PlayerPrefs.SetString(_languageKey, language.ToString());
  861. PlayerPrefs.Save();
  862. }
  863. public void LoadLanguage()
  864. {
  865. language = (Language)Enum.Parse(typeof(Language), PlayerPrefs.GetString(_languageKey, "ENG"));
  866. }
  867. #endregion
  868. #region PlaySE(AudioClip clip)
  869. public SoundObject PlaySE(AudioClip clip)
  870. {
  871. SoundObject _soundObject = Instantiate(soundObject);
  872. _soundObject.PlaySE(clip);
  873. return _soundObject;
  874. }
  875. #endregion
  876. #region カードIndexからカードを取得
  877. public CEntity_Base getCardEntityByCardID(int cardIndex)
  878. {
  879. //int searchIndex = cardIndex - 1;
  880. //int count = 0;
  881. CEntity_Base cEntity_Base = SortedCardList.First(entity => entity.CardIndex == cardIndex);
  882. return cEntity_Base;
  883. //TODO: REMOVE IN FUTURE
  884. /*do
  885. {
  886. if (count != 0)
  887. {
  888. searchIndex += (int)Math.Pow(-1, count % 2) * count / 2;
  889. }
  890. if (0 <= searchIndex)
  891. {
  892. if (searchIndex <= SortedCardList.Length - 1)
  893. {
  894. CEntity_Base cEntity_Base = SortedCardList[searchIndex];
  895. if (cEntity_Base != null)
  896. {
  897. if (cEntity_Base.CardIndex == cardIndex)
  898. {
  899. return cEntity_Base;
  900. }
  901. }
  902. }
  903. else
  904. {
  905. for (int i = 0; i < 300; i++)
  906. {
  907. CEntity_Base cEntity_Base = SortedCardList[SortedCardList.Length - 1 - i];
  908. if (cEntity_Base != null)
  909. {
  910. if (cEntity_Base.CardIndex == cardIndex)
  911. {
  912. return cEntity_Base;
  913. }
  914. }
  915. }
  916. return null;
  917. }
  918. }
  919. if (count != 0)
  920. {
  921. searchIndex -= (int)Math.Pow(-1, count % 2) * count / 2;
  922. }
  923. count++;
  924. }
  925. while (count <= 20);
  926. return null;*/
  927. }
  928. #endregion
  929. public Coroutine LoadingTextCoroutine;
  930. bool _endBattle = false;
  931. public void EndBattle()
  932. {
  933. if (!_endBattle)
  934. {
  935. _endBattle = true;
  936. StartCoroutine(EndBattleCoroutine());
  937. }
  938. }
  939. public IEnumerator EndBattleCoroutine()
  940. {
  941. if (Opening.instance == null)
  942. {
  943. yield break;
  944. }
  945. Opening.instance.openingObject.SetActive(true);
  946. //yield return StartCoroutine(Opening.instance.LoadingObject_Unload.StartLoading("Now Loading"));
  947. //Camera camera1 = Camera.main;
  948. //Destroy(camera1.gameObject);
  949. //yield return null;
  950. isAI = false;
  951. long random = RandomUtility.GetSecureRandom();
  952. GameRandom.Seed(random);
  953. Debug.Log($"random number sequence initialization, GameRandom.Seed:{random}");
  954. var unload = SceneManager.UnloadSceneAsync("BattleScene");
  955. yield return unload;
  956. yield return Resources.UnloadUnusedAssets();
  957. yield return StartCoroutine(Opening.instance.LoadingObject_Unload.StartLoading("Now Loading"));
  958. //Opening.instance.MainCamera.gameObject.SetActive(true);
  959. foreach (Camera camera in Opening.instance.openingCameras)
  960. {
  961. camera.gameObject.SetActive(true);
  962. }
  963. Opening.instance.LoadingObject_light.gameObject.SetActive(false);
  964. yield return ContinuousController.instance.StartCoroutine(PhotonUtility.SetPlayerName());
  965. if (isRandomMatch)
  966. {
  967. Debug.Log("Unload from Random Match");
  968. yield return StartCoroutine(Opening.instance.battle.lobbyManager_RandomMatch.CloseLobbyCoroutine());
  969. yield return StartCoroutine(Opening.instance.battle.selectBattleMode.SetUpSelectBattleModeCoroutine());
  970. }
  971. else
  972. {
  973. Debug.Log("Unload from Room Match");
  974. yield return StartCoroutine(Opening.instance.battle.roomManager.Init(true));
  975. yield return new WaitForSeconds(0.1f);
  976. }
  977. yield return new WaitWhile(() => GManager.instance != null);
  978. Opening.instance.LoadingObject.gameObject.SetActive(false);
  979. yield return StartCoroutine(Opening.instance.LoadingObject_Unload.EndLoading());
  980. _endBattle = false;
  981. if (!isRandomMatch)
  982. {
  983. Hashtable PlayerProp = PhotonNetwork.LocalPlayer.CustomProperties;
  984. if (PlayerProp.TryGetValue("isBattle", out object value))
  985. {
  986. PlayerProp["isBattle"] = false;
  987. }
  988. else
  989. {
  990. PlayerProp.Add("isBattle", false);
  991. }
  992. PhotonNetwork.LocalPlayer.SetCustomProperties(PlayerProp);
  993. }
  994. Scene newScene = SceneManager.GetSceneByName("Opening");
  995. SceneManager.SetActiveScene(newScene);
  996. for (int i = 0; i < 3; i++)
  997. {
  998. yield return new WaitForSeconds(0.1f);
  999. EventSystem.current.SetSelectedGameObject(Opening.instance.battle.selectBattleMode.transform.GetChild(0).gameObject);
  1000. }
  1001. //GUI.UnfocusWindow();
  1002. yield return null;
  1003. //StartCoroutine(DestroyEffectCoroutine());
  1004. if (Opening.instance.OpeningBGM != null)
  1005. {
  1006. if (!Opening.instance.OpeningBGM.isPlaying)
  1007. {
  1008. Opening.instance.OpeningBGM.StartPlayBGM(Opening.instance.bgm);
  1009. }
  1010. }
  1011. }
  1012. private void Update()
  1013. {
  1014. #if UNITY_WINDOWS
  1015. if (Input.GetKey(KeyCode.Escape))
  1016. {
  1017. Application.Quit();
  1018. }
  1019. #endif
  1020. }
  1021. int _frameCount = 0;
  1022. int _updateFrame = 40;
  1023. void LateUpdate()
  1024. {
  1025. #region Update only once every few frames
  1026. _frameCount++;
  1027. if (_frameCount < _updateFrame)
  1028. {
  1029. return;
  1030. }
  1031. else
  1032. {
  1033. _frameCount = 0;
  1034. }
  1035. #endregion
  1036. if (PhotonNetwork.InRoom)
  1037. {
  1038. if (!isAI)
  1039. {
  1040. bool notEnterOther = false;
  1041. if (PhotonNetwork.PlayerList.Length == 1)
  1042. {
  1043. if (GManager.instance != null)
  1044. {
  1045. notEnterOther = true;
  1046. }
  1047. }
  1048. if (notEnterOther)
  1049. {
  1050. if (PhotonNetwork.CurrentRoom.MaxPlayers != 1)
  1051. {
  1052. PhotonNetwork.CurrentRoom.MaxPlayers = 1;
  1053. }
  1054. }
  1055. else
  1056. {
  1057. if (PhotonNetwork.CurrentRoom.MaxPlayers != 2)
  1058. {
  1059. PhotonNetwork.CurrentRoom.MaxPlayers = 2;
  1060. }
  1061. }
  1062. }
  1063. }
  1064. }
  1065. public bool isAI { get; set; } = false;
  1066. //Flag that the sharing of the random number sequence is over.
  1067. public bool DoneSetRandom { get; set; } = false;
  1068. public bool CanSetRandom { get; set; } = false;
  1069. [PunRPC]
  1070. public void SetRandom(long random)
  1071. {
  1072. StartCoroutine(SetRandomCoroutine(random));
  1073. }
  1074. IEnumerator SetRandomCoroutine(long random)
  1075. {
  1076. yield return new WaitWhile(() => !CanSetRandom);
  1077. GameRandom.Seed(random);
  1078. DoneSetRandom = true;
  1079. Debug.Log($"random number sequence initialization, GameRandom.Seed:{random}");
  1080. }
  1081. }
  1082. #region Manage random numbers
  1083. public static class RandomUtility
  1084. {
  1085. /// <summary>
  1086. /// Generates a cryptographically secure 64-bit random seed.
  1087. /// Uses OS entropy pool via System.Security.Cryptography.
  1088. /// </summary>
  1089. public static long GetSecureRandom()
  1090. {
  1091. byte[] bytes = new byte[8];
  1092. using (var rng = RandomNumberGenerator.Create())
  1093. {
  1094. rng.GetBytes(bytes);
  1095. }
  1096. return BitConverter.ToInt64(bytes, 0);
  1097. }
  1098. #region IsSucceedProbability(float Probability)
  1099. public static bool IsSucceedProbability(float Probability)
  1100. {
  1101. if (Probability >= 1)
  1102. {
  1103. return true;
  1104. }
  1105. if (Probability <= 0)
  1106. {
  1107. return false;
  1108. }
  1109. float random = GameRandom.Range(0f, 1f);
  1110. if (random <= Probability)
  1111. {
  1112. return true;
  1113. }
  1114. return false;
  1115. }
  1116. #endregion
  1117. #region Shuffle the deck
  1118. public static List<CEntity_Base> ShuffledDeckCards(List<CEntity_Base> DeckCards)
  1119. {
  1120. List<CEntity_Base> CardDatas = new List<CEntity_Base>();
  1121. CardDatas.AddRange(DeckCards);
  1122. // Fisher-Yates shuffle using GameRandom (Xoshiro256**)
  1123. int n = CardDatas.Count;
  1124. while (n > 0)
  1125. {
  1126. n--;
  1127. // Random index from 0 to n (inclusive) — Range takes exclusive max
  1128. int k = GameRandom.Range(0, n + 1);
  1129. // Swap elements at indices n and k
  1130. CEntity_Base temp = CardDatas[n];
  1131. CardDatas[n] = CardDatas[k];
  1132. CardDatas[k] = temp;
  1133. }
  1134. return CardDatas;
  1135. }
  1136. public static List<CardSource> ShuffledDeckCards(List<CardSource> DeckCards)
  1137. {
  1138. List<CardSource> CardDatas = new List<CardSource>();
  1139. CardDatas.AddRange(DeckCards);
  1140. // Fisher-Yates shuffle using GameRandom (Xoshiro256**)
  1141. int n = CardDatas.Count;
  1142. while (n > 0)
  1143. {
  1144. n--;
  1145. // Random index from 0 to n (inclusive) — Range takes exclusive max
  1146. int k = GameRandom.Range(0, n + 1);
  1147. // Swap elements at indices n and k
  1148. CardSource temp = CardDatas[n];
  1149. if (!temp.IsFlipped)
  1150. {
  1151. temp.SetReverse();
  1152. if(temp.Owner.SecurityCards.Contains(temp))
  1153. GManager.OnSecurityStackChanged?.Invoke(temp.Owner);
  1154. }
  1155. CardDatas[n] = CardDatas[k];
  1156. CardDatas[k] = temp;
  1157. }
  1158. return CardDatas;
  1159. }
  1160. #endregion
  1161. }
  1162. #endregion
  1163. #region Manage connections to Photon
  1164. public class PhotonUtility
  1165. {
  1166. #region Disconnected from Photon
  1167. public static IEnumerator DisconnectCoroutine()
  1168. {
  1169. #region Exit Room
  1170. if (PhotonNetwork.InRoom)
  1171. {
  1172. PhotonNetwork.LeaveRoom();
  1173. }
  1174. yield return new WaitWhile(() => PhotonNetwork.InRoom);
  1175. #endregion
  1176. #region Exit from the lobby
  1177. if (PhotonNetwork.InLobby)
  1178. {
  1179. PhotonNetwork.LeaveLobby();
  1180. }
  1181. yield return new WaitWhile(() => PhotonNetwork.InLobby);
  1182. #endregion
  1183. #region Disconnected from Photon
  1184. if (PhotonNetwork.IsConnected)
  1185. {
  1186. PhotonNetwork.Disconnect();
  1187. }
  1188. yield return new WaitWhile(() => PhotonNetwork.IsConnected);
  1189. #endregion
  1190. }
  1191. #endregion
  1192. #region Connect to Photon server
  1193. public static IEnumerator ConnectToMasterServerCoroutine()
  1194. {
  1195. if (!PhotonNetwork.IsConnected || ContinuousController.instance.LastConnectServerRegion != ContinuousController.instance.serverRegion)
  1196. {
  1197. if (PhotonNetwork.IsConnected)
  1198. {
  1199. yield return ContinuousController.instance.StartCoroutine(DisconnectCoroutine());
  1200. yield return new WaitWhile(() => PhotonNetwork.IsConnected);
  1201. }
  1202. PhotonNetwork.NetworkingClient.AppId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime;
  1203. PhotonNetwork.ConnectToRegion(ContinuousController.instance.serverRegion);
  1204. PhotonNetwork.NickName = ContinuousController.instance.PlayerName;
  1205. PhotonNetwork.GameVersion = ContinuousController.instance.GameVerString;
  1206. ContinuousController.instance.LastConnectServerRegion = ContinuousController.instance.serverRegion;
  1207. }
  1208. yield return new WaitWhile(() => !PhotonNetwork.IsConnectedAndReady);
  1209. }
  1210. #endregion
  1211. #region Connect to Photon Server and Lobby
  1212. public static IEnumerator ConnectToLobbyCoroutine()
  1213. {
  1214. #region Connect to Photon server
  1215. yield return ContinuousController.instance.StartCoroutine(ConnectToMasterServerCoroutine());
  1216. #endregion
  1217. #region Save player name to custom properties
  1218. yield return ContinuousController.instance.StartCoroutine(SetPlayerName());
  1219. #endregion
  1220. #region Save the number of wins to a custom property
  1221. Hashtable hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1222. object value;
  1223. hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1224. if (hash.TryGetValue(ContinuousController.WinCountKey, out value))
  1225. {
  1226. hash[ContinuousController.WinCountKey] = ContinuousController.instance.WinCount;
  1227. }
  1228. else
  1229. {
  1230. hash.Add(ContinuousController.WinCountKey, ContinuousController.instance.WinCount);
  1231. }
  1232. PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
  1233. while (true)
  1234. {
  1235. Hashtable _hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1236. if (_hash.TryGetValue(ContinuousController.WinCountKey, out value))
  1237. {
  1238. if ((int)value == ContinuousController.instance.WinCount)
  1239. {
  1240. break;
  1241. }
  1242. }
  1243. yield return null;
  1244. }
  1245. #endregion
  1246. #region Connect to Lobby
  1247. if (!PhotonNetwork.InLobby)
  1248. {
  1249. PhotonNetwork.JoinLobby();
  1250. }
  1251. yield return new WaitWhile(() => !PhotonNetwork.InLobby);
  1252. yield return new WaitUntil(() => PhotonNetwork.InLobby && PhotonNetwork.IsConnectedAndReady);
  1253. #endregion
  1254. }
  1255. #endregion
  1256. #region Save player name to properties
  1257. public static IEnumerator SetPlayerName()
  1258. {
  1259. Hashtable hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1260. object value;
  1261. hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1262. if (hash.TryGetValue(ContinuousController.PlayerNameKey, out value))
  1263. {
  1264. hash[ContinuousController.PlayerNameKey] = ContinuousController.instance.PlayerName;
  1265. }
  1266. else
  1267. {
  1268. hash.Add(ContinuousController.PlayerNameKey, ContinuousController.instance.PlayerName);
  1269. }
  1270. PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
  1271. while (true)
  1272. {
  1273. Hashtable _hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1274. if (_hash.TryGetValue(ContinuousController.PlayerNameKey, out value))
  1275. {
  1276. if ((string)value == ContinuousController.instance.PlayerName)
  1277. {
  1278. break;
  1279. }
  1280. }
  1281. yield return null;
  1282. }
  1283. }
  1284. #endregion
  1285. #region Save deck data to custom properties
  1286. public static IEnumerator SignUpBattleDeckData()
  1287. {
  1288. Hashtable hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1289. if (hash.TryGetValue(ContinuousController.DeckDataPropertyKey, out object value))
  1290. {
  1291. hash[ContinuousController.DeckDataPropertyKey] = ContinuousController.instance.BattleDeckData.GetThisDeckCode();
  1292. }
  1293. else
  1294. {
  1295. hash.Add(ContinuousController.DeckDataPropertyKey, ContinuousController.instance.BattleDeckData.GetThisDeckCode());
  1296. }
  1297. PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
  1298. while (true)
  1299. {
  1300. Hashtable _hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1301. if (_hash.TryGetValue(ContinuousController.DeckDataPropertyKey, out value))
  1302. {
  1303. if ((string)value == ContinuousController.instance.BattleDeckData.GetThisDeckCode())
  1304. {
  1305. break;
  1306. }
  1307. }
  1308. yield return null;
  1309. }
  1310. }
  1311. #endregion
  1312. #region Remove custom properties from deck data
  1313. public static IEnumerator DeleteBattleDeckData()
  1314. {
  1315. Hashtable hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1316. if (hash.TryGetValue(ContinuousController.DeckDataPropertyKey, out object value))
  1317. {
  1318. hash.Remove(ContinuousController.DeckDataPropertyKey);
  1319. }
  1320. PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
  1321. while (true)
  1322. {
  1323. Hashtable _hash = PhotonNetwork.LocalPlayer.CustomProperties;
  1324. if (!_hash.TryGetValue(ContinuousController.DeckDataPropertyKey, out value))
  1325. {
  1326. break;
  1327. }
  1328. yield return null;
  1329. }
  1330. }
  1331. #endregion
  1332. }
  1333. #endregion
  1334. public enum Language
  1335. {
  1336. ENG,
  1337. JPN,
  1338. }