private static void ReplaceSkillDrivers(CharacterMaster characterMaster, BaseAI baseAI, GameObject newCharacterMasterPrefab)
        {
            //Chat.AddMessage($"{characterMaster.name} has transformed into {newCharacterMasterPrefab.name}");
            foreach (var skillDriver in characterMaster.GetComponents <AISkillDriver>())
            {
                Destroy(skillDriver);
            }

            var listOfPrefabDrivers = newCharacterMasterPrefab.GetComponents <AISkillDriver>();

            List <AISkillDriver> newSkillDrivers = new List <AISkillDriver>();

            foreach (var skillDriver in listOfPrefabDrivers)
            {
                var newDriver = characterMaster.gameObject.AddComponent <AISkillDriver>();
                newSkillDrivers.Add(newDriver);
                newDriver.activationRequiresAimConfirmation = skillDriver.activationRequiresAimConfirmation;
                newDriver.activationRequiresAimTargetLoS    = skillDriver.activationRequiresAimTargetLoS;
                newDriver.activationRequiresTargetLoS       = skillDriver.activationRequiresTargetLoS;
                newDriver.aimType                   = skillDriver.aimType;
                newDriver.buttonPressType           = skillDriver.buttonPressType;
                newDriver.customName                = skillDriver.customName;
                newDriver.driverUpdateTimerOverride = skillDriver.driverUpdateTimerOverride;
                newDriver.ignoreNodeGraph           = skillDriver.ignoreNodeGraph;
                newDriver.maxDistance               = skillDriver.maxDistance;
                newDriver.maxTargetHealthFraction   = skillDriver.maxTargetHealthFraction;
                newDriver.maxUserHealthFraction     = skillDriver.maxUserHealthFraction;
                newDriver.minDistance               = skillDriver.minDistance;
                newDriver.minTargetHealthFraction   = skillDriver.minTargetHealthFraction;
                newDriver.minUserHealthFraction     = skillDriver.minUserHealthFraction;
                newDriver.moveInputScale            = skillDriver.moveInputScale;
                newDriver.movementType              = skillDriver.movementType;
                newDriver.moveTargetType            = skillDriver.moveTargetType;
                //newDriver.name = skillDriver.name;
                newDriver.nextHighPriorityOverride = skillDriver.nextHighPriorityOverride;
                newDriver.noRepeat              = skillDriver.noRepeat;
                newDriver.requiredSkill         = skillDriver.requiredSkill;
                newDriver.requireEquipmentReady = skillDriver.requireEquipmentReady;
                newDriver.requireSkillReady     = skillDriver.requireSkillReady;
                newDriver.resetCurrentEnemyOnNextDriverSelection = skillDriver.resetCurrentEnemyOnNextDriverSelection;
                newDriver.selectionRequiresAimTarget             = skillDriver.selectionRequiresAimTarget;
                newDriver.selectionRequiresOnGround  = skillDriver.selectionRequiresOnGround;
                newDriver.selectionRequiresTargetLoS = skillDriver.selectionRequiresTargetLoS;
                newDriver.shouldFireEquipment        = skillDriver.shouldFireEquipment;
                newDriver.shouldSprint    = skillDriver.shouldSprint;
                newDriver.shouldTapButton = skillDriver.shouldTapButton;
                newDriver.skillSlot       = skillDriver.skillSlot;
            }
            var array = newSkillDrivers.ToArray();

            baseAI.skillDrivers = array;

            var esm       = characterMaster.GetComponent <EntityStateMachine>();
            var customESM = newCharacterMasterPrefab.GetComponent <EntityStateMachine>();

            esm.customName       = customESM.customName;
            esm.initialStateType = customESM.initialStateType;
            esm.mainStateType    = customESM.mainStateType;
            esm.nextState        = customESM.nextState;
        }
        private void CharacterMaster_OnBodyDeath(On.RoR2.CharacterMaster.orig_OnBodyDeath orig, CharacterMaster self)
        {
            characterMaster = self;
            if (NetworkServer.active)
            {
                deathFootPosition = self.GetBody().footPosition;
                BaseAI[] components = self.GetComponents <BaseAI>();
                for (int i = 0; i < components.Length; i++)
                {
                    components[i].OnBodyDeath();
                }
                PlayerCharacterMasterController component = self.GetComponent <PlayerCharacterMasterController>();
                if (component)
                {
                    component.OnBodyDeath();
                }
                int itemAllNum = 0;
                list.Clear();
                if (self.teamIndex == TeamIndex.Player)
                {
                    for (int i = 0; i < Enum.GetValues(typeof(ItemIndex)).Length; i++)
                    {
                        ItemIndex itemIndex = (ItemIndex)i;
                        if (itemIndex <= ItemIndex.None || itemIndex >= ItemIndex.Count)
                        {
                            continue;
                        }

                        int num = self.inventory.GetItemCount(itemIndex);
                        if (num > 0)
                        {
                            list.Add(itemIndex);
                        }

                        itemAllNum += num;

                        itemStacks[i] = num;
                    }
                }
                string usename           = Util.GetBestMasterName(self);
                bool   tempHerosNeverDie = itemAllNum >= RemoveItemNum;
                if (tempHerosNeverDie)
                {
                    int tempNum = 0;
                    if (userPlayerRespawnNum.ContainsKey(usename) == false)
                    {
                        userPlayerRespawnNum[usename] = 0;
                    }
                    else
                    {
                        tempNum = userPlayerRespawnNum[usename];
                    }
                    if (tempNum >= RespawnNum)
                    {
                        tempHerosNeverDie = false;
                    }
                }

                if (self.inventory.GetItemCount(ItemIndex.ExtraLife) > 0)
                {
                    self.inventory.RemoveItem(ItemIndex.ExtraLife, 1);
                    self.Invoke("RespawnExtraLife", 2f);
                    self.Invoke("PlayExtraLifeSFX", 1f);
                }
                else if (tempHerosNeverDie)
                {
                    for (int i = 0; i < RemoveItemNum; i++)
                    {
                        RandomRemoveItemOne();
                    }
                    userPlayerRespawnNum[usename] += 1;

                    this.Invoke("RespawnExtraLife", 2f);
                    self.Invoke("PlayExtraLifeSFX", 1f);
                }
                else
                {
                    if (self.destroyOnBodyDeath)
                    {
                        UnityEngine.Object.Destroy(self.gameObject);
                    }
                    self.preventGameOver = false;
                    FieldInfo field = self.GetType().GetField("preventRespawnUntilNextStageServer", BindingFlags.NonPublic | BindingFlags.Instance);
                    field.SetValue(self, true);
                }
                MethodInfo methodInfo = self.GetType().GetMethod("ResetLifeStopwatch", BindingFlags.NonPublic | BindingFlags.Instance);
                methodInfo.Invoke(self, null);
            }
            UnityEvent unityEvent = self.onBodyDeath;

            if (unityEvent == null)
            {
                return;
            }
            unityEvent.Invoke();
        }