internal void Update() // limited to 2s update since its low priority
        {
            if (OwnerCharacter != null && Time.time - lastUpdateTime > 2f)
            {
                lastUpdateTime = Time.time;

                if (Value != OwnerCharacter.Stats.ManaPoint * NecromancyBase.settings.Transcendence_DamageBonus)
                {
                    Value = OwnerCharacter.Stats.ManaPoint * NecromancyBase.settings.Transcendence_DamageBonus;

                    if (IsRegistered)
                    {
                        OwnerCharacter.Stats.RemoveStatStack(this.AffectedStat, this.SourceID, this.IsModifier);

                        var m_statStack = OwnerCharacter.Stats.AddStatStack(
                            this.AffectedStat,
                            new StatStack(
                                this.m_sourceID,
                                this.Lifespan,
                                this.Value * ((!this.IsModifier) ? 1f : 0.01f),
                                null),
                            this.IsModifier
                            );
                        At.SetValue(m_statStack, typeof(AffectStat), this as AffectStat, "m_statStack");
                    }
                }
            }
        }
Пример #2
0
        protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
        {
            if (SummonManager.Instance == null)
            {
                return;
            }

            if (SummonManager.Instance.FindWeakestSummon(_affectedCharacter.UID) is Character summonChar &&
                summonChar.isActiveAndEnabled)
            {
                // change blast position to the summon's position
                _infos[0] = summonChar.transform.position;
                base.ActivateLocally(_affectedCharacter, _infos);

                // kill the summon
                summonChar.Stats.ReceiveDamage(999f);

                // fix for cooldown not working on this skill for some reason
                var skill = this.ParentItem as Skill;
                At.SetValue(Time.time, typeof(Skill), skill, "m_lastActivationTime");
                At.SetValue(-1, typeof(Skill), skill, "m_lastCooldownProgress");

                // plague aura interaction
                if (PlagueAuraProximityCondition.IsInsidePlagueAura(summonChar.transform.position))
                {
                    // if you're inside a plague aura, detonate resets your Summon cooldown.
                    if (_affectedCharacter.Inventory.SkillKnowledge.GetItemFromItemID(8890103) is Skill summonSkill)
                    {
                        summonSkill.ResetCoolDown();
                    }
                }
            }
        }
Пример #3
0
        public static void SetupFrenzy()
        {
            var frenzySkill = ResourcesPrefabManager.Instance.GetItemPrefab(8890105) as Skill;

            // setup skill
            frenzySkill.CastSheathRequired = -1;

            // destroy the existing skills, but keep the rest (VFX / Sound).
            DestroyImmediate(frenzySkill.transform.Find("Lightning").gameObject);
            DestroyImmediate(frenzySkill.transform.Find("SummonSoul").gameObject);

            // set custom spellcast anim
            At.SetValue(Character.SpellCastType.Focus, typeof(Item), frenzySkill as Item, "m_activateEffectAnimType");

            var effects = new GameObject("Effects");

            effects.transform.parent = frenzySkill.transform;

            effects.AddComponent <Frenzy>();
        }
        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);
        }