public override void OnLoad()
        {
            base.OnLoad();
            itemDef.name = "MysticsItems_DasherDisc";
            SetItemTierWhenAvailable(ItemTier.Tier3);
            itemDef.tags = new ItemTag[]
            {
                ItemTag.Utility
            };
            MysticsItemsContent.Resources.unlockableDefs.Add(GetUnlockableDef());
            itemDef.pickupModelPrefab = PrepareModel(Main.AssetBundle.LoadAsset <GameObject>("Assets/Items/Dasher Disc/Model.prefab"));
            itemDef.pickupIconSprite  = Main.AssetBundle.LoadAsset <Sprite>("Assets/Items/Dasher Disc/Icon.png");
            Material mat = itemDef.pickupModelPrefab.transform.Find("mdlDasherDisc").GetComponent <MeshRenderer>().sharedMaterial;

            HopooShaderToMaterial.Standard.Apply(mat);
            HopooShaderToMaterial.Standard.Emission(mat, 4f);
            HopooShaderToMaterial.Standard.Gloss(mat);
            MysticsItemsDasherDiscSpinner spinner = itemDef.pickupModelPrefab.transform.Find("mdlDasherDisc").gameObject.AddComponent <MysticsItemsDasherDiscSpinner>();

            spinner.trail     = itemDef.pickupModelPrefab.transform.Find("mdlDasherDisc").Find("Particle System").gameObject;
            itemDisplayPrefab = PrepareItemDisplayModel(PrefabAPI.InstantiateClone(itemDef.pickupModelPrefab, itemDef.pickupModelPrefab.name + "Display", false));
            itemDisplayPrefab.transform.Find("mdlDasherDisc").localScale = Vector3.one * 5f;

            controllerPrefab.AddComponent <GenericOwnership>();
            NetworkedBodyAttachment networkedBodyAttachment = controllerPrefab.AddComponent <NetworkedBodyAttachment>();

            networkedBodyAttachment.forceHostAuthority = true;
            EntityStateMachine stateMachine = controllerPrefab.AddComponent <EntityStateMachine>();

            stateMachine.mainStateType = stateMachine.initialStateType = new SerializableEntityStateType(typeof(DiscBaseState.Ready));
            NetworkStateMachine networkStateMachine = controllerPrefab.AddComponent <NetworkStateMachine>();

            networkStateMachine.SetFieldValue("stateMachines", new EntityStateMachine[] {
                stateMachine
            });
            DiscController component = controllerPrefab.AddComponent <DiscController>();
            GameObject     follower  = PrefabAPI.InstantiateClone(itemDisplayPrefab, "DasherDiscFollower", false);

            follower.transform.SetParent(controllerPrefab.transform);
            component.follower    = follower;
            component.disc        = follower.transform.Find("mdlDasherDisc").gameObject;
            component.discSpinner = component.disc.GetComponent <MysticsItemsDasherDiscSpinner>();

            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(DiscBaseState));
            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(DiscBaseState.Ready));
            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(DiscBaseState.Trigger));
            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(DiscBaseState.Invincible));

            On.RoR2.CharacterBody.Awake += (orig, self) =>
            {
                orig(self);
                self.onInventoryChanged += delegate()
                {
                    if (NetworkServer.active)
                    {
                        self.AddItemBehavior <MysticsItemsDasherDiscBehaviour>(self.inventory.GetItemCount(itemDef));
                    }
                };
            };
        }
Exemple #2
0
        private void RW_DoStateMachines()
        {
            NetworkStateMachine    net   = this.RW_body.GetComponent <NetworkStateMachine>();
            CharacterDeathBehavior death = this.RW_body.GetComponent <CharacterDeathBehavior>();

            death.idleStateMachine = new EntityStateMachine[2];
            death.deathState       = new SerializableEntityStateType(typeof(EntityStates.Commando.DeathState));



            EntityStateMachine[] netStates = net.stateMachines;// this.stateMachines.Get( net );

            Array.Resize <EntityStateMachine>(ref netStates, 3);

            SetStateOnHurt hurtState = this.RW_body.GetComponent <SetStateOnHurt>();

            hurtState.canBeFrozen     = true;
            hurtState.canBeHitStunned = false;
            hurtState.canBeStunned    = true;
            hurtState.hitThreshold    = 5f;
            hurtState.hurtState       = new SerializableEntityStateType(typeof(EntityStates.FrozenState));

            foreach (EntityStateMachine esm in this.RW_body.GetComponents <EntityStateMachine>())
            {
                switch (esm.customName)
                {
                case "Body":
                    esm.initialStateType         = new SerializableEntityStateType(typeof(SpawnTeleporterState));
                    esm.mainStateType            = new SerializableEntityStateType(typeof(GenericCharacterMain));
                    netStates[0]                 = esm;
                    hurtState.targetStateMachine = esm;
                    death.deathStateMachine      = esm;
                    break;

                case "Weapon":
                    esm.initialStateType      = new SerializableEntityStateType(typeof(Idle));
                    esm.mainStateType         = new SerializableEntityStateType(typeof(Idle));
                    netStates[1]              = esm;
                    death.idleStateMachine[0] = esm;
                    break;

                case "Gaze":
                    esm.initialStateType      = new SerializableEntityStateType(typeof(Idle));
                    esm.mainStateType         = new SerializableEntityStateType(typeof(Idle));
                    netStates[2]              = esm;
                    death.idleStateMachine[1] = esm;
                    break;

                default:
                    break;
                }
            }

            net.stateMachines = netStates;
            //this.stateMachines.Set( net, netStates );
        }
        public override void OnLoad()
        {
            equipmentDef.name = "MysticsItems_MechanicalArm";
            ConfigManager.Balance.CreateEquipmentCooldownOption(equipmentDef, "Equipment: Mechanical Arm", 20f);
            equipmentDef.canDrop = true;
            ConfigManager.Balance.CreateEquipmentEnigmaCompatibleOption(equipmentDef, "Equipment: Mechanical Arm", true);
            ConfigManager.Balance.CreateEquipmentCanBeRandomlyTriggeredOption(equipmentDef, "Equipment: Mechanical Arm", false);
            equipmentDef.pickupModelPrefab = PrepareModel(Main.AssetBundle.LoadAsset <GameObject>("Assets/Equipment/Mechanical Arm/Model.prefab"));
            equipmentDef.pickupIconSprite  = Main.AssetBundle.LoadAsset <Sprite>("Assets/Equipment/Mechanical Arm/Icon.png");

            void ApplyToModels(GameObject model)
            {
                var mat = model.GetComponentInChildren <SkinnedMeshRenderer>().sharedMaterial;

                HopooShaderToMaterial.Standard.Apply(mat);
                HopooShaderToMaterial.Standard.Gloss(mat);
                HopooShaderToMaterial.Standard.Emission(mat, 1.5f, new Color32(191, 15, 3, 255));
            }

            ApplyToModels(equipmentDef.pickupModelPrefab);

            ModelPanelParameters modelPanelParameters = equipmentDef.pickupModelPrefab.GetComponent <ModelPanelParameters>();

            modelPanelParameters.minDistance = 6f;
            modelPanelParameters.maxDistance = 12f;

            itemDisplayPrefab = PrepareItemDisplayModel(Main.AssetBundle.LoadAsset <GameObject>("Assets/Equipment/Mechanical Arm/MovingModel.prefab"));
            onSetupIDRS      += () =>
            {
                AddDisplayRule("CommandoBody", "Chest", new Vector3(0.07816F, 0.25502F, -0.15061F), new Vector3(0F, 180F, 0F), new Vector3(0.07862F, 0.07862F, 0.07862F));
                AddDisplayRule("HuntressBody", "Chest", new Vector3(0.10676F, 0.14576F, -0.04849F), new Vector3(0F, 180F, 0F), new Vector3(0.03776F, 0.03776F, 0.03776F));
                AddDisplayRule("Bandit2Body", "Chest", new Vector3(0.00326F, 0.18527F, -0.12067F), new Vector3(0F, 185.5073F, 0F), new Vector3(0.05941F, 0.05941F, 0.05941F));
                AddDisplayRule("ToolbotBody", "Chest", new Vector3(2.63852F, 1.90061F, 0.02656F), new Vector3(0F, 180F, 0F), new Vector3(0.56946F, 0.56946F, 0.56946F));
                AddDisplayRule("EngiBody", "Chest", new Vector3(0.01994F, 0.13958F, -0.23417F), new Vector3(0F, 180F, 0F), new Vector3(0.06142F, 0.06142F, 0.06142F));
                AddDisplayRule("MageBody", "Chest", new Vector3(0.09002F, 0.03363F, -0.2332F), new Vector3(0F, 175.5407F, 0F), new Vector3(0.05358F, 0.05358F, 0.05358F));
                AddDisplayRule("MercBody", "Chest", new Vector3(0.00246F, 0.14756F, -0.16344F), new Vector3(0F, 202.2791F, 0F), new Vector3(0.08846F, 0.08846F, 0.08846F));
                AddDisplayRule("TreebotBody", "PlatformBase", new Vector3(0.53248F, 0.66126F, 0F), new Vector3(0F, 180F, 0F), new Vector3(0.19873F, 0.19873F, 0.19873F));
                AddDisplayRule("LoaderBody", "MechBase", new Vector3(-0.03249F, 0.00003F, -0.06065F), new Vector3(0F, 206.8929F, 0F), new Vector3(0.09891F, 0.09891F, 0.09796F));
                AddDisplayRule("CrocoBody", "SpineChest2", new Vector3(0F, -0.86934F, 0.00013F), new Vector3(0F, 0F, 0F), new Vector3(0.83816F, 0.83816F, 0.83816F));
                AddDisplayRule("CaptainBody", "Chest", new Vector3(-0.00812F, 0.17595F, -0.14316F), new Vector3(0F, 218.1953F, 0F), new Vector3(0.09604F, 0.09604F, 0.09604F));
                AddDisplayRule("ScavBody", "Backpack", new Vector3(6.49963F, 6.38849F, 0.00031F), new Vector3(0F, 180F, 0F), new Vector3(2.02387F, 2.02387F, 2.02387F));
                AddDisplayRule("EquipmentDroneBody", "HeadCenter", new Vector3(0.4758F, 0F, -0.48188F), new Vector3(270F, 180F, 0F), new Vector3(0.42601F, 0.42601F, 0.42601F));
                if (SoftDependencies.SoftDependenciesCore.itemDisplaysSniper)
                {
                    AddDisplayRule("SniperClassicBody", "Chest", new Vector3(0.1706F, 0.13246F, -0.20744F), new Vector3(0F, 180F, 0F), new Vector3(0.053F, 0.053F, 0.053F));
                }
                AddDisplayRule("RailgunnerBody", "Backpack", new Vector3(0.08517F, 0.21948F, 0.00002F), new Vector3(0F, 180F, 0F), new Vector3(0.09344F, 0.09344F, 0.09344F));
                AddDisplayRule("VoidSurvivorBody", "Center", new Vector3(-0.0074F, 0.3145F, -0.08637F), new Vector3(359.7796F, 219.7314F, 0.26983F), new Vector3(0.07043F, 0.07043F, 0.07043F));
            };

            ChildLocator childLocator = itemDisplayPrefab.AddComponent <ChildLocator>();

            NetworkedBodyAttachment networkedBodyAttachment = mechanicalArmControllerPrefab.AddComponent <NetworkedBodyAttachment>();

            networkedBodyAttachment.shouldParentToAttachedBody = true;
            networkedBodyAttachment.forceHostAuthority         = true;

            EntityStateMachine entityStateMachine = mechanicalArmControllerPrefab.AddComponent <EntityStateMachine>();

            entityStateMachine.initialStateType = entityStateMachine.mainStateType = new EntityStates.SerializableEntityStateType(typeof(MysticsItemsMechanicalArmState.Idle));

            NetworkStateMachine networkStateMachine = mechanicalArmControllerPrefab.AddComponent <NetworkStateMachine>();

            networkStateMachine.SetFieldValue("stateMachines", new EntityStateMachine[] {
                entityStateMachine
            });

            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(MysticsItemsMechanicalArmState));
            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(MysticsItemsMechanicalArmState.Idle));
            MysticsItemsContent.Resources.entityStateTypes.Add(typeof(MysticsItemsMechanicalArmState.Swing));

            ModelLocator modelLocator = mechanicalArmControllerPrefab.AddComponent <ModelLocator>();

            modelLocator.dontReleaseModelOnDeath  = false;
            modelLocator.autoUpdateModelTransform = false;
            modelLocator.dontDetatchFromParent    = true;
            modelLocator.preserveModel            = true;

            PrefabAPI.InstantiateClone(
                Main.AssetBundle.LoadAsset <GameObject>("Assets/Equipment/Mechanical Arm/MovingModel.prefab")
                .transform.Find("HitboxGroup").gameObject,
                "HitboxGroup",
                false
                ).transform.SetParent(mechanicalArmControllerPrefab.transform);
            Object.Destroy(itemDisplayPrefab.transform.Find("HitboxGroup").gameObject);
            HitBoxGroup hitBoxGroup = mechanicalArmControllerPrefab.transform.Find("HitboxGroup").gameObject.AddComponent <HitBoxGroup>();

            hitBoxGroup.groupName = "MysticsItems_MechanicalArmSwing";
            hitBoxGroup.hitBoxes  = new HitBox[]
            {
                mechanicalArmControllerPrefab.transform.Find("HitboxGroup/Hitbox").gameObject.AddComponent <HitBox>()
            };
            hitBoxGroup.gameObject.SetActive(true);

            AnimationCurve MakeGenericCurve()
            {
                return(new AnimationCurve {
                    keys = new Keyframe[] { new Keyframe(0, 1), new Keyframe(1, 1) }
                });
            }

            Transform armRoot = null;

            foreach (var child in itemDisplayPrefab.GetComponentsInChildren <Transform>())
            {
                var childName = child.name;
                if (childName == "arm.1")
                {
                    armRoot = child;
                    var ntp = new ChildLocator.NameTransformPair
                    {
                        name      = "Arm1",
                        transform = child
                    };
                    HGArrayUtilities.ArrayAppend(ref childLocator.transformPairs, ref ntp);
                }
                else
                {
                    if (childName.StartsWith("arm.", false, System.Globalization.CultureInfo.InvariantCulture))
                    {
                        var ntp = new ChildLocator.NameTransformPair
                        {
                            name      = "Arm" + childName.Remove(0, "arm.".Length),
                            transform = child
                        };
                        HGArrayUtilities.ArrayAppend(ref childLocator.transformPairs, ref ntp);

                        DynamicBone dynamicBone = child.gameObject.AddComponent <DynamicBone>();
                        dynamicBone.m_Root              = child;
                        dynamicBone.m_UpdateRate        = 60;
                        dynamicBone.m_UpdateMode        = DynamicBone.UpdateMode.Normal;
                        dynamicBone.m_Damping           = 0.8f;
                        dynamicBone.m_DampingDistrib    = MakeGenericCurve();
                        dynamicBone.m_Elasticity        = 0.1f;
                        dynamicBone.m_ElasticityDistrib = MakeGenericCurve();
                        dynamicBone.m_Stiffness         = 0.9f;
                        dynamicBone.m_StiffnessDistrib  = MakeGenericCurve();
                        dynamicBone.m_Inert             = 0f;
                        dynamicBone.m_InertDistrib      = MakeGenericCurve();
                        dynamicBone.m_Radius            = 0f;
                        dynamicBone.m_RadiusDistrib     = MakeGenericCurve();
                    }
                }
            }

            On.RoR2.EquipmentSlot.FixedUpdate += (orig, self) =>
            {
                orig(self);
                if (NetworkServer.active)
                {
                    MysticsItemsMechanicalArmState armController = MysticsItemsMechanicalArmState.FindMechanicalArmController(self.gameObject);

                    bool carryingThisEquipment = self.equipmentIndex == equipmentDef.equipmentIndex;
                    if (carryingThisEquipment != (armController != null))
                    {
                        if (carryingThisEquipment)
                        {
                            var armControllerInstance = Object.Instantiate <GameObject>(mechanicalArmControllerPrefab);
                            armControllerInstance.GetComponent <NetworkedBodyAttachment>().AttachToGameObjectAndSpawn(self.gameObject);
                            return;
                        }
                        Object.Destroy(armController.gameObject);
                    }
                }
            };

            var swingEffectPrefab = MysticsItemsMechanicalArmState.Swing.swingEffectPrefab = Main.AssetBundle.LoadAsset <GameObject>("Assets/Equipment/Mechanical Arm/SwingEffect.prefab");
            ScaleParticleSystemDuration scaleParticleSystemDuration = swingEffectPrefab.AddComponent <ScaleParticleSystemDuration>();

            scaleParticleSystemDuration.particleSystems = swingEffectPrefab.GetComponentsInChildren <ParticleSystem>();
            scaleParticleSystemDuration.initialDuration = 1f;
            ShakeEmitter shakeEmitter = swingEffectPrefab.AddComponent <ShakeEmitter>();

            shakeEmitter.duration = 0.2f;
            shakeEmitter.radius   = 20f;
            shakeEmitter.wave     = new Wave
            {
                amplitude = 4f,
                frequency = 4f
            };
            shakeEmitter.amplitudeTimeDecay = true;
            shakeEmitter.shakeOnStart       = true;
            shakeEmitter.shakeOnEnable      = false;

            MysticsItemsMechanicalArmState.Swing.hitEffectPrefab = LegacyResourcesAPI.Load <GameObject>("Prefabs/Effects/ImpactEffects/SawmerangImpact");
            var snd = ScriptableObject.CreateInstance <NetworkSoundEventDef>();

            snd.eventName = "MysticsItems_Play_mechanicalArm_impact";
            MysticsItemsContent.Resources.networkSoundEventDefs.Add(snd);
            MysticsItemsMechanicalArmState.Swing.impactSound = snd;

            GenericGameEvents.OnHitEnemy += GenericGameEvents_OnHitEnemy;

            RecalculateStatsAPI.GetStatCoefficients += RecalculateStatsAPI_GetStatCoefficients;
        }
Exemple #4
0
        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();
            }
        }
Exemple #5
0
        private void AW_GetBody()
        {
            this.AW_body = Resources.Load <GameObject>("Prefabs/CharacterBodies/AncientWispBody").ClonePrefab("WispBossBody", true);

            var sound = this.AW_body.AddComponent <StartEndSound>();

            sound.startSound = "Play_huntress_R_aim_loop";
            sound.endSound   = "Stop_huntress_R_aim_loop";

            var charBody = this.AW_body.GetComponent <CharacterBody>();

            charBody.baseNameToken     = Rein.Properties.Tokens.ANCIENT_WISP_BODY_NAME;
            charBody.subtitleNameToken = Rein.Properties.Tokens.ANCIENT_WISP_BODY_SUBNAME;

            //LanguageCore.AddLanguageToken( "ANCIENT_WISP_BODY_NAME", "Ancient Wisp" );
            //LanguageCore.AddLanguageToken( "ANCIENT_WISP_BODY_SUBNAME", "Banished and Chained" );
            //R2API.AssetPlus.Languages.AddToken( "ANCIENT_WISP_BODY_NAME", "Ancient Wisp" );
            //R2API.AssetPlus.Languages.AddToken( "ANCIENT_WISP_BODY_SUBNAME", "Banished and Chained" );

            charBody.baseMaxHealth  = 10000;
            charBody.levelMaxHealth = 3000;

            charBody.baseRegen  = 0f;
            charBody.levelRegen = 0f;

            charBody.baseMaxShield  = 0f;
            charBody.levelMaxShield = 0f;

            charBody.baseMoveSpeed  = 15f;
            charBody.levelMoveSpeed = 0f;

            charBody.baseAcceleration = 10f;

            charBody.baseJumpPower  = 0f;
            charBody.levelJumpPower = 0f;

            charBody.baseDamage  = 40f;
            charBody.levelDamage = 8f;

            charBody.baseAttackSpeed  = 1f;
            charBody.levelAttackSpeed = 0f;

            charBody.baseCrit  = 0f;
            charBody.levelCrit = 0f;

            charBody.baseArmor  = 30f;
            charBody.levelArmor = 0f;

            charBody.baseJumpCount = 0;



            NetworkStateMachine    net   = this.AW_body.GetComponent <NetworkStateMachine>();
            CharacterDeathBehavior death = this.AW_body.GetComponent <CharacterDeathBehavior>();

            death.idleStateMachine = new EntityStateMachine[1];
            death.deathState       = new EntityStates.SerializableEntityStateType(typeof(EntityStates.Commando.DeathState));

            EntityStateMachine[] netStates = net.stateMachines;
            Array.Resize <EntityStateMachine>(ref netStates, 2);


            SetStateOnHurt hurtState = this.AW_body.AddOrGetComponent <SetStateOnHurt>();

            hurtState.canBeFrozen     = false;
            hurtState.canBeHitStunned = false;
            hurtState.canBeStunned    = false;
            hurtState.hitThreshold    = 5f;
            hurtState.hurtState       = new SerializableEntityStateType(typeof(EntityStates.FrozenState));

            SkillsCore.AddSkill(typeof(AWDefaultMain));
            SkillsCore.AddSkill(typeof(AWEnrageTransition));
            SkillsCore.AddSkill(typeof(AWEnrageMainState));

            foreach (EntityStateMachine esm in this.AW_body.GetComponents <EntityStateMachine>())
            {
                switch (esm.customName)
                {
                case "Body":
                    netStates[0]                 = esm;
                    esm.mainStateType            = new SerializableEntityStateType(typeof(AWDefaultMain)); //typeof( AWDefaultMain ).EntityStateType();
                    esm.initialStateType         = new SerializableEntityStateType(typeof(AWDefaultMain)); //typeof( AWDefaultMain ).EntityStateType();
                    hurtState.targetStateMachine = esm;
                    death.deathStateMachine      = esm;
                    break;

                case "Weapon":
                    esm.initialStateType      = new SerializableEntityStateType(typeof(Idle));
                    esm.mainStateType         = new SerializableEntityStateType(typeof(Idle));
                    netStates[1]              = esm;
                    death.idleStateMachine[0] = esm;
                    break;

                default:
                    break;
                }
            }

            net.stateMachines = netStates;
        }
        public static void Create()
        {
            stanWorshipperBody = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("prefabs/characterbodies/BanditBody"), "StanWorshipperBody", true);
            stanWorshipperBody.GetComponent <NetworkIdentity>().localPlayerAuthority = true;

            CharacterBody bodyComponent = stanWorshipperBody.GetComponent <CharacterBody>();

            bodyComponent.bodyIndex             = BodyIndex.None;
            bodyComponent.baseNameToken         = "STANWORSHIPPER_NAME";
            bodyComponent.subtitleNameToken     = "STANWORSHIPPER_SUBTITLE";
            bodyComponent.bodyFlags             = CharacterBody.BodyFlags.ImmuneToExecutes;
            bodyComponent.rootMotionInMainState = false;
            bodyComponent.mainRootSpeed         = 0;
            bodyComponent.baseMaxHealth         = 100;
            bodyComponent.levelMaxHealth        = 28;
            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            = 13;
            bodyComponent.levelDamage           = 3.3f;
            bodyComponent.baseAttackSpeed       = 1;
            bodyComponent.levelAttackSpeed      = 0;
            bodyComponent.baseCrit                 = 1;
            bodyComponent.levelCrit                = 0;
            bodyComponent.baseArmor                = 5;
            bodyComponent.levelArmor               = 0;
            bodyComponent.baseJumpCount            = 1;
            bodyComponent.sprintingSpeedMultiplier = 1.45f;
            bodyComponent.wasLucky                 = false;
            bodyComponent.hideCrosshair            = false;
            bodyComponent.hullClassification       = HullClassification.Human;
            bodyComponent.portraitIcon             = Resources.Load <Texture>("textures/bodyicons/ScavBody");
            bodyComponent.isChampion               = false;
            bodyComponent.currentVehicle           = null;
            bodyComponent.skinIndex                = 0U;
            bodyComponent.bodyColor                = new Color(0.6f, 0.3f, 0f);

            NetworkStateMachine networkStateMachine      = stanWorshipperBody.GetComponent <NetworkStateMachine>();
            EntityStateMachine  customEntityStateMachine = stanWorshipperBody.AddComponent <EntityStateMachine>();

            customEntityStateMachine.customName       = "Sacrifice";
            customEntityStateMachine.mainStateType    = new SerializableEntityStateType(typeof(Idle));
            customEntityStateMachine.initialStateType = new SerializableEntityStateType(typeof(Idle));
            ArrayUtils.ArrayAppend(ref networkStateMachine.stateMachines, customEntityStateMachine);

            //Adds a default placeholder skin to prevent weird errors (another disgusting waste of my time :D).
            GameObject          model          = stanWorshipperBody.GetComponent <ModelLocator>().modelTransform.gameObject;
            CharacterModel      characterModel = model.GetComponent <CharacterModel>();
            ModelSkinController skinController = model.AddComponent <ModelSkinController>();

            CharacterModel.RendererInfo[] renderInfos = characterModel.baseRendererInfos;
            LoadoutAPI.SkinDefInfo        skinDefInfo = new LoadoutAPI.SkinDefInfo
            {
                BaseSkins             = Array.Empty <SkinDef>(),
                GameObjectActivations = new SkinDef.GameObjectActivation[0],
                Icon                        = Assets.emptyIcon,
                MeshReplacements            = new SkinDef.MeshReplacement[0],
                MinionSkinReplacements      = new SkinDef.MinionSkinReplacement[0],
                Name                        = "STANWORSHIPPER_NAME",
                NameToken                   = "STANWORSHIPPER_NAME",
                ProjectileGhostReplacements = new SkinDef.ProjectileGhostReplacement[0],
                RendererInfos               = renderInfos,
                RootObject                  = model
            };
            SkinDef skin = LoadoutAPI.CreateNewSkinDef(skinDefInfo);

            skinController.skins = new SkinDef[] { skin };

            //Doppelganger
            stanWorshipperDoppelganger = PrefabAPI.InstantiateClone(Resources.Load <GameObject>("Prefabs/CharacterMasters/CommandoMonsterMaster"), "StanWorshipperMonsterMaster", true);
            if (!stanWorshipperDoppelganger.GetComponent <NetworkIdentity>())
            {
                stanWorshipperDoppelganger.AddComponent <NetworkIdentity>();
            }

            CharacterMaster component = stanWorshipperDoppelganger.GetComponent <CharacterMaster>();

            component.bodyPrefab = stanWorshipperBody;
        }
 public static void _SetStateMachines(this NetworkStateMachine inst, params EntityStateMachine[] stateMachines) => inst.stateMachines = stateMachines;   // => _stateMachines.Set( inst, stateMachines );
 public static EntityStateMachine[] _GetStateMachines(this NetworkStateMachine inst) => inst.stateMachines;  // _stateMachines.Get( inst );
Exemple #9
0
        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);
        }