| | | 1 | | using System.Collections.Generic; |
| | | 2 | | using UnityEngine; |
| | | 3 | | using System.Collections; |
| | | 4 | | |
| | | 5 | | public class Fire : MonoBehaviour, IWaterInteractable |
| | | 6 | | { |
| | | 7 | | [Header("Debug")] |
| | 54 | 8 | | public bool debug = false; |
| | | 9 | | |
| | | 10 | | [Header("State")] |
| | 54 | 11 | | public bool isOn = false; |
| | 54 | 12 | | public float timeToOnMin = 3f; |
| | 54 | 13 | | public float timeToOnMax = 3f; |
| | | 14 | | public float timeToOn; |
| | | 15 | | [SerializeField] |
| | 54 | 16 | | private float timeToOnDelta = 0f; |
| | | 17 | | [SerializeField] |
| | 54 | 18 | | private bool shouldTurnOn = false; |
| | | 19 | | |
| | | 20 | | [Header("Neighbors")] |
| | | 21 | | [SerializeField] |
| | 54 | 22 | | private int onNeighbors = 0; |
| | 54 | 23 | | private bool hasDownNeighbor = false; |
| | 54 | 24 | | public float maxNeighborDistance = 4f; |
| | | 25 | | [Range(1f, 3f)] |
| | 54 | 26 | | public float downMultiplier = 1f; |
| | 54 | 27 | | public float downNeighborDist = 0.5f; |
| | | 28 | | |
| | | 29 | | [Header("Fire Turning Off")] |
| | 54 | 30 | | private bool isTurningOff = false; |
| | 54 | 31 | | public float maxHitInterval = 2f; |
| | 54 | 32 | | public float currentHitInterval = 0f; |
| | 54 | 33 | | public float totalHitTime = 10f; |
| | 54 | 34 | | public float currentHitTime = 0f; |
| | | 35 | | |
| | | 36 | | [Header("Neighbors")] |
| | | 37 | | // This list shouldn't be initialized in the code |
| | | 38 | | // We can leave it like this, in case the programmer decides to manually input some of them |
| | | 39 | | public List<Fire> neighbors; |
| | 54 | 40 | | public int onNeighborsThreshold = 2; |
| | 54 | 41 | | public float minNeighborDownDistance = 3f; |
| | | 42 | | |
| | | 43 | | [Header("Particle System")] |
| | | 44 | | public GameObject mainEffectGo; |
| | | 45 | | private ParticleSystem pSystem; |
| | | 46 | | |
| | | 47 | | void Awake() |
| | 27 | 48 | | { |
| | 27 | 49 | | this.pSystem = this.mainEffectGo.GetComponent<ParticleSystem>(); |
| | 27 | 50 | | this.timeToOn = Random.Range(this.timeToOnMin, this.timeToOnMax); |
| | 27 | 51 | | } |
| | | 52 | | |
| | | 53 | | void Update() |
| | 597375 | 54 | | { |
| | | 55 | | // Handle turning on |
| | 597375 | 56 | | if (this.shouldTurnOn && !this.isOn) |
| | 4369 | 57 | | { |
| | 4369 | 58 | | this.timeToOnDelta += (Time.deltaTime * (this.hasDownNeighbor ? this.downMultiplier : 1f)); |
| | | 59 | | // If over the limit with the neighbors |
| | 4369 | 60 | | if (this.timeToOnDelta >= this.timeToOn) |
| | 4 | 61 | | { |
| | 4 | 62 | | this.isOn = true; |
| | 4 | 63 | | this.shouldTurnOn = false; |
| | 4 | 64 | | this.timeToOnDelta = 0f; |
| | 4 | 65 | | this.isTurningOff = false; |
| | 4 | 66 | | this.currentHitTime = 0f; |
| | 4 | 67 | | this.UpdateFireState(true); |
| | 4 | 68 | | } |
| | 4369 | 69 | | } |
| | | 70 | | // Handle turning off |
| | 597375 | 71 | | if (this.isTurningOff && this.isOn) { |
| | | 72 | | // Add to the timers |
| | 0 | 73 | | this.currentHitTime += Time.deltaTime; |
| | 0 | 74 | | this.currentHitInterval += Time.deltaTime; |
| | | 75 | | // If the current interval timer is larger than the limit, it stops turning off |
| | 0 | 76 | | if (this.currentHitInterval >= this.maxHitInterval) { |
| | 0 | 77 | | this.isTurningOff = false; |
| | 0 | 78 | | this.currentHitTime = 0f; |
| | 0 | 79 | | } else if (this.currentHitTime >= this.totalHitTime) { |
| | | 80 | | // Fire turns off |
| | 0 | 81 | | this.isOn = false; |
| | 0 | 82 | | this.shouldTurnOn = false; |
| | 0 | 83 | | this.timeToOnDelta = 0f; |
| | 0 | 84 | | this.isTurningOff = false; |
| | 0 | 85 | | this.currentHitTime = 0f; |
| | 0 | 86 | | this.UpdateFireState(true); |
| | 0 | 87 | | } |
| | 0 | 88 | | } |
| | 597375 | 89 | | } |
| | | 90 | | |
| | | 91 | | public void NotifyNeighborState(bool fireOn) |
| | 15 | 92 | | { |
| | | 93 | | // Update the count |
| | 30 | 94 | | if (fireOn) this.onNeighbors++; |
| | 0 | 95 | | else this.onNeighbors--; |
| | 15 | 96 | | this.CheckNeighborState(); |
| | 15 | 97 | | } |
| | | 98 | | |
| | | 99 | | /* ------------------------------------------------------------------------------ */ |
| | | 100 | | /* STATE */ |
| | | 101 | | /* ------------------------------------------------------------------------------ */ |
| | | 102 | | |
| | | 103 | | public void UpdateFireState(bool notify) |
| | 31 | 104 | | { |
| | 31 | 105 | | if (this.isOn) |
| | 24 | 106 | | { |
| | 24 | 107 | | this.pSystem.Play(); |
| | 24 | 108 | | } |
| | | 109 | | else |
| | 7 | 110 | | { |
| | 7 | 111 | | this.pSystem.Stop(); |
| | 7 | 112 | | } |
| | 31 | 113 | | if (notify) |
| | 4 | 114 | | { |
| | 4 | 115 | | this.NotifyAllNeighbors(); |
| | 4 | 116 | | FireController.Instance.FireChanged(this.isOn ? 1 : -1); |
| | 4 | 117 | | } |
| | 31 | 118 | | } |
| | | 119 | | |
| | | 120 | | public void WaterHit(Vector3 normal) |
| | | 121 | | { |
| | | 122 | | // Reset timer when hit |
| | | 123 | | this.isTurningOff = true; |
| | | 124 | | this.currentHitInterval = 0f; |
| | | 125 | | } |
| | | 126 | | |
| | | 127 | | // Method to externally turn on the fire, without notifying the neighbors |
| | | 128 | | public void SetIsOn(bool _isOn) |
| | 27 | 129 | | { |
| | 27 | 130 | | this.isOn = _isOn; |
| | 27 | 131 | | this.UpdateFireState(false); |
| | 27 | 132 | | } |
| | | 133 | | |
| | | 134 | | /* ------------------------------------------------------------------------------ */ |
| | | 135 | | /* NEIGHBORS */ |
| | | 136 | | /* ------------------------------------------------------------------------------ */ |
| | | 137 | | |
| | | 138 | | public void FindNeighbors(Fire[] allFires, int fireId) |
| | 27 | 139 | | { |
| | | 140 | | // Count how many of the neighbors are on |
| | 27 | 141 | | this.onNeighbors = 0; |
| | | 142 | | // Find all the neighbors within the given distance |
| | 1512 | 143 | | for (int i = 0; i < allFires.Length; i++) |
| | 729 | 144 | | { |
| | | 145 | | // If neighbor is within distance, add it |
| | 729 | 146 | | if (i != fireId && Vector3.Distance(this.gameObject.transform.position, allFires[i].gameObject.transform.pos |
| | 72 | 147 | | { |
| | 72 | 148 | | neighbors.Add(allFires[i]); |
| | 72 | 149 | | if (allFires[i].isOn) |
| | 52 | 150 | | { |
| | 52 | 151 | | this.onNeighbors++; |
| | 52 | 152 | | } |
| | 72 | 153 | | } |
| | 729 | 154 | | } |
| | | 155 | | // Check on the neighbor state |
| | 27 | 156 | | this.CheckNeighborState(); |
| | 27 | 157 | | } |
| | | 158 | | |
| | | 159 | | private void CheckNeighborState() |
| | 42 | 160 | | { |
| | | 161 | | /* |
| | | 162 | | If we are over the neighbor limit, the fire is off and is not turning on, |
| | | 163 | | it should start counting |
| | | 164 | | */ |
| | 42 | 165 | | if (this.onNeighbors >= this.onNeighborsThreshold) |
| | 34 | 166 | | { |
| | 34 | 167 | | if (!this.isOn && !this.shouldTurnOn) |
| | 4 | 168 | | { |
| | 4 | 169 | | this.shouldTurnOn = true; |
| | 4 | 170 | | this.timeToOnDelta = 0f; |
| | | 171 | | // Find if any of the neihbors is down |
| | 4 | 172 | | this.hasDownNeighbor = false; |
| | 57 | 173 | | foreach (Fire neighbor in this.neighbors) { |
| | 15 | 174 | | this.hasDownNeighbor = this.hasDownNeighbor || (this.transform.position.y - neighbor.transform.posit |
| | 15 | 175 | | } |
| | 4 | 176 | | } |
| | 34 | 177 | | } |
| | | 178 | | else |
| | 8 | 179 | | { |
| | 8 | 180 | | this.shouldTurnOn = false; |
| | 8 | 181 | | this.timeToOnDelta = 0f; |
| | 8 | 182 | | } |
| | 42 | 183 | | } |
| | | 184 | | |
| | | 185 | | private void NotifyAllNeighbors() |
| | 4 | 186 | | { |
| | 57 | 187 | | foreach (Fire fire in this.neighbors) fire.NotifyNeighborState(this.isOn); |
| | 4 | 188 | | } |
| | | 189 | | |
| | | 190 | | /* ------------------------------------------------------------------------------ */ |
| | | 191 | | /* DEBUG */ |
| | | 192 | | /* ------------------------------------------------------------------------------ */ |
| | | 193 | | |
| | | 194 | | void OnDrawGizmosSelected() |
| | | 195 | | { |
| | | 196 | | if (debug) |
| | | 197 | | { |
| | | 198 | | // Display the explosion radius when selected |
| | | 199 | | Gizmos.color = Color.red; |
| | | 200 | | Gizmos.DrawWireSphere(this.transform.position, this.maxNeighborDistance); |
| | | 201 | | } |
| | | 202 | | } |
| | | 203 | | |
| | | 204 | | private IEnumerator TurnOffSprite() |
| | | 205 | | { |
| | | 206 | | Component[] particleSystems = GetComponentsInChildren(typeof(ParticleSystem)); |
| | | 207 | | for (int i = 0; i < 10; i++) |
| | | 208 | | { |
| | | 209 | | for(int s=0; s < particleSystems.Length; s++) |
| | | 210 | | { |
| | | 211 | | ParticleSystem system = (ParticleSystem)particleSystems[s]; |
| | | 212 | | ParticleSystem.MainModule main = system.main; |
| | | 213 | | main.maxParticles = system.main.maxParticles / 2; |
| | | 214 | | yield return new WaitForSeconds(0.01f); |
| | | 215 | | } |
| | | 216 | | } |
| | | 217 | | this.pSystem.Stop(); |
| | | 218 | | for (int s = 0; s < particleSystems.Length; s++) |
| | | 219 | | { |
| | | 220 | | ParticleSystem system = (ParticleSystem)particleSystems[s]; |
| | | 221 | | system.Stop(); |
| | | 222 | | } |
| | | 223 | | } |
| | | 224 | | |
| | | 225 | | private IEnumerator TurnOnSprite() |
| | | 226 | | { |
| | | 227 | | Component[] particleSystems = GetComponentsInChildren(typeof(ParticleSystem)); |
| | | 228 | | for (int s = 0; s < particleSystems.Length; s++) |
| | | 229 | | { |
| | | 230 | | ParticleSystem system = (ParticleSystem)particleSystems[s]; |
| | | 231 | | ParticleSystem.MainModule main = system.main; |
| | | 232 | | main.maxParticles = 1000; |
| | | 233 | | } |
| | | 234 | | this.pSystem.Play(); |
| | | 235 | | for (int s = 0; s < particleSystems.Length; s++) |
| | | 236 | | { |
| | | 237 | | ParticleSystem system = (ParticleSystem)particleSystems[s]; |
| | | 238 | | system.Play(); |
| | | 239 | | } |
| | | 240 | | yield return new WaitForSeconds(0.01f); |
| | | 241 | | } |
| | | 242 | | |
| | | 243 | | |
| | | 244 | | } |