void RunResponse(RSResponse response, RSManager manager, ref RSQuery query, GameObject gameObject) { // update response's dontResayBefore timer and disabled bool // based on response's norepeat flag response.JustFired(); if (this.flags.HasFlag(RSResponseGroupFlags.PermitRepeats)) { //TODO(dan): if this response is First, we should have a // special bool on the response called CanBeFirst, which we // set to false here, so that this response is no longer // marked as the 'first' response to call. because it // already has been. // maybe it'd be worth just disabling the response right now // if it has the first flag, but I'd need to try out the system // to figure out whether that's the most intuiative way to // handle this certain combination of flags: // group[PermitRepeats] response[First] // // though to be honest, having a NoRepeat flag on the response // would deliver the above proposed functionality, so it // instead probably makes sense to do the CanBeFirst thing. return; } bool anyResponsesYetToFire = false; foreach (var ri in this.responses) { if (!ri.Disabled) { anyResponsesYetToFire = true; break; } } if (!anyResponsesYetToFire) { if (this.flags.HasFlag(RSResponseGroupFlags.NoRepeat)) { this.disabled = true; return; } // reset all resettable responses because we're bloody out foreach (var ri in this.responses) { if (!ri.Flags.HasFlag(RSResponseFlags.NoRepeat)) { ri.Disabled = false; } } } // actually run the response and do response-like things for it. manager.DispatchResponse(response, ref query, gameObject); }
public void Run(ref RSQuery query, RSManager manager, GameObject gameObject) { // simple, run the first rule that matches. // this will always be the most specific rule because of how we // insert rules into our bucket. foreach (var rule in this.rules) { if (rule.Run(ref query, manager, gameObject)) { break; } } }
public bool Run(RSManager manager, ref RSQuery query, GameObject gameObject) { // we've got NoRepeat and have been disabled if (this.disabled) { return(false); } Debug.Log("Running ResponseGroup called " + this.Name); if (this.firstResponse != null) { RSResponse firstResponse = this.responses[(int)this.firstResponse]; if (firstResponse.CanFire()) { this.RunResponse(firstResponse, manager, ref query, gameObject); return(true); } } RSResponse lastResponse = null; if (this.lastResponse != null) { lastResponse = this.responses[(int)this.lastResponse]; // confirm that no other un-disabled responses can be run bool anyOtherResponsesCanFire = false; foreach (var response in this.responses) { if (!response.Disabled) { anyOtherResponsesCanFire = true; break; } } if (!anyOtherResponsesCanFire && lastResponse.CanFire()) { this.RunResponse(lastResponse, manager, ref query, gameObject); return(true); } // going forward in this function, lastResponse is one that we // shouldn't call because if we were to call it it would've // already happened above ^ } if (this.flags.HasFlag(RSResponseGroupFlags.Sequential)) { // run responses sequentially foreach (var response in this.responses) { if (response.CanFire()) { this.RunResponse(response, manager, ref query, gameObject); return(true); } } } else { // get a random response, weighted appropriately, and fire it. float totalWeight = 0; RSResponse finalResponseWeSaw = null; foreach (var response in this.responses) { if (response != lastResponse && response.CanFire()) { totalWeight += response.Weight; finalResponseWeSaw = response; } } if (finalResponseWeSaw == null) { // no valid responses return(false); } float weight = UnityEngine.Random.Range(0F, totalWeight); foreach (var response in this.responses) { if (response == lastResponse) { continue; } if (response.CanFire()) { weight -= response.Weight; } if (weight <= 0 || response == finalResponseWeSaw) { this.RunResponse(response, manager, ref query, gameObject); return(true); } } } return(false); }