123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using KairoEngine.Core;
- using KairoEngine.Core.GameActions;
- using KairoEngine.Stockpiles;
- using Sirenix.OdinInspector;
- using KairoEngine.GameTools.Selectables;
- using KairoEngine.SFX;
- namespace KairoEngine.Grids
- {
- [CreateAssetMenu(fileName = "PlaceObjectType", menuName = "KairoEngine/BuildingSystem/PlaceObjectType")]
- [HideMonoScript]
- public class PlacedObjectType : ScriptableObject
- {
- public static Dir GetNextDir(Dir dir)
- {
- switch (dir)
- {
- default:
- case Dir.Down: return Dir.Left;
- case Dir.Left: return Dir.Up;
- case Dir.Up: return Dir.Right;
- case Dir.Right: return Dir.Down;
- }
- }
- public enum Dir
- {
- Down,
- Up,
- Left,
- Right
- }
- [BoxGroup("Properties", showLabel: false)] public string title;
- [BoxGroup("Properties")] public string category;
- [BoxGroup("Properties")] public Transform prefab;
- [BoxGroup("Properties")] public Transform visual;
- [BoxGroup("Properties")] public Sprite image;
- [BoxGroup("Properties")] public Sprite icon;
- [BoxGroup("Properties")] public SFXClip createdSound;
- [BoxGroup("Properties")] public SFXClip removedSound;
- [BoxGroup("Properties")] public bool isDestructable = true;
- [BoxGroup("Properties"), HorizontalGroup("Properties/size"), LabelText("Width/Height")] public int width;
- [BoxGroup("Properties"), HorizontalGroup("Properties/size", 0.3f), HideLabel] public int height;
- [BoxGroup("Properties"), TextArea(2, 8), HideLabel, PropertySpace(4, 4)] public string description;
- [PropertySpace(1, 1)] public List<KairoEngine.Stockpiles.Stockpile> cost = new List<KairoEngine.Stockpiles.Stockpile>();
- [PropertySpace(1, 1)] public List<PlaceableObjectConnector> connectors = new List<PlaceableObjectConnector>();
- [PropertySpace(1, 1)] public List<BuildingEffectArea> effectAreas = new List<BuildingEffectArea>();
- [FoldoutGroup("Rules"), PropertySpace(2, 2)]
- [InfoBox("Rules for positioning the building in the game world", InfoMessageType.Info)]
- public ConditionType rulesetCondition;
- [ListDrawerSettings(HideAddButton = false, HideRemoveButton = false, DraggableItems = false, Expanded = true, ShowPaging = false, ShowItemCount = true)]
- [PropertySpace(2, 2)]
- [FoldoutGroup("Rules")]
- public List<PlaceableObjectRuleGroup> ruleset = new List<PlaceableObjectRuleGroup>();
- [FoldoutGroup("Functionality")]
- [HideLabel, InlineProperty, OnInspectorInit("SetupContext"), PropertySpace(2, 4)]
- public GameActionContext context = new GameActionContext();
- [FoldoutGroup("Functionality")]
- [TabGroup("Functionality/Triggers", "On Action"), PropertySpace(1, 2)]
- [InfoBox("Actions that can be triggered by the player or game events", InfoMessageType.Info)]
- [LabelText("Actions")]
- public List<SelectableObjectAction> objectActions;
- [FoldoutGroup("Functionality")]
- [TabGroup("Functionality/Triggers", "On Create"), InlineProperty, HideLabel, PropertySpace(1, 2)]
- [InfoBox("Execute actions when the building is placed", InfoMessageType.Info)]
- public GameActionsController onCreateController;
- [FoldoutGroup("Functionality")]
- [TabGroup("Functionality/Triggers", "On Update"), InlineProperty, HideLabel, PropertySpace(1, 2)]
- [InfoBox("Executes every frame while the building is active", InfoMessageType.Info)]
- public GameActionsController onUpdateController;
- [FoldoutGroup("Functionality")]
- [TabGroup("Functionality/Triggers", "On Remove"), InlineProperty, HideLabel, PropertySpace(1, 2)]
- [InfoBox("Executes when the building is removed", InfoMessageType.Info)]
- public GameActionsController onRemoveController;
- public int GetRotationAngle(Dir dir)
- {
- switch (dir)
- {
- default:
- case Dir.Down: return 0;
- case Dir.Left: return 90;
- case Dir.Up: return 180;
- case Dir.Right: return 270;
- }
- }
- public Vector2Int GetRotationOffset(Dir dir)
- {
- switch (dir)
- {
- default:
- case Dir.Down: return new Vector2Int(0, 0);
- case Dir.Left: return new Vector2Int(0, width);
- case Dir.Up: return new Vector2Int(width, height);
- case Dir.Right: return new Vector2Int(height, 0);
- }
- }
- public Vector2Int GetRotationOffset(Dir dir, int width, int height)
- {
- switch (dir)
- {
- default:
- case Dir.Down: return new Vector2Int(0, 0);
- case Dir.Left: return new Vector2Int(0, width);
- case Dir.Up: return new Vector2Int(width, height);
- case Dir.Right: return new Vector2Int(height, 0);
- }
- }
- public List<Vector2Int> GetGridPositionList(Vector2Int offset, Dir dir)
- {
- List<Vector2Int> gridPositionList = new List<Vector2Int>();
- switch (dir)
- {
- default:
- case Dir.Down:
- case Dir.Up:
- for(int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- gridPositionList.Add(offset + new Vector2Int(x, y));
- }
- }
- break;
- case Dir.Left:
- case Dir.Right:
- for (int x = 0; x < height; x++)
- {
- for (int y = 0; y < width; y++)
- {
- gridPositionList.Add(offset + new Vector2Int(x, y));
- }
- }
- break;
- }
- return gridPositionList;
- }
- public bool CanPlaceObject(Grid<GridObject> grid, Vector3 worldPos, PlacedObjectType.Dir dir)
- {
- grid.GetGridPosition(worldPos, out int x, out int y);
- return CanPlaceObject(grid, x, y, dir);
- }
- public bool CanPlaceObject(Grid<GridObject> grid, int x, int y, PlacedObjectType.Dir dir)
- {
- return EvaluateRuleset(grid, x, y, dir);
- }
- public bool EvaluateRuleset(Grid<GridObject> grid, int x, int y, PlacedObjectType.Dir dir)
- {
- List<bool> results = new List<bool>();
- for (int i = 0; i < ruleset.Count; i++)
- {
- results.Add(ruleset[i].Evaluate(grid, this, x, y, dir));
- }
- if(rulesetCondition == ConditionType.AND)
- {
- foreach (var value in results)
- {
- if(value == false) return false;
- }
- return true;
- }
- else
- {
- foreach (var value in results)
- {
- if(value == true) return true;
- }
- return false;
- }
- }
- public List<PlaceableObjectRule> GetRulesetError(Grid<GridObject> grid, int x, int y, PlacedObjectType.Dir dir)
- {
- List<PlaceableObjectRule> brokenRules = new List<PlaceableObjectRule>();
- for (int i = 0; i < ruleset.Count; i++)
- {
- for (int a = 0; a < ruleset[i].rules.Count; a++)
- {
- bool result = ruleset[i].rules[a].Evaluate(grid, this, x, y, dir);
- if(result == false) brokenRules.Add(ruleset[i].rules[a]);
- }
- }
- return brokenRules;
- }
- public Vector2Int GetConnectorPositionOffset(int index, PlacedObjectType.Dir dir)
- {
- PlaceableObjectConnector connector = connectors[index];
- switch (dir)
- {
- default:
- case Dir.Down: return connector.position;
- case Dir.Left: return new Vector2Int(connector.position.y, (connector.position.x * -1) + width - 1);
- case Dir.Up: return new Vector2Int((connector.position.x * -1) + width - 1, (connector.position.y * -1) + height - 1);
- case Dir.Right: return new Vector2Int((connector.position.y * -1) + height - 1, connector.position.x);
- }
- }
- public Vector2Int GetConnectorTargetPositionOffset(int index, PlacedObjectType.Dir objectDir)
- {
- var targetDir = connectors[index].dir;
- return GetPositionOffsetFromDirection(objectDir, targetDir);
- }
- public Vector2Int GetPositionOffsetFromDirection(PlacedObjectType.Dir objectDir, PlacedObjectType.Dir targetDir)
- {
- switch (objectDir)
- {
- default:
- case Dir.Down:
- switch (targetDir)
- {
- default:
- case Dir.Down: return new Vector2Int(0, -1);
- case Dir.Left: return new Vector2Int(-1, 0);
- case Dir.Up: return new Vector2Int(0, 1);
- case Dir.Right: return new Vector2Int(1, 0);
- }
- case Dir.Left:
- switch (targetDir)
- {
- default:
- case Dir.Down: return new Vector2Int(-1, 0);
- case Dir.Left: return new Vector2Int(0, 1);
- case Dir.Up: return new Vector2Int(1, 0);
- case Dir.Right: return new Vector2Int(0, -1);
- }
- case Dir.Up:
- switch (targetDir)
- {
- default:
- case Dir.Down: return new Vector2Int(0, 1);
- case Dir.Left: return new Vector2Int(1, 0);
- case Dir.Up: return new Vector2Int(0, -1);
- case Dir.Right: return new Vector2Int(-1, 0);
- }
- case Dir.Right:
- switch (targetDir)
- {
- default:
- case Dir.Down: return new Vector2Int(1, 0);
- case Dir.Left: return new Vector2Int(0, -1);
- case Dir.Up: return new Vector2Int(-1, 0);
- case Dir.Right: return new Vector2Int(0, 1);
- }
- }
- }
- private void SetupContext()
- {
- if(context == null) return;
- onCreateController.context = context;
- onUpdateController.context = context;
- onRemoveController.context = context;
- for (int i = 0; i < objectActions.Count; i++)
- {
- if(objectActions[i] != null) objectActions[i].actions.context = context;
- }
- if(!context.HasVariable("Building GameObject"))
- {
- var variable = new GameActionContextGameObject();
- variable.name = "Building GameObject";
- variable.value = null;
- variable.canEdit = false;
- context.variables.Add(variable);
- }
- }
- public Vector2Int OffsetValue(Vector2Int offset, Dir dir)
- {
- switch (dir)
- {
- default:
- case Dir.Down: return new Vector2Int(offset.x, offset.y);
- case Dir.Left: return new Vector2Int(offset.y, offset.x * -1);
- case Dir.Up: return new Vector2Int(offset.x * -1, offset.y * -1);
- case Dir.Right: return new Vector2Int(offset.y * -1, offset.x);
- }
- }
- }
- }
|