Exemplo n.º 1
0
        private static void BuildWestBrosBossPrefab(AssetBundle assetBundle, out GameObject outObject, WestBros whichBro, bool isSmiley, tk2dSpriteCollectionData sourceSpriteCollection, tk2dSpriteAnimation sourceAnimations, bool keepIntroDoer = false)
        {
            GameObject prefab = ExpandCustomEnemyDatabase.GetOfficialEnemyByGuid(isSmiley
                ? "ea40fcc863d34b0088f490f4e57f8913"              // Smiley
                : "c00390483f394a849c36143eb878998f").gameObject; // Shades

            outObject = UnityEngine.Object.Instantiate(prefab, Vector3.zero, Quaternion.identity);

            try
            {
                string name = $"West Bros {whichBro}";

                outObject.SetActive(false);
                outObject.name = name;

                AIActor actor = outObject.GetComponent <AIActor>();

                actor.healthHaver.overrideBossName = "Western Bros";

                actor.EnemyId   = UnityEngine.Random.Range(100000, 999999);
                actor.ActorName = name;

                EncounterTrackable Encounterable = outObject.GetComponent <EncounterTrackable>();

                switch (whichBro)
                {
                case WestBros.Angel:
                    actor.EnemyGuid             = "275354563e244f558be87fcff4b07f9f";
                    Encounterable.EncounterGuid = "7d6e1faf682d4402b29535020313f383";
                    break;

                case WestBros.Nome:
                    actor.EnemyGuid             = "3a1a33a905bb4b669e7d798f20674c4c";
                    Encounterable.EncounterGuid = "78cb8889dc884dd9b3aafe64558d858e";
                    break;

                case WestBros.Tuc:
                    actor.EnemyGuid             = "d2e7ea9ea9a444cebadd3bafa0832cd1";
                    Encounterable.EncounterGuid = "1df53371ce084dafb46f6bcd5a6c1c5f";
                    break;
                }

                // TODO at some distant point in time
                Encounterable.journalData.PrimaryDisplayName           = name;
                Encounterable.journalData.NotificationPanelDescription = name;
                Encounterable.journalData.AmmonomiconFullEntry         = name;

                // x BroController
                // x BulletBroDeathController
                // x BulletBrosIntroDoer
                // x BulletBroSeekTargetBehavior // movement behaviour
                //   BulletBroRepositionBehavior // completely unused

                var oldBroController = outObject.GetComponent <BroController>();
                var newBroController = outObject.AddComponent <ExpandWesternBroController>();

                newBroController.enrageAnim          = oldBroController.enrageAnim;
                newBroController.enrageAnimTime      = oldBroController.enrageAnimTime;
                newBroController.enrageHealToPercent = oldBroController.enrageHealToPercent;
                newBroController.overheadVfx         = oldBroController.overheadVfx;
                newBroController.postEnrageMoveSpeed = oldBroController.postEnrageMoveSpeed;

                newBroController.whichBro = whichBro;
                newBroController.postSecondEnrageMoveSpeed = newBroController.postEnrageMoveSpeed;

                UnityEngine.Object.Destroy(oldBroController);

                UnityEngine.Object.Destroy(outObject.GetComponent <BulletBroDeathController>());
                outObject.AddComponent <ExpandWesternBroDeathController>();

                var newMovementBehavior = new ExpandWesternBroSeekTargetBehavior();
                var oldMovementBehavior = actor.behaviorSpeculator.MovementBehaviors.First() as BulletBroSeekTargetBehavior;

                newMovementBehavior.CustomRange     = oldMovementBehavior.CustomRange;
                newMovementBehavior.PathInterval    = oldMovementBehavior.PathInterval;
                newMovementBehavior.StopWhenInRange = oldMovementBehavior.StopWhenInRange;

                actor.behaviorSpeculator.MovementBehaviors = new List <MovementBehaviorBase>()
                {
                    newMovementBehavior
                };

                // only smiley has a bossIntroDoer, so the stuff after this would null reference if done with shade
                if (isSmiley)
                {
                    if (!keepIntroDoer)
                    {
                        UnityEngine.Object.Destroy(outObject.GetComponent <BulletBrosIntroDoer>());
                        UnityEngine.Object.Destroy(outObject.GetComponent <GenericIntroDoer>());
                    }
                    else
                    {
                        // BulletBrosIntroDoer is a SpecificIntroDoer; it does not inherent from GenericIntroDoer, it requires it to be present
                        BulletBrosIntroDoer bulletBrosIntroDoer = outObject.GetComponent <BulletBrosIntroDoer>();

                        // destroy it so we can add our own
                        UnityEngine.Object.Destroy(bulletBrosIntroDoer);

                        GenericIntroDoer genericIntroDoer = outObject.GetComponent <GenericIntroDoer>();

                        genericIntroDoer.portraitSlideSettings.bossNameString     = "Western Bros";
                        genericIntroDoer.portraitSlideSettings.bossSubtitleString = "Triple Tap";
                        genericIntroDoer.portraitSlideSettings.bossQuoteString    = string.Empty;

                        genericIntroDoer.portraitSlideSettings.bossArtSprite = assetBundle.LoadAsset <Texture2D>("WesternBrosBossCard");

                        genericIntroDoer.triggerType     = GenericIntroDoer.TriggerType.PlayerEnteredRoom;
                        genericIntroDoer.OnIntroFinished = () => { };

                        ExpandWesternBroIntroDoer specificIntroDoer = outObject.AddComponent <ExpandWesternBroIntroDoer>();
                    }
                }

                var animationsAsset = assetBundle.LoadAsset <GameObject>($"WestBrosAnimations_{whichBro}");

                List <tk2dSpriteAnimationClip> animationClips = new List <tk2dSpriteAnimationClip>();

                foreach (tk2dSpriteAnimationClip clip in sourceAnimations.clips)
                {
                    if (clip.name.StartsWith($"{whichBro.ToString().ToLower()}_"))
                    {
                        animationClips.Add(ExpandUtility.DuplicateAnimationClip(clip));
                    }
                }

                List <tk2dSpriteAnimationClip> clipsToAdd = new List <tk2dSpriteAnimationClip>();

                foreach (tk2dSpriteAnimationClip clip in animationClips)
                {
                    clip.name = clip.name.Replace($"{whichBro.ToString().ToLower()}_", string.Empty);

                    clip.name = clip.name.Replace("dash_front", "dash_forward");
                    clip.name = clip.name.Replace("move_front", "move_forward");

                    if (clip.name.EndsWith("_prime"))
                    {
                        clip.frames[5].eventAudio   = "Play_ENM_bullet_dash_01";
                        clip.frames[5].triggerEvent = true;
                    }
                    else if (clip.name.StartsWith("move_"))
                    {
                        clip.frames[2].eventAudio   = "PLay_FS_ENM";
                        clip.frames[2].triggerEvent = true;
                    }
                    else if (clip.name == "anger")
                    {
                        // we change the west bros anger animation from a loop to a loop section so the anger SFX only plays once.
                        // to do this we simply clone every frame once and make it loop at the first copied frame.

                        var angerFrames = clip.frames.ToList();

                        foreach (var frame in clip.frames)
                        {
                            tk2dSpriteAnimationFrame clonedFrame = new tk2dSpriteAnimationFrame();

                            ExpandUtility.ReflectionShallowCopyFields(clonedFrame, frame, BindingFlags.Public | BindingFlags.Instance);

                            angerFrames.Add(clonedFrame);
                        }

                        // it's important to do this before changing clip.frames
                        clip.loopStart              = clip.frames.Length;
                        clip.frames                 = angerFrames.ToArray();
                        clip.wrapMode               = tk2dSpriteAnimationClip.WrapMode.LoopSection;
                        clip.frames[0].eventAudio   = "Play_BOSS_bulletbros_anger_01";
                        clip.frames[0].triggerEvent = true;
                    }
                    else if (clip.name == "death_right")
                    {
                        clip.name = "die";

                        tk2dSpriteAnimationClip dieFrontRight = ExpandUtility.DuplicateAnimationClip(clip);
                        dieFrontRight.name = "die_front_right";
                        clipsToAdd.Add(dieFrontRight);
                    }
                    else if (clip.name == "death_left")
                    {
                        clip.name = "die_left";

                        tk2dSpriteAnimationClip dieFrontLeft = ExpandUtility.DuplicateAnimationClip(clip);
                        dieFrontLeft.name = "die_front_left";
                        clipsToAdd.Add(dieFrontLeft);
                    }
                    else if (clip.name == "idle_front")
                    {
                        clip.name = "idle";

                        tk2dSpriteAnimationClip bigShot = ExpandUtility.DuplicateAnimationClip(clip);
                        bigShot.wrapMode = tk2dSpriteAnimationClip.WrapMode.Once;
                        bigShot.name     = "big_shot";
                        clipsToAdd.Add(bigShot);

                        tk2dSpriteAnimationClip charge = ExpandUtility.DuplicateAnimationClip(clip);
                        charge.wrapMode = tk2dSpriteAnimationClip.WrapMode.Loop;
                        charge.name     = "charge";
                        clipsToAdd.Add(charge);

                        // not really necessary since it's nuked from the animator further down
                        tk2dSpriteAnimationClip appear = ExpandUtility.DuplicateAnimationClip(clip);
                        appear.wrapMode = tk2dSpriteAnimationClip.WrapMode.Once;
                        appear.name     = "appear";
                        clipsToAdd.Add(appear);

                        tk2dSpriteAnimationClip introGunToggle = ExpandUtility.DuplicateAnimationClip(clip);
                        introGunToggle.wrapMode = tk2dSpriteAnimationClip.WrapMode.Once;
                        introGunToggle.name     = "intro2";
                        clipsToAdd.Add(introGunToggle);

                        introGunToggle.frames[0].eventInfo    = "guntoggle";
                        introGunToggle.frames[0].triggerEvent = true;
                    }
                    else if (clip.name == "summon")
                    {
                        clip.name     = "whistle";
                        clip.wrapMode = tk2dSpriteAnimationClip.WrapMode.Once;
                        // the summon vfx don't look right
                        // clip.frames[0].eventVfx = "summon_vfx";
                        // clip.frames[0].triggerEvent = true;
                    }
                    else if (clip.name == "pound")
                    {
                        clip.name = "jump_attack";
                        // Uses modified sound that plays faster on the first half to account for west bros having faster animation.
                        clip.frames[0].eventAudio   = "Play_EX_BOSS_westbros_slam_01";
                        clip.frames[0].triggerEvent = true;
                    }
                    else if (clip.name == "intro")
                    {
                        clip.wrapMode = tk2dSpriteAnimationClip.WrapMode.Once;
                        // this is setup in case we want the intro to continue looping during the boss card instead of the idle animation
                        // requires to change the intro doer so it sets finished to true once it reaches the first loop

                        //if (whichBro == WestBros.Nome)
                        //{
                        //    // nome's intro animation wasn't looping at the end like the others
                        //    var list = clip.frames.ToList();

                        //    list.RemoveAt(20);
                        //    list.RemoveAt(20);

                        //    clip.frames = list.ToArray();

                        //    clip.loopStart = 23;

                        //    clip.frames[23] = clip.frames[0];
                        //    clip.frames[24] = clip.frames[1];
                        //    clip.frames[25] = clip.frames[2];
                        //    clip.frames[26] = clip.frames[3];
                        //}
                        //else if (whichBro == WestBros.Tuc)
                        //{
                        //    // tuc's intro animation was off by one frame compared to the others
                        //    var list = clip.frames.ToList();

                        //    list.RemoveAt(15);

                        //    clip.frames = list.ToArray();

                        //    clip.loopStart = 21;
                        //}
                    }
                }

                animationClips.AddRange(clipsToAdd);

                tk2dSpriteAnimation spriteAnimation = animationsAsset.AddComponent <tk2dSpriteAnimation>();

                spriteAnimation.clips = animationClips.ToArray();

                tk2dSpriteAnimator spriteAnimator = outObject.GetComponent <tk2dSpriteAnimator>();

                spriteAnimator.Library = spriteAnimation;

                tk2dSprite sprite = outObject.GetComponent <tk2dSprite>();
                sprite.SetSprite(sourceSpriteCollection, $"BB_{whichBro.ToString().ToLower()}_idle_front_001");
                sprite.PlaceAtPositionByAnchor(new Vector3(0f, 0f), tk2dBaseSprite.Anchor.LowerCenter);

                AIAnimator animator = outObject.GetComponent <AIAnimator>();
                // removes the 'appear' animation
                animator.OtherAnimations.RemoveAt(0);

                outObject.transform.Find("shadow").localPosition += new Vector3(1.52f, 0.02f, 0);

                var shooter = SetupAIShooter(outObject);
                shooter.handObject = WestBrosHandPrefab.GetComponent <PlayerHandController>();

                DebrisObject hatPrefab = null;

                switch (whichBro)
                {
                case WestBros.Angel:
                    shooter.gunAttachPoint.position = new Vector3(-1.05f, 0.5f);
                    WestBrosAngelGUID = actor.EnemyGuid;
                    hatPrefab         = WestBrosAngelHatPrefab.GetComponent <DebrisObject>();
                    break;

                case WestBros.Nome:
                    shooter.gunAttachPoint.position = new Vector3(-1.05f, 0.4f);
                    WestBrosNomeGUID = actor.EnemyGuid;
                    hatPrefab        = WestBrosNomeHatPrefab.GetComponent <DebrisObject>();
                    break;

                case WestBros.Tuc:
                    shooter.gunAttachPoint.position = new Vector3(-1.05f, 0.5f);
                    WestBrosTucGUID = actor.EnemyGuid;
                    hatPrefab       = WestBrosTucHatPrefab.GetComponent <DebrisObject>();
                    break;
                }

                shooter.equippedGunId = WestBrosRevolverGenerator.GetWestBrosRevolverID(whichBro);

                if (shooter.equippedGunId == -1)
                {
                    ETGModConsole.Log("The West Bros Gun ID should have been set at this point already, but it wasn't. Assigning fallback gun.");
                    shooter.equippedGunId = isSmiley ? 35 : 22;
                }

                var hatLauncher = outObject.GetComponentInChildren <ExplosionDebrisLauncher>();

                // basically changes smiley's debris launcher into shades'
                hatLauncher.specifyArcDegrees = false;
                hatLauncher.minShards         = 1;
                hatLauncher.maxShards         = 1;

                hatLauncher.debrisSources = new DebrisObject[] { hatPrefab };

                // move the ring of bullets spawned by jumping
                var shootPoint = outObject.transform.Find("shoot point");
                shootPoint.position += new Vector3(1.5f, 0);

                // move the actual pixel colliders
                var rigidbody = outObject.GetComponent <SpeculativeRigidbody>();

                foreach (var item in rigidbody.PixelColliders)
                {
                    item.ManualOffsetX = 32;
                    item.Regenerate(outObject.transform);
                }

                // TODO balance
                actor.healthHaver.ForceSetCurrentHealth(600);
                actor.healthHaver.SetHealthMaximum(600);

                actor.RegenerateCache();

                ExpandCustomEnemyDatabase.AddEnemyToDatabase(outObject, actor.EnemyGuid, true);
                FakePrefab.MarkAsFakePrefab(outObject);
                UnityEngine.Object.DontDestroyOnLoad(outObject);
            }
            catch (Exception e)
            {
                ETGModConsole.Log($"Error setting up the western bro {whichBro}: " + e.ToString());
            }
        }
        public static void GenerateGungeoneerMimicBoss(AssetBundle expandSharedAssets1, GameObject aiActorObject, PlayerController sourcePlayer = null)
        {
            if (sourcePlayer == null)
            {
                sourcePlayer = GameManager.Instance.PrimaryPlayer;
            }
            if (sourcePlayer == null)
            {
                return;
            }

            tk2dSprite playerSprite = aiActorObject.AddComponent <tk2dSprite>();

            ExpandUtility.DuplicateSprite(playerSprite, (sourcePlayer.sprite as tk2dSprite));

            // If Player sprite was flipped (aka, player aiming/facing towards the left), then this could cause sprite being shifted left on AIActor.
            // Always set false to ensure this doesn't happen.
            playerSprite.FlipX = false;

            ExpandUtility.GenerateAIActorTemplate(aiActorObject, out m_CorpseObject, aiActorObject.name, System.Guid.NewGuid().ToString(), GunAttachOffset: new Vector3(0.3f, 0.25f, 0), StartingGunID: 472);

            AIActor CachedEnemyActor = aiActorObject.GetComponent <AIActor>();

            if (!aiActorObject | !CachedEnemyActor)
            {
                return;
            }

            if (ExpandStats.debugMode)
            {
                ETGModConsole.Log("Spawning '" + CachedEnemyActor.ActorName + "' with GUID: " + CachedEnemyActor.EnemyGuid + " .", false);
            }

            GameObject m_NewHandObject = new GameObject("PlayerMimicHand");
            tk2dSprite m_HandSprite    = m_NewHandObject.AddComponent <tk2dSprite>();

            ExpandUtility.DuplicateSprite(m_HandSprite, sourcePlayer.primaryHand.gameObject.GetComponent <tk2dSprite>());
            PlayerHandController m_HandController = m_NewHandObject.AddComponent <PlayerHandController>();

            m_HandController.ForceRenderersOff = false;
            m_HandController.handHeightFromGun = 0.05f;

            CachedEnemyActor.aiShooter.handObject = m_HandController;

            // Generate BossCard based on current Player.
            Texture2D BossCardForeground = ExpandUtility.FlipTexture(Instantiate(sourcePlayer.BosscardSprites[0]));
            // Mirror thing will be used as static background. (will be the same for all possible boss cards)
            Texture2D BossCardBackground = expandSharedAssets1.LoadAsset <Texture2D>("MimicInMirror_BossCardBackground");
            // Combine foreground boss card generated from PlayerController onto the static background image loased in earlier. Resolutions must match!
            Texture2D BossCardTexture = ExpandUtility.CombineTextures(BossCardBackground, BossCardForeground);



            GenericIntroDoer miniBossIntroDoer = aiActorObject.AddComponent <GenericIntroDoer>();

            aiActorObject.AddComponent <ExpandGungeoneerMimicIntroDoer>();
            miniBossIntroDoer.triggerType              = GenericIntroDoer.TriggerType.PlayerEnteredRoom;
            miniBossIntroDoer.initialDelay             = 0.15f;
            miniBossIntroDoer.cameraMoveSpeed          = 14;
            miniBossIntroDoer.specifyIntroAiAnimator   = null;
            miniBossIntroDoer.BossMusicEvent           = "Play_MUS_Boss_Theme_Beholster";
            miniBossIntroDoer.PreventBossMusic         = false;
            miniBossIntroDoer.InvisibleBeforeIntroAnim = false;
            miniBossIntroDoer.preIntroAnim             = string.Empty;
            miniBossIntroDoer.preIntroDirectionalAnim  = string.Empty;
            miniBossIntroDoer.introAnim                  = "idle";
            miniBossIntroDoer.introDirectionalAnim       = string.Empty;
            miniBossIntroDoer.continueAnimDuringOutro    = false;
            miniBossIntroDoer.cameraFocus                = null;
            miniBossIntroDoer.roomPositionCameraFocus    = Vector2.zero;
            miniBossIntroDoer.restrictPlayerMotionToRoom = false;
            miniBossIntroDoer.fusebombLock               = false;
            miniBossIntroDoer.AdditionalHeightOffset     = 0;
            miniBossIntroDoer.portraitSlideSettings      = new PortraitSlideSettings()
            {
                bossNameString          = "Dopplegunner",
                bossSubtitleString      = "Imposter!",
                bossQuoteString         = "Clone gone rogue...",
                bossSpritePxOffset      = IntVector2.Zero,
                topLeftTextPxOffset     = IntVector2.Zero,
                bottomRightTextPxOffset = IntVector2.Zero,
                bgColor = new Color(0, 0, 1, 1)
            };
            if (BossCardTexture)
            {
                miniBossIntroDoer.portraitSlideSettings.bossArtSprite = BossCardTexture;
                miniBossIntroDoer.SkipBossCard             = false;
                CachedEnemyActor.healthHaver.bossHealthBar = HealthHaver.BossBarType.MainBar;
            }
            else
            {
                miniBossIntroDoer.SkipBossCard             = true;
                CachedEnemyActor.healthHaver.bossHealthBar = HealthHaver.BossBarType.SubbossBar;
            }
            miniBossIntroDoer.HideGunAndHand        = true;
            miniBossIntroDoer.SkipFinalizeAnimation = true;
            miniBossIntroDoer.RegenerateCache();


            CachedEnemyActor.BaseMovementSpeed = 8f;
            CachedEnemyActor.MovementSpeed     = 8f;

            CachedEnemyActor.healthHaver.SetHealthMaximum(1000);
            CachedEnemyActor.healthHaver.ForceSetCurrentHealth(1000);
            CachedEnemyActor.healthHaver.overrideBossName = "Dopplegunner";
            CachedEnemyActor.healthHaver.RegenerateCache();

            CachedEnemyActor.EnemyId             = Random.Range(2000, 9999);
            CachedEnemyActor.EnemyGuid           = System.Guid.NewGuid().ToString();
            CachedEnemyActor.OverrideDisplayName = ("Dopplegunner");
            CachedEnemyActor.ActorName           = ("Dopplegunner");
            CachedEnemyActor.name = ("Dopplegunner");

            CachedEnemyActor.CanTargetEnemies = false;
            CachedEnemyActor.CanTargetPlayers = true;

            if (sourcePlayer.characterIdentity == PlayableCharacters.Bullet)
            {
                CachedEnemyActor.EnemySwitchState = "Metal_Bullet_Man";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Convict)
            {
                CachedEnemyActor.EnemySwitchState = "Convict";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.CoopCultist)
            {
                CachedEnemyActor.EnemySwitchState = "Cultist";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Cosmonaut)
            {
                CachedEnemyActor.EnemySwitchState = "Cosmonaut";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Guide)
            {
                CachedEnemyActor.EnemySwitchState = "Guide";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Gunslinger)
            {
                CachedEnemyActor.EnemySwitchState = "Gunslinger";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Ninja)
            {
                CachedEnemyActor.EnemySwitchState = "Ninja";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Pilot)
            {
                CachedEnemyActor.EnemySwitchState = "Rogue";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Robot)
            {
                CachedEnemyActor.EnemySwitchState = "Robot";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Soldier)
            {
                CachedEnemyActor.EnemySwitchState = "Marine";
            }
            else if (sourcePlayer.characterIdentity == PlayableCharacters.Eevee)
            {
                CachedEnemyActor.EnemySwitchState = "Convict";
                ExpandShaders.ApplyParadoxPlayerShader(CachedEnemyActor.sprite);
            }
            else
            {
                CachedEnemyActor.EnemySwitchState = "Gun Cultist";
            }


            ExpandGungeoneerMimicBossController playerMimicController = aiActorObject.AddComponent <ExpandGungeoneerMimicBossController>();

            playerMimicController.m_Player = sourcePlayer;

            aiActorObject.AddComponent <ExpandGungeoneerMimicDeathController>();

            if (CachedEnemyActor.GetComponent <ExpandGungeoneerMimicIntroDoer>())
            {
                GenericIntroDoer genericIntroDoer = CachedEnemyActor.gameObject.GetComponent <GenericIntroDoer>();
                FieldInfo        field            = typeof(GenericIntroDoer).GetField("m_specificIntroDoer", BindingFlags.Instance | BindingFlags.NonPublic);
                field.SetValue(genericIntroDoer, CachedEnemyActor.GetComponent <ExpandGungeoneerMimicIntroDoer>());
            }

            CachedEnemyActor.aiAnimator.enabled = false;
            CachedEnemyActor.spriteAnimator.Stop();
            CachedEnemyActor.spriteAnimator.DefaultClipId     = 0;
            CachedEnemyActor.spriteAnimator.playAutomatically = false;

            List <tk2dSpriteAnimationClip> m_AnimationClips = new List <tk2dSpriteAnimationClip>();

            foreach (tk2dSpriteAnimationClip clip in sourcePlayer.spriteAnimator.Library.clips)
            {
                if (!string.IsNullOrEmpty(clip.name))
                {
                    if (clip.name.ToLower() == "dodge")
                    {
                        m_AnimationClips.Add(clip);
                        if (clip.frames != null && clip.frames.Length > 0)
                        {
                            if (!sourcePlayer.UseArmorlessAnim)
                            {
                                CachedEnemyActor.sprite.SetSprite(clip.frames[0].spriteId);
                            }
                        }
                    }
                    else if (clip.name.ToLower() == "dodge_armorless")
                    {
                        m_AnimationClips.Add(clip);
                        if (clip.frames != null && clip.frames.Length > 0)
                        {
                            if (sourcePlayer.UseArmorlessAnim)
                            {
                                CachedEnemyActor.sprite.SetSprite(clip.frames[0].spriteId);
                            }
                        }
                    }
                    else if (clip.name.ToLower() == "run_down")
                    {
                        m_AnimationClips.Add(clip);
                    }
                    else if (clip.name.ToLower() == "run_down_armorless")
                    {
                        m_AnimationClips.Add(clip);
                    }
                    else if (clip.name.ToLower() == "death_shot")
                    {
                        m_AnimationClips.Add(clip);
                    }
                    else if (clip.name.ToLower() == "death_shot_armorless")
                    {
                        m_AnimationClips.Add(clip);
                    }
                }
            }

            if (m_AnimationClips.Count > 0)
            {
                if (!CachedEnemyActor.spriteAnimator.Library)
                {
                    CachedEnemyActor.spriteAnimator.Library = aiActorObject.AddComponent <tk2dSpriteAnimation>();
                }
                CachedEnemyActor.spriteAnimator.Library.clips = m_AnimationClips.ToArray();
            }

            CachedEnemyActor.healthHaver.RegenerateCache();

            BehaviorSpeculator customBehaviorSpeculator = aiActorObject.AddComponent <BehaviorSpeculator>();

            customBehaviorSpeculator.OverrideBehaviors               = new List <OverrideBehaviorBase>(0);
            customBehaviorSpeculator.TargetBehaviors                 = new List <TargetBehaviorBase>(0);
            customBehaviorSpeculator.MovementBehaviors               = new List <MovementBehaviorBase>(0);
            customBehaviorSpeculator.AttackBehaviors                 = new List <AttackBehaviorBase>(0);
            customBehaviorSpeculator.OtherBehaviors                  = new List <BehaviorBase>(0);
            customBehaviorSpeculator.InstantFirstTick                = false;
            customBehaviorSpeculator.TickInterval                    = 0.1f;
            customBehaviorSpeculator.PostAwakenDelay                 = 0.5f;
            customBehaviorSpeculator.RemoveDelayOnReinforce          = false;
            customBehaviorSpeculator.OverrideStartingFacingDirection = false;
            customBehaviorSpeculator.StartingFacingDirection         = -90f;
            customBehaviorSpeculator.SkipTimingDifferentiator        = false;
            customBehaviorSpeculator.RegenerateCache();

            // BehaviorSpeculator is a serialized object. You must build these lists (or create new empty lists) and save them before the game can instantiate it correctly!
            ISerializedObject m_TargetBehaviorSpeculatorSeralized = customBehaviorSpeculator;

            m_TargetBehaviorSpeculatorSeralized.SerializedObjectReferences = new List <Object>(0);
            m_TargetBehaviorSpeculatorSeralized.SerializedStateKeys        = new List <string>()
            {
                "OverrideBehaviors", "TargetBehaviors", "MovementBehaviors", "AttackBehaviors", "OtherBehaviors"
            };
            m_TargetBehaviorSpeculatorSeralized.SerializedStateValues = new List <string>()
            {
                "[]", "[]", "[]", "[]", "[]"
            };

            CachedEnemyActor.RegenerateCache();
            return;
        }