/// <summary> /// Gets the prefab game object /// </summary> public sealed override GameObject GetGameObject() { V2.Logger.Debug($"[FishFramework] Initializing fish: {this.ClassID}"); GameObject mainObj = modelPrefab; Renderer[] renderers = mainObj.GetComponentsInChildren <Renderer>(); foreach (Renderer rend in renderers) { rend.material.shader = Shader.Find("MarmosetUBER"); } Rigidbody rb = mainObj.EnsureComponent <Rigidbody>(); rb.useGravity = false; rb.angularDrag = 1f; WorldForces forces = mainObj.EnsureComponent <WorldForces>(); forces.useRigidbody = rb; forces.aboveWaterDrag = 0f; forces.aboveWaterGravity = 9.81f; forces.handleDrag = true; forces.handleGravity = true; forces.underwaterDrag = 1f; forces.underwaterGravity = 0; #if BELOWZERO || SUBNAUTICA_EXP forces.waterDepth = Ocean.GetOceanLevel(); #else forces.waterDepth = Ocean.main.GetOceanLevel(); #endif forces.enabled = false; forces.enabled = true; mainObj.EnsureComponent <EntityTag>().slotType = EntitySlot.Type.Creature; mainObj.EnsureComponent <PrefabIdentifier>().ClassId = this.ClassID; mainObj.EnsureComponent <TechTag>().type = this.TechType; mainObj.EnsureComponent <SkyApplier>().renderers = renderers; mainObj.EnsureComponent <LargeWorldEntity>().cellLevel = LargeWorldEntity.CellLevel.Near; mainObj.EnsureComponent <LiveMixin>().health = 10f; Creature creature = mainObj.EnsureComponent <Creature>(); creature.initialCuriosity = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f); creature.initialFriendliness = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f); creature.initialHunger = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f); SwimBehaviour behaviour = null; if (isWaterCreature) { behaviour = mainObj.EnsureComponent <SwimBehaviour>(); SwimRandom swim = mainObj.EnsureComponent <SwimRandom>(); swim.swimVelocity = swimSpeed; swim.swimRadius = swimRadius; swim.swimInterval = swimInterval; } else { behaviour = mainObj.EnsureComponent <WalkBehaviour>(); WalkOnGround walk = mainObj.EnsureComponent <WalkOnGround>(); OnSurfaceMovement move = mainObj.EnsureComponent <OnSurfaceMovement>(); move.onSurfaceTracker = mainObj.EnsureComponent <OnSurfaceTracker>(); } Locomotion loco = mainObj.EnsureComponent <Locomotion>(); loco.useRigidbody = rb; mainObj.EnsureComponent <EcoTarget>().type = EcoTargetType.Peeper; mainObj.EnsureComponent <CreatureUtils>(); mainObj.EnsureComponent <VFXSchoolFishRepulsor>(); SplineFollowing spline = mainObj.EnsureComponent <SplineFollowing>(); spline.locomotion = loco; spline.levelOfDetail = mainObj.EnsureComponent <BehaviourLOD>(); spline.GoTo(mainObj.transform.position + mainObj.transform.forward, mainObj.transform.forward, 5f); behaviour.splineFollowing = spline; if (pickupable) { mainObj.EnsureComponent <Pickupable>(); } creature.ScanCreatureActions(); return(mainObj); }
public static void Postfix(Creature __instance, ref CreatureAction __result, List <CreatureAction> ___actions, CreatureAction ___prevBestAction, int ___indexLastActionChecked) { float distToPlayer = Vector3.Distance(Player.main.transform.position, __instance.transform.position); /* * if (__instance.name.Contains("GhostLeviathan")) * { * Logger.Output("Dist: " + distToPlayer); * } */ // Determine the effectiveness of our module float myMaxRange; switch (StealthModulePatcher.stealthQuality) { case (StealthQuality.None): myMaxRange = float.MaxValue; break; case (StealthQuality.Low): myMaxRange = 80f; break; case (StealthQuality.Medium): myMaxRange = 60f; break; case (StealthQuality.High): myMaxRange = 40f; break; case (StealthQuality.Debug): myMaxRange = float.MinValue; break; default: myMaxRange = float.MaxValue; break; } if (StealthModulePatcher.stealthQuality == StealthQuality.None) { return; } if (___actions.Count == 0) { __result = null; return; } if (__instance.liveMixin && !__instance.liveMixin.IsAlive()) { SwimBehaviour component = __instance.transform.root.GetComponent <SwimBehaviour>(); if (component) { component.Idle(); } __result = null; return; } float num = 0f; CreatureAction creatureAction = null; if (___prevBestAction != null) { creatureAction = ___prevBestAction; // check if this action is violent string actionName1 = creatureAction.GetType().Name; // || actionName1 == "MoveTowardsTarget" if (actionName1 == "AttackLastTarget" || actionName1 == "AttackCyclops" || actionName1 == "EMPAttack" || actionName1 == "MushroomAttack") { // check whether we're in range of the player if (distToPlayer < myMaxRange) { // continue as usual } else { // special case for AttackLastTarget... target could be not the player if (actionName1 == "AttackLastTarget") { if (((AttackLastTarget)creatureAction).lastTarget.target) { if (((AttackLastTarget)creatureAction).lastTarget.target.name == "Player") { Logger.Log(__instance.name + " is replacing " + creatureAction.GetType().Name + "(Player) with SwimRandom."); creatureAction = new SwimRandom(); } } } else { Logger.Log(__instance.name + " is replacing " + creatureAction.GetType().Name + " with SwimRandom."); creatureAction = new SwimRandom(); } } } num = creatureAction.Evaluate(__instance); } ___indexLastActionChecked++; if (___indexLastActionChecked >= ___actions.Count) { ___indexLastActionChecked = 0; } CreatureAction creatureAction2 = ___actions[___indexLastActionChecked]; // check if this action is violent string actionName2 = creatureAction2.GetType().Name; if (actionName2 == "AttackLastTarget" || actionName2 == "AttackCyclops" || actionName2 == "EMPAttack" || actionName2 == "MushroomAttack") { // check whether we're in range of the player if (distToPlayer < myMaxRange) { // continue as usual } else { // special case for AttackLastTarget... target could be not the player if (actionName2 == "AttackLastTarget") { if (((AttackLastTarget)creatureAction2).lastTarget.target) { if (((AttackLastTarget)creatureAction2).lastTarget.target.name == "Player") { Logger.Log(__instance.name + " is replacing " + creatureAction2.GetType().Name + "(Player) with SwimRandom (2)"); creatureAction2 = new SwimRandom(); } } } else { Logger.Log(__instance.name + " is replacing " + creatureAction2.GetType().Name + " with SwimRandom (2)"); creatureAction2 = new SwimRandom(); } } } float num2 = creatureAction2.Evaluate(__instance); if (num2 > num && !global::Utils.NearlyEqual(num2, 0f, 1E-45f)) { creatureAction = creatureAction2; } __result = creatureAction; return; }
public override GameObject GetGameObject() { Console.WriteLine("[FishFramework] Getting object from asset bundle"); GameObject mainObj = bundle.LoadAsset <GameObject>(PrefabFileName); mainObj.AddComponent <ScaleFixer>().scale = scale; Console.WriteLine("[FishFramework] Setting correct shaders on renderers"); Renderer[] renderers = mainObj.GetComponentsInChildren <Renderer>(); foreach (Renderer rend in renderers) { rend.material.shader = Shader.Find("MarmosetUBER"); } Console.WriteLine("[FishFramework] Adding essential components to object"); Rigidbody rb = mainObj.AddOrGet <Rigidbody>(); rb.useGravity = false; rb.angularDrag = 1f; WorldForces forces = mainObj.AddOrGet <WorldForces>(); forces.useRigidbody = rb; forces.aboveWaterDrag = 0f; forces.aboveWaterGravity = 9.81f; forces.handleDrag = true; forces.handleGravity = true; forces.underwaterDrag = 1f; forces.underwaterGravity = 0; forces.waterDepth = Ocean.main.GetOceanLevel(); forces.enabled = false; forces.enabled = true; mainObj.AddOrGet <EntityTag>().slotType = EntitySlot.Type.Creature; mainObj.AddOrGet <PrefabIdentifier>().ClassId = ClassID; mainObj.AddOrGet <TechTag>().type = TechType; mainObj.AddOrGet <SkyApplier>().renderers = renderers; mainObj.AddOrGet <LargeWorldEntity>().cellLevel = LargeWorldEntity.CellLevel.Near; mainObj.AddOrGet <LiveMixin>().health = 10f; Creature creature = mainObj.AddOrGet <Creature>(); creature.initialCuriosity = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f); creature.initialFriendliness = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f); creature.initialHunger = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f); SwimBehaviour behaviour = null; if (isWaterCreature) { behaviour = mainObj.AddOrGet <SwimBehaviour>(); SwimRandom swim = mainObj.AddOrGet <SwimRandom>(); swim.swimVelocity = swimSpeed; swim.swimRadius = swimRadius; swim.swimInterval = 1f; } else { behaviour = mainObj.AddOrGet <WalkBehaviour>(); WalkOnGround walk = mainObj.AddOrGet <WalkOnGround>(); OnSurfaceMovement move = mainObj.AddOrGet <OnSurfaceMovement>(); move.onSurfaceTracker = mainObj.AddOrGet <OnSurfaceTracker>(); } Locomotion loco = mainObj.AddOrGet <Locomotion>(); loco.useRigidbody = rb; mainObj.AddOrGet <EcoTarget>().type = EcoTargetType.Peeper; mainObj.AddOrGet <CreatureUtils>(); mainObj.AddOrGet <VFXSchoolFishRepulsor>(); SplineFollowing spline = mainObj.AddOrGet <SplineFollowing>(); spline.locomotion = loco; spline.levelOfDetail = mainObj.AddOrGet <BehaviourLOD>(); spline.GoTo(mainObj.transform.position + mainObj.transform.forward, mainObj.transform.forward, 5f); behaviour.splineFollowing = spline; creature.ScanCreatureActions(); Console.WriteLine("[FishFramework] Adding pickupable component"); if (pickupable) { mainObj.AddOrGet <Pickupable>(); } Console.WriteLine("[FishFramework] Adding custom components"); foreach (Type type in componentsToAdd) { try { mainObj.AddComponent(type); } catch { Console.WriteLine("[FishFramework] Failed to add component " + type.Name + " to GameObject"); } } return(mainObj); }
public CreatureSpeedConfig(SwimRandom swimRandom, long techTypeHash, float originVelocity) { this.SwimRandom = swimRandom; this.TechTypeHash = techTypeHash; this.OriginVelocity = originVelocity; }