public static IEnumerator UpdateFleeGoal(Motile m, MotileAction action)
        {
            m.TargetMovementSpeed = m.State.MotileProps.SpeedRun;

            if (action.LiveTarget == null)
            {
                action.TryToFinish();
                yield break;
            }

            if (m.AvoidingObstacle)
            {
                yield break;
            }

            mAvoid         = action.LiveTarget.Position;
            mFleeDirection = (m.LastKnownPosition - mAvoid).normalized;
            mGoalPosition  = m.LastKnownPosition;

            if (action.TerritoryType == MotileTerritoryType.Den)
            {
                //chose a position that's within the den radius
                float distanceToDenEdge = Vector3.Distance(action.TerritoryBase.Position, m.LastKnownPosition);
                mGoalPosition = m.LastKnownPosition + (mFleeDirection * Mathf.Min(distanceToDenEdge, action.Range));
            }
            else
            {
                //just move the goal
                mGoalPosition = m.LastKnownPosition + (mFleeDirection * action.Range);
            }
            mRandomTerrainHit.groundedHeight = m.terrainHit.groundedHeight;
            mRandomTerrainHit.overhangHeight = m.terrainHit.overhangHeight;
            mRandomTerrainHit.feetPosition   = mGoalPosition;
            mGoalPosition.y       = GameWorld.Get.TerrainHeightAtInGamePosition(ref mRandomTerrainHit);
            m.GoalObject.position = mGoalPosition;
            double finishTime = WorldClock.AdjustedRealTime + 0.1f;

            while (WorldClock.AdjustedRealTime < finishTime)
            {
                yield return(null);
            }

            yield break;
        }
Exemple #2
0
        public bool TryToOccupyNode(WorldItem newOccupant)
        {
            if (newOccupant == mReservant)
            {
                mOccupant = mReservant;
                return(true);
            }

            if (!CanOccupy(newOccupant) || !HasOccupantReached(newOccupant))                                      //whoops, we either can't use this or we're too far away
            {
                return(false);
            }

            if (HasOccupant && newOccupant != mOccupant)                                      //if we've made it this far and we have an occupant
            //they need to be displaced
            {
                VacateNode(mOccupant);
            }

            //hooray we're the new occupant
            State.NumTimesOccupied++;
            mOccupant = newOccupant;
            if (State.OccupantName == mOccupant.FileName)                                      //if we match the specific occupant for this node
            {
                State.NumTimesOccupiedSpecific++;
            }

            if (!mSendingEvents)
            {
                StartCoroutine(SendEvents(ActionNodeBehavior.OnOccupy));
            }

            //align to action node direction
            //load custom animation
            //if we have a speech, this will be overridden
            Motile motile = null;

            if (mOccupant.Is <Motile>(out motile))
            {
                //if we told the occupant to come here
                MotileAction topAction = motile.TopAction;
                if (topAction.Type == MotileActionType.GoToActionNode &&
                    topAction.LiveTarget == this)                                                       //finish the action
                {
                    topAction.TryToFinish();
                }
            }

            //alrighty time for the speech givin'
            //see if this new occupant is talkative
            Talkative talkative = null;

            if (mOccupant.Is <Talkative>(out talkative))
            {
                Speech speech      = null;
                bool   foundSpeech = false;
                switch (State.Speech)
                {
                case ActionNodeSpeech.None:
                default:
                    //there'll be no speechifying today
                    break;

                case ActionNodeSpeech.RandomAnyone:
                    //use speech flags to pull a random speech for anyone who uses this node
                    //not implemented
                    break;

                case ActionNodeSpeech.CustomAnyone:
                    //use speech flags to pull a specified speech for anyone who uses this node
                    //not implemented
                    break;

                case ActionNodeSpeech.RandomCharOnly:
                    //use speech flags to pull a random speech for the specific character that uses this node
                    //not implemented
                    break;

                case ActionNodeSpeech.CustomCharOnly:
                    //use speech flags to pull a specified speech for the specific character that uses this node
                    foundSpeech = Mods.Get.Runtime.LoadMod <Speech>(ref speech, "Speech", State.CustomSpeech);
                    break;

                case ActionNodeSpeech.SequenceCharOnly:
                    //use the custom speech name to get the next speech in a sequence
                    string speechName          = State.CustomSpeech;
                    int    currentSpeechNumber = 1;
                    bool   keepLooking         = true;
                    //TODO look into putting this in Talkative
                    while (keepLooking)                                                                              //get the next speech
                    {
                        speechName = State.CustomSpeech.Replace("[#]", currentSpeechNumber.ToString());
                        if (Mods.Get.Runtime.LoadMod <Speech>(ref speech, "Speech", speechName))                                                                                          //load the speech and see if it's been given by our character
                        {
                            int numTimesStartedBy = speech.NumTimesStartedBy(mOccupant.FileName);
                            if (numTimesStartedBy <= 0)                                                                                                      //if the speech hasn't been started by this character before, use it
                            {
                                keepLooking = false;
                                foundSpeech = true;
                            }
                            else                                                                                                        //otherwise increment the speech number and keep looking
                            {
                                currentSpeechNumber++;
                            }
                        }
                        else                                                                                            //no more speeches to try, oh well
                        {
                            keepLooking = false;
                        }
                    }
                    break;
                }

                if (foundSpeech)
                {
                    talkative.GiveSpeech(speech, this);
                }
            }
            //if we've gotten this far we're golden
            return(true);
        }