protected IEnumerator UpdateTraps() { while (Traps.Count > 0) { //Debug.Log("Updating traps: " + Traps.Count.ToString()); for (int i = Traps.LastIndex(); i >= 0; i--) { //Debug.Log("Checking trap"); ITrap trap = Traps[i]; if (trap == null) { Traps.RemoveAt(i); } else if (trap.IsFinished || trap.Mode != TrapMode.Set) { trap.SkillUpdating = false; Traps.RemoveAt(i); } else { //okay, the trap is set and it's not finished and it has intersecting dens for (int j = trap.IntersectingDens.LastIndex(); j >= 0; j--) { ICreatureDen den = trap.IntersectingDens[j]; if (den == null || den.IsFinished) { trap.IntersectingDens.RemoveAt(j); } else if (trap.CanCatch.Count > 0 && !trap.CanCatch.Contains(den.NameOfCreature) || trap.Exceptions.Count > 0 && trap.Exceptions.Contains(den.NameOfCreature)) { //make sure this trap can actually catch what's in it trap.IntersectingDens.RemoveAt(j); } else { //is it time to check this trap yet? is the player nearby? if ((WorldClock.AdjustedRealTime - trap.TimeLastChecked) > Globals.TrappingMinimumRTCheckInterval) { bool readyToCheck = true; if (trap.RequiresMinimumPlayerDistance && Vector3.Distance(Player.Local.Position, trap.Owner.tr.position) < Globals.TrappingMinimumCorpseSpawnDistance) { readyToCheck = false; } if (readyToCheck) { trap.TimeLastChecked = WorldClock.AdjustedRealTime; //odds of catching something increases over time float oddsOfCatchingSomething = trap.SkillOnSet; double timeSinceSet = WorldClock.AdjustedRealTime - trap.TimeSet; oddsOfCatchingSomething = Mathf.Clamp01((float)(oddsOfCatchingSomething + (Globals.TrappingOddsTimeMultiplier * timeSinceSet))); //okay, figure out how close to the den we are float distanceToCenterOfDen = Vector3.Distance(trap.Owner.tr.position, den.transform.position); float distanceToDen = distanceToCenterOfDen - den.Radius; float trapRadius = Skill.SkillEffectRadius( Effects.UnskilledEffectRadius, Effects.SkilledEffectRadius, Effects.MasteredEffectRadius, trap.SkillOnSet, //this is the only difference between this & a normal skill check State.HasBeenMastered); if (trapRadius >= distanceToCenterOfDen) { //wuhoo, huge bonus odds! oddsOfCatchingSomething = Mathf.Clamp01(oddsOfCatchingSomething * Globals.TrappingOddsDistanceMultiplier); } else if (trapRadius >= distanceToDen) { //okay, no huge bonus but still cool } else { oddsOfCatchingSomething = 0f; } if (oddsOfCatchingSomething > 0f && UnityEngine.Random.value < oddsOfCatchingSomething) { Debug.Log("Caught something at creature den"); if (den.TrapsSpawnCorpse) { float timeSinceDeath = UnityEngine.Random.Range(0f, (float)timeSinceSet); den.SpawnCreatureCorpse(trap.Owner.Position + Vector3.up, "Trap", timeSinceDeath); } //the trap will take care of itself trap.OnCatchTarget(State.NormalizedMasteryLevel); //we're done with this trap until it's triggered again Traps.RemoveAt(i); } } } } } } double waitUntil = Frontiers.WorldClock.AdjustedRealTime + 1f; while (Frontiers.WorldClock.AdjustedRealTime < waitUntil) { yield return(null); } } yield return(null); } mUpdatingTraps = false; yield break; }
public void OnAddedToGroup() { //save so the creature den spawner won't get confused //WorldItems.Get.Save(worlditem, true); //initialize the body parts //Body.Initialize (worlditem); //add the body's renderers to worlditem renderers //so they're disabled when appropriate //worlditem.Renderers.AddRange (Body.Renderers); if (Den == null) { IStackOwner owner = null; if (worlditem.Group.HasOwner(out owner)) { Den = (ICreatureDen)owner.worlditem.GetComponent(typeof(ICreatureDen)); //else - we don't have a den so we'll set default roaming distance from props } } if (Den != null) { Den.AddCreature(this.worlditem); } //set up the collective thought object CurrentThought.OnFleeFromIt += FleeFromThing; CurrentThought.OnKillIt += AttackThing; CurrentThought.OnEatIt += EatThing; CurrentThought.OnFollowIt += FollowThing; CurrentThought.OnWatchIt += WatchThing; //CurrentThought.OnMateWithIt += MateWithThing; Motile motile = null; if (worlditem.Is <Motile> (out motile)) { //create motile behaviors //TODO create more logical behaviors for creatures without a den mFollowAction = new MotileAction(); mFollowAction.Name = "Follow action by Creature"; mFollowAction.Type = MotileActionType.FollowTargetHolder; mFollowAction.FollowType = MotileFollowType.Follower; mFollowAction.Expiration = MotileExpiration.TargetOutOfRange; mFollowAction.OutOfRange = Den.Radius; mFollowAction.Range = Den.Radius; //mFollowAction.TerritoryType = MotileTerritoryType.Den; mFollowAction.TerritoryBase = Den; mEatAction = new MotileAction(); mEatAction.Name = "Eat action by Creature"; mEatAction.Type = MotileActionType.FollowGoal; mEatAction.Expiration = MotileExpiration.TargetInRange; mEatAction.Range = Template.MotileTemplate.MotileProps.RVORadius * 2; //mEatAction.TerritoryType = MotileTerritoryType.Den; mEatAction.TerritoryBase = Den; mReturnToDenAction = new MotileAction(); mReturnToDenAction.Name = "Return to Den action by Creature"; mReturnToDenAction.Type = MotileActionType.FollowGoal; mReturnToDenAction.Expiration = MotileExpiration.TargetInRange; mReturnToDenAction.Range = Template.MotileTemplate.MotileProps.RVORadius; mReturnToDenAction.LiveTarget = Den.IOI; //mReturnToDenAction.TerritoryType = MotileTerritoryType.Den; mReturnToDenAction.TerritoryBase = Den; mFleeThreatAction = new MotileAction(); mFleeThreatAction.Name = "Flee threat action by Creature"; mFleeThreatAction.Type = MotileActionType.FleeGoal; mFleeThreatAction.Expiration = MotileExpiration.TargetOutOfRange; mFleeThreatAction.YieldBehavior = MotileYieldBehavior.DoNotYield; mFleeThreatAction.OutOfRange = Den.Radius; mFleeThreatAction.Range = Looker.AwarenessDistanceTypeToVisibleDistance(Template.LookerTemplate.AwarenessDistance); //mFleeThreatAction.TerritoryType = MotileTerritoryType.Den; mFleeThreatAction.TerritoryBase = Den; mPursueGoalAction = new MotileAction(); mPursueGoalAction.Name = "Pursue goal action by Creature"; mPursueGoalAction.Type = MotileActionType.FollowGoal; mPursueGoalAction.Expiration = MotileExpiration.TargetInRange; mPursueGoalAction.YieldBehavior = MotileYieldBehavior.YieldAndWait; mPursueGoalAction.Range = Template.MotileTemplate.MotileProps.RVORadius; //mPursueGoalAction.TerritoryType = MotileTerritoryType.Den; mPursueGoalAction.TerritoryBase = Den; mFocusAction = new MotileAction(); mFocusAction.Name = "Focus action by Creature"; mFocusAction.Type = MotileActionType.FocusOnTarget; mFocusAction.Expiration = MotileExpiration.Duration; mFocusAction.RTDuration = ShortTermMemoryToRT(Template.Props.ShortTermMemory); mFocusAction.YieldBehavior = MotileYieldBehavior.YieldAndFinish; //mFocusAction.TerritoryType = MotileTerritoryType.Den; mFocusAction.TerritoryBase = Den; mWanderAction = motile.BaseAction; mWanderAction.Name = "Base Action (wander) Set By Creature"; mWanderAction.Type = MotileActionType.WanderIdly; mWanderAction.LiveTarget = Den.IOI; //mWanderAction.TerritoryType = MotileTerritoryType.Den; mWanderAction.TerritoryBase = Den; mWanderAction.Range = Den.Radius; mWanderAction.OutOfRange = Den.Radius; if (!IsDead) { motile.StartMotileActions(); } } if (IsDead) { motile.IsRagdoll = true; Body.SetRagdoll(true, 0.1f); Body.transform.position = worlditem.transform.position + Vector3.up; Body.transform.Rotate(UnityEngine.Random.Range(0f, 360f), UnityEngine.Random.Range(0f, 360f), UnityEngine.Random.Range(0f, 360f)); OnDie(); } else { RefreshBehavior(); } }