public void DestroyThingsOnOpen() { SfxLocator sfxLocator = GetComponent <SfxLocator>(); if (sfxLocator) { Util.PlaySound(sfxLocator.openSound, gameObject); } if (ppDuration) { ppDuration.enabled = true; } if (positionIndicator) { positionIndicator.gameObject.SetActive(false); } ObjectScaleCurve objectScaleCurve = GetComponentInChildren <ObjectScaleCurve>(); if (objectScaleCurve) { objectScaleCurve.enabled = true; } if (NetworkServer.active) { new SyncDestroyThingsOnOpen(gameObject.GetComponent <NetworkIdentity>().netId).Send(NetworkDestination.Clients); } }
internal static GameObject CreatePrefab(string bodyName, string modelName, BodyInfo bodyInfo) { if (!Resources.Load <GameObject>("Prefabs/CharacterBodies/" + bodyInfo.bodyNameToClone + "Body")) { Debug.LogError(bodyInfo.bodyNameToClone + "Body is not a valid body, character creation failed"); return(null); } GameObject newPrefab = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("Prefabs/CharacterBodies/" + bodyInfo.bodyNameToClone + "Body"), bodyName); GameObject model = CreateModel(newPrefab, modelName); if (model == null) { model = newPrefab.GetComponentInChildren <CharacterModel>().gameObject; } Transform modelBaseTransform = SetupModel(newPrefab, model.transform, bodyInfo); // old templar stuff or code stuff newPrefab.GetComponent <SetStateOnHurt>().canBeHitStunned = false; newPrefab.tag = "Player"; if (newPrefab.GetComponent <DeathRewards>()) { newPrefab.GetComponent <DeathRewards>().logUnlockableDef = null; } SfxLocator componentInChildren3 = newPrefab.GetComponentInChildren <SfxLocator>(); componentInChildren3.fallDamageSound = "Play_char_land_fall_damage"; #region CharacterBody CharacterBody bodyComponent = newPrefab.GetComponent <CharacterBody>(); bodyComponent.name = bodyInfo.bodyName; bodyComponent.baseNameToken = bodyInfo.bodyNameToken; bodyComponent.subtitleNameToken = bodyInfo.subtitleNameToken; bodyComponent.portraitIcon = bodyInfo.characterPortrait; bodyComponent.crosshairPrefab = bodyInfo.crosshair; bodyComponent.bodyFlags = CharacterBody.BodyFlags.ImmuneToExecutes; bodyComponent.rootMotionInMainState = false; bodyComponent.baseMaxHealth = bodyInfo.maxHealth; bodyComponent.levelMaxHealth = bodyInfo.healthGrowth; bodyComponent.baseRegen = bodyInfo.healthRegen; bodyComponent.levelRegen = bodyComponent.baseRegen * 0.2f; bodyComponent.baseMaxShield = bodyInfo.shield; bodyComponent.levelMaxShield = bodyInfo.shieldGrowth; bodyComponent.baseMoveSpeed = bodyInfo.moveSpeed; bodyComponent.levelMoveSpeed = bodyInfo.moveSpeedGrowth; bodyComponent.baseAcceleration = bodyInfo.acceleration; bodyComponent.baseJumpPower = bodyInfo.jumpPower; bodyComponent.levelJumpPower = bodyInfo.jumpPowerGrowth; bodyComponent.baseDamage = bodyInfo.damage; bodyComponent.levelDamage = bodyComponent.baseDamage * 0.2f; bodyComponent.baseAttackSpeed = bodyInfo.attackSpeed; bodyComponent.levelAttackSpeed = bodyInfo.attackSpeedGrowth; bodyComponent.baseArmor = bodyInfo.armor; bodyComponent.levelArmor = bodyInfo.armorGrowth; bodyComponent.baseCrit = bodyInfo.crit; bodyComponent.levelCrit = bodyInfo.critGrowth; bodyComponent.baseJumpCount = bodyInfo.jumpCount; bodyComponent.sprintingSpeedMultiplier = 1.45f; bodyComponent.hideCrosshair = false; bodyComponent.aimOriginTransform = modelBaseTransform.Find("AimOrigin"); bodyComponent.hullClassification = HullClassification.Human; bodyComponent.preferredPodPrefab = bodyInfo.podPrefab; bodyComponent.isChampion = false; bodyComponent.bodyColor = bodyInfo.bodyColor; //templar stuff bodyComponent.SetSpreadBloom(0f, false); bodyComponent.spreadBloomCurve = Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody").GetComponent <CharacterBody>().spreadBloomCurve; bodyComponent.spreadBloomDecayTime = Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody").GetComponent <CharacterBody>().spreadBloomDecayTime; bodyComponent.crosshairPrefab = Resources.Load <GameObject>("Prefabs/Crosshair/SimpleDotCrosshair"); bodyComponent.baseCrit = 1f; #endregion SetupCharacterDirection(newPrefab, modelBaseTransform, model.transform); SetupCameraTargetParams(newPrefab); SetupModelLocator(newPrefab, modelBaseTransform, model.transform); SetupRigidbody(newPrefab); SetupCapsuleCollider(newPrefab); SetupMainHurtbox(newPrefab, model); SetupFootstepController(model); SetupRagdoll(model); SetupAimAnimator(newPrefab, model); bodyPrefabs.Add(newPrefab); return(newPrefab); }
internal static void CreatePrefab() { // first clone the commando prefab so we can turn that into our own survivor characterPrefab = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody"), "ExampleSurvivorBody", true, "C:\\Users\\test\\Documents\\ror2mods\\ExampleSurvivor\\ExampleSurvivor\\ExampleSurvivor\\ExampleSurvivor.cs", "CreatePrefab", 151); characterPrefab.GetComponent <NetworkIdentity>().localPlayerAuthority = true; // create the model here, we're gonna replace commando's model with our own GameObject model = CreateModel(characterPrefab); GameObject gameObject = new GameObject("ModelBase"); gameObject.transform.parent = characterPrefab.transform; gameObject.transform.localPosition = new Vector3(0f, -0.81f, 0f); gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localScale = new Vector3(1f, 1f, 1f); GameObject gameObject2 = new GameObject("CameraPivot"); gameObject2.transform.parent = gameObject.transform; gameObject2.transform.localPosition = new Vector3(0f, 1.6f, 0f); gameObject2.transform.localRotation = Quaternion.identity; gameObject2.transform.localScale = Vector3.one; GameObject gameObject3 = new GameObject("AimOrigin"); gameObject3.transform.parent = gameObject.transform; gameObject3.transform.localPosition = new Vector3(0f, 1.4f, 0f); gameObject3.transform.localRotation = Quaternion.identity; gameObject3.transform.localScale = Vector3.one; Transform transform = model.transform; transform.parent = gameObject.transform; transform.localPosition = Vector3.zero; transform.localScale = new Vector3(0.01f, 0.01f, 0.01f); transform.localRotation = Quaternion.identity; CharacterDirection characterDirection = characterPrefab.GetComponent <CharacterDirection>(); characterDirection.moveVector = Vector3.zero; characterDirection.targetTransform = gameObject.transform; characterDirection.overrideAnimatorForwardTransform = null; characterDirection.rootMotionAccumulator = null; characterDirection.modelAnimator = model.GetComponentInChildren <Animator>(); characterDirection.driveFromRootRotation = false; characterDirection.turnSpeed = 720f; // set up the character body here CharacterBody bodyComponent = characterPrefab.GetComponent <CharacterBody>(); bodyComponent.bodyIndex = -1; bodyComponent.baseNameToken = "EXAMPLESURVIVOR_NAME"; // name token bodyComponent.subtitleNameToken = "EXAMPLESURVIVOR_SUBTITLE"; // subtitle token- used for umbras bodyComponent.bodyFlags = CharacterBody.BodyFlags.ImmuneToExecutes; bodyComponent.rootMotionInMainState = false; bodyComponent.mainRootSpeed = 0; bodyComponent.baseMaxHealth = 90; bodyComponent.levelMaxHealth = 24; bodyComponent.baseRegen = 0.5f; bodyComponent.levelRegen = 0.25f; bodyComponent.baseMaxShield = 0; bodyComponent.levelMaxShield = 0; bodyComponent.baseMoveSpeed = 7; bodyComponent.levelMoveSpeed = 0; bodyComponent.baseAcceleration = 80; bodyComponent.baseJumpPower = 15; bodyComponent.levelJumpPower = 0; bodyComponent.baseDamage = 15; bodyComponent.levelDamage = 3f; bodyComponent.baseAttackSpeed = 1; bodyComponent.levelAttackSpeed = 0; bodyComponent.baseCrit = 1; bodyComponent.levelCrit = 0; bodyComponent.baseArmor = 0; bodyComponent.levelArmor = 0; bodyComponent.baseJumpCount = 1; bodyComponent.sprintingSpeedMultiplier = 1.45f; bodyComponent.wasLucky = false; bodyComponent.hideCrosshair = false; bodyComponent.aimOriginTransform = gameObject3.transform; bodyComponent.hullClassification = HullClassification.Human; bodyComponent.portraitIcon = Assets.charPortrait; bodyComponent.isChampion = false; bodyComponent.currentVehicle = null; bodyComponent.skinIndex = 0U; // the charactermotor controls the survivor's movement and stuff CharacterMotor characterMotor = characterPrefab.GetComponent <CharacterMotor>(); characterMotor.walkSpeedPenaltyCoefficient = 1f; characterMotor.characterDirection = characterDirection; characterMotor.muteWalkMotion = false; characterMotor.mass = 100f; characterMotor.airControl = 0.25f; characterMotor.disableAirControlUntilCollision = false; characterMotor.generateParametersOnAwake = true; characterMotor.useGravity = true; characterMotor.isFlying = false; InputBankTest inputBankTest = characterPrefab.GetComponent <InputBankTest>(); inputBankTest.moveVector = Vector3.zero; CameraTargetParams cameraTargetParams = characterPrefab.GetComponent <CameraTargetParams>(); cameraTargetParams.cameraParams = Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody").GetComponent <CameraTargetParams>().cameraParams; cameraTargetParams.cameraPivotTransform = null; cameraTargetParams.aimMode = CameraTargetParams.AimType.Standard; cameraTargetParams.recoil = Vector2.zero; cameraTargetParams.idealLocalCameraPos = Vector3.zero; cameraTargetParams.dontRaycastToPivot = false; // this component is used to locate the character model(duh), important to set this up here ModelLocator modelLocator = characterPrefab.GetComponent <ModelLocator>(); modelLocator.modelTransform = transform; modelLocator.modelBaseTransform = gameObject.transform; modelLocator.dontReleaseModelOnDeath = false; modelLocator.autoUpdateModelTransform = true; modelLocator.dontDetatchFromParent = false; modelLocator.noCorpse = false; modelLocator.normalizeToFloor = false; // set true if you want your character to rotate on terrain like acrid does modelLocator.preserveModel = false; // childlocator is something that must be set up in the unity project, it's used to find any child objects for things like footsteps or muzzle flashes // also important to set up if you want quality ChildLocator childLocator = model.GetComponent <ChildLocator>(); // this component is used to handle all overlays and whatever on your character, without setting this up you won't get any cool effects like burning or freeze on the character // it goes on the model object of course CharacterModel characterModel = model.AddComponent <CharacterModel>(); characterModel.body = bodyComponent; characterModel.baseRendererInfos = new CharacterModel.RendererInfo[] { // set up multiple rendererinfos if needed, but for this example there's only the one new CharacterModel.RendererInfo { defaultMaterial = model.GetComponentInChildren <SkinnedMeshRenderer>().material, renderer = model.GetComponentInChildren <SkinnedMeshRenderer>(), defaultShadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On, ignoreOverlays = false } }; characterModel.autoPopulateLightInfos = true; characterModel.invisibilityCount = 0; characterModel.temporaryOverlays = new List <TemporaryOverlay>(); TeamComponent teamComponent = null; if (characterPrefab.GetComponent <TeamComponent>() != null) { teamComponent = characterPrefab.GetComponent <TeamComponent>(); } else { teamComponent = characterPrefab.GetComponent <TeamComponent>(); } teamComponent.hideAllyCardDisplay = false; teamComponent.teamIndex = TeamIndex.None; HealthComponent healthComponent = characterPrefab.GetComponent <HealthComponent>(); healthComponent.health = 90f; healthComponent.shield = 0f; healthComponent.barrier = 0f; healthComponent.magnetiCharge = 0f; healthComponent.body = null; healthComponent.dontShowHealthbar = false; healthComponent.globalDeathEventChanceCoefficient = 1f; characterPrefab.GetComponent <Interactor>().maxInteractionDistance = 3f; characterPrefab.GetComponent <InteractionDriver>().highlightInteractor = true; // this disables ragdoll since the character's not set up for it, and instead plays a death animation CharacterDeathBehavior characterDeathBehavior = characterPrefab.GetComponent <CharacterDeathBehavior>(); characterDeathBehavior.deathStateMachine = characterPrefab.GetComponent <EntityStateMachine>(); characterDeathBehavior.deathState = new SerializableEntityStateType(typeof(GenericCharacterDeath)); // edit the sfxlocator if you want different sounds SfxLocator sfxLocator = characterPrefab.GetComponent <SfxLocator>(); sfxLocator.deathSound = "Play_ui_player_death"; sfxLocator.barkSound = ""; sfxLocator.openSound = ""; sfxLocator.landingSound = "Play_char_land"; sfxLocator.fallDamageSound = "Play_char_land_fall_damage"; sfxLocator.aliveLoopStart = ""; sfxLocator.aliveLoopStop = ""; Rigidbody rigidbody = characterPrefab.GetComponent <Rigidbody>(); rigidbody.mass = 100f; rigidbody.drag = 0f; rigidbody.angularDrag = 0f; rigidbody.useGravity = false; rigidbody.isKinematic = true; rigidbody.interpolation = RigidbodyInterpolation.None; rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete; rigidbody.constraints = RigidbodyConstraints.None; CapsuleCollider capsuleCollider = characterPrefab.GetComponent <CapsuleCollider>(); capsuleCollider.isTrigger = false; capsuleCollider.material = null; capsuleCollider.center = new Vector3(0f, 0f, 0f); capsuleCollider.radius = 0.5f; capsuleCollider.height = 1.82f; capsuleCollider.direction = 1; KinematicCharacterMotor kinematicCharacterMotor = characterPrefab.GetComponent <KinematicCharacterMotor>(); kinematicCharacterMotor.CharacterController = characterMotor; kinematicCharacterMotor.Capsule = capsuleCollider; kinematicCharacterMotor.Rigidbody = rigidbody; capsuleCollider.radius = 0.5f; capsuleCollider.height = 1.82f; capsuleCollider.center = new Vector3(0, 0, 0); capsuleCollider.material = null; kinematicCharacterMotor.DetectDiscreteCollisions = false; kinematicCharacterMotor.GroundDetectionExtraDistance = 0f; kinematicCharacterMotor.MaxStepHeight = 0.2f; kinematicCharacterMotor.MinRequiredStepDepth = 0.1f; kinematicCharacterMotor.MaxStableSlopeAngle = 55f; kinematicCharacterMotor.MaxStableDistanceFromLedge = 0.5f; kinematicCharacterMotor.PreventSnappingOnLedges = false; kinematicCharacterMotor.MaxStableDenivelationAngle = 55f; kinematicCharacterMotor.RigidbodyInteractionType = RigidbodyInteractionType.None; kinematicCharacterMotor.PreserveAttachedRigidbodyMomentum = true; kinematicCharacterMotor.HasPlanarConstraint = false; kinematicCharacterMotor.PlanarConstraintAxis = Vector3.up; kinematicCharacterMotor.StepHandling = StepHandlingMethod.None; kinematicCharacterMotor.LedgeHandling = true; kinematicCharacterMotor.InteractiveRigidbodyHandling = true; kinematicCharacterMotor.SafeMovement = false; // this sets up the character's hurtbox, kinda confusing, but should be fine as long as it's set up in unity right HurtBoxGroup hurtBoxGroup = model.AddComponent <HurtBoxGroup>(); HurtBox componentInChildren = model.GetComponentInChildren <CapsuleCollider>().gameObject.AddComponent <HurtBox>(); componentInChildren.gameObject.layer = LayerIndex.entityPrecise.intVal; componentInChildren.healthComponent = healthComponent; componentInChildren.isBullseye = true; componentInChildren.damageModifier = HurtBox.DamageModifier.Normal; componentInChildren.hurtBoxGroup = hurtBoxGroup; componentInChildren.indexInGroup = 0; hurtBoxGroup.hurtBoxes = new HurtBox[] { componentInChildren }; hurtBoxGroup.mainHurtBox = componentInChildren; hurtBoxGroup.bullseyeCount = 1; // this is for handling footsteps, not needed but polish is always good FootstepHandler footstepHandler = model.AddComponent <FootstepHandler>(); footstepHandler.baseFootstepString = "Play_player_footstep"; footstepHandler.sprintFootstepOverrideString = ""; footstepHandler.enableFootstepDust = true; footstepHandler.footstepDustPrefab = Resources.Load <GameObject>("Prefabs/GenericFootstepDust"); // ragdoll controller is a pain to set up so we won't be doing that here.. RagdollController ragdollController = model.AddComponent <RagdollController>(); ragdollController.bones = null; ragdollController.componentsToDisableOnRagdoll = null; // this handles the pitch and yaw animations, but honestly they are nasty and a huge pain to set up so i didn't bother AimAnimator aimAnimator = model.AddComponent <AimAnimator>(); aimAnimator.inputBank = inputBankTest; aimAnimator.directionComponent = characterDirection; aimAnimator.pitchRangeMax = 55f; aimAnimator.pitchRangeMin = -50f; aimAnimator.yawRangeMin = -44f; aimAnimator.yawRangeMax = 44f; aimAnimator.pitchGiveupRange = 30f; aimAnimator.yawGiveupRange = 10f; aimAnimator.giveupDuration = 8f; }
public static void Create() { body = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody"), "UrsaBody", true); NetworkIdentity networkIdentity = body.GetComponent <NetworkIdentity>(); networkIdentity.localPlayerAuthority = true; GameObject model = CreateModel(body); GameObject gameObject = new GameObject("ModelBase"); gameObject.transform.parent = body.transform; gameObject.transform.localPosition = new Vector3(0f, -0.81f, 0f); gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localScale = new Vector3(1f, 1f, 1f); GameObject gameObject2 = new GameObject("CameraPivot"); gameObject2.transform.parent = gameObject.transform; gameObject2.transform.localPosition = new Vector3(0f, 1.6f, 0f); gameObject2.transform.localRotation = Quaternion.identity; gameObject2.transform.localScale = Vector3.one; GameObject gameObject3 = new GameObject("AimOrigin"); gameObject3.transform.parent = gameObject.transform; gameObject3.transform.localPosition = new Vector3(0f, 1.4f, 0f); gameObject3.transform.localRotation = Quaternion.identity; gameObject3.transform.localScale = Vector3.one; Transform transform = model.transform; transform.parent = gameObject.transform; transform.localPosition = Vector3.zero; transform.localScale = new Vector3(1f, 1f, 1f); transform.localRotation = Quaternion.identity; CharacterDirection characterDirection = body.GetComponent <CharacterDirection>(); characterDirection.moveVector = Vector3.zero; characterDirection.targetTransform = gameObject.transform; characterDirection.overrideAnimatorForwardTransform = null; characterDirection.rootMotionAccumulator = null; characterDirection.modelAnimator = model.GetComponentInChildren <Animator>(); characterDirection.driveFromRootRotation = false; characterDirection.turnSpeed = 720f; CharacterBody bodyComponent = body.GetComponent <CharacterBody>(); bodyComponent.bodyIndex = BodyIndex.None; bodyComponent.baseNameToken = "URSA_NAME"; bodyComponent.subtitleNameToken = "URSA_SUBTITLE"; bodyComponent.bodyFlags = CharacterBody.BodyFlags.ImmuneToExecutes; bodyComponent.rootMotionInMainState = false; bodyComponent.mainRootSpeed = 0; bodyComponent.baseMaxHealth = Core.Config.baseMaxHealth.Value; bodyComponent.levelMaxHealth = Core.Config.levelMaxHealth.Value; bodyComponent.baseRegen = Core.Config.baseRegen.Value; bodyComponent.levelRegen = Core.Config.levelRegen.Value; bodyComponent.baseMaxShield = Core.Config.baseMaxShield.Value; bodyComponent.levelMaxShield = Core.Config.levelMaxShield.Value; bodyComponent.baseMoveSpeed = Core.Config.baseMoveSpeed.Value; bodyComponent.levelMoveSpeed = Core.Config.levelMoveSpeed.Value; bodyComponent.baseAcceleration = Core.Config.baseAcceleration.Value; bodyComponent.baseJumpPower = Core.Config.baseJumpPower.Value; bodyComponent.levelJumpPower = Core.Config.levelJumpPower.Value; bodyComponent.baseJumpCount = Core.Config.baseJumpCount.Value; bodyComponent.baseDamage = Core.Config.baseDamage.Value; bodyComponent.levelDamage = Core.Config.levelDamage.Value; bodyComponent.baseAttackSpeed = Core.Config.baseAttackSpeed.Value; bodyComponent.levelAttackSpeed = Core.Config.levelAttackSpeed.Value; bodyComponent.baseCrit = Core.Config.baseCrit.Value; bodyComponent.levelCrit = Core.Config.levelCrit.Value; bodyComponent.baseArmor = Core.Config.baseArmor.Value; bodyComponent.levelArmor = Core.Config.levelArmor.Value; bodyComponent.sprintingSpeedMultiplier = Core.Config.sprintingSpeedMultiplier.Value; bodyComponent.wasLucky = false; bodyComponent.hideCrosshair = false; bodyComponent.crosshairPrefab = Resources.Load <GameObject>("prefabs/crosshair/simpledotcrosshair"); bodyComponent.aimOriginTransform = gameObject3.transform; bodyComponent.hullClassification = HullClassification.Human; bodyComponent.portraitIcon = Core.Assets.portrait.texture; bodyComponent.isChampion = false; bodyComponent.currentVehicle = null; bodyComponent.skinIndex = 0U; LoadoutAPI.AddSkill(typeof(States.UrsaMain)); var stateMachine = body.GetComponent <EntityStateMachine>(); stateMachine.mainStateType = new SerializableEntityStateType(typeof(States.UrsaMain)); CharacterMotor characterMotor = body.GetComponent <CharacterMotor>(); characterMotor.walkSpeedPenaltyCoefficient = 1f; characterMotor.characterDirection = characterDirection; characterMotor.muteWalkMotion = false; characterMotor.mass = 200f; characterMotor.airControl = 0.25f; characterMotor.disableAirControlUntilCollision = false; characterMotor.generateParametersOnAwake = true; //characterMotor.useGravity = true; //characterMotor.isFlying = false; InputBankTest inputBankTest = body.GetComponent <InputBankTest>(); inputBankTest.moveVector = Vector3.zero; CameraTargetParams cameraTargetParams = body.GetComponent <CameraTargetParams>(); cameraTargetParams.cameraParams = Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody").GetComponent <CameraTargetParams>().cameraParams; cameraTargetParams.cameraPivotTransform = null; cameraTargetParams.aimMode = CameraTargetParams.AimType.Standard; cameraTargetParams.recoil = Vector2.zero; cameraTargetParams.idealLocalCameraPos = Vector3.zero; cameraTargetParams.dontRaycastToPivot = false; ModelLocator modelLocator = body.GetComponent <ModelLocator>(); modelLocator.modelTransform = transform; modelLocator.modelBaseTransform = gameObject.transform; modelLocator.dontReleaseModelOnDeath = false; modelLocator.autoUpdateModelTransform = true; modelLocator.dontDetatchFromParent = false; modelLocator.noCorpse = false; modelLocator.normalizeToFloor = true; modelLocator.preserveModel = false; ChildLocator childLocator = model.GetComponent <ChildLocator>(); HitBoxGroup rightClawHitBoxGroup = model.AddComponent <HitBoxGroup>(); HitBoxGroup leftClawHitBoxGroup = model.AddComponent <HitBoxGroup>(); GameObject rightClawGameObject = new GameObject("RightClawHitBox"); Transform rightClaw = childLocator.FindChild("R_Hand"); rightClawGameObject.transform.parent = rightClaw; rightClawGameObject.transform.localPosition = new Vector3(-0.2f, 0.2f, 0.3f); rightClawGameObject.transform.localScale = Vector3.one * 6.25f; rightClawGameObject.transform.localRotation = Quaternion.identity; HitBox rightClawHitBox = rightClawGameObject.AddComponent <HitBox>(); GameObject leftClawGameObject = new GameObject("LeftClawHitBox"); Transform leftClaw = childLocator.FindChild("L_Hand"); leftClawGameObject.transform.parent = leftClaw; leftClawGameObject.transform.localPosition = new Vector3(-0.2f, 0.2f, 0.3f); leftClawGameObject.transform.localScale = Vector3.one * 6.25f; leftClawGameObject.transform.localRotation = Quaternion.identity; HitBox leftClawHitBox = leftClawGameObject.AddComponent <HitBox>(); rightClawHitBoxGroup.hitBoxes = new HitBox[] { rightClawHitBox }; rightClawHitBoxGroup.groupName = "RightClaw"; leftClawHitBoxGroup.hitBoxes = new HitBox[] { leftClawHitBox }; leftClawHitBoxGroup.groupName = "LeftClaw"; Light rightLight = rightClaw.gameObject.AddComponent <Light>(); rightLight.type = LightType.Point; rightLight.color = Color.yellow; rightLight.range = 0.85f; rightLight.intensity = 95f; rightLight.enabled = false; Light leftLight = leftClaw.gameObject.AddComponent <Light>(); leftLight.type = LightType.Point; leftLight.color = Color.yellow; leftLight.range = 0.85f; leftLight.intensity = 95f; leftLight.enabled = false; CharacterModel characterModel = model.AddComponent <CharacterModel>(); characterModel.body = bodyComponent; List <CharacterModel.RendererInfo> rendererInfos = new List <CharacterModel.RendererInfo>(); foreach (SkinnedMeshRenderer i in model.GetComponentsInChildren <SkinnedMeshRenderer>()) { CharacterModel.RendererInfo info = new CharacterModel.RendererInfo { defaultMaterial = i.material, renderer = i, defaultShadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On, ignoreOverlays = false }; rendererInfos.Add(info); } characterModel.baseRendererInfos = rendererInfos.ToArray(); characterModel.autoPopulateLightInfos = true; characterModel.invisibilityCount = 0; characterModel.temporaryOverlays = new List <TemporaryOverlay>(); ModelSkinController skinController = model.AddComponent <ModelSkinController>(); LoadoutAPI.SkinDefInfo skinDefInfo = new LoadoutAPI.SkinDefInfo { BaseSkins = Array.Empty <SkinDef>(), GameObjectActivations = new SkinDef.GameObjectActivation[0], Icon = Core.Assets.defaultSkinIcon, MeshReplacements = new SkinDef.MeshReplacement[0], MinionSkinReplacements = new SkinDef.MinionSkinReplacement[0], Name = "URSA_SKIN_DEFAULT_NAME", NameToken = "URSA_SKIN_DEFAULT_NAME", ProjectileGhostReplacements = new SkinDef.ProjectileGhostReplacement[0], RendererInfos = rendererInfos.ToArray(), RootObject = model, }; SkinDef skin = LoadoutAPI.CreateNewSkinDef(skinDefInfo); skinController.skins = new SkinDef[] { skin }; TeamComponent teamComponent = null; if (body.GetComponent <TeamComponent>() != null) { teamComponent = body.GetComponent <TeamComponent>(); } else { teamComponent = body.GetComponent <TeamComponent>(); } teamComponent.hideAllyCardDisplay = false; teamComponent.teamIndex = TeamIndex.None; HealthComponent healthComponent = body.GetComponent <HealthComponent>(); healthComponent.health = 90f; healthComponent.shield = 0f; healthComponent.barrier = 0f; healthComponent.magnetiCharge = 0f; healthComponent.body = null; healthComponent.dontShowHealthbar = false; healthComponent.globalDeathEventChanceCoefficient = 1f; body.GetComponent <Interactor>().maxInteractionDistance = 3f; body.GetComponent <InteractionDriver>().highlightInteractor = true; CharacterDeathBehavior characterDeathBehavior = body.GetComponent <CharacterDeathBehavior>(); characterDeathBehavior.deathStateMachine = body.GetComponent <EntityStateMachine>(); characterDeathBehavior.deathState = new SerializableEntityStateType(typeof(GenericCharacterDeath)); SfxLocator sfxLocator = body.GetComponent <SfxLocator>(); sfxLocator.deathSound = "Play_ui_player_death"; sfxLocator.barkSound = ""; sfxLocator.openSound = ""; sfxLocator.landingSound = "Play_char_land"; sfxLocator.fallDamageSound = "Play_char_land_fall_damage"; sfxLocator.aliveLoopStart = ""; sfxLocator.aliveLoopStop = ""; Rigidbody rigidbody = body.GetComponent <Rigidbody>(); rigidbody.mass = 100f; rigidbody.drag = 0f; rigidbody.angularDrag = 0f; rigidbody.useGravity = false; rigidbody.isKinematic = true; rigidbody.interpolation = RigidbodyInterpolation.None; rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete; rigidbody.constraints = RigidbodyConstraints.None; CapsuleCollider capsuleCollider = body.GetComponent <CapsuleCollider>(); capsuleCollider.isTrigger = false; capsuleCollider.material = null; capsuleCollider.center = new Vector3(0f, 0f, 0f); capsuleCollider.radius = 0.5f; capsuleCollider.height = 1.82f; capsuleCollider.direction = 1; KinematicCharacterMotor kinematicCharacterMotor = body.GetComponent <KinematicCharacterMotor>(); kinematicCharacterMotor.CharacterController = characterMotor; kinematicCharacterMotor.Capsule = capsuleCollider; kinematicCharacterMotor.Rigidbody = rigidbody; capsuleCollider.radius = 0.5f; capsuleCollider.height = 1.82f; capsuleCollider.center = new Vector3(0, 0, 0); capsuleCollider.material = null; kinematicCharacterMotor.DetectDiscreteCollisions = false; kinematicCharacterMotor.GroundDetectionExtraDistance = 0f; kinematicCharacterMotor.MaxStepHeight = 0.2f; kinematicCharacterMotor.MinRequiredStepDepth = 0.1f; kinematicCharacterMotor.MaxStableSlopeAngle = 55f; kinematicCharacterMotor.MaxStableDistanceFromLedge = 0.5f; kinematicCharacterMotor.PreventSnappingOnLedges = false; kinematicCharacterMotor.MaxStableDenivelationAngle = 55f; kinematicCharacterMotor.RigidbodyInteractionType = RigidbodyInteractionType.None; kinematicCharacterMotor.PreserveAttachedRigidbodyMomentum = true; kinematicCharacterMotor.HasPlanarConstraint = false; kinematicCharacterMotor.PlanarConstraintAxis = Vector3.up; kinematicCharacterMotor.StepHandling = StepHandlingMethod.None; kinematicCharacterMotor.LedgeHandling = true; kinematicCharacterMotor.InteractiveRigidbodyHandling = true; kinematicCharacterMotor.SafeMovement = false; HurtBoxGroup hurtBoxGroup = model.AddComponent <HurtBoxGroup>(); HurtBox componentInChildren = model.GetComponentInChildren <CapsuleCollider>().gameObject.AddComponent <HurtBox>(); componentInChildren.gameObject.layer = LayerIndex.entityPrecise.intVal; componentInChildren.healthComponent = healthComponent; componentInChildren.isBullseye = true; componentInChildren.damageModifier = HurtBox.DamageModifier.Normal; componentInChildren.hurtBoxGroup = hurtBoxGroup; componentInChildren.indexInGroup = 0; hurtBoxGroup.hurtBoxes = new HurtBox[] { componentInChildren }; hurtBoxGroup.mainHurtBox = componentInChildren; hurtBoxGroup.bullseyeCount = 1; FootstepHandler footstepHandler = model.AddComponent <FootstepHandler>(); footstepHandler.baseFootstepString = "Play_player_footstep"; footstepHandler.sprintFootstepOverrideString = ""; footstepHandler.enableFootstepDust = true; footstepHandler.footstepDustPrefab = Resources.Load <GameObject>("Prefabs/GenericFootstepDust"); RagdollController ragdollController = model.AddComponent <RagdollController>(); ragdollController.bones = null; ragdollController.componentsToDisableOnRagdoll = null; AimAnimator aimAnimator = model.AddComponent <AimAnimator>(); aimAnimator.inputBank = inputBankTest; aimAnimator.directionComponent = characterDirection; aimAnimator.pitchRangeMax = 55f; aimAnimator.pitchRangeMin = -50f; aimAnimator.yawRangeMin = -44f; aimAnimator.yawRangeMax = 44f; aimAnimator.pitchGiveupRange = 30f; aimAnimator.yawGiveupRange = 10f; aimAnimator.giveupDuration = 8f; // Adds component used for keeping track of individual Ursa's Fury Swipes damage bonus from Enrage. body.AddComponent <Miscellaneous.FurySwipesController>(); // Particle System that only emits when Overpower buff is active. ParticleSystem.EmissionModule overpowerParticleSystemEmission = childLocator.FindChild("OverpowerParticles").GetComponent <ParticleSystem>().emission; overpowerParticleSystemEmission.enabled = false; //Doppelganger doppelgangerMaster = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("Prefabs/CharacterMasters/CommandoMonsterMaster"), "UrsaDoppelGanger", true); CharacterMaster component = doppelgangerMaster.GetComponent <CharacterMaster>(); component.bodyPrefab = body; }
internal static void CreatePrefab() { SniperMain.sniperBodyPrefab = PrefabsCore.CreatePrefab("Sniper", true); SniperMain.sniperBodyPrefab.tag = "Finish"; GameObject obj = SniperMain.sniperBodyPrefab; NetworkIdentity netId = obj.AddOrGetComponent <NetworkIdentity>(); netId.localPlayerAuthority = true; var modelBase = new GameObject("ModelBase"); modelBase.transform.parent = obj.transform; modelBase.transform.localPosition = new Vector3(0f, -0.81f, 0f); modelBase.transform.localRotation = Quaternion.identity; modelBase.transform.localScale = new Vector3(1f, 1f, 1f); var cameraPivot = new GameObject("CameraPivot"); cameraPivot.transform.parent = modelBase.transform; cameraPivot.transform.localPosition = new Vector3(0f, 1.6f, 0f); cameraPivot.transform.localRotation = Quaternion.identity; cameraPivot.transform.localScale = Vector3.one; var aimOrigin = new GameObject("AimOrigin"); aimOrigin.transform.parent = modelBase.transform; aimOrigin.transform.localPosition = new Vector3(0f, 1.4f, 0f); aimOrigin.transform.localRotation = Quaternion.identity; aimOrigin.transform.localScale = Vector3.one; GameObject model = ModelModule.GetModel(); Transform modelTransform = model.transform; modelTransform.parent = modelBase.transform; modelTransform.localPosition = Vector3.zero; modelTransform.localScale = Vector3.one; modelTransform.localRotation = Quaternion.identity; CharacterDirection direction = obj.AddOrGetComponent <CharacterDirection>(); direction.moveVector = Vector3.zero; direction.targetTransform = modelBase.transform; direction.overrideAnimatorForwardTransform = null; direction.rootMotionAccumulator = null; direction.modelAnimator = null; direction.driveFromRootRotation = false; direction.turnSpeed = 720f; //CharacterBody borkBorkBody = null; //if(borkBorkBody is null) return; //borkBorkBody.baseMaxHealth = 150f; //borkBorkBody.baseMoveSpeed = 9f; //borkBorkBody.baseJumpPower = 20f; //borkBorkBody.baseDamage = 12f; SniperCharacterBody body = obj.AddOrGetComponent <SniperCharacterBody>(); body.bodyIndex = (BodyIndex)(-1); body.baseNameToken = Tokens.SNIPER_NAME; body.subtitleNameToken = Tokens.SNIPER_SUBTITLE; body.bodyFlags = CharacterBody.BodyFlags.ImmuneToExecutes; body.rootMotionInMainState = false; body.mainRootSpeed = 0f; body.baseMaxHealth = 130f; body.levelMaxHealth = 39f; body.baseRegen = 2f; body.levelRegen = 0.4f; body.baseMaxShield = 0f; body.levelMaxShield = 0f; body.baseMoveSpeed = 7f; body.levelMoveSpeed = 0f; body.baseAcceleration = 60f; body.baseJumpPower = 15f; body.levelJumpPower = 0f; body.baseDamage = 12f; body.levelDamage = 3.6f; body.baseAttackSpeed = 1f; body.levelAttackSpeed = 0f; body.baseCrit = 1f; body.levelCrit = 0f; body.baseArmor = 0f; body.levelArmor = 0f; body.baseJumpCount = 1; body.sprintingSpeedMultiplier = 1.45f; body.wasLucky = false; body.spreadBloomDecayTime = 1f; body.spreadBloomCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); body.crosshairPrefab = UIModule.GetCrosshair(); body.hideCrosshair = false; body.aimOriginTransform = aimOrigin.transform; body.hullClassification = HullClassification.Human; body.portraitIcon = UIModule.GetPortraitIcon(); body.isChampion = false; body.currentVehicle = null; body.preferredPodPrefab = MiscModule.GetPodPrefab(); body.preferredInitialStateType = SkillsCore.StateType <Uninitialized>(); body.skinIndex = 0u; CharacterMotor motor = obj.AddOrGetComponent <CharacterMotor>(); motor.walkSpeedPenaltyCoefficient = 1f; motor.characterDirection = direction; motor.muteWalkMotion = false; motor.mass = 100f; motor.airControl = 0.25f; motor.disableAirControlUntilCollision = false; motor.generateParametersOnAwake = true; motor.useGravity = true; motor.isFlying = false; InputBankTest input = obj.AddOrGetComponent <InputBankTest>(); input.moveVector = Vector3.zero; CameraTargetParams ctp = obj.AddOrGetComponent <CameraTargetParams>(); ctp.cameraParams = MiscModule.GetCharCameraParams(); ctp.cameraPivotTransform = null; ctp.aimMode = CameraTargetParams.AimType.Standard; ctp.recoil = Vector2.zero; ctp.idealLocalCameraPos = Vector3.zero; ctp.dontRaycastToPivot = false; ModelLocator modelLocator = obj.AddOrGetComponent <ModelLocator>(); modelLocator.modelTransform = modelTransform; modelLocator.modelBaseTransform = modelBase.transform; modelLocator.dontReleaseModelOnDeath = false; modelLocator.autoUpdateModelTransform = true; modelLocator.dontDetatchFromParent = false; modelLocator.noCorpse = false; modelLocator.normalizeToFloor = false; modelLocator.preserveModel = false; EntityStateMachine bodyMachine = obj.AddOrGetComponent <EntityStateMachine>(); bodyMachine.customName = "Body"; bodyMachine.initialStateType = SkillsCore.StateType <SpawnTeleporterState>(); bodyMachine.mainStateType = SkillsCore.StateType <GenericCharacterMain>(); EntityStateMachine weaponMachine = obj.AddComponent <EntityStateMachine>(); weaponMachine.customName = "Weapon"; weaponMachine.initialStateType = SkillsCore.StateType <Idle>(); weaponMachine.mainStateType = SkillsCore.StateType <Idle>(); EntityStateMachine scopeMachine = obj.AddComponent <EntityStateMachine>(); scopeMachine.customName = "Scope"; scopeMachine.initialStateType = SkillsCore.StateType <Idle>(); scopeMachine.mainStateType = SkillsCore.StateType <Idle>(); EntityStateMachine reloadMachine = obj.AddComponent <EntityStateMachine>(); reloadMachine.customName = "Reload"; reloadMachine.initialStateType = SkillsCore.StateType <Idle>(); reloadMachine.mainStateType = SkillsCore.StateType <Idle>(); EntityStateMachine[] allStateMachines = new[] { bodyMachine, weaponMachine, scopeMachine, reloadMachine }; EntityStateMachine[] nonBodyStateMachines = new[] { weaponMachine, scopeMachine, reloadMachine }; GenericSkill ammoSkill = obj.AddOrGetComponent <GenericSkill>(); ammoSkill._skillFamily = SkillFamiliesModule.GetAmmoSkillFamily(); HooksModule.AddReturnoverride(ammoSkill); //GenericSkill passiveSkill = obj.AddComponent<GenericSkill>(); //passiveSkill._skillFamily = SkillFamiliesModule.GetPassiveSkillFamily(); //HooksModule.AddReturnoverride( passiveSkill ); GenericSkill primarySkill = obj.AddComponent <GenericSkill>(); primarySkill._skillFamily = SkillFamiliesModule.GetPrimarySkillFamily(); GenericSkill secondarySkill = obj.AddComponent <GenericSkill>(); secondarySkill._skillFamily = SkillFamiliesModule.GetSecondarySkillFamily(); GenericSkill utilitySkill = obj.AddComponent <GenericSkill>(); utilitySkill._skillFamily = SkillFamiliesModule.GetUtilitySkillFamily(); GenericSkill specialSkill = obj.AddComponent <GenericSkill>(); specialSkill._skillFamily = SkillFamiliesModule.GetSpecialSkillFamily(); SkillLocator skillLocator = obj.AddOrGetComponent <SkillLocator>(); skillLocator.primary = primarySkill; skillLocator.secondary = secondarySkill; skillLocator.utility = utilitySkill; skillLocator.special = specialSkill; skillLocator.passiveSkill = new SkillLocator.PassiveSkill { enabled = false, icon = null, skillDescriptionToken = null, skillNameToken = null, }; TeamComponent team = obj.AddOrGetComponent <TeamComponent>(); team.hideAllyCardDisplay = false; team.teamIndex = TeamIndex.None; HealthComponent health = obj.AddOrGetComponent <HealthComponent>(); health.health = 100; health.shield = 0; health.barrier = 0; health.magnetiCharge = 0; health.body = null; health.dontShowHealthbar = false; health.globalDeathEventChanceCoefficient = 1f; Interactor interactor = obj.AddOrGetComponent <Interactor>(); interactor.maxInteractionDistance = 3f; InteractionDriver interaction = obj.AddOrGetComponent <InteractionDriver>(); interaction.highlightInteractor = true; CharacterDeathBehavior death = obj.AddOrGetComponent <CharacterDeathBehavior>(); death.deathStateMachine = bodyMachine; death.deathState = SkillsCore.StateType <EntityStates.Commando.DeathState>(); death.idleStateMachine = nonBodyStateMachines; CharacterNetworkTransform netTrans = obj.AddOrGetComponent <CharacterNetworkTransform>(); netTrans.positionTransmitInterval = 0.05f; netTrans.lastPositionTransmitTime = Single.MinValue; netTrans.interpolationFactor = 3f; netTrans.debugDuplicatePositions = false; netTrans.debugSnapshotReceived = false; NetworkStateMachine netStates = obj.AddOrGetComponent <NetworkStateMachine>(); netStates.stateMachines = allStateMachines; //stateMachines.Set( netStates, allStateMachines ); CharacterEmoteDefinitions emotes = obj.AddOrGetComponent <CharacterEmoteDefinitions>(); emotes.emoteDefinitions = null; EquipmentSlot equip = obj.AddOrGetComponent <EquipmentSlot>(); SfxLocator sfx = obj.AddOrGetComponent <SfxLocator>(); sfx.deathSound = "Play_ui_player_death"; sfx.barkSound = ""; sfx.openSound = ""; sfx.landingSound = "Play_char_land"; sfx.fallDamageSound = "Play_char_land_fall_damage"; sfx.aliveLoopStart = ""; sfx.aliveLoopStop = ""; Rigidbody rb = obj.AddOrGetComponent <Rigidbody>(); rb.mass = 100f; rb.drag = 0f; rb.angularDrag = 0f; rb.useGravity = false; rb.isKinematic = true; rb.interpolation = RigidbodyInterpolation.None; rb.collisionDetectionMode = CollisionDetectionMode.Discrete; rb.constraints = RigidbodyConstraints.None; CapsuleCollider col = obj.AddOrGetComponent <CapsuleCollider>(); col.isTrigger = false; col.material = null; col.center = new Vector3(0f, 0f, 0f); col.radius = 0.5f; col.height = 1.82f; col.direction = 1; KinematicCharacterMotor kinCharMot = obj.AddOrGetComponent <KinematicCharacterMotor>(); kinCharMot.CharacterController = motor; kinCharMot.Capsule = col; kinCharMot.Rigidbody = rb; kinCharMot.CapsuleRadius = 0.5f; kinCharMot.CapsuleHeight = 1.82f; kinCharMot.CapsuleYOffset = 0f; kinCharMot.CapsulePhysicsMaterial = null; kinCharMot.DetectDiscreteCollisions = false; kinCharMot.GroundDetectionExtraDistance = 0f; kinCharMot.MaxStepHeight = 0.2f; kinCharMot.MinRequiredStepDepth = 0.1f; kinCharMot.MaxStableSlopeAngle = 55f; kinCharMot.MaxStableDistanceFromLedge = 0.5f; kinCharMot.PreventSnappingOnLedges = false; kinCharMot.MaxStableDenivelationAngle = 55f; kinCharMot.RigidbodyInteractionType = RigidbodyInteractionType.None; kinCharMot.PreserveAttachedRigidbodyMomentum = true; kinCharMot.HasPlanarConstraint = false; kinCharMot.PlanarConstraintAxis = Vector3.up; kinCharMot.StepHandling = StepHandlingMethod.None; kinCharMot.LedgeHandling = true; kinCharMot.InteractiveRigidbodyHandling = true; kinCharMot.SafeMovement = false; SetStateOnHurt hurt = obj.AddOrGetComponent <SetStateOnHurt>(); hurt.hitThreshold = 5f; hurt.targetStateMachine = bodyMachine; hurt.idleStateMachine = nonBodyStateMachines; hurt.hurtState = SkillsCore.StateType <Idle>(); hurt.canBeHitStunned = false; hurt.canBeStunned = false; hurt.canBeFrozen = true; CharacterModel charModel = model.AddOrGetComponent <CharacterModel>(); charModel.body = body; charModel.itemDisplayRuleSet = ItemDisplayModule.GetSniperItemDisplay(model.AddOrGetComponent <ChildLocator>()); HurtBoxGroup hurtBoxGroup = model.AddOrGetComponent <HurtBoxGroup>(); HurtBox tempHb = model.GetComponentInChildren <HurtBox>(); tempHb.gameObject.layer = LayerIndex.entityPrecise.intVal; tempHb.healthComponent = health; tempHb.isBullseye = true; tempHb.damageModifier = HurtBox.DamageModifier.Normal; tempHb.hurtBoxGroup = hurtBoxGroup; tempHb.indexInGroup = 0; hurtBoxGroup.hurtBoxes = new[] { tempHb, }; hurtBoxGroup.mainHurtBox = tempHb; hurtBoxGroup.bullseyeCount = 1; FootstepHandler footsteps = model.AddComponent <FootstepHandler>(); footsteps.baseFootstepString = "Play_player_footstep"; footsteps.sprintFootstepOverrideString = ""; footsteps.enableFootstepDust = true; footsteps.footstepDustPrefab = UnityEngine.Resources.Load <GameObject>("Prefabs/GenericFootstepDust"); RagdollController ragdoll = model.AddOrGetComponent <RagdollController>(); ragdoll.bones = null; // FUTURE: Setup sniper ragdoll controller ragdoll.componentsToDisableOnRagdoll = null; AimAnimator aimAnimator = model.AddOrGetComponent <AimAnimator>(); aimAnimator.inputBank = input; aimAnimator.directionComponent = direction; aimAnimator.pitchRangeMax = 55f; aimAnimator.pitchRangeMin = -50f; aimAnimator.yawRangeMin = -40f; aimAnimator.yawRangeMax = 45f; aimAnimator.pitchGiveupRange = 30f; aimAnimator.yawGiveupRange = 10f; aimAnimator.giveupDuration = 8f; ModelSkinController skinController = model.AddOrGetComponent <ModelSkinController>(); SkinDef[] skinsArray = skinController.skins; for (Int32 i = 0; i < skinsArray.Length; ++i) { SkinDef skin = skinsArray[i]; skin.minionSkinReplacements = new[] { new SkinDef.MinionSkinReplacement { minionBodyPrefab = DecoyModule.GetDecoyPrefab(), minionSkin = skin }, }; } foreach (IRuntimePrefabComponent comp in obj.GetComponents <IRuntimePrefabComponent>()) { comp.InitializePrefab(); } }
private void ModifyClayMan() { AISkillDriver clayPrimary = clayMaster.GetComponent <AISkillDriver>(); clayPrimary.maxDistance = 16f; clayMaster.GetComponent <CharacterMaster>().bodyPrefab = clayObject; LanguageAPI.Add("CLAY_BODY_NAME", "Clay Man"); LanguageAPI.Add("CLAY_BODY_LORE", "Quick with his sword and quicker with his feet; the agility of these clay 'people' is unexpected with a form so roughly shaped.\n\nWhen faced with one of the few creatures here which I feel some humanity in, my aloneness closes in. Why do they have clay pots on their heads? Could it be protection from this cruel reality, or maybe just to hide the scars from this brutal planet."); clayObject.AddComponent <Interactor>().maxInteractionDistance = 3f; clayObject.AddComponent <InteractionDriver>(); ModelLocator clayModelLocator = clayObject.GetComponent <ModelLocator>(); clayModelLocator.modelTransform.gameObject.layer = LayerIndex.entityPrecise.intVal; clayModelLocator.modelTransform.localScale *= 1.2f; clayModelLocator.noCorpse = true; CharacterDeathBehavior clayCDB = clayObject.GetComponent <CharacterDeathBehavior>(); clayCDB.deathState = Resources.Load <GameObject>("prefabs/characterbodies/WispBody").GetComponent <CharacterDeathBehavior>().deathState; CharacterBody clayCB = clayObject.GetComponent <CharacterBody>(); clayCB.baseNameToken = "CLAY_BODY_NAME"; clayCB.baseJumpPower = 22f; clayCB.baseMaxHealth = 140f; clayCB.levelMaxHealth = clayCB.baseMaxHealth * 0.3f; clayCB.baseArmor = 0f; clayCB.baseDamage = 11f; clayCB.levelDamage = clayCB.baseDamage * 0.2f; clayCB.baseMoveSpeed = 9f; clayCB.baseRegen = 0f; clayCB.levelRegen = 0f; clayCB.bodyFlags = CharacterBody.BodyFlags.ImmuneToGoo; //Debug.Log(clayCB.GetComponent<DeathRewards>().logUnlockableName); /*UnlockableDef clayLog = ScriptableObject.CreateInstance<UnlockableDef>(); * clayCB.GetComponent<DeathRewards>().logUnlockableDef = clayLog;*/ SetStateOnHurt claySSoH = clayObject.AddComponent <SetStateOnHurt>(); claySSoH.canBeFrozen = true; claySSoH.canBeStunned = true; claySSoH.canBeHitStunned = false; claySSoH.hitThreshold = 0.15f; SfxLocator claySFX = clayObject.GetComponent <SfxLocator>(); claySFX.deathSound = "Play_clayboss_M1_explo"; claySFX.barkSound = ""; //Ice Fix Credits: SushiDev int i = 0; EntityStateMachine[] esmr = new EntityStateMachine[2]; foreach (EntityStateMachine esm in clayObject.GetComponentsInChildren <EntityStateMachine>()) { switch (esm.customName) { case "Body": claySSoH.targetStateMachine = esm; break; default: if (i < 2) { esmr[i] = esm; } i++; break; } } #region hitbox Component[] clayComponents = clayObject.GetComponentsInChildren <Transform>(); Transform clayTransform = null; Transform clayHeadTransform = null; Transform claySwordHitboxTransform = null; foreach (Transform t in clayComponents) { if (t.name == "chest") { clayTransform = t; } else if (t.name == "head") { clayHeadTransform = t; } else if (t.name == "Hitbox") { claySwordHitboxTransform = t; } if (clayTransform != null && clayHeadTransform != null && claySwordHitboxTransform != null) { break; } } ItemDisplays.headTransform = clayHeadTransform; HurtBoxGroup clayHurtBoxGroup = clayModelLocator.modelTransform.gameObject.AddComponent <HurtBoxGroup>(); claySwordHitboxTransform.localScale *= 2.4f; //2.8 -> 2.4 #region chest clayTransform.gameObject.layer = LayerIndex.entityPrecise.intVal; CapsuleCollider clayCollider = clayTransform.gameObject.AddComponent <CapsuleCollider>(); clayCollider.center -= new Vector3(0, 0.6f, 0); clayCollider.height *= 0.25f; clayCollider.radius *= 1.16f; HurtBox clayHurtBox = clayTransform.gameObject.AddComponent <HurtBox>(); clayHurtBox.isBullseye = true; clayHurtBox.healthComponent = clayObject.GetComponent <HealthComponent>(); clayHurtBox.damageModifier = HurtBox.DamageModifier.Normal; clayHurtBox.hurtBoxGroup = clayHurtBoxGroup; clayHurtBox.indexInGroup = 0; //clayHurtBox.name = "ChestHurtbox"; #endregion #region head clayHeadTransform.gameObject.layer = LayerIndex.entityPrecise.intVal; CapsuleCollider clayHeadCollider = clayHeadTransform.gameObject.AddComponent <CapsuleCollider>(); clayHeadCollider.height *= 0.4f; clayHeadCollider.radius *= 0.3f; clayHeadCollider.center += new Vector3(0, 0.2f, 0); HurtBox clayHeadHurtBox = clayHeadTransform.gameObject.AddComponent <HurtBox>(); clayHeadHurtBox.isBullseye = false; clayHeadHurtBox.healthComponent = clayObject.GetComponent <HealthComponent>(); clayHeadHurtBox.damageModifier = HurtBox.DamageModifier.SniperTarget; clayHeadHurtBox.hurtBoxGroup = clayHurtBoxGroup; clayHeadHurtBox.indexInGroup = 1; //clayHeadHurtBox.name = "HeadHurtbox"; #endregion HurtBox[] clayHurtBoxArray = new HurtBox[] { clayHurtBox, clayHeadHurtBox }; clayHurtBoxGroup.bullseyeCount = 1; clayHurtBoxGroup.hurtBoxes = clayHurtBoxArray; clayHurtBoxGroup.mainHurtBox = clayHurtBox; #endregion EntityLocator clayLocator = clayObject.AddComponent <EntityLocator>(); clayLocator.entity = clayObject; }
public static void CreatePrefab() { // first clone the commando prefab so we can turn that into our own survivor characterPrefab = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody"), "RocketeerBody", true, "C:\\Users\\Tinde\\Desktop\\Lurgypai\\ROR2\\mods\\Projects\\files\\ExampleSurvivor\\ExampleSurvivor\\ExampleSurvivor\\ExampleSurvivor\\Rocketeer.cs", "CreatePrefab", 151); characterPrefab.GetComponent <NetworkIdentity>().localPlayerAuthority = true; // set up the character body here CharacterBody bodyComponent = characterPrefab.GetComponent <CharacterBody>(); GameObject gameObject4 = new GameObject("AimOrigin"); bodyComponent.name = "RocketeerBody"; bodyComponent.baseNameToken = "ROCKETEER_NAME"; bodyComponent.subtitleNameToken = "ROCKETEER_SUBTITLE"; bodyComponent.bodyFlags = CharacterBody.BodyFlags.ImmuneToExecutes; bodyComponent.rootMotionInMainState = false; bodyComponent.mainRootSpeed = 0f; bodyComponent.baseMaxHealth = 85f; bodyComponent.levelMaxHealth = 20f; bodyComponent.baseRegen = 1.0f; bodyComponent.levelRegen = 0.2f; bodyComponent.baseMaxShield = 0f; bodyComponent.levelMaxShield = 0f; bodyComponent.baseMoveSpeed = 7f; bodyComponent.levelMoveSpeed = 0f; bodyComponent.baseAcceleration = 80f; bodyComponent.baseJumpPower = 15f; bodyComponent.levelJumpPower = 0f; bodyComponent.baseDamage = 13f; bodyComponent.levelDamage = 2.7f; bodyComponent.baseAttackSpeed = 1f; bodyComponent.levelAttackSpeed = 0f; bodyComponent.baseCrit = 1f; bodyComponent.levelCrit = 0f; bodyComponent.baseArmor = 20f; bodyComponent.levelArmor = 0f; bodyComponent.baseJumpCount = 1; bodyComponent.sprintingSpeedMultiplier = 1.45f; bodyComponent.wasLucky = false; bodyComponent.hideCrosshair = false; bodyComponent.crosshairPrefab = Resources.Load <GameObject>("Prefabs/Crosshair/StandardCrosshair"); bodyComponent.aimOriginTransform = gameObject4.transform; bodyComponent.hullClassification = HullClassification.Human; bodyComponent.isChampion = false; bodyComponent.currentVehicle = null; bodyComponent.skinIndex = 0U; bodyComponent.bodyColor = characterColor; bodyComponent.tag = "Player"; // the charactermotor controls the survivor's movement and stuff CharacterMotor characterMotor = characterPrefab.GetComponent <CharacterMotor>(); characterMotor.walkSpeedPenaltyCoefficient = 1f; characterMotor.muteWalkMotion = false; characterMotor.mass = 95f; characterMotor.airControl = 0.7f; characterMotor.disableAirControlUntilCollision = false; characterMotor.generateParametersOnAwake = true; //characterMotor.useGravity = true; //characterMotor.isFlying = false; InputBankTest inputBankTest = characterPrefab.GetComponent <InputBankTest>(); inputBankTest.moveVector = Vector3.zero; CameraTargetParams cameraTargetParams = characterPrefab.GetComponent <CameraTargetParams>(); cameraTargetParams.cameraParams = Resources.Load <GameObject>("Prefabs/CharacterBodies/CommandoBody").GetComponent <CameraTargetParams>().cameraParams; cameraTargetParams.cameraPivotTransform = null; cameraTargetParams.recoil = Vector2.zero; cameraTargetParams.idealLocalCameraPos = Vector3.zero; cameraTargetParams.dontRaycastToPivot = false; // this component is used to locate the character model(duh), important to set this up here ModelLocator modelLocator = characterPrefab.GetComponent <ModelLocator>(); //modelLocator.modelTransform = transform; //modelLocator.modelBaseTransform = gameObject.transform; modelLocator.dontReleaseModelOnDeath = false; modelLocator.autoUpdateModelTransform = true; modelLocator.dontDetatchFromParent = false; modelLocator.noCorpse = false; modelLocator.normalizeToFloor = false; // set true if you want your character to rotate on terrain like acrid does modelLocator.preserveModel = false; TeamComponent teamComponent = null; if (characterPrefab.GetComponent <TeamComponent>() != null) { teamComponent = characterPrefab.GetComponent <TeamComponent>(); } else { teamComponent = characterPrefab.GetComponent <TeamComponent>(); } teamComponent.hideAllyCardDisplay = false; teamComponent.teamIndex = TeamIndex.None; HealthComponent healthComponent = characterPrefab.GetComponent <HealthComponent>(); healthComponent.health = 100f; healthComponent.shield = 0f; healthComponent.barrier = 0f; healthComponent.magnetiCharge = 0f; healthComponent.body = null; healthComponent.dontShowHealthbar = false; healthComponent.globalDeathEventChanceCoefficient = 1f; characterPrefab.GetComponent <Interactor>().maxInteractionDistance = 3f; characterPrefab.GetComponent <InteractionDriver>().highlightInteractor = true; // this disables ragdoll since the character's not set up for it, and instead plays a death animation CharacterDeathBehavior characterDeathBehavior = characterPrefab.GetComponent <CharacterDeathBehavior>(); characterDeathBehavior.deathStateMachine = characterPrefab.GetComponent <EntityStateMachine>(); characterDeathBehavior.deathState = new SerializableEntityStateType(typeof(GenericCharacterDeath)); // edit the sfxlocator if you want different sounds SfxLocator sfxLocator = characterPrefab.GetComponent <SfxLocator>(); sfxLocator.deathSound = "Play_ui_player_death"; sfxLocator.barkSound = ""; sfxLocator.openSound = ""; sfxLocator.landingSound = "Play_char_land"; sfxLocator.fallDamageSound = "Play_char_land_fall_damage"; sfxLocator.aliveLoopStart = ""; sfxLocator.aliveLoopStop = ""; Rigidbody rigidbody = characterPrefab.GetComponent <Rigidbody>(); rigidbody.mass = 100f; rigidbody.drag = 0f; rigidbody.angularDrag = 0f; rigidbody.useGravity = false; rigidbody.isKinematic = true; rigidbody.interpolation = RigidbodyInterpolation.None; rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete; rigidbody.constraints = RigidbodyConstraints.None; CapsuleCollider capsuleCollider = characterPrefab.GetComponent <CapsuleCollider>(); capsuleCollider.isTrigger = false; capsuleCollider.material = null; capsuleCollider.center = new Vector3(0f, 0f, 0f); capsuleCollider.radius = 0.5f; capsuleCollider.height = 1.82f; capsuleCollider.direction = 1; KinematicCharacterMotor kinematicCharacterMotor = characterPrefab.GetComponent <KinematicCharacterMotor>(); kinematicCharacterMotor.CharacterController = characterMotor; kinematicCharacterMotor.Capsule = capsuleCollider; kinematicCharacterMotor.Rigidbody = rigidbody; capsuleCollider.radius = 0.5f; capsuleCollider.height = 1.82f; capsuleCollider.center = new Vector3(0, 0, 0); capsuleCollider.material = null; kinematicCharacterMotor.DetectDiscreteCollisions = false; kinematicCharacterMotor.GroundDetectionExtraDistance = 0f; kinematicCharacterMotor.MaxStepHeight = 0.2f; kinematicCharacterMotor.MinRequiredStepDepth = 0.1f; kinematicCharacterMotor.MaxStableSlopeAngle = 55f; kinematicCharacterMotor.MaxStableDistanceFromLedge = 0.5f; kinematicCharacterMotor.PreventSnappingOnLedges = false; kinematicCharacterMotor.MaxStableDenivelationAngle = 55f; kinematicCharacterMotor.RigidbodyInteractionType = RigidbodyInteractionType.None; kinematicCharacterMotor.PreserveAttachedRigidbodyMomentum = true; kinematicCharacterMotor.HasPlanarConstraint = false; kinematicCharacterMotor.PlanarConstraintAxis = Vector3.up; kinematicCharacterMotor.StepHandling = StepHandlingMethod.None; kinematicCharacterMotor.LedgeHandling = true; kinematicCharacterMotor.InteractiveRigidbodyHandling = true; kinematicCharacterMotor.SafeMovement = false; characterPrefab.AddComponent <RocketeerShinyJetpackController>(); }
private static GameObject CreateDecoyPrefab() { GameObject obj = PrefabsCore.CreatePrefab("SniperDecoy", true); TeamComponent teamComp = obj.AddOrGetComponent <TeamComponent>(); teamComp.hideAllyCardDisplay = false; teamComp.teamIndex = TeamIndex.None; NetworkIdentity netId = obj.AddOrGetComponent <NetworkIdentity>(); Transform modelBase = new GameObject("ModelBase").transform; modelBase.parent = obj.transform; modelBase.localPosition = new Vector3(0f, -0.81f, 0f); modelBase.localScale = Vector3.one; modelBase.localRotation = Quaternion.identity; GameObject mdlSniper = UnityEngine.Object.Instantiate <GameObject>(ModelModule.GetModel(), modelBase); mdlSniper.transform.localPosition = Vector3.zero; mdlSniper.transform.localScale = Vector3.one; mdlSniper.transform.localRotation = Quaternion.identity; CharacterBody body = obj.AddOrGetComponent <CharacterBody>(); body.bodyIndex = (BodyIndex)(-1); body.baseNameToken = Properties.Tokens.SNIPER_NAME; body.subtitleNameToken = Properties.Tokens.SNIPER_SUBTITLE; body.bodyFlags = CharacterBody.BodyFlags.ResistantToAOE | CharacterBody.BodyFlags.ImmuneToExecutes; body.rootMotionInMainState = false; body.mainRootSpeed = 0f; // CLEANUP: Abstract out base stats for decoy and sniper body.baseMaxHealth = 130f; body.levelMaxHealth = 39f; body.baseRegen = 1f; body.levelRegen = 0.2f; body.baseMaxShield = 0f; body.levelMaxShield = 0f; body.baseMoveSpeed = 0f; body.levelMoveSpeed = 0f; body.baseAcceleration = 0f; body.baseJumpPower = 0f; body.levelJumpPower = 0f; body.baseDamage = 12f; body.levelDamage = 2.4f; body.baseAttackSpeed = 1f; body.levelAttackSpeed = 0f; body.baseCrit = 0f; body.levelCrit = 0f; body.baseArmor = 50f; body.levelArmor = 10f; body.baseJumpCount = 1; body.sprintingSpeedMultiplier = 0f; //body.killCount = 0; body.wasLucky = false; body.spreadBloomDecayTime = 0.45f; body.spreadBloomCurve = new AnimationCurve(); body.crosshairPrefab = null; body.hideCrosshair = false; body.aimOriginTransform = body.transform; body.hullClassification = HullClassification.Human; body.portraitIcon = UIModule.GetPortraitIcon(); body.isChampion = false; body.currentVehicle = null; body.preferredPodPrefab = null; body.preferredInitialStateType = SkillsCore.StateType <GenericCharacterMain>(); body.skinIndex = 0u; CharacterModel model = mdlSniper.AddOrGetComponent <CharacterModel>(); model.body = body; model.itemDisplayRuleSet = ItemDisplayModule.GetSniperItemDisplay(model.AddOrGetComponent <ChildLocator>()); HealthComponent health = obj.AddOrGetComponent <HealthComponent>(); health.health = 100; health.shield = 0; health.barrier = 0; health.magnetiCharge = 0; health.body = null; health.dontShowHealthbar = false; health.globalDeathEventChanceCoefficient = 1f; HurtBoxGroup hurtBoxGroup = model.AddOrGetComponent <HurtBoxGroup>(); HurtBox tempHb = model.GetComponentInChildren <HurtBox>(); tempHb.gameObject.layer = LayerIndex.entityPrecise.intVal; tempHb.healthComponent = health; tempHb.isBullseye = true; tempHb.damageModifier = HurtBox.DamageModifier.Normal; tempHb.hurtBoxGroup = hurtBoxGroup; tempHb.indexInGroup = 0; hurtBoxGroup.hurtBoxes = new[] { tempHb, }; hurtBoxGroup.mainHurtBox = tempHb; hurtBoxGroup.bullseyeCount = 1; InputBankTest inputs = obj.AddOrGetComponent <InputBankTest>(); inputs.moveVector = Vector3.zero; CameraTargetParams cameraTargetParams = obj.AddOrGetComponent <CameraTargetParams>(); cameraTargetParams.cameraParams = MiscModule.GetCharCameraParams(); cameraTargetParams.cameraPivotTransform = null; cameraTargetParams.aimMode = CameraTargetParams.AimType.Standard; cameraTargetParams.recoil = Vector2.zero; cameraTargetParams.idealLocalCameraPos = Vector3.zero; cameraTargetParams.dontRaycastToPivot = false; ModelLocator modelLocator = obj.AddOrGetComponent <ModelLocator>(); modelLocator.modelTransform = mdlSniper.transform; modelLocator.modelBaseTransform = modelBase; modelLocator.dontReleaseModelOnDeath = false; modelLocator.autoUpdateModelTransform = true; modelLocator.dontDetatchFromParent = false; modelLocator.noCorpse = true; modelLocator.normalizeToFloor = false; modelLocator.preserveModel = false; EntityStateMachine esm = obj.AddOrGetComponent <EntityStateMachine>(); esm.customName = "Body"; esm.initialStateType = SkillsCore.StateType <BeingADecoy>(); esm.mainStateType = SkillsCore.StateType <BeingADecoy>(); SkillLocator skillLocator = obj.AddOrGetComponent <SkillLocator>(); skillLocator.primary = null; skillLocator.secondary = null; skillLocator.utility = null; skillLocator.special = null; CharacterDeathBehavior deathBehaviour = obj.AddOrGetComponent <CharacterDeathBehavior>(); deathBehaviour.deathStateMachine = esm; deathBehaviour.deathState = SkillsCore.StateType <DecoyDeathState>(); deathBehaviour.idleStateMachine = Array.Empty <EntityStateMachine>(); CharacterNetworkTransform netTrans = obj.AddOrGetComponent <CharacterNetworkTransform>(); netTrans.positionTransmitInterval = 0.1f; netTrans.lastPositionTransmitTime = Single.NegativeInfinity; netTrans.interpolationFactor = 2f; netTrans.debugDuplicatePositions = false; netTrans.debugSnapshotReceived = false; NetworkStateMachine netStates = obj.AddOrGetComponent <NetworkStateMachine>(); //netStates._SetStateMachines( esm ); netStates.stateMachines = new[] { esm }; Interactor interactor = obj.AddOrGetComponent <Interactor>(); interactor.maxInteractionDistance = 1f; InteractionDriver interactionDriver = obj.AddOrGetComponent <InteractionDriver>(); interactionDriver.highlightInteractor = false; CapsuleCollider cap = obj.AddOrGetComponent <CapsuleCollider>(); cap.isTrigger = false; cap.material = null; cap.center = Vector3.zero; cap.radius = 0.5f; cap.height = 1.82f; cap.direction = 1; SetStateOnHurt hurtState = obj.AddOrGetComponent <SetStateOnHurt>(); hurtState.hitThreshold = 5f; hurtState.targetStateMachine = esm; hurtState.idleStateMachine = Array.Empty <EntityStateMachine>(); hurtState.hurtState = SkillsCore.StateType <Idle>(); hurtState.canBeHitStunned = false; hurtState.canBeFrozen = true; hurtState.canBeStunned = false; SfxLocator sfx = obj.AddOrGetComponent <SfxLocator>(); // FUTURE: Death sounds for decoy Rigidbody rb = obj.AddOrGetComponent <Rigidbody>(); rb.mass = 1000f; rb.drag = 0f; rb.angularDrag = 0f; rb.useGravity = false; rb.isKinematic = true; rb.interpolation = RigidbodyInterpolation.None; rb.collisionDetectionMode = CollisionDetectionMode.Discrete; CharacterMotor charMot = obj.AddOrGetComponent <CharacterMotor>(); charMot.walkSpeedPenaltyCoefficient = 1f; CharacterDirection charDir = charMot.characterDirection = obj.AddOrGetComponent <CharacterDirection>(); charMot.muteWalkMotion = false; charMot.mass = 1000f; charMot.airControl = 0.25f; charMot.disableAirControlUntilCollision = false; charMot.generateParametersOnAwake = true; charMot.useGravity = true; charMot.isFlying = false; charDir.moveVector = Vector3.zero; charDir.targetTransform = modelBase; charDir.overrideAnimatorForwardTransform = null; charDir.rootMotionAccumulator = null; charDir.modelAnimator = null; charDir.driveFromRootRotation = false; charDir.driveFromRootRotation = false; charDir.turnSpeed = 180f; KinematicCharacterController.KinematicCharacterMotor kinCharMot = obj.AddOrGetComponent <KinematicCharacterController.KinematicCharacterMotor>(); kinCharMot.CharacterController = charMot; kinCharMot.Capsule = cap; kinCharMot.Rigidbody = rb; kinCharMot.CapsuleRadius = 0.5f; kinCharMot.CapsuleHeight = 1.8f; kinCharMot.CapsuleYOffset = 0f; kinCharMot.DetectDiscreteCollisions = false; kinCharMot.GroundDetectionExtraDistance = 0f; kinCharMot.MaxStepHeight = 0.5f; kinCharMot.MinRequiredStepDepth = 0.1f; kinCharMot.MaxStableSlopeAngle = 55f; kinCharMot.MaxStableDistanceFromLedge = 0.5f; kinCharMot.PreventSnappingOnLedges = false; kinCharMot.MaxStableDenivelationAngle = 55f; kinCharMot.RigidbodyInteractionType = KinematicCharacterController.RigidbodyInteractionType.None; kinCharMot.PreserveAttachedRigidbodyMomentum = true; kinCharMot.HasPlanarConstraint = false; kinCharMot.PlanarConstraintAxis = Vector3.up; kinCharMot.StepHandling = KinematicCharacterController.StepHandlingMethod.Standard; kinCharMot.LedgeHandling = true; kinCharMot.InteractiveRigidbodyHandling = true; kinCharMot.SafeMovement = false; _ = obj.AddComponent <DecoyDeployableSync>(); obj.layer = LayerIndex.fakeActor.intVal; foreach (IRuntimePrefabComponent comp in obj.GetComponents <IRuntimePrefabComponent>()) { comp.InitializePrefab(); } BodiesCore.Add(obj); return(obj); }
public override void OnLoad() { base.OnLoad(); itemDef.name = "MysticsItems_RiftLens"; SetItemTierWhenAvailable(ItemTier.Lunar); itemDef.tags = new ItemTag[] { ItemTag.Utility, ItemTag.AIBlacklist, ItemTag.CannotCopy, ItemTag.OnStageBeginEffect }; MysticsItemsContent.Resources.unlockableDefs.Add(GetUnlockableDef()); itemDef.pickupModelPrefab = PrepareModel(Main.AssetBundle.LoadAsset <GameObject>("Assets/Items/Rift Lens/Model.prefab")); itemDef.pickupIconSprite = Main.AssetBundle.LoadAsset <Sprite>("Assets/Items/Rift Lens/Icon.png"); ModelPanelParameters modelPanelParams = itemDef.pickupModelPrefab.GetComponentInChildren <ModelPanelParameters>(); modelPanelParams.minDistance = 2; modelPanelParams.maxDistance = 6; itemDisplayPrefab = PrepareItemDisplayModel(PrefabAPI.InstantiateClone(itemDef.pickupModelPrefab, itemDef.pickupModelPrefab.name + "Display", false)); onSetupIDRS += () => { AddDisplayRule("CommandoBody", "Head", new Vector3(0.1f, 0.25f, 0.15f), new Vector3(20f, 210f, 0f), new Vector3(0.06f, 0.06f, 0.06f)); AddDisplayRule("HuntressBody", "Head", new Vector3(-0.0009F, 0.2635F, 0.1117F), new Vector3(0F, 180F, 0F), new Vector3(0.03F, 0.03F, 0.03F)); AddDisplayRule("Bandit2Body", "Head", new Vector3(0F, 0.057F, 0.135F), new Vector3(0F, 180F, 180F), new Vector3(0.028F, 0.028F, 0.028F)); AddDisplayRule("ToolbotBody", "Head", new Vector3(0.409F, 3.049F, -1.067F), new Vector3(60F, 0F, 180F), new Vector3(0.3F, 0.3F, 0.3F)); AddDisplayRule("EngiBody", "HeadCenter", new Vector3(0.098F, 0.019F, 0.127F), new Vector3(1.506F, 213.327F, 354.045F), new Vector3(0.029F, 0.029F, 0.029F)); AddDisplayRule("EngiTurretBody", "Head", new Vector3(0.005F, 0.525F, 2.043F), new Vector3(0F, 180F, 0F), new Vector3(0.108F, 0.083F, 0.083F)); AddDisplayRule("EngiWalkerTurretBody", "Head", new Vector3(0.006F, 0.774F, 0.853F), new Vector3(0F, 177.859F, 0F), new Vector3(0.306F, 0.306F, 0.306F)); AddDisplayRule("MageBody", "Head", new Vector3(0.048F, 0.06F, 0.117F), new Vector3(13.941F, 189.822F, 2.364F), new Vector3(0.026F, 0.026F, 0.026F)); AddDisplayRule("MercBody", "Head", new Vector3(0.05F, 0.156F, 0.151F), new Vector3(10.716F, 202.078F, 355.897F), new Vector3(0.053F, 0.053F, 0.053F)); AddDisplayRule("TreebotBody", "HeadCenter", new Vector3(-0.005F, 0.058F, -0.002F), new Vector3(85.226F, 270F, 270F), new Vector3(0.098F, 0.098F, 0.098F)); AddDisplayRule("LoaderBody", "Head", new Vector3(0.051F, 0.125F, 0.134F), new Vector3(10.267F, 205.465F, 354.736F), new Vector3(0.047F, 0.04F, 0.048F)); AddDisplayRule("CrocoBody", "Head", new Vector3(-1.531F, 1.934F, 0.459F), new Vector3(14.526F, 104.513F, 346.531F), new Vector3(0.236F, 0.236F, 0.236F)); AddDisplayRule("CaptainBody", "HandR", new Vector3(-0.085F, 0.108F, 0.013F), new Vector3(69.075F, 70.114F, 350.542F), new Vector3(0.026F, 0.03F, 0.042F)); AddDisplayRule("BrotherBody", "Head", BrotherInfection.blue, new Vector3(0.003F, -0.01F, 0.061F), new Vector3(349.888F, 70.121F, 339.729F), new Vector3(0.133F, 0.133F, 0.133F)); AddDisplayRule("ScavBody", "Head", new Vector3(5.068F, 4.15F, -0.55F), new Vector3(46.576F, 301.45F, 310.155F), new Vector3(1.363F, 1.363F, 1.363F)); if (SoftDependencies.SoftDependenciesCore.itemDisplaysSniper) { AddDisplayRule("SniperClassicBody", "GunBarrel", new Vector3(0.00002F, 0.07266F, -0.32569F), new Vector3(0F, 180F, 0F), new Vector3(0.02325F, 0.02325F, 0.02325F)); } AddDisplayRule("RailgunnerBody", "GunScope", new Vector3(-0.07466F, -0.14553F, 0.31781F), new Vector3(0F, 180F, 0F), new Vector3(0.02909F, 0.02909F, 0.02909F)); AddDisplayRule("VoidSurvivorBody", "Head", new Vector3(0.00001F, 0.17385F, 0.09392F), new Vector3(58.31651F, 180F, 180F), new Vector3(0.03831F, 0.03831F, 0.03831F)); }; MysticsItemsRiftChest component = riftChest.AddComponent <MysticsItemsRiftChest>(); SfxLocator sfxLocator = riftChest.AddComponent <SfxLocator>(); sfxLocator.openSound = "Play_env_riftchest_open"; riftChest.AddComponent <GenericDisplayNameProvider>().displayToken = "MYSTICSITEMS_RIFTCHEST_NAME"; PurchaseInteraction purchaseInteraction = riftChest.AddComponent <PurchaseInteraction>(); purchaseInteraction.displayNameToken = "MYSTICSITEMS_RIFTCHEST_NAME"; purchaseInteraction.contextToken = "MYSTICSITEMS_RIFTCHEST_CONTEXT"; ChestBehavior chestBehavior = riftChest.AddComponent <ChestBehavior>(); chestBehavior.dropTable = Addressables.LoadAssetAsync <PickupDropTable>("RoR2/Base/Chest1/dtChest1.asset").WaitForCompletion(); riftChest.transform.Find("InteractionCollider").gameObject.AddComponent <EntityLocator>().entity = riftChest; riftChest.transform.Find("RiftOrigin/Sprite").gameObject.AddComponent <Billboard>(); ObjectScaleCurve objectScaleCurve = riftChest.transform.Find("RiftOrigin").gameObject.AddComponent <ObjectScaleCurve>(); objectScaleCurve.useOverallCurveOnly = true; objectScaleCurve.overallCurve = new AnimationCurve() { keys = new Keyframe[] { new Keyframe(0f, 1f), new Keyframe(1f, 0f) } }; objectScaleCurve.timeMax = 0.5f; objectScaleCurve.enabled = false; //post processing GameObject ppHolder = Object.Instantiate(PrefabAPI.InstantiateClone(new GameObject("RiftLensPostProcessing"), "RiftLensPostProcessing", false), riftChest.transform); ppHolder.layer = LayerIndex.postProcess.intVal; PostProcessVolume pp = ppHolder.AddComponent <PostProcessVolume>(); pp.isGlobal = false; pp.weight = 1f; pp.priority = 50; pp.blendDistance = 10f; SphereCollider sphereCollider = ppHolder.AddComponent <SphereCollider>(); sphereCollider.radius = 5f; sphereCollider.isTrigger = true; PostProcessProfile ppProfile = ScriptableObject.CreateInstance <PostProcessProfile>(); ppProfile.name = "ppRiftLens"; LensDistortion lensDistortion = ppProfile.AddSettings <LensDistortion>(); lensDistortion.SetAllOverridesTo(true); lensDistortion.intensity.value = -30f; lensDistortion.scale.value = 1f; ColorGrading colorGrading = ppProfile.AddSettings <ColorGrading>(); colorGrading.colorFilter.value = new Color32(178, 242, 255, 255); colorGrading.colorFilter.overrideState = true; pp.sharedProfile = ppProfile; PostProcessDuration ppDuration = pp.gameObject.AddComponent <PostProcessDuration>(); ppDuration.ppVolume = pp; ppDuration.ppWeightCurve = new AnimationCurve { keys = new Keyframe[] { new Keyframe(0f, 1f, 0f, Mathf.Tan(-45f * Mathf.Deg2Rad)), new Keyframe(1f, 0f, Mathf.Tan(135f * Mathf.Deg2Rad), 0f) }, preWrapMode = WrapMode.Clamp, postWrapMode = WrapMode.Clamp }; ppDuration.maxDuration = 1; ppDuration.destroyOnEnd = true; ppDuration.enabled = false; component.ppDuration = ppDuration; riftChestSpawnCard = ScriptableObject.CreateInstance <InteractableSpawnCard>(); riftChestSpawnCard.name = "iscMysticsItems_UnstableRift"; riftChestSpawnCard.directorCreditCost = 0; riftChestSpawnCard.forbiddenFlags = NodeFlags.NoChestSpawn; riftChestSpawnCard.hullSize = HullClassification.Human; riftChestSpawnCard.nodeGraphType = MapNodeGroup.GraphType.Ground; riftChestSpawnCard.occupyPosition = true; riftChestSpawnCard.orientToFloor = false; riftChestSpawnCard.sendOverNetwork = true; riftChestSpawnCard.prefab = riftChest; GenericGameEvents.OnPopulateScene += (rng) => { int riftsToSpawn = 0; foreach (CharacterMaster characterMaster in CharacterMaster.readOnlyInstancesList) { if (characterMaster.teamIndex == TeamIndex.Player) { int thisItemCount = characterMaster.inventory.GetItemCount(itemDef); if (thisItemCount > 0) { characterMaster.inventory.RemoveItem(MysticsItemsContent.Items.MysticsItems_RiftLensDebuff, characterMaster.inventory.GetItemCount(MysticsItemsContent.Items.MysticsItems_RiftLensDebuff)); characterMaster.inventory.GiveItem(MysticsItemsContent.Items.MysticsItems_RiftLensDebuff, baseRifts + riftsPerStack * (thisItemCount - 1)); riftsToSpawn += baseRifts.Value + riftsPerStack.Value * (thisItemCount - 1); } } } if (riftsToSpawn > 0) { for (int i = 0; i < riftsToSpawn; i++) { GameObject riftChest = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest(riftChestSpawnCard, new DirectorPlacementRule { placementMode = DirectorPlacementRule.PlacementMode.Random }, rng)); } } MysticsItemsRiftLensBehaviour.CalculateCountdownForAll(); }; On.RoR2.CharacterBody.OnInventoryChanged += (orig, self) => { orig(self); self.AddItemBehavior <MysticsItemsRiftLensBehaviour>(self.inventory.GetItemCount(itemDef)); }; ObjectivePanelController.collectObjectiveSources += ObjectivePanelController_collectObjectiveSources; hudPanelPrefab = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load <GameObject>("Prefabs/UI/HudModules/HudCountdownPanel"), "RiftLensHUDPanel"); hudPanelPrefab.transform.Find("Juice/Container/CountdownTitleLabel").GetComponent <LanguageTextMeshController>().token = "OBJECTIVE_MYSTICSITEMS_RIFTLENS_FLAVOUR"; var col = new Color32(0, 157, 255, 255); hudPanelPrefab.transform.Find("Juice/Container/Border").GetComponent <Image>().color = col; hudPanelPrefab.transform.Find("Juice/Container/CountdownLabel").GetComponent <HGTextMeshProUGUI>().color = col; PositionIndicator positionIndicator = riftPositionIndicator.AddComponent <PositionIndicator>(); positionIndicator.insideViewObject = riftPositionIndicator.transform.Find("InsideFrame").gameObject; positionIndicator.outsideViewObject = riftPositionIndicator.transform.Find("OutsideFrame").gameObject; positionIndicator.alwaysVisibleObject = riftPositionIndicator.transform.Find("Sprite").gameObject; positionIndicator.shouldRotateOutsideViewObject = true; positionIndicator.outsideViewRotationOffset = 90f; GenericGameEvents.OnPlayerCharacterDeath += GenericGameEvents_OnPlayerCharacterDeath; }