protected IEnumerator ConsiderOptions() { //we care about luminite more than meteors //and meteors more than other things //if we're hostile then we care about that before items of interest if (worlditem.Is <Hostile> (out hostile)) { if (HasThingToInvestigate && hostile.PrimaryTarget != ThingToInvestigate) { //maybe the thing we want to investigate is closer than the target if (Vector3.Distance(ThingToInvestigate.Position, worlditem.Position) < Vector3.Distance(hostile.PrimaryTarget.Position, worlditem.Position)) { //Debug.Log ("Orb is more interested in thing than in hostile target, going for hostile target"); //finish being hostile, check out the thing instead hostile.Finish(); //wait for the hostile to finish yield return(null); } } else if (hostile.TimeSinceAdded > Creature.ShortTermMemoryToRT(creature.Template.Props.ShortTermMemory)) { //bored now! hostile.Finish(); } else { //keep being hostile for now yield break; } } double waitUntil = WorldClock.AdjustedRealTime + 0.05f + UnityEngine.Random.value; while (WorldClock.AdjustedRealTime < waitUntil) { yield return(null); } yield return(null); if (HasThingToInvestigate) { OrbSpeak(OrbSpeakUnit.TargetIsStrangeInvestigatingTarget, worlditem.tr); BehaviorState = OrbBehaviorState.SeekingItemOfInterest; } else if (HasLuminiteToGather) { OrbSpeak(OrbSpeakUnit.DetectedLuminiteInRawState, worlditem.tr); if (Vector3.Distance(LuminiteToGather.worlditem.Position, worlditem.Position) < motile.State.MotileProps.RVORadius * 5) { BehaviorState = OrbBehaviorState.EatingLuminite; } else { BehaviorState = OrbBehaviorState.SeekingLuminite; } } else if (HasMeteorToGather) { OrbSpeak(OrbSpeakUnit.TargetIsStrangeInvestigatingTarget, worlditem.tr); if (Vector3.Distance(MeteorToGather.worlditem.Position, worlditem.Position) < motile.State.MotileProps.RVORadius * 5) { BehaviorState = OrbBehaviorState.EatingMeteor; } else { BehaviorState = OrbBehaviorState.SeekingMeteor; } } else { //we don't have a thing to investigate, a meteor to grab or luminite to gather Meteor closestMeteor = null; Meteor meteorToCheck = null; float closestSoFar = Mathf.Infinity; float current = 0f; for (int i = 0; i < Meteors.Get.MeteorsSpawned.Count; i++) { current = Vector3.Distance(Meteors.Get.MeteorsSpawned [i].worlditem.Position, worlditem.Position); if (current < closestSoFar) { meteorToCheck = Meteors.Get.MeteorsSpawned [i]; if (meteorToCheck.IncomingGatherer != null && meteorToCheck.IncomingGatherer != this) { //better check if we're closer if (Vector3.Distance(meteorToCheck.IncomingGatherer.Position, meteorToCheck.worlditem.Position) > current) { //we're stealing this closestSoFar = current; closestMeteor = meteorToCheck; } } else { closestSoFar = current; closestMeteor = meteorToCheck; } } } if (closestMeteor != null) { OrbSpeak(OrbSpeakUnit.DetectedLuminiteInRefinedState, worlditem.tr); MeteorToGather = closestMeteor; BehaviorState = OrbBehaviorState.SeekingMeteor; } yield return(null); } yield break; }
public void OnCollectiveThoughtStart() { IItemOfInterest ioi = creature.CurrentThought.CurrentItemOfInterest; if (ioi == mMeteorToGather || ioi == mLuminiteToGather || ioi == mThingToInvestigate) { return; } switch (BehaviorState) { case OrbBehaviorState.Burrowing: case OrbBehaviorState.Despawning: case OrbBehaviorState.Unpowered: case OrbBehaviorState.EatingLuminite: case OrbBehaviorState.EatingMeteor: default: return; case OrbBehaviorState.ConsideringOptions: case OrbBehaviorState.Awakening: if (ioi.IOIType == ItemOfInterestType.Player || ioi != null && ioi.HasAtLeastOne(ThingsOrbsFindInteresting)) { ThingToInvestigate = ioi; } break; case OrbBehaviorState.SeekingLuminite: case OrbBehaviorState.SeekingMeteor: if (ioi.IOIType == ItemOfInterestType.Player || ioi != null && ioi.HasAtLeastOne(ThingsOrbsFindInteresting)) { //stop and consider the thing for a moment against our other options ThingToInvestigate = ioi; } BehaviorState = OrbBehaviorState.ConsideringOptions; break; } //see what we're doing if (worlditem.Is <Hostile> (out hostile)) { return; } //ignore it by default creature.CurrentThought.Should(IOIReaction.IgnoreIt); if (ioi == damageable.LastDamageSource) { //always attack a threat creature.CurrentThought.Should(IOIReaction.KillIt, 3); OrbSpeak(OrbSpeakUnit.TargetIsHostileEngagingTarget, worlditem.tr); return; } else { //see if it's something we care about if (ioi.Has("Luminite")) { Luminite luminite = ioi.worlditem.Get <Luminite> (); //if we're already gathering luminite if (HasLuminiteToGather) { if (mLuminiteToGather == luminite) { //d'oh, already gathering, forget it return; } //go for the closer one if (Vector3.Distance(luminite.worlditem.Position, worlditem.Position) < Vector3.Distance(LuminiteToGather.worlditem.Position, worlditem.Position)) { LuminiteToGather = luminite; BehaviorState = OrbBehaviorState.ConsideringOptions; } } else { LuminiteToGather = luminite; LuminiteToGather.IncomingGatherer = this.worlditem; BehaviorState = OrbBehaviorState.ConsideringOptions; } } else if (ioi.Has("Meteor")) { Meteor meteor = ioi.worlditem.Get <Meteor> (); if (HasMeteorToGather) { if (mMeteorToGather == meteor) { //d'oh, already gathering, forget it return; } //go for the closer one if (Vector3.Distance(meteor.worlditem.Position, worlditem.Position) < Vector3.Distance(MeteorToGather.worlditem.Position, worlditem.Position)) { MeteorToGather = meteor; BehaviorState = OrbBehaviorState.ConsideringOptions; } } else { MeteorToGather = meteor; BehaviorState = OrbBehaviorState.ConsideringOptions; } } else { //see if it has any of the things we care about if (ioi.IOIType == ItemOfInterestType.Player || ioi.HasAtLeastOne(ThingsOrbsFindInteresting)) { ThingToInvestigate = ioi; BehaviorState = OrbBehaviorState.ConsideringOptions; } } } }