public void LocalTrainerSetup(Character trainer, string _)
        {
            // remove unwanted components
            DestroyImmediate(trainer.GetComponent <CharacterStats>());
            DestroyImmediate(trainer.GetComponent <StartingEquipment>());

            // add NPCLookFollow component
            trainer.gameObject.AddComponent <NPCLookFollow>();

            // =========== setup Trainer DialogueTree from the template ===========

            var trainertemplate = Instantiate(Resources.Load("editor/templates/TrainerTemplate")) as GameObject;

            trainertemplate.transform.parent   = trainer.transform;
            trainertemplate.transform.position = trainer.transform.position;

            // set Dialogue Actor name
            var necroActor = trainertemplate.GetComponentInChildren <DialogueActor>();

            necroActor.SetName(trainerTemplate.Name);

            // get "Trainer" component, and set the SkillTreeUID to our custom tree UID
            Trainer trainerComp = trainertemplate.GetComponentInChildren <Trainer>();

            At.SetValue(SkillManager.NecromancyTree.UID, typeof(Trainer), trainerComp, "m_skillTreeUID");

            // setup dialogue tree
            var graphController = trainertemplate.GetComponentInChildren <DialogueTreeController>();
            var graph           = (graphController as GraphOwner <DialogueTreeExt>).graph;

            // the template comes with an empty ActorParameter, we can use that for our NPC actor.
            var actors = At.GetValue(typeof(DialogueTree), graph as DialogueTree, "_actorParameters") as List <DialogueTree.ActorParameter>;

            actors[0].actor = necroActor;
            actors[0].name  = necroActor.name;

            // setup the actual dialogue now
            List <Node> nodes = At.GetValue(typeof(Graph), graph, "_nodes") as List <Node>;

            var rootStatement = graph.AddNode <StatementNodeExt>();

            rootStatement.statement = new Statement("Do you seek to harness the power of Corruption, traveler?");
            rootStatement.SetActorName(necroActor.name);

            var multiChoice1 = graph.AddNode <MultipleChoiceNodeExt>();

            multiChoice1.availableChoices.Add(new MultipleChoiceNodeExt.Choice {
                statement = new Statement {
                    text = "I'm interested, what can you teach me?"
                }
            });
            multiChoice1.availableChoices.Add(new MultipleChoiceNodeExt.Choice {
                statement = new Statement {
                    text = "Who are you?"
                }
            });
            multiChoice1.availableChoices.Add(new MultipleChoiceNodeExt.Choice {
                statement = new Statement {
                    text = "What is this place?"
                }
            });

            // the template already has an action node for opening the Train menu.
            // Let's grab that and change the trainer to our custom Trainer component (setup above).
            var openTrainer = nodes[1] as ActionNode;

            (openTrainer.action as TrainDialogueAction).Trainer = new BBParameter <Trainer>(trainerComp);

            // create some custom dialogue
            var answer1 = graph.AddNode <StatementNodeExt>();

            answer1.statement = new Statement("I wish I could remember...");
            answer1.SetActorName(necroActor.name);

            var answer2 = graph.AddNode <StatementNodeExt>();

            answer2.statement = new Statement("This is the fortress of the Plague Doctor, a powerful Lich. I've learned a lot about Corruption within these walls.");
            answer2.SetActorName(necroActor.name);

            // ===== finalize nodes =====
            nodes.Clear();
            // add the nodes we want to use
            nodes.Add(rootStatement);
            nodes.Add(multiChoice1);
            nodes.Add(openTrainer);
            nodes.Add(answer1);
            nodes.Add(answer2);
            graph.primeNode = rootStatement;
            graph.ConnectNodes(rootStatement, multiChoice1);    // prime node triggers the multiple choice
            graph.ConnectNodes(multiChoice1, openTrainer, 0);   // choice1: open trainer
            graph.ConnectNodes(multiChoice1, answer1, 1);       // choice2: answer1
            graph.ConnectNodes(answer1, rootStatement);         // - choice2 goes back to root node
            graph.ConnectNodes(multiChoice1, answer2, 2);       // choice3: answer2
            graph.ConnectNodes(answer2, rootStatement);         // - choice3 goes back to root node
            // set root node

            // set the trainer active
            trainer.gameObject.SetActive(true);
        }
Esempio n. 2
0
        // skill setup called from SkillManager
        #region Tendrils Skill Setup
        public static void SetupTendrils()
        {
            // ============== setup base skill ==============

            var tendrils = ResourcesPrefabManager.Instance.GetItemPrefab(8890100) as AttackSkill;

            // setup skill
            tendrils.CastModifier           = Character.SpellCastModifier.Mobile; // can move while casting but movement speed is 0.3x
            tendrils.MobileCastMovementMult = 0.3f;

            // clear existing effects
            SideLoader.SL.DestroyChildren(tendrils.transform);

            // ============= normal effects =============== //

            // create new effects
            var effects = new GameObject("Effects");

            effects.transform.parent = tendrils.transform;

            // add our custom PlagueAura proximity condition component (INVERT = TRUE, we DONT want the aura on these effects).
            var auraCondition1 = effects.AddComponent <PlagueAuraProximityCondition>();

            auraCondition1.ProximityDist           = 2.5f;
            auraCondition1.RequiredActivatedItemID = 8999050;
            auraCondition1.Invert = true;

            // create the Tendrils effect, a custom class derived from ShootProjectile
            ShootTendrils shootTendrils = effects.AddComponent <ShootTendrils>();
            var           orig          = ResourcesPrefabManager.Instance.GetItemPrefab(8300292).transform.Find("Effects").GetComponent <ShootProjectile>();

            At.InheritBaseValues(shootTendrils, orig);

            shootTendrils.SyncType = SyncTypes.Everyone;

            // disable clone target before cloning it
            var origProjectile = shootTendrils.BaseProjectile.gameObject;

            origProjectile.SetActive(false);
            var projectileObj = Instantiate(origProjectile);

            DontDestroyOnLoad(projectileObj);
            //projectileObj.SetActive(true);

            projectileObj.name = "NoxiousTendrils";

            // get the actual Projectile component from our new Projectile Object, and set our "BaseProjectile" to this component
            var projectile = projectileObj.GetComponent <RaycastProjectile>();

            shootTendrils.BaseProjectile     = projectile;
            shootTendrils.IntanstiatedAmount = 8; // 2 per character, potential 3 summoned skeletons, so 8 total subeffects needed.

            projectile.Lifespan       = 0.75f;
            projectile.DisableOnHit   = false;
            projectile.EndMode        = Projectile.EndLifeMode.LifetimeOnly;
            projectile.HitEnemiesOnly = true;

            // sound play
            if (projectileObj.GetComponentInChildren <SoundPlayer>() is SoundPlayer lightPlayer)
            {
                lightPlayer.Sounds = new List <GlobalAudioManager.Sounds> {
                    GlobalAudioManager.Sounds.SFX_FireThrowLight
                };
            }

            // heal on hit
            if (projectile.GetComponentInChildren <AffectHealthParentOwner>() is AffectHealthParentOwner heal)
            {
                heal.AffectQuantity = NecromancyBase.settings.ShootTendrils_Heal_NoPlagueAura;
            }

            // change damage and hit effects
            var hit = projectile.transform.Find("HitEffects").gameObject;

            hit.GetComponent <PunctualDamage>().Damages   = NecromancyBase.settings.ShootTendrils_Damage_NoPlagueAura;
            hit.GetComponent <PunctualDamage>().Knockback = NecromancyBase.settings.ShootTendrils_Knockback_NoPlagueAura;
            var comp = hit.AddComponent <AddStatusEffectBuildUp>();

            comp.Status       = ResourcesPrefabManager.Instance.GetStatusEffectPrefab("Curse");
            comp.BuildUpValue = 25;

            // adjust visuals
            foreach (ParticleSystem ps in projectileObj.GetComponentsInChildren <ParticleSystem>())
            {
                var m = ps.main;
                m.startColor = Color.green;
                m.startSize  = new ParticleSystem.MinMaxCurve(0.05f, 0.09f);
            }

            // ================= plague aura interaction effects ===============

            var plagueEffectsObj = new GameObject("Effects");

            plagueEffectsObj.transform.parent = tendrils.transform;

            // add our custom PlagueAura proximity condition component
            var auraCondition2 = plagueEffectsObj.AddComponent <PlagueAuraProximityCondition>();

            auraCondition2.ProximityDist           = 2.5f;
            auraCondition2.RequiredActivatedItemID = 8999050;
            auraCondition2.Invert = false;

            // add our custom ShootTendrils component
            ShootTendrils strongTendrils = plagueEffectsObj.AddComponent <ShootTendrils>();

            At.InheritBaseValues(strongTendrils, orig);

            // clone the projectile
            origProjectile.SetActive(false);
            var strongProjObj = Instantiate(origProjectile);

            DontDestroyOnLoad(strongProjObj);
            origProjectile.SetActive(true);

            strongProjObj.name = "StrongNoxiousTendrils";
            var strongProj = strongProjObj.GetComponent <RaycastProjectile>();

            strongTendrils.BaseProjectile     = strongProj;
            strongTendrils.IntanstiatedAmount = 8;

            strongProj.Lifespan       = 0.75f;
            strongProj.DisableOnHit   = false;
            strongProj.EndMode        = Projectile.EndLifeMode.LifetimeOnly;
            strongProj.HitEnemiesOnly = true;

            // sound play
            if (strongProjObj.GetComponentsInChildren <SoundPlayer>() is SoundPlayer[] strongPlayers && strongPlayers.Count() > 0)
            {
                foreach (SoundPlayer player in strongPlayers)
                {
                    player.Sounds = new List <GlobalAudioManager.Sounds> {
                        GlobalAudioManager.Sounds.SFX_SKILL_ElemantalProjectileWind_Shot
                    };
                }
            }
            // heal on hit
            if (strongProj.GetComponentInChildren <AffectHealthParentOwner>() is AffectHealthParentOwner strongHeal)
            {
                //DestroyImmediate(heal);
                strongHeal.AffectQuantity = NecromancyBase.settings.ShootTendrils_Heal_InsideAura;
            }

            // change damage and hit effects.
            var strongHit = strongProj.transform.Find("HitEffects").gameObject;

            strongHit.GetComponent <PunctualDamage>().Damages   = NecromancyBase.settings.ShootTendrils_Damage_InsideAura;
            strongHit.GetComponent <PunctualDamage>().Knockback = NecromancyBase.settings.ShootTendrils_Knockback_InsideAura;
            comp              = strongHit.AddComponent <AddStatusEffectBuildUp>();
            comp.Status       = ResourcesPrefabManager.Instance.GetStatusEffectPrefab("Curse");
            comp.BuildUpValue = 60;

            // adjust visuals
            foreach (ParticleSystem ps in strongProjObj.GetComponentsInChildren <ParticleSystem>())
            {
                var m = ps.main;
                m.startColor = Color.green;
                m.startSize  = new ParticleSystem.MinMaxCurve(0.12f, 0.20f);
            }
        }
Esempio n. 3
0
        // skill setup called by Skillmanager init
        #region Detonate Skill
        public static void SetupDetonate()
        {
            var detonateSkill = ResourcesPrefabManager.Instance.GetItemPrefab(8890106) as AttackSkill;

            // setup skill
            detonateSkill.CastSheathRequired = -1;
            detonateSkill.RequiredOffHandTypes.Clear();
            detonateSkill.RequiredTags = new TagSourceSelector[0];
            detonateSkill.StartVFX     = null;

            // destroy these existing effects
            Destroy(detonateSkill.transform.Find("RunicRay").gameObject);
            DestroyImmediate(detonateSkill.transform.Find("Effects").gameObject);

            // hang onto the ShootBlast, we want to use this
            var shootBlast = detonateSkill.transform.Find("RunicBlast").GetChild(0).GetComponent <ShootBlast>();

            // ======== setup weak blast ============

            // create new Effects object
            var effects = new GameObject("Effects");

            effects.transform.parent = detonateSkill.transform;
            var detonateBlast = effects.AddComponent <DetonateBlast>();

            At.InheritBaseValues(detonateBlast, shootBlast);
            // destroy the old RunicBlast now that we stole the blast component
            Destroy(detonateSkill.transform.Find("RunicBlast").gameObject);

            // add condition. Required item on summon is Mertons Bones.
            var condition = effects.AddComponent <DetonateCondition>();

            condition.RequiredSummonEquipment = 3200030;
            condition.Invert = false;

            // disable clone target before cloning it
            var origBlast = detonateBlast.BaseBlast.gameObject;

            origBlast.SetActive(false);
            var blastObj = Instantiate(origBlast);

            DontDestroyOnLoad(blastObj);
            blastObj.name = "DetonateBlast";

            var blast = blastObj.GetComponentInChildren <CircularBlast>();

            detonateBlast.BaseBlast = blast;

            if (blast.GetComponentInChildren <PunctualDamage>() is PunctualDamage pDamage)
            {
                //pDamage.Damages = new DamageType[]
                //{
                //    new DamageType(DamageType.Types.Decay, 40),
                //    new DamageType(DamageType.Types.Ethereal, 20)
                //};
                pDamage.Damages = NecromancyBase.settings.DeathRitual_WeakExplosionDamage;
                //pDamage.Knockback = 75;
                pDamage.Knockback = NecromancyBase.settings.DeathRitual_WeakKnockback;
            }

            var explosionFX = blast.transform.Find("ExplosionFX").gameObject;

            foreach (ParticleSystem particles in explosionFX.GetComponentsInChildren <ParticleSystem>())
            {
                var m = particles.main;
                m.startColor = Color.green;
            }

            // =========== STRONG DETONATION (blue ghost) ================= //

            var effects2 = new GameObject("Effects");

            effects2.transform.parent = detonateSkill.transform;
            var detonateBlast2 = effects2.AddComponent <DetonateBlast>();

            At.InheritBaseValues(detonateBlast2, detonateBlast);

            // add condition. Required item on summon is Blue Ghost robes.
            var condition2 = effects2.AddComponent <DetonateCondition>();

            condition2.RequiredSummonEquipment = 3200040;
            condition2.Invert = false;

            origBlast.SetActive(false);
            var blastObj2 = Instantiate(origBlast);

            origBlast.SetActive(false);
            DontDestroyOnLoad(blastObj2);
            blastObj2.name = "StrongDetonateBlast";

            var blast2 = blastObj2.GetComponent <CircularBlast>();

            detonateBlast2.BaseBlast = blast2;

            if (blast2.GetComponentInChildren <PunctualDamage>() is PunctualDamage pDamage2)
            {
                pDamage2.Damages = new DamageType[]
                {
                    new DamageType(DamageType.Types.Decay, 50),
                    new DamageType(DamageType.Types.Ethereal, 20),
                    new DamageType(DamageType.Types.Frost, 20)
                };
                pDamage2.Knockback = 150;

                var comp = pDamage2.gameObject.AddComponent <AddStatusEffect>();
                comp.Status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab("Slow Down");
            }

            var explosionFX2 = blast2.transform.Find("ExplosionFX").gameObject;

            foreach (ParticleSystem particles in explosionFX2.GetComponentsInChildren <ParticleSystem>())
            {
                var m = particles.main;
                m.startColor = new Color()
                {
                    r = 0.2f, g = 0.4f, b = 1, a = 1
                };                                                               // cyan-ish
            }
        }