예제 #1
0
        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);
        }
예제 #2
0
 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;
         }
     }
 }
예제 #3
0
        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);
        }