Advertisement
Draco18s

Json Things

Oct 17th, 2018
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 28.99 KB | None | 0 0
  1. using Assets.draco18s.config;
  2. using Assets.draco18s.dunmake.enums;
  3. using Assets.draco18s.dunmake.init;
  4. using Assets.draco18s.dunmake.objects;
  5. using Assets.draco18s.dunmake.tiles;
  6. using Assets.draco18s.util;
  7. using Assets.draco18s.ui;
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using UnityEngine;
  12. using UnityEngine.EventSystems;
  13. using UnityEngine.UI;
  14. using Newtonsoft.Json;
  15. using Newtonsoft.Json.Serialization;
  16. using System.Linq;
  17. using Newtonsoft.Json.Linq;
  18.  
  19. namespace Assets.draco18s.dunmake.game {
  20.     public class Main : MonoBehaviour {
  21.         public static Camera cam;
  22.         public static Main instance;
  23.         private GameObject lastBlock;
  24.         private MaterialPropertyBlock block;
  25.         private static List<List<DungeonTile>> world;
  26.         private List<GameObject> flowArrows;
  27.         private Tool activeTool = Tool.DIG;
  28.         private DungeonTile selectedTile;
  29.         private TileObject selectedBuildItem;
  30.         private GameObject selectedGhostInstance;
  31.         private List<GameObject> markers;
  32.         private int availableMana = 0;
  33.         private int dungeonFloorNum = 1;
  34.  
  35.         private void Awake() {
  36.             cam = Camera.main;
  37.             instance = this;
  38.             TileObjects.init();
  39.             GameObject go;
  40.             world = new List<List<DungeonTile>>();
  41.             flowArrows = new List<GameObject>();
  42.             block = new MaterialPropertyBlock();
  43.             markers = new List<GameObject>();
  44.             for(int x = -55; x <= 55; x++) {
  45.                 List<DungeonTile> list = new List<DungeonTile>();
  46.                 for(int y = -55; y <= 55; y++) {
  47.                     go = Instantiate(PrefabManager.instance.DungeonTile);
  48.                     go.transform.position = new Vector3(x, 0, y);
  49.                     DungeonTile dt = new DungeonTile(go);
  50.                     if(Math.Abs(x) - 50 >= 0 || Math.Abs(y) - 50 >= 0) {
  51.                         Destroy(go.GetComponent<Collider>());
  52.                         go.GetComponent<Renderer>().GetPropertyBlock(block);
  53.                         block.SetColor("_Color", Color.gray);
  54.                         go.GetComponent<Renderer>().SetPropertyBlock(block);
  55.                     }
  56.                     if(Math.Abs(x) - 50 < 0 && Math.Abs(y) - 50 < 0)
  57.                         list.Add(dt);
  58.                 }
  59.                 if(Math.Abs(x) - 50 < 0)
  60.                     world.Add(list);
  61.             }
  62.             Localization.initialize();
  63.             InitBlankMap();
  64.             //UIManager.instance.init();
  65.             UIManager.instance.initInventory();
  66.  
  67.             /*JsonSerializerSettings settings = new JsonSerializerSettings();
  68.             settings.ContractResolver = new Main.ContractResolver();
  69.             //settings.TypeNameHandling = TypeNameHandling.ALL;
  70.             string json = JsonConvert.SerializeObject(world[40][40], Formatting.Indented, settings);
  71.             //Debug.Log(json);
  72.             //world = JsonConvert.DeserializeObject<List<List<DungeonTile>>>(json, settings);*/
  73.         }
  74.  
  75.         private static void InitBlankMap() {
  76.             SetEmpty(world[40][40].dispObj);
  77.             SetEmpty(world[40][41].dispObj);
  78.             SetEmpty(world[40][42].dispObj);
  79.             SetEmpty(world[40][43].dispObj);
  80.             SetEmpty(world[40][44].dispObj);
  81.             SetEmpty(world[40][45].dispObj);
  82.             SetEmpty(world[39][42].dispObj);
  83.             SetEmpty(world[38][42].dispObj);
  84.  
  85.             instance.activeTool = Tool.PLACE;
  86.             instance.selectedBuildItem = TileObjects.EntranceStairs;
  87.             instance.lastBlock = instance.GetTileAt(40, 40).dispObj;
  88.             instance.UseActiveTool();
  89.             instance.activeTool = Tool.PLACE;
  90.             instance.selectedBuildItem = TileObjects.DungeonCore;
  91.             instance.lastBlock = instance.GetTileAt(40, 45).dispObj;
  92.             instance.UseActiveTool();
  93.             instance.lastBlock = instance.GetTileAt(38, 42).dispObj;
  94.             instance.activeTool = Tool.PLACE;
  95.             instance.selectedBuildItem = TileObjects.TreasureChest;
  96.             instance.UseActiveTool();
  97.             instance.GetTileAt(38, 42).tileObjRef.RightClick(instance.GetTileAt(38, 42), instance.GetTileAt(38, 42).tileObjGo);
  98.             instance.activeTool = Tool.DIG;
  99.  
  100.             instance.RecalculateFlow();
  101.             instance.CalculateCosts();
  102.         }
  103.  
  104.         public static void settingsOnValueChanged(Dropdown dropdown) {
  105.             instance.selectedTile.tileObjRef.OnSettingChanged(instance.selectedTile, dropdown.options[dropdown.value]);
  106.             UIManager.DisableListeners();
  107.             instance.selectedTile.tileObjRef.OnSelected(instance.selectedTile, dropdown);
  108.             UIManager.EnsableListeners();
  109.             instance.selectedTile.tileObjRef.OnAdded(instance.selectedTile, instance.selectedTile.tileObjGo);
  110.             instance.RecalculateFlow();
  111.         }
  112.  
  113.         private void Update() {
  114.             SelectAndClickBlocks();
  115.             MoveCamera();
  116.             Button btn = UIManager.instance.lowerui.transform.Find("DigButton").GetComponent<Button>();
  117.             ColorBlock cc = btn.colors;
  118.             cc.normalColor = activeTool == Tool.DIG?ColorHelper.LBLUE : Color.white;
  119.             cc.highlightedColor = activeTool == Tool.DIG ? ColorHelper.LBLUE : Color.white;
  120.             btn.colors = cc;
  121.             btn = UIManager.instance.lowerui.transform.Find("ClearButton").GetComponent<Button>();
  122.             cc = btn.colors;
  123.             cc.normalColor = activeTool == Tool.CLEAR ? ColorHelper.LBLUE : Color.white;
  124.             cc.highlightedColor = activeTool == Tool.CLEAR ? ColorHelper.LBLUE : Color.white;
  125.             btn.colors = cc;
  126.             btn = UIManager.instance.lowerui.transform.Find("WireButton").GetComponent<Button>();
  127.             cc = btn.colors;
  128.             cc.normalColor = activeTool == Tool.WIRES ? ColorHelper.LBLUE : Color.white;
  129.             cc.highlightedColor = activeTool == Tool.WIRES ? ColorHelper.LBLUE : Color.white;
  130.             btn.colors = cc;
  131.             btn = UIManager.instance.lowerui.transform.Find("SelectButton").GetComponent<Button>();
  132.             cc = btn.colors;
  133.             cc.normalColor = activeTool == Tool.SELECT ? ColorHelper.LBLUE : Color.white;
  134.             cc.highlightedColor = activeTool == Tool.SELECT ? ColorHelper.LBLUE : Color.white;
  135.             btn.colors = cc;
  136.         }
  137.  
  138.         private void SelectAndClickBlocks() {
  139.             RaycastHit hit;
  140.             Ray ray = cam.ScreenPointToRay(Input.mousePosition);
  141.             if(Physics.Raycast(ray, out hit)) {
  142.                 if(lastBlock != null && lastBlock != hit.transform.gameObject) {
  143.                     lastBlock.GetComponent<Renderer>().GetPropertyBlock(block);
  144.                     block.SetColor("_Color", Color.white);
  145.                     lastBlock.GetComponent<Renderer>().SetPropertyBlock(block);
  146.                 }
  147.                 lastBlock = hit.transform.gameObject;
  148.                 if(activeTool == Tool.DIG) {
  149.                     lastBlock.GetComponent<Renderer>().GetPropertyBlock(block);
  150.                     block.SetColor("_Color", Color.red);
  151.                     lastBlock.GetComponent<Renderer>().SetPropertyBlock(block);
  152.                 }
  153.                 if(EventSystem.current != null && !EventSystem.current.IsPointerOverGameObject()) {
  154.                     if(Input.GetMouseButtonUp(0)) {
  155.                         UseActiveTool();
  156.                     }
  157.                     if(Input.GetMouseButtonUp(1)) {
  158.                         DungeonTile dt = GetTileAt(lastBlock.transform.position);
  159.                         if((dt.state & TileState.FILLED) == 0) {
  160.                             if(dt.tileObjRef != null) {
  161.                                 dt.tileObjRef.RightClick(dt, dt.tileObjGo);
  162.                             }
  163.                         }
  164.                     }
  165.                     if(Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1)) {
  166.                         RecalculateFlow();
  167.                         CalculateCosts();
  168.                     }
  169.                     else if(selectedGhostInstance) {
  170.                         DungeonTile dt = GetTileAt(lastBlock.transform.position);
  171.                         if((dt.state & TileState.FILLED) == 0) {
  172.                             selectedGhostInstance.SetActive(true);
  173.                             selectedGhostInstance.transform.position = lastBlock.transform.position + Vector3.up;
  174.                         }
  175.                         else {
  176.                             selectedGhostInstance.SetActive(false);
  177.                         }
  178.                     }
  179.                 }
  180.             }
  181.             else if(lastBlock != null) {
  182.                 lastBlock.GetComponent<Renderer>().GetPropertyBlock(block);
  183.                 block.SetColor("_Color", Color.white);
  184.                 lastBlock.GetComponent<Renderer>().SetPropertyBlock(block);
  185.                 lastBlock = null;
  186.                 if(selectedGhostInstance)
  187.                     selectedGhostInstance.SetActive(false);
  188.             }
  189.         }
  190.  
  191.         private void UseActiveTool() {
  192.             if(activeTool == Tool.SELECT) {
  193.                 DungeonTile dt = GetTileAt(lastBlock.transform.position);
  194.                 if(selectedTile != dt && selectedTile != null)
  195.                     selectedTile.tileObjRef.OnUnselected(selectedTile);
  196.                 if(dt.tileObjRef != null && dt.tileObjRef.HasSelectionWindow(dt)) {
  197.                    
  198.                     Vector3 vec = cam.WorldToScreenPoint(dt.dispObj.transform.position);
  199.                     vec.z = 0;
  200.                     vec.x -= 100;
  201.                     vec.y += 30;
  202.                     if(vec.x < 90) {
  203.                         vec.x += 190;
  204.                     }
  205.                     vec.y = Math.Max(vec.y, 235);
  206.                     vec.y = Math.Min(vec.y, 635);
  207.                     vec.x -= Screen.width / 2;
  208.                     vec.y -= Screen.height / 2;
  209.                     UIManager.instance.tileObjSettingsPanel.transform.localPosition = vec;
  210.                     UIManager.instance.tileObjSettingsPanel.SetActive(true);
  211.                     UIManager.DisableListeners();
  212.                     Dropdown[] l = UIManager.instance.tileObjSettingsPanel.GetComponentsInChildren<Dropdown>(true);
  213.                     foreach(Dropdown dd in l) {
  214.                         dt.tileObjRef.OnSelected(dt, dd);
  215.                         dd.gameObject.SetActive(dd.options.Count > 0);
  216.                     }
  217.                     UIManager.EnsableListeners();
  218.                     selectedTile = dt;
  219.                 }
  220.                 else {
  221.                     UIManager.instance.tileObjSettingsPanel.SetActive(false);
  222.                 }
  223.             }
  224.             if(activeTool == Tool.DIG) {
  225.                 if(Math.Abs(lastBlock.transform.position.x) - 50 < 0 && Math.Abs(lastBlock.transform.position.z) - 50 < 0) {
  226.                     if(lastBlock.transform.position.y >= 0) {
  227.                         SetEmpty(lastBlock);
  228.                     }
  229.                     else {
  230.                         SetFilled(lastBlock);
  231.                     }
  232.                 }
  233.             }
  234.             if(activeTool == Tool.PLACE) {
  235.                 DungeonTile dt = GetTileAt(lastBlock.transform.position);
  236.                 ClearTile(dt);
  237.                 if((dt.state & TileState.FILLED) == 0) {
  238.                     GameObject go = Instantiate(selectedBuildItem.prefab);
  239.                     go.transform.position = lastBlock.transform.position + Vector3.up;
  240.                     dt.tileObjGo = go;
  241.                     dt.tileObjRef = selectedBuildItem;
  242.                     dt.tileObjFacing = dt.tileObjRef.GetDefaultFacing();
  243.                     dt.tileObjRef.OnAdded(dt, dt.tileObjGo);
  244.                 }
  245.                 if(!Input.GetButton("Shift"))
  246.                     SetActiveTool(Tool.DIG);
  247.             }
  248.             if(activeTool == Tool.CLEAR) {
  249.                 DungeonTile dt = GetTileAt(lastBlock.transform.position);
  250.                 if((dt.state & TileState.FILLED) == 0) {
  251.                     ClearTile(dt);
  252.                 }
  253.             }
  254.             if(activeTool == Tool.WIRES) {
  255.                 DungeonTile dt = GetTileAt(lastBlock.transform.position);
  256.                 if((dt.state & TileState.FILLED) == 0) {
  257.                     ManaChannelState st = dt.wireState;
  258.                     if(st == ManaChannelState.NONE)
  259.                         st = ManaChannelState.INACTIVE;
  260.                     else
  261.                         st = ManaChannelState.NONE;
  262.                     dt.SetWireState(st);
  263.                 }
  264.             }
  265.         }
  266.  
  267.         public static void SetActiveTool(Tool tool) {
  268.             UIManager.instance.tileObjSettingsPanel.SetActive(false);
  269.             instance.activeTool = tool;
  270.             Destroy(instance.selectedGhostInstance);
  271.             instance.selectedGhostInstance = null;
  272.             if(instance.selectedTile != null) {
  273.                 instance.selectedTile.tileObjRef.OnUnselected(instance.selectedTile);
  274.                 instance.selectedTile = null;
  275.             }
  276.         }
  277.  
  278.         public static void SetActiveTool(Tool tool, object obj) {
  279.             UIManager.instance.tileObjSettingsPanel.SetActive(false);
  280.             instance.activeTool = tool;
  281.             if(obj is TileObject) {
  282.                 Destroy(instance.selectedGhostInstance);
  283.                 instance.selectedGhostInstance = null;
  284.  
  285.                 instance.selectedBuildItem = (TileObject)obj;
  286.                 instance.selectedGhostInstance = Instantiate(instance.selectedBuildItem.prefab);
  287.                 instance.selectedGhostInstance.SetActive(false);
  288.  
  289.                 Renderer[] renderers = instance.selectedGhostInstance.GetComponentsInChildren<Renderer>();
  290.                 bool areAnyMasked = false;
  291.                 foreach(Renderer r in renderers) {
  292.                     areAnyMasked = r.material.shader.ToString().StartsWith("Mask");
  293.                 }
  294.                 if(!areAnyMasked) {
  295.                     Shader sh = Shader.Find("Custom/Ghost");
  296.                     foreach(Renderer r in renderers) {
  297.                         r.material.shader = sh;
  298.                     }
  299.                 }
  300.                 else {
  301.                     //Shader sh = Shader.Find("Custom/Ghost2");
  302.                     //foreach(Renderer r in renderers) {
  303.                         //r.material.shader = sh;
  304.                     //}
  305.                 }
  306.             }
  307.             if(instance.selectedTile != null) {
  308.                 instance.selectedTile.tileObjRef.OnUnselected(instance.selectedTile);
  309.                 instance.selectedTile = null;
  310.             }
  311.         }
  312.  
  313.         private static void ShowFlowError(FlowError err) {
  314.             UIManager.ShowError(err.ToString());
  315.         }
  316.  
  317.         private int CalculateCosts() {
  318.             int val = 0;
  319.             for(int x = 0; x < 99; x++) {
  320.                 for(int y = 0; y < 99; y++) {
  321.                     if((world[x][y].state & TileState.FILLED) == 0)
  322.                         if(world[x][y].tileObjRef != null)
  323.                             val += world[x][y].tileObjRef.buildCost;
  324.                 }
  325.             }
  326.             int max = (20 + dungeonFloorNum * 5);
  327.             max *= max;
  328.             max *= 2;
  329.             UIManager.instance.availableMana.text = Localization.translateToLocal("ui.available_mana.text",val,availableMana,max);
  330.             if(val > availableMana) {
  331.                 UIManager.ShowError("ui.overspent.text");
  332.             }
  333.             if(availableMana > max) {
  334.                 UIManager.ShowError("ui.floor_too_large.text");
  335.             }
  336.             return val;
  337.         }
  338.  
  339.         private void RecalculateFlow() {
  340.             foreach(GameObject go in markers) {
  341.                 Destroy(go);
  342.             }
  343.             foreach(GameObject go in flowArrows) {
  344.                 Destroy(go);
  345.             }
  346.             FlowError err = DoRecalculateFlow();
  347.             if(err != FlowError.NONE) {
  348.                 ShowFlowError(err);
  349.             }
  350.             else {
  351.                 foreach(GameObject go in markers) {
  352.                     Destroy(go);
  353.                 }
  354.                 foreach(GameObject go in flowArrows) {
  355.                     Destroy(go);
  356.                 }
  357.                 UIManager.ShowError("");
  358.             }
  359.         }
  360.  
  361.         private FlowError DoRecalculateFlow() {
  362.             FlowError result;
  363.             List<DungeonTile> allof;
  364.             List<DungeonTile> unescapeSet = new List<DungeonTile>();
  365.             List<DungeonTile> recurseSet = new List<DungeonTile>();
  366.  
  367.             for(int x = 0; x < 99; x++) {
  368.                 for(int y = 0; y < 99; y++) {
  369.                     if(world[x][y].tileObjRef is IFlowAlteringSource)
  370.                         ((IFlowAlteringSource)world[x][y].tileObjRef).UpdateFlow(world[x][y], new Vector2Int(x, y), FlowRestriction.UNKNOWN);
  371.                 }
  372.             }
  373.  
  374.             allof = FindAllTilesOfType(TileState.SURFACE_ACCESS_ENTR);
  375.             if(allof.Count > 1)
  376.                 return FlowError.MORE_THAN_ONE_ENTRANCE;
  377.             if(allof.Count == 0)
  378.                 return FlowError.MISSING_ENTRANCE;
  379.             allof = FindAllTilesOfType(TileState.CORE);
  380.             if(allof.Count > 1)
  381.                 return FlowError.MORE_THAN_ONE_CORE;
  382.             if(allof.Count == 0)
  383.                 return FlowError.MISSING_CORE;
  384.             foreach(DungeonTile dt in allof) {
  385.                 result = RecalculateReachabilityFrom(dt, SecretDoor.DENY, ref unescapeSet, WireRecurse.YES, ref recurseSet);
  386.                 if(result != FlowError.NONE && !(result == FlowError.UNESCAPABLE_AREA1 || result == FlowError.UNESCAPABLE_AREA2))
  387.                     return result;
  388.             }
  389.            
  390.             for(int x = 0; x < 99; x++) {
  391.                 for(int y = 0; y < 99; y++) {
  392.                     if((world[x][y].state & TileState.FILLED) == 0)
  393.                         unescapeSet.Add(world[x][y]);
  394.                 }
  395.             }
  396.             availableMana = unescapeSet.Count * 2;
  397.             allof = FindAllTilesOfType(TileState.SURFACE_ACCESS_EXIT);
  398.             //allof.RemoveAt(allof.FindIndex(x => (x.state & TileState.SURFACE_ACCESS_ENTR) > 0));
  399.             result = FlowError.NONE;
  400.             foreach(DungeonTile dt in allof) {
  401.                 result |= RecalculateReachabilityFrom(dt, SecretDoor.DENY, ref unescapeSet, WireRecurse.NONE, ref recurseSet);
  402.             }
  403.             unescapeSet.RemoveAll(x => x.tileObjRef != null && x.tileObjRef is IUnwalkable);
  404.             if(((result & FlowError.UNESCAPABLE_AREA1) > 0 || (result & FlowError.UNESCAPABLE_AREA2) > 0) && unescapeSet.Count > 0) {
  405.                 int max = 30;
  406.                 DungeonTile c = FindAllTilesOfType(TileState.CORE)[0];
  407.                 unescapeSet.Sort((x, y) => (x.position - c.position).sqrMagnitude.CompareTo((y.position - c.position).sqrMagnitude));
  408.                 foreach(DungeonTile udt in unescapeSet) {
  409.                     GameObject arr = Instantiate(PrefabManager.instance.MarkerArrow);
  410.                     markers.Add(arr);
  411.                     arr.transform.position = udt.dispObj.transform.position + Vector3.up * 1.5f;
  412.                     max--;
  413.                     if(max <= 0) break;
  414.                 }
  415.                 return FlowError.UNESCAPABLE_AREA1;
  416.             }
  417.             result &= ~(FlowError.UNESCAPABLE_AREA1);
  418.             result &= ~(FlowError.UNESCAPABLE_AREA2);
  419.             if(result != FlowError.NONE) {
  420.                 return result;
  421.             }
  422.  
  423.             /*allof = FindAllTilesOfType(TileState.CORE);
  424.             foreach(DungeonTile dt in allof) {
  425.                 result = RecalculateReachabilityFrom(dt, ref unescapeSet);
  426.             }*/
  427.             foreach(GameObject go in flowArrows) {
  428.                 Destroy(go);
  429.             }
  430.             List<DungeonTile> obstructed = new List<DungeonTile>();
  431.             result = ValidateObjectPlacement(ref obstructed);
  432.             foreach(DungeonTile odt in obstructed) {
  433.                 GameObject arr = Instantiate(PrefabManager.instance.MarkerArrow);
  434.                 markers.Add(arr);
  435.                 arr.transform.position = odt.dispObj.transform.position + Vector3.up * 1.5f;
  436.             }
  437.  
  438.             if(result == FlowError.NONE) {
  439.                 allof = FindAllTilesOfType(TileState.REWARD);
  440.                 if(allof.Count == 0)
  441.                     return FlowError.NO_REWARDS;
  442.                 unescapeSet.Clear();
  443.                 FlowError result2 = FlowError.NONE;
  444.                 foreach(DungeonTile dt in allof) {
  445.                     result2 = RecalculateReachabilityFrom(dt, SecretDoor.ALLOW, ref unescapeSet, WireRecurse.YES, ref recurseSet);
  446.                     if(result2 != FlowError.NONE && result2 != FlowError.UNESCAPABLE_AREA2)
  447.                         return FlowError.UNREACHABLE_AREA;
  448.                 }
  449.             }
  450.             return result;
  451.         }
  452.  
  453.         private List<DungeonTile> FindAllTilesOfType(TileState type) {
  454.             List<DungeonTile> searchSet = new List<DungeonTile>();
  455.             for(int x = 0; x < 99; x++) {
  456.                 for(int y = 0; y < 99; y++) {
  457.                     if((world[x][y].state & type) > 0)
  458.                         searchSet.Add(world[x][y]);
  459.                 }
  460.             }
  461.             return searchSet;
  462.         }
  463.  
  464.         private FlowError RecalculateReachabilityFrom(DungeonTile center, SecretDoor secrets, ref List<DungeonTile> unescapables, WireRecurse followWire, ref List<DungeonTile> recurseSet) {
  465.             foreach(GameObject go in flowArrows) {
  466.                 Destroy(go);
  467.             }
  468.             List<DungeonTile> dugSet = new List<DungeonTile>();
  469.             for(int x = 0; x < 99; x++) {
  470.                 for(int y = 0; y < 99; y++) {
  471.                     if((world[x][y].state & TileState.FILLED) == 0)
  472.                         dugSet.Add(world[x][y]);
  473.                 }
  474.             }
  475.             if(center == null && (center.state & TileState.CORE) > 0) return FlowError.MISSING_CORE;
  476.             unescapables.Remove(center);
  477.             DungeonTilePath coreTilePath = new DungeonTilePath(center, null);
  478.             List<DungeonTilePath> openSet = new List<DungeonTilePath>();
  479.             List<DungeonTilePath> closedSet = new List<DungeonTilePath>();
  480.             for(int x = -1; x <= 1; x++) {
  481.                 for(int y = -1; y <= 1; y++) {
  482.                     if(x == 0 && y == 0) continue;
  483.                     DungeonTile dt = GetTileAt(x + center.position.x, y + center.position.y);
  484.                     if((dt.state & TileState.FILLED) == 0) {
  485.                         DungeonTilePath ths = new DungeonTilePath(dt, coreTilePath);
  486.                         if((FlowAllowed(ths) || (secrets == SecretDoor.ALLOW && (ths.tile.tileObjRef == TileObjects.SecretDoor || ths.next.tile.tileObjRef == TileObjects.SecretDoor))) && checkDiagonal(ths))
  487.                             openSet.Add(ths);
  488.                     }
  489.                 }
  490.             }
  491.             while(openSet.Count > 0) {
  492.                 DungeonTilePath dp = openSet[0];
  493.                 openSet.RemoveAt(0);
  494.                 if(dp.tile.wireState == ManaChannelState.INACTIVE && (dp.tile.tileObjRef is Door) && ((Door)dp.tile.tileObjRef).isOneWay == false) {
  495.                     if(followWire == WireRecurse.YES && !recurseSet.Contains(dp.tile)) {
  496.                         List<DungeonTile> unescapeSet = FindWireActivation(dp.tile);
  497.                         if(unescapeSet.Count == 0) {
  498.                             GameObject arr = Instantiate(PrefabManager.instance.MarkerArrow);
  499.                             markers.Add(arr);
  500.                             arr.transform.position = dp.tile.dispObj.transform.position + Vector3.up * 1.5f;
  501.                             return FlowError.UNACTIVATABLE_OBJECT;
  502.                         }
  503.                         List<DungeonTile> allof = FindAllTilesOfType(TileState.SURFACE_ACCESS_ENTR);
  504.                         FlowError result = FlowError.NONE;
  505.                         recurseSet.Add(dp.tile);
  506.                         foreach(DungeonTile dt in allof) {
  507.                             result |= RecalculateReachabilityFrom(dt, secrets, ref unescapeSet, WireRecurse.YES, ref recurseSet);
  508.                         }
  509.                         if(unescapeSet.Count > 0) {
  510.                             foreach(DungeonTile dt in unescapeSet) {
  511.                                 GameObject arr = Instantiate(PrefabManager.instance.MarkerArrow);
  512.                                 markers.Add(arr);
  513.                                 arr.transform.position = dt.dispObj.transform.position + Vector3.up * 1.5f;
  514.                             }
  515.                             return FlowError.UNREACHABLE_OBJECTIVE;
  516.                         }
  517.                     }
  518.                     else if(followWire == WireRecurse.INPROGRESS) {
  519.                         continue;
  520.                     }
  521.                 }
  522.                 unescapables.Remove(dp.tile);
  523.                 dugSet.Remove(dp.tile);
  524.                 closedSet.Add(dp);
  525.                 GameObject arrow = Instantiate(PrefabManager.instance.FlowArrow);
  526.                 arrow.transform.position = dp.tile.dispObj.transform.position;
  527.                 flowArrows.Add(arrow);
  528.                 arrow.transform.LookAt(dp.next.tile.dispObj.transform);
  529.                 for(int x = -1; x <= 1; x++) {
  530.                     for(int y = -1; y <= 1; y++) {
  531.                         if(x == 0 && y == 0) continue;
  532.                         DungeonTile dt = GetTileAt(x + dp.tile.position.x, y + dp.tile.position.y);
  533.                         DungeonTilePath ths = new DungeonTilePath(dt, dp);
  534.                         if((dt.state & TileState.FILLED) == 0 && openSet.FindIndex(p => p.tile == dt) < 0 && closedSet.FindIndex(p => p.tile == dt) < 0) {
  535.                             if(secrets == SecretDoor.ALLOW && (ths.tile.tileObjRef == TileObjects.SecretDoor || ths.next.tile.tileObjRef == TileObjects.SecretDoor)) {
  536.                                 Debug.Log("Door allowed");
  537.                             }
  538.  
  539.                             if(((FlowAllowed(ths) && checkDiagonal(ths)) || (secrets == SecretDoor.ALLOW && (ths.tile.tileObjRef == TileObjects.SecretDoor || ths.next.tile.tileObjRef == TileObjects.SecretDoor)))) {
  540.                                 openSet.Add(ths);
  541.                             }
  542.                         }
  543.                     }
  544.                 }
  545.                 openSet.Sort((x, y) => x.distance.CompareTo(y.distance));
  546.             }
  547.             FlowError res = closedSet.FindIndex(x => (x.tile.state & TileState.SURFACE_ACCESS_ENTR) > 0) >= 0 ? FlowError.NONE : FlowError.UNREACHABLE_CORE;
  548.             if(res != FlowError.NONE) {
  549.                 if((center.state & TileState.CORE) > 0)
  550.                     return res;
  551.                 return FlowError.UNESCAPABLE_AREA1;
  552.             }
  553.             if(dugSet.Count > 0) return FlowError.UNESCAPABLE_AREA2;
  554.             return res;
  555.         }
  556.  
  557.         private List<DungeonTile> FindWireActivation(DungeonTile coreTile) {
  558.             DungeonTilePath coreTilePath = new DungeonTilePath(coreTile, null);
  559.             List<DungeonTilePath> openSet = new List<DungeonTilePath>();
  560.             List<DungeonTilePath> closedSet = new List<DungeonTilePath>();
  561.             for(int x = -1; x <= 1; x++) {
  562.                 for(int y = -1; y <= 1; y++) {
  563.                     if(Math.Abs(x) + Math.Abs(y) != 1) continue;
  564.                     DungeonTile dt = GetTileAt(x + coreTile.position.x, y + coreTile.position.y);
  565.                     if((dt.wireState != ManaChannelState.NONE)) {
  566.                         DungeonTilePath ths = new DungeonTilePath(dt, coreTilePath);
  567.                         openSet.Add(ths);
  568.                     }
  569.                 }
  570.             }
  571.             while(openSet.Count > 0) {
  572.                 DungeonTilePath dp = openSet[0];
  573.                 openSet.RemoveAt(0);
  574.                 closedSet.Add(dp);
  575.                 for(int x = -1; x <= 1; x++) {
  576.                     for(int y = -1; y <= 1; y++) {
  577.                         if(Math.Abs(x) + Math.Abs(y) != 1) continue;
  578.                         DungeonTile dt = GetTileAt(x + dp.tile.position.x, y + dp.tile.position.y);
  579.                         if((dt.wireState != ManaChannelState.NONE) && openSet.FindIndex(p => p.tile == dt) < 0 && closedSet.FindIndex(p => p.tile == dt) < 0) {
  580.                             DungeonTilePath ths = new DungeonTilePath(dt, dp);
  581.                             openSet.Add(ths);
  582.                         }
  583.                     }
  584.                 }
  585.                 openSet.Sort((x, y) => x.distance.CompareTo(y.distance));
  586.             }
  587.             List<DungeonTilePath> list = closedSet.FindAll(x => x.tile.wireState == ManaChannelState.ACTIVE);
  588.             List<DungeonTile> ret = new List<DungeonTile>();
  589.             foreach(DungeonTilePath dtp in list) {
  590.                 ret.Add(dtp.tile);
  591.             }
  592.             return ret;
  593.         }
  594.  
  595.         private FlowError ValidateObjectPlacement(ref List<DungeonTile> errorLoc) {
  596.             for(int x = 0; x < 99; x++) {
  597.                 for(int y = 0; y < 99; y++) {
  598.                     if(world[x][y].tileObjRef != null && world[x][y].tileObjRef.buffer > 0) {
  599.                         if(!ValidateBuffer(world[x][y], world[x][y].tileObjRef.buffer, ref errorLoc)) {
  600.                             errorLoc.Add(world[x][y]);
  601.                         }
  602.                     }
  603.                 }
  604.             }
  605.             if(errorLoc.Count > 0) return FlowError.CROWDED_OBJECT;
  606.             return FlowError.NONE;
  607.         }
  608.  
  609.         private bool ValidateBuffer(DungeonTile center, int dist, ref List<DungeonTile> errorLoc) {
  610.             bool ret = true;
  611.             if(dist <= 0) return ret;
  612.             for(int x = -dist; x <= dist; x++) {
  613.                 for(int y = -dist; y <= dist; y++) {
  614.                     if(x == 0 && y == 0) continue;
  615.                     DungeonTile dt = GetTileAt(x + center.position.x, y + center.position.y);
  616.                     if(dt.tileObjRef != null && !(dt.tileObjRef is IUnwalkable)) {
  617.                         errorLoc.Add(dt);
  618.                         ret = false;
  619.                     }
  620.                 }
  621.             }
  622.             return ret;
  623.         }
  624.  
  625.         private bool FlowAllowed(DungeonTilePath dp) {
  626.             if(dp.tile == dp.next.tile) {
  627.                 return true;
  628.             }
  629.             FlowRestriction flowDirOut = FlowRestriction.UNKNOWN;
  630.             FlowRestriction flowDirIn = FlowRestriction.UNKNOWN;
  631.             if(dp.next.tile.position.x - dp.tile.position.x > 0) {
  632.                 flowDirOut |= FlowRestriction.EAST;
  633.                 flowDirIn |= FlowRestriction.WEST;
  634.             }
  635.             if(dp.next.tile.position.x - dp.tile.position.x < 0) {
  636.                 flowDirOut |= FlowRestriction.WEST;
  637.                 flowDirIn |= FlowRestriction.EAST;
  638.             }
  639.             if(dp.next.tile.position.y - dp.tile.position.y > 0) {
  640.                 flowDirOut |= FlowRestriction.NORTH;
  641.                 flowDirIn |= FlowRestriction.SOUTH;
  642.             }
  643.             if(dp.next.tile.position.y - dp.tile.position.y < 0) {
  644.                 flowDirOut |= FlowRestriction.SOUTH;
  645.                 flowDirIn |= FlowRestriction.NORTH;
  646.             }
  647.             if(flowDirOut == FlowRestriction.UNKNOWN) {
  648.                 Debug.Log("FLARGLEBLARG");
  649.             }
  650.             return (flowDirOut & dp.tile.allowedDirectionsOut) == flowDirOut && (flowDirIn & dp.next.tile.allowedDirectionsIn) > 0;
  651.         }
  652.  
  653.         private bool checkDiagonal(DungeonTilePath dp) {
  654.             DungeonTile dt1 = GetTileAt(dp.next.tile.position.x, dp.tile.position.y);
  655.             DungeonTile dt2 = GetTileAt(dp.tile.position.x, dp.next.tile.position.y);
  656.             bool p1 = !((dt1.state & TileState.FILLED) > 0 || (dt2.state & TileState.FILLED) > 0);
  657.             DungeonTilePath dpa = new DungeonTilePath(dt1, dp.next);
  658.             DungeonTilePath dpb = new DungeonTilePath(dt2, dp.next);
  659.             bool p2 = FlowAllowed(dpa) && FlowAllowed(dpb);
  660.             bool p3 = FlowAllowed(new DungeonTilePath(dp.tile, dpa)) && FlowAllowed(new DungeonTilePath(dp.tile, dpb));
  661.             //Debug.Log(p2);
  662.             return p1 && p2 && p3;
  663.         }
  664.  
  665.         public DungeonTile GetTileAt(Vector3 pos) {
  666.             int x = (int)pos.x + 49;
  667.             int y = (int)pos.z + 49;
  668.             return GetTileAt(x, y);
  669.         }
  670.  
  671.         public DungeonTile GetTileAt(int x, int y) {
  672.             if(x >= world.Count || x < 0 || y >= world.Count || y < 0) return null;
  673.             return world[x][y];
  674.         }
  675.  
  676.         private static void SetFilled(GameObject lastBlock) {
  677.             DungeonTile dt = world[(int)lastBlock.transform.position.x + 49][(int)lastBlock.transform.position.z + 49];
  678.             if((dt.state & TileState.CORE) > 0 || (dt.state & TileState.SURFACE_ACCESS_ENTR) > 0) {
  679.                 return;
  680.             }
  681.             lastBlock.transform.position = new Vector3(lastBlock.transform.position.x, 0, lastBlock.transform.position.z);
  682.             //TODO: clear decorations and objects
  683.             ClearTile(dt);
  684.             dt.allowedDirectionsOut = (FlowRestriction.NORTH | FlowRestriction.SOUTH | FlowRestriction.EAST | FlowRestriction.WEST);
  685.             dt.state |= TileState.FILLED;
  686.             dt.SetWireState(ManaChannelState.NONE);
  687.             dt.tileObjMetadata = 0;
  688.         }
  689.  
  690.         private static void ClearTile(DungeonTile dt) {
  691.             if(dt.tileObjRef != null) {
  692.                 dt.tileObjRef.OnRemoved(dt, dt.tileObjGo);
  693.                 dt.tileObjRef = null;
  694.                 Destroy(dt.tileObjGo);
  695.                 dt.tileObjGo = null;
  696.                 dt.state &= TileState.FILLED;
  697.                 dt.tileObjFacing = Facing.UNKNOWN;
  698.                 dt.allowedDirectionsIn = dt.allowedDirectionsOut = (FlowRestriction.NORTH | FlowRestriction.SOUTH | FlowRestriction.EAST | FlowRestriction.WEST);
  699.             }
  700.             //dt.decorationRef
  701.         }
  702.  
  703.         private static void SetEmpty(GameObject lastBlock) {
  704.             DungeonTile dt = world[(int)lastBlock.transform.position.x + 49][(int)lastBlock.transform.position.z + 49];
  705.             lastBlock.transform.position = new Vector3(lastBlock.transform.position.x, -1, lastBlock.transform.position.z);
  706.             dt.state &= ~TileState.FILLED;
  707.         }
  708.  
  709.         private void MoveCamera() {
  710.             if(EventSystem.current != null && EventSystem.current.currentSelectedGameObject == UIManager.instance.searchInput) {
  711.                 return;
  712.             }
  713.             float h = Input.GetAxis("Horizontal");
  714.             float v = Input.GetAxis("Vertical");
  715.             Vector3 r = cam.transform.right;
  716.             Vector3 f = cam.transform.forward;
  717.             Vector3 move = new Vector3(h, 0, v);
  718.  
  719.             move = cam.transform.TransformVector(move);
  720.             move.y = 0;
  721.  
  722.             move = cam.transform.localPosition + move.normalized * Time.deltaTime * 7;
  723.             move = MathHelper.clamp(move, new Rect(-38, -38, 93, 93));
  724.             move = move - cam.transform.position;
  725.  
  726.             move = cam.transform.localPosition + move.normalized * Time.deltaTime * 7;
  727.             move = MathHelper.clamp(move, new Rect(-38, -38, 93, 93));
  728.             cam.transform.localPosition = move;
  729.             //-38,-38
  730.             //55,55
  731.         }
  732.  
  733.         private enum WireRecurse {
  734.             NONE,
  735.             INPROGRESS,
  736.             YES
  737.         }
  738.  
  739.         public class ContractResolver : DefaultContractResolver {
  740.             public override JsonContract ResolveContract(Type type) {
  741.                 JsonContract contract = base.ResolveContract(type);
  742.                 if(typeof(TileObject).IsAssignableFrom(type)) {
  743.                     contract.Converter = new TileObject.Converter();
  744.                 }
  745.                 if(typeof(Vector2Int).IsAssignableFrom(type)) {
  746.                     contract.Converter = new Vector2IntConverter();
  747.                 }
  748.                 return contract;
  749.             }
  750.  
  751.             protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
  752.                 IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
  753.                
  754.                 foreach(JsonProperty prop in properties) {
  755.                     prop.DefaultValueHandling = DefaultValueHandling.Ignore;
  756.                 }
  757.  
  758.                 return properties;
  759.             }
  760.         }
  761.  
  762.         public class Vector2IntConverter : JsonConverter {
  763.             public override bool CanConvert(Type objectType) {
  764.                 return typeof(Vector2Int).IsAssignableFrom(objectType);
  765.             }
  766.  
  767.             public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
  768.                 JObject jObject = JObject.Load(reader);
  769.                 return new Vector2Int((int)jObject.GetValue("x"), (int)jObject.GetValue("y"));
  770.             }
  771.  
  772.             public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
  773.                 Vector2Int v = (Vector2Int)value;
  774.                 JObject o = new JObject();
  775.                 o.Add(new JProperty("x", v.x));
  776.                 o.Add(new JProperty("y", v.y));
  777.                 o.WriteTo(writer);
  778.             }
  779.  
  780.             public override bool CanRead {
  781.                 get { return true; }
  782.             }
  783.         }
  784.     }
  785. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement