您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

1071 行
34 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using CIGEnums;
  4. using SUISS.Core;
  5. using SUISS.Scheduling;
  6. using SUISS.Storage;
  7. using SUISSEngine;
  8. using UnityEngine;
  9. public class CIGExpansions : MonoBehaviour
  10. {
  11. private void Awake()
  12. {
  13. foreach (CIGExpansionDefinition cigexpansionDefinition in this.blockDefinitions)
  14. {
  15. if (cigexpansionDefinition.initiallyUnlocked)
  16. {
  17. this._initiallyUnlockedBlocks++;
  18. }
  19. }
  20. this.constants = UnityEngine.Object.FindObjectOfType<CIGGameConstants>();
  21. if (this.constants == null)
  22. {
  23. UnityEngine.Debug.LogWarning(string.Format("{0}: unable to find a CIGGameConstants object", base.name));
  24. }
  25. if (this.blockSizeU <= 0 || this.blockSizeV <= 0)
  26. {
  27. throw new ArgumentException("Block size must be at least 1x1.", (this.blockSizeU > 0) ? "blockSizeV" : "blockSizeU");
  28. }
  29. if (this.grid == null)
  30. {
  31. UnityEngine.Debug.LogError(string.Format("{0}::Grid: No grid.", base.name));
  32. return;
  33. }
  34. }
  35. private void OnGridDeserialized()
  36. {
  37. this.CreateBlocks();
  38. this.CalculateUnlockedTileCountByType();
  39. this.NewBlockUnlocked = new Action<IsometricGrid, CIGExpansions.ExpansionBlock>(SingletonMonobehaviour<CIGGameStats>.Instance.OnNewBlockUnlocked);
  40. SingletonMonobehaviour<Scheduler>.Instance.ExecuteNextFrame(base.gameObject, delegate ()
  41. {
  42. this.PlaceBuySigns();
  43. });
  44. }
  45. public int NumberOfInitiallyUnlockedBlocks { get; protected set; }
  46. public int GoldCostCounter
  47. {
  48. get
  49. {
  50. Dictionary<string, object> root = Storage.Get(StorageLifecycle.Game).Root;
  51. if (root.ContainsKey(this.GoldCostCounterKey))
  52. {
  53. return (int)root[this.GoldCostCounterKey];
  54. }
  55. return 0;
  56. }
  57. protected set
  58. {
  59. Dictionary<string, object> root = Storage.Get(StorageLifecycle.Game).Root;
  60. root[this.GoldCostCounterKey] = value;
  61. }
  62. }
  63. public int BlocksU
  64. {
  65. get
  66. {
  67. return this.blocksU;
  68. }
  69. }
  70. public int BlocksV
  71. {
  72. get
  73. {
  74. return this.blocksV;
  75. }
  76. }
  77. public int UnlockedBlocks
  78. {
  79. get
  80. {
  81. return this.unlockedBlocks;
  82. }
  83. private set
  84. {
  85. this.unlockedBlocks = value;
  86. }
  87. }
  88. public int UnlockedBlocksWithGold
  89. {
  90. get
  91. {
  92. return this.unlockedBlocksWithGold;
  93. }
  94. private set
  95. {
  96. this.unlockedBlocksWithGold = value;
  97. }
  98. }
  99. public bool ExpansionsAreOnSale
  100. {
  101. get
  102. {
  103. return false;
  104. }
  105. }
  106. public decimal BaseRoiExpansion
  107. {
  108. get
  109. {
  110. if (this.constants != null)
  111. {
  112. return this.constants.baseRoiExpansion;
  113. }
  114. return 0.75m;
  115. }
  116. }
  117. public decimal ExtraRoiExpansion
  118. {
  119. get
  120. {
  121. if (this.constants != null)
  122. {
  123. return this.constants.extraRoiExpansion;
  124. }
  125. return 0.22m;
  126. }
  127. }
  128. public decimal MinProfitPerHourForCashCost
  129. {
  130. get
  131. {
  132. if (this.constants != null)
  133. {
  134. return this.constants.minProfitPerHourForCashCost;
  135. }
  136. return 100000m;
  137. }
  138. }
  139. public decimal BaseGoldCost
  140. {
  141. get
  142. {
  143. if (this.constants != null)
  144. {
  145. return this.constants.baseGoldCost;
  146. }
  147. return 25m;
  148. }
  149. }
  150. public decimal ExtraGoldCost
  151. {
  152. get
  153. {
  154. if (this.constants != null)
  155. {
  156. return this.constants.extraGoldCost;
  157. }
  158. return 5m;
  159. }
  160. }
  161. public bool HaveExpansionsLeft
  162. {
  163. get
  164. {
  165. return this.unlockableBlocks.Count > 0;
  166. }
  167. }
  168. public decimal ProfitPerHour
  169. {
  170. get
  171. {
  172. if (this.profitPerHour == -1m)
  173. {
  174. this.CalculatePriceVariables();
  175. }
  176. if (SingletonMonobehaviour<CIGGameStats>.IsAvailable)
  177. {
  178. this.profitPerHour = SingletonMonobehaviour<CIGGameStats>.Instance.GlobalProfitPerHour.GetValue("Cash");
  179. }
  180. return this.profitPerHour;
  181. }
  182. private set
  183. {
  184. this.profitPerHour = value;
  185. }
  186. }
  187. public int UsedElements
  188. {
  189. get
  190. {
  191. if (this.usedElems == -1)
  192. {
  193. this.CalculatePriceVariables();
  194. }
  195. return this.usedElems;
  196. }
  197. private set
  198. {
  199. this.usedElems = value;
  200. }
  201. }
  202. public int UnusedElements
  203. {
  204. get
  205. {
  206. if (this.unusedElems == -1)
  207. {
  208. this.CalculatePriceVariables();
  209. }
  210. return this.unusedElems;
  211. }
  212. private set
  213. {
  214. this.unusedElems = value;
  215. }
  216. }
  217. public int GetUnlockedElementCount(int type)
  218. {
  219. if (this.unlockedTileCountByType.ContainsKey(type))
  220. {
  221. return this.unlockedTileCountByType[type];
  222. }
  223. return 0;
  224. }
  225. public CIGExpansions.ExpansionBlock GetBlock(int u, int v)
  226. {
  227. if (u < 0 || u >= this.blocksU || v < 0 || v >= this.blocksV)
  228. {
  229. return null;
  230. }
  231. return this.blocks[u, v];
  232. }
  233. public bool HasBuySign(GridIndex index)
  234. {
  235. CIGExpansions.ExpansionBlock blockForIndex = this.GetBlockForIndex(index);
  236. return blockForIndex != null && blockForIndex.CanUnlock;
  237. }
  238. public IEnumerable<CIGExpansions.ExpansionBlock> AllBlocks
  239. {
  240. get
  241. {
  242. if (this.blocks == null && !this.CreateBlocks())
  243. {
  244. UnityEngine.Debug.LogWarning("Couldn't create expansion blocks.");
  245. yield break;
  246. }
  247. CIGExpansions.ExpansionBlock[,] array = this.blocks;
  248. int length = array.GetLength(0);
  249. int length2 = array.GetLength(1);
  250. for (int i = 0; i < length; i++)
  251. {
  252. for (int j = 0; j < length2; j++)
  253. {
  254. CIGExpansions.ExpansionBlock b = array[i, j];
  255. yield return b;
  256. }
  257. }
  258. yield break;
  259. }
  260. }
  261. public void DidUnlockTileWithType(int type)
  262. {
  263. if (this.unlockedTileCountByType.ContainsKey(type))
  264. {
  265. (this.unlockedTileCountByType)[type] = this.unlockedTileCountByType[type] + 1;
  266. }
  267. else
  268. {
  269. this.unlockedTileCountByType.Add(type, 1);
  270. }
  271. }
  272. public CIGExpansions.ExpansionBlock GetBlockForIndex(GridIndex index)
  273. {
  274. if (this.blocks == null && !this.CreateBlocks())
  275. {
  276. UnityEngine.Debug.LogWarning("Couldn't create expansion blocks.");
  277. return null;
  278. }
  279. int num = index.u / this.blockSizeU;
  280. if (num < 0 || num >= this.blocksU)
  281. {
  282. if (index.u >= this.grid.Size.u)
  283. {
  284. UnityEngine.Debug.LogWarning("Out of bounds");
  285. }
  286. return null;
  287. }
  288. int num2 = index.v / this.blockSizeV;
  289. if (num2 < 0 || num2 >= this.blocksV)
  290. {
  291. if (index.v >= this.grid.Size.v)
  292. {
  293. UnityEngine.Debug.LogWarning("Out of bounds");
  294. }
  295. return null;
  296. }
  297. return this.blocks[num, num2];
  298. }
  299. public void UnlockBlock(CIGExpansions.ExpansionBlock block, Currencies price)
  300. {
  301. if (block.Unlock(price))
  302. {
  303. int num = Mathf.RoundToInt((float)price.GetValue("Gold"));
  304. if (num > 0)
  305. {
  306. SingletonMonobehaviour<CIGGameStats>.Instance.AddGoldSpent_Expansions(num);
  307. }
  308. if (this.NewBlockUnlocked != null)
  309. {
  310. this.NewBlockUnlocked(this.grid, block);
  311. }
  312. }
  313. }
  314. private bool CreateBlocks()
  315. {
  316. if (this.blocks != null)
  317. {
  318. return true;
  319. }
  320. if (this.grid == null)
  321. {
  322. UnityEngine.Debug.LogWarning("this.grid == null");
  323. return false;
  324. }
  325. if (this.blockDefinitions == null)
  326. {
  327. UnityEngine.Debug.LogWarning("this.blockDefinitions == null");
  328. return false;
  329. }
  330. this.blocksU = (this.blocksV = 0);
  331. this.NumberOfInitiallyUnlockedBlocks = 0;
  332. foreach (CIGExpansionDefinition cigexpansionDefinition in this.blockDefinitions)
  333. {
  334. this.blocksU = Mathf.Max(this.blocksU, cigexpansionDefinition.u + 1);
  335. this.blocksV = Mathf.Max(this.blocksV, cigexpansionDefinition.v + 1);
  336. if (cigexpansionDefinition.initiallyUnlocked)
  337. {
  338. this.NumberOfInitiallyUnlockedBlocks++;
  339. }
  340. }
  341. if (this.blocksU * this.blockSizeU > this.grid.sizeU || this.blocksV * this.blockSizeV > this.grid.sizeV)
  342. {
  343. UnityEngine.Debug.LogWarning(string.Format("Grid size mismatch: {0} x {1} > {2} or {3} x {4} > {5}", new object[]
  344. {
  345. this.blocksU,
  346. this.blockSizeU,
  347. this.grid.sizeU,
  348. this.blocksV,
  349. this.blockSizeV,
  350. this.grid.sizeV
  351. }));
  352. }
  353. this.blocks = new CIGExpansions.ExpansionBlock[this.blocksU, this.blocksV];
  354. foreach (CIGExpansionDefinition cigexpansionDefinition2 in this.blockDefinitions)
  355. {
  356. GridIndex index = cigexpansionDefinition2.Index;
  357. index.u *= this.blockSizeU;
  358. index.v *= this.blockSizeV;
  359. GridSize size = new GridSize(this.blockSizeU, this.blockSizeV);
  360. CIGExpansions.ExpansionBlock expansionBlock = new CIGExpansions.ExpansionBlock(this, cigexpansionDefinition2, index, size);
  361. this.blocks[cigexpansionDefinition2.u, cigexpansionDefinition2.v] = expansionBlock;
  362. }
  363. return true;
  364. }
  365. protected void PlaceBuySigns()
  366. {
  367. for (int i = 0; i < this.blocksV; i++)
  368. {
  369. for (int j = 0; j < this.blocksU; j++)
  370. {
  371. CIGExpansions.ExpansionBlock expansionBlock = this.blocks[j, i];
  372. if (expansionBlock != null)
  373. {
  374. expansionBlock.UpdateCanUnlock();
  375. }
  376. }
  377. }
  378. }
  379. private void OnSerialize(Dictionary<string, object> values)
  380. {
  381. values["CIGExpansions.profitPerHour"] = this.profitPerHour;
  382. values["CIGExpansions.usedElems"] = this.usedElems;
  383. values["CIGExpansions.unusedElems"] = this.unusedElems;
  384. }
  385. private void OnDeserialize(Dictionary<string, object> values)
  386. {
  387. this.ProfitPerHour = (decimal)values.Get("CIGExpansions.profitPerHour", -1m);
  388. this.UsedElements = (int)values.Get("CIGExpansions.usedElems", -1);
  389. this.UnusedElements = (int)values.Get("CIGExpansions.unusedElems", -1);
  390. }
  391. private void CalculatePriceVariables()
  392. {
  393. CIGGameStats instance = SingletonMonobehaviour<CIGGameStats>.Instance;
  394. this.ProfitPerHour = Math.Floor(instance.GlobalProfitPerHour.GetValue("Cash"));
  395. int num = 0;
  396. int num2 = 0;
  397. for (int i = 0; i < this.BlocksU; i++)
  398. {
  399. for (int j = 0; j < this.BlocksV; j++)
  400. {
  401. CIGExpansions.ExpansionBlock block = this.GetBlock(i, j);
  402. if (block != null && block.Unlocked)
  403. {
  404. for (int k = block.Origin.u; k < block.Origin.u + block.Size.u; k++)
  405. {
  406. for (int l = block.Origin.v; l < block.Origin.v + block.Size.v; l++)
  407. {
  408. GridElement gridElement = this.grid[k, l];
  409. if (gridElement.Type != -1 && gridElement.IsFullyVisible)
  410. {
  411. num++;
  412. if (gridElement.Tile != null)
  413. {
  414. num2++;
  415. }
  416. }
  417. }
  418. }
  419. }
  420. }
  421. }
  422. this.UsedElements = num2;
  423. this.UnusedElements = num - num2;
  424. this.serializing.Serialize();
  425. }
  426. private void CalculateUnlockedTileCountByType()
  427. {
  428. int[] array = new int[10];
  429. for (int i = 0; i < this.BlocksU; i++)
  430. {
  431. for (int j = 0; j < this.BlocksV; j++)
  432. {
  433. CIGExpansions.ExpansionBlock block = this.GetBlock(i, j);
  434. if (block != null && block.Unlocked)
  435. {
  436. for (int k = block.Origin.u; k < block.Origin.u + block.Size.u; k++)
  437. {
  438. for (int l = block.Origin.v; l < block.Origin.v + block.Size.v; l++)
  439. {
  440. GridElement gridElement = this.grid[k, l];
  441. int type = gridElement.Type;
  442. if (type >= 0 && type < 100)
  443. {
  444. if (type >= array.Length)
  445. {
  446. Array.Resize<int>(ref array, type + 1);
  447. }
  448. array[type]++;
  449. }
  450. }
  451. }
  452. }
  453. }
  454. }
  455. this.unlockedTileCountByType = new Dictionary<int, int>();
  456. for (int m = 1; m < array.Length; m++)
  457. {
  458. if (array[m] > 0)
  459. {
  460. this.unlockedTileCountByType[m] = array[m];
  461. }
  462. }
  463. }
  464. public int blockSizeU = 8;
  465. public int blockSizeV = 8;
  466. public GameObject buySignPrefab;
  467. [SelfReference]
  468. public IsometricIsland island;
  469. [ChildReference]
  470. public IsometricGrid grid;
  471. [SelfReference]
  472. public Serializing serializing;
  473. public CIGExpansionDefinition[] blockDefinitions;
  474. private const decimal DefaultProfitPerHour = -1m;
  475. private const int DefaultUsedElems = -1;
  476. private const int DefaultUnusedElems = -1;
  477. private CIGGameConstants constants;
  478. private int blocksU;
  479. private int blocksV;
  480. private CIGExpansions.ExpansionBlock[,] blocks;
  481. private int unlockedBlocks;
  482. private int unlockedBlocksWithGold;
  483. private decimal profitPerHour = -1m;
  484. private int usedElems = -1;
  485. private int unusedElems = -1;
  486. private Dictionary<int, int> unlockedTileCountByType = new Dictionary<int, int>();
  487. private HashSet<CIGExpansions.ExpansionBlock> unlockableBlocks = new HashSet<CIGExpansions.ExpansionBlock>();
  488. public Action<IsometricGrid, CIGExpansions.ExpansionBlock> NewBlockUnlocked;
  489. protected int _initiallyUnlockedBlocks;
  490. private readonly string GoldCostCounterKey = "ExpansionsGoldCostCounter";
  491. private const string ProfitPerHourKey = "CIGExpansions.profitPerHour";
  492. private const string UsedElemsKey = "CIGExpansions.usedElems";
  493. private const string UnusedElemsKey = "CIGExpansions.unusedElems";
  494. public class ExpansionBlock
  495. {
  496. public ExpansionBlock(CIGExpansions parent, CIGExpansionDefinition def, GridIndex origin, GridSize size)
  497. {
  498. this.parent = parent;
  499. this.u = def.u;
  500. this.v = def.v;
  501. this.origin = origin;
  502. this.size = size;
  503. this.unlockByDefault = def.initiallyUnlocked;
  504. this.automaticUnlock = def.automaticUnlock;
  505. this.defName = def.name;
  506. string key = string.Concat(new object[]
  507. {
  508. parent.grid.serializing.StorageKey,
  509. "_Expansion[",
  510. this.u,
  511. ",",
  512. this.v,
  513. "]"
  514. });
  515. this.state = Storage.Get(StorageLifecycle.Game).GetDictionary(key);
  516. if (!this.state.ContainsKey("Unlocked"))
  517. {
  518. this.state["Unlocked"] = false;
  519. }
  520. if (!this.state.ContainsKey("BoughtFor"))
  521. {
  522. this.state["BoughtFor"] = null;
  523. }
  524. this.CanUnlock = false;
  525. this.buySign = null;
  526. if (this.Unlocked)
  527. {
  528. parent.UnlockedBlocks++;
  529. if (this.UnlockedWithGold)
  530. {
  531. parent.UnlockedBlocksWithGold++;
  532. }
  533. for (int i = this.origin.v; i < this.origin.v + this.size.v; i++)
  534. {
  535. for (int j = this.origin.u; j < this.origin.u + this.size.u; j++)
  536. {
  537. parent.grid[j, i].Unlocked = true;
  538. }
  539. }
  540. }
  541. else if (this.unlockByDefault)
  542. {
  543. this.CanUnlock = true;
  544. if (!this.CanUnlock)
  545. {
  546. UnityEngine.Debug.LogWarning(string.Format("Unable to unlock by default, visfrac = {0}", this.VisibleFraction));
  547. }
  548. this.Unlock(null);
  549. }
  550. }
  551. public Currencies Price
  552. {
  553. get
  554. {
  555. Currencies currencies = null;
  556. if (state.ContainsKey("Price"))
  557. {
  558. currencies = (state["Price"] as Currencies);
  559. }
  560. if (currencies == null || currencies.IsEmpty())
  561. {
  562. currencies = (Currencies)(state["Price"] = CalculatePrice());
  563. }
  564. return currencies;
  565. }
  566. }
  567. public int U
  568. {
  569. get
  570. {
  571. return this.u;
  572. }
  573. }
  574. public int V
  575. {
  576. get
  577. {
  578. return this.v;
  579. }
  580. }
  581. public GridIndex Origin
  582. {
  583. get
  584. {
  585. return this.origin;
  586. }
  587. }
  588. public GridSize Size
  589. {
  590. get
  591. {
  592. return this.size;
  593. }
  594. }
  595. public bool Unlocked
  596. {
  597. get
  598. {
  599. return (bool)this.state["Unlocked"];
  600. }
  601. }
  602. public bool CanUnlock
  603. {
  604. get
  605. {
  606. if (this.canUnlock && this.VisibleFraction >= 0.5f)
  607. {
  608. this.parent.unlockableBlocks.Add(this);
  609. return true;
  610. }
  611. this.parent.unlockableBlocks.Remove(this);
  612. return false;
  613. }
  614. set
  615. {
  616. this.canUnlock = value;
  617. if (value && !this.Unlocked && this.VisibleFraction >= 0.5f)
  618. {
  619. this.parent.unlockableBlocks.Add(this);
  620. }
  621. else
  622. {
  623. this.parent.unlockableBlocks.Remove(this);
  624. }
  625. }
  626. }
  627. public bool UnlockedWithGold
  628. {
  629. get
  630. {
  631. Currencies currencies = (Currencies)this.state["BoughtFor"];
  632. return !(currencies == null) && currencies.ContainsPositive("Gold");
  633. }
  634. }
  635. public int AvailableElements
  636. {
  637. get
  638. {
  639. if (this.availableElements == -1)
  640. {
  641. this.CalculateElementStats();
  642. }
  643. return this.availableElements;
  644. }
  645. }
  646. public int VisibleElements
  647. {
  648. get
  649. {
  650. if (this.visibleElements == -1)
  651. {
  652. this.CalculateElementStats();
  653. }
  654. return this.visibleElements;
  655. }
  656. }
  657. public float AvailableFraction
  658. {
  659. get
  660. {
  661. return (float)this.AvailableElements / (float)(this.Size.u * this.Size.v);
  662. }
  663. }
  664. public float VisibleFraction
  665. {
  666. get
  667. {
  668. return (float)this.VisibleElements / (float)(this.Size.u * this.Size.v);
  669. }
  670. }
  671. public void UpdateCanUnlock()
  672. {
  673. bool flag = false;
  674. if (!this.Unlocked)
  675. {
  676. if (this.parent.GetBlock(this.u, this.v - 1) != null && this.parent.GetBlock(this.u, this.v - 1).Unlocked)
  677. {
  678. flag = true;
  679. }
  680. if (this.parent.GetBlock(this.u + 1, this.v) != null && this.parent.GetBlock(this.u + 1, this.v).Unlocked)
  681. {
  682. flag = true;
  683. }
  684. if (this.parent.GetBlock(this.u, this.v + 1) != null && this.parent.GetBlock(this.u, this.v + 1).Unlocked)
  685. {
  686. flag = true;
  687. }
  688. if (this.parent.GetBlock(this.u - 1, this.v) != null && this.parent.GetBlock(this.u - 1, this.v).Unlocked)
  689. {
  690. flag = true;
  691. }
  692. }
  693. bool flag2 = this.canUnlock;
  694. this.CanUnlock = flag;
  695. if (this.CanUnlock)
  696. {
  697. if (!flag2 && this.automaticUnlock)
  698. {
  699. this.Unlock(Currencies.Zero);
  700. }
  701. else if (this.buySign == null)
  702. {
  703. IsometricIsland island = this.parent.island;
  704. IsometricGrid grid = island.grid;
  705. bool flag3 = false;
  706. List<GridIndex> list = new List<GridIndex>();
  707. GridIndex gridIndex = new GridIndex(int.MinValue, int.MinValue);
  708. GridIndex gridIndex2 = new GridIndex(int.MaxValue, int.MaxValue);
  709. for (int i = this.origin.v; i < this.origin.v + this.size.v; i++)
  710. {
  711. for (int j = this.origin.u; j < this.origin.u + this.size.u; j++)
  712. {
  713. if (grid.IsWithinBounds(j, i))
  714. {
  715. if (grid[j, i].Tile != null && grid[j, i].Tile.GetComponent<CIGUnlockBuilding>() != null)
  716. {
  717. flag3 = true;
  718. }
  719. if (grid[j, i].Type > 0)
  720. {
  721. gridIndex.u = Math.Max(j, gridIndex.u);
  722. gridIndex.v = Math.Max(i, gridIndex.v);
  723. gridIndex2.u = Math.Min(j, gridIndex2.u);
  724. gridIndex2.v = Math.Min(i, gridIndex2.v);
  725. list.Add(new GridIndex(j, i));
  726. }
  727. }
  728. }
  729. }
  730. GridIndex centre = new GridIndex(gridIndex2.u + (gridIndex.u - gridIndex2.u) / 2, gridIndex2.v + (gridIndex.v - gridIndex2.v) / 2);
  731. list.Sort(delegate (GridIndex lhs, GridIndex rhs)
  732. {
  733. int num = lhs.u - centre.u;
  734. int num2 = lhs.v - centre.v;
  735. int num3 = rhs.u - centre.u;
  736. int num4 = rhs.v - centre.v;
  737. int num5 = num * num + num2 * num2;
  738. int num6 = num3 * num3 + num4 * num4;
  739. if (num5 < num6)
  740. {
  741. return -1;
  742. }
  743. if (num5 > num6)
  744. {
  745. return 1;
  746. }
  747. return 0;
  748. });
  749. if (list.Count > 0)
  750. {
  751. for (int k = 0; k < list.Count; k++)
  752. {
  753. GridIndex index = list[k];
  754. GridTile gridTile = grid[index].Tile;
  755. if (gridTile != null && gridTile.GetComponent<Scenery>() != null)
  756. {
  757. island.builder.DestroyTile(gridTile);
  758. gridTile = null;
  759. }
  760. GridIndex index2 = new GridIndex(index.u, index.v + 1);
  761. if (!index2.isInvalid && grid.IsWithinBounds(index2))
  762. {
  763. GridTile tile = grid[index2].Tile;
  764. if (tile != null && tile.GetComponent<Scenery>() != null)
  765. {
  766. island.builder.DestroyTile(tile);
  767. }
  768. }
  769. if (gridTile == null && island.builder.BuildAt(this.parent.buySignPrefab, index, false, true))
  770. {
  771. this.buySign = island.grid[index].Tile;
  772. Clickable.Instance(this.buySign).OnClickEvent += this.OnBuySignClick;
  773. if (flag3)
  774. {
  775. CIGBuySign component = this.buySign.GetComponent<CIGBuySign>();
  776. if (component != null)
  777. {
  778. component.EnableChest();
  779. }
  780. }
  781. break;
  782. }
  783. }
  784. }
  785. else if (this.AvailableElements > 0)
  786. {
  787. UnityEngine.Debug.LogError(string.Format("No sign index count on {0} (has {1} available elements)", this.defName, this.AvailableElements));
  788. }
  789. }
  790. }
  791. else if (this.buySign != null)
  792. {
  793. Clickable.Instance(this.buySign).OnClickEvent -= this.OnBuySignClick;
  794. this.parent.island.builder.DestroyTile(this.buySign);
  795. this.buySign = null;
  796. }
  797. }
  798. public bool Unlock(Currencies spent)
  799. {
  800. if (this.Unlocked || !this.CanUnlock)
  801. {
  802. UnityEngine.Debug.LogWarning(string.Format("Unlocked || !CanUnlock ({0} {1})", this.Unlocked, this.CanUnlock));
  803. return false;
  804. }
  805. IsometricIsland island = this.parent.island;
  806. this.state["Unlocked"] = true;
  807. this.state["BoughtFor"] = spent;
  808. this.parent.UnlockedBlocks++;
  809. if (spent != null)
  810. {
  811. decimal num = UnityEngine.Random.Range(2, 6);
  812. int num2 = Mathf.Max(0, this.parent.UnlockedBlocks - this.parent.NumberOfInitiallyUnlockedBlocks);
  813. if (num2 == 1 || num2 % 10 == 0)
  814. {
  815. num = 10m;
  816. }
  817. if (spent.ContainsPositive("Gold"))
  818. {
  819. this.parent.UnlockedBlocksWithGold++;
  820. this.parent.GoldCostCounter = Math.Max(-3, this.parent.GoldCostCounter + 1);
  821. num *= 2m;
  822. }
  823. else
  824. {
  825. this.parent.GoldCostCounter = this.parent.GoldCostCounter - 1;
  826. }
  827. bool flag = false;
  828. if (this.buySign != null)
  829. {
  830. CIGBuySign component = this.buySign.GetComponent<CIGBuySign>();
  831. if (component != null)
  832. {
  833. component.Buy(PlingType.Gold, "Gold", num);
  834. flag = true;
  835. }
  836. }
  837. if (!flag)
  838. {
  839. UnityEngine.Debug.LogWarning("No sign found.");
  840. }
  841. }
  842. this.UpdateCanUnlock();
  843. int num3 = this.u;
  844. int num4 = this.v;
  845. num4--;
  846. CIGExpansions.ExpansionBlock block = this.parent.GetBlock(num3, num4);
  847. if (block != null)
  848. {
  849. block.UpdateCanUnlock();
  850. }
  851. num4++;
  852. num3++;
  853. block = this.parent.GetBlock(num3, num4);
  854. if (block != null)
  855. {
  856. block.UpdateCanUnlock();
  857. }
  858. num3--;
  859. num4++;
  860. block = this.parent.GetBlock(num3, num4);
  861. if (block != null)
  862. {
  863. block.UpdateCanUnlock();
  864. }
  865. num4--;
  866. num3--;
  867. block = this.parent.GetBlock(num3, num4);
  868. if (block != null)
  869. {
  870. block.UpdateCanUnlock();
  871. }
  872. num3++;
  873. ((CIGBuilder)island.builder).ExpansionBlockDidUnlock(this.parent, this);
  874. this.parent.serializing.Serialize();
  875. this.parent.unlockableBlocks.Remove(this);
  876. return true;
  877. }
  878. private void OnBuySignClick(GameObject target)
  879. {
  880. SingletonMonobehaviour<PopupManager>.Instance.RequestFirstPopup<BuyExpansionPopupState>(delegate (State state)
  881. {
  882. SingletonMonobehaviour<CIGGameStats>.Instance.AddScreenViewed("buy_expansion");
  883. ((BuyExpansionPopupState)state).Block = this;
  884. });
  885. }
  886. private void CalculateElementStats()
  887. {
  888. this.availableElements = 0;
  889. this.visibleElements = 0;
  890. for (int i = this.origin.u; i < this.origin.u + this.size.u; i++)
  891. {
  892. for (int j = this.origin.v; j < this.origin.v + this.size.v; j++)
  893. {
  894. GridElement gridElement = this.parent.grid[i, j];
  895. if (gridElement.Type > 0)
  896. {
  897. this.availableElements++;
  898. }
  899. if (gridElement.IsVisible)
  900. {
  901. this.visibleElements++;
  902. }
  903. }
  904. }
  905. }
  906. public Currencies CalculatePrice()
  907. {
  908. if (this.AvailableElements == 0)
  909. {
  910. return Currencies.Zero;
  911. }
  912. string text = "Cash";
  913. string text2 = "Gold";
  914. decimal num = (decimal)this.AvailableFraction;
  915. int usedElements = this.parent.UsedElements;
  916. int num2 = this.parent.UnusedElements / 2;
  917. decimal profitPerHour = this.parent.ProfitPerHour;
  918. long value = (long)this.parent.MinProfitPerHourForCashCost;
  919. if (profitPerHour > value && usedElements > 0)
  920. {
  921. value = (long)profitPerHour / (long)usedElements * (long)(usedElements + num2);
  922. }
  923. decimal baseRoiExpansion = this.parent.BaseRoiExpansion;
  924. decimal extraRoiExpansion = this.parent.ExtraRoiExpansion;
  925. decimal d = baseRoiExpansion + extraRoiExpansion * Mathf.Max(0, this.parent.UnlockedBlocks - this.parent._initiallyUnlockedBlocks);
  926. decimal factorForExpansionCostsCash = SingletonMonobehaviour<CIGVariables>.Instance.FactorForExpansionCostsCash;
  927. decimal num3 = value * d * num * factorForExpansionCostsCash;
  928. decimal num4 = 5m * (decimal)Math.Pow(10.0, Math.Floor(Math.Log10((double)num3)) - 2.0);
  929. decimal num5 = num4 * Math.Ceiling(num3 / num4);
  930. if (num5 < 50000m)
  931. {
  932. num5 = 50000m;
  933. }
  934. decimal d2 = num * Math.Max(10, 25 + 5 * this.parent.GoldCostCounter);
  935. decimal num6 = 5m * Math.Ceiling(d2 / 5m);
  936. if (this.parent.ExpansionsAreOnSale)
  937. {
  938. num3 = Math.Ceiling(num3 / 2m);
  939. d2 = Math.Ceiling(d2 / 2m);
  940. }
  941. return new Currencies(new object[]
  942. {
  943. text,
  944. num5,
  945. text2,
  946. num6
  947. });
  948. }
  949. public string ToString()
  950. {
  951. return string.Format("[ExpansionBlock: U={0}, V={1}, Origin={2}, Size={3}, Unlocked={4}]", new object[]
  952. {
  953. this.u,
  954. this.v,
  955. this.origin,
  956. this.size,
  957. this.Unlocked
  958. });
  959. }
  960. private const string UnlockedKey = "Unlocked";
  961. private const string BoughtForKey = "BoughtFor";
  962. private const string PriceKey = "Price";
  963. private CIGExpansions parent;
  964. private int u;
  965. private int v;
  966. private GridIndex origin;
  967. private GridSize size;
  968. private Dictionary<string, object> state;
  969. private bool canUnlock;
  970. private GridTile buySign;
  971. private int availableElements = -1;
  972. private int visibleElements = -1;
  973. private bool unlockByDefault;
  974. private bool automaticUnlock;
  975. private string defName;
  976. }
  977. }