public virtual void DispatchResponse(RSResponse response, ref RSQuery query, GameObject gameObject) { // just dispatch it to the entity who's having the response. if // managers want to they can override this later. RSEntity entity = gameObject.GetComponent(typeof(RSEntity)) as RSEntity; entity.DispatchResponse(response, ref query); }
// Start is called before the first frame update void Start() { // load all response system info from our csv files. //TODO(dan): this is probably very slow? we could create caches split // up by our bucket keys automagically, that will be regenerated // automagically if either our bucket keys change or the source csv // files change. Or something, idk. //TODO(dan): depending on how much our files expand, we could just skip // lines in the csv that don't apply to the current RSManager, given // that they're scene-specific. Eh, worry about that later when we // actually have enough content for it to affect us in a real way. DirectoryInfo rootdi = new DirectoryInfo(Path.Combine(Application.dataPath, rootRSFolder)); foreach (var di in rootdi.EnumerateDirectories()) { foreach (var fi in di.EnumerateFiles()) { switch (fi.Name) { case "concepts.csv": this.LoadConceptsCSV(fi.FullName); break; case "criteria.csv": this.LoadCriteriaCSV(fi.FullName); break; case "responses.csv": this.LoadResponsesCSV(fi.FullName); break; case "rules.csv": this.LoadRulesCSV(fi.FullName); break; } } } // init all entities for idling. foreach (GameObject entityGO in GameObject.FindGameObjectsWithTag("ResponseSystemEntity")) { RSEntity entity = entityGO.GetComponent(typeof(RSEntity)) as RSEntity; if (entity.canIdle) { Debug.Log("Found idling entity " + entity.Name); var idleTime = DateTime.Now.AddSeconds(entity.secondsBetweenIdle + UnityEngine.Random.Range(entity.idleJitter * -1, entity.idleJitter)); this.entityNextIdleTime.Add(entityGO, idleTime); } } // populate our base facts this.InitFacts(); // spin off idle coroutine StartCoroutine("IdleLoop"); }
IEnumerator IdleLoop() { GameObject nextIdlingEntity = null; while (true) { if (nextIdlingEntity != null) { RSEntity entity = nextIdlingEntity.GetComponent(typeof(RSEntity)) as RSEntity; // update idle time var nextIdleTime = DateTime.Now.AddSeconds(entity.secondsBetweenIdle + UnityEngine.Random.Range(entity.idleJitter * -1, entity.idleJitter)); this.entityNextIdleTime[nextIdlingEntity] = nextIdleTime; // actually make the entity idle Debug.Log("entity " + entity.Name + " is idling"); var query = new RSQuery(); query.Set("concept", "idle"); query.Set("who", entity.Name); entity.UpdateFacts(); query.AddFactDictionary(ref entity.Facts); this.UpdateFacts(); query.AddFactDictionary(ref this.Facts); this.Run(ref query, nextIdlingEntity); } // find next idling entity DateTime idleTime = DateTime.MaxValue; foreach (KeyValuePair <GameObject, DateTime> val in this.entityNextIdleTime) { if (val.Value.CompareTo(idleTime) < 0) { idleTime = val.Value; nextIdlingEntity = val.Key; } } float idleSecs = (float)idleTime.Subtract(DateTime.Now).TotalSeconds; if (this.idleMungeSeconds < idleSecs) { yield return(new WaitForSeconds(idleSecs)); } else { yield return(null); } } }