void initialise() { initialised = true; // make sure there is a parent if (transform.parent == null) { return; } if (parent == null) { parent = transform.parent.gameObject; } if (parent == null) { Debug.LogError("BuffParent component has no parent"); return; } // find the parent's protection class parentProtection = parent.gameObject.GetComponent <ProtectionClass>(); if (parentProtection) { if (ward != 0) { parentProtection.GainWard(ward); } if (wardPercentage != 0 && parent.GetComponent <BaseHealth>()) { parentProtection.GainWard((wardPercentage * parent.GetComponent <BaseHealth>().maxHealth)); } } if (increasedSize != 0) { SizeManager sizeManager = parent.GetComponent <SizeManager>(); if (sizeManager) { sizeManager.increaseSize(increasedSize); } } // find the parent's base health if (lifeRegen != 0) { parentHealth = parent.GetComponent <BaseHealth>(); parentHealth.addedHealthRegenPerSecond += lifeRegen; } // find the parent's base mana if (manaCostDivider != 0) { parentMana = parent.GetComponent <BaseMana>(); parentMana.addedManaCostDivider += manaCostDivider; } // find the parent's demo ward regen if (wardRegen != 0) { parentProtection.wardRegen += wardRegen; } // find the parent's base stats if (speed != 0) { parentBaseStats = parent.GetComponent <BaseStats>(); if (parentBaseStats != null) { parentBaseStats.ChangeStatModifier(Tags.Properties.Movespeed, speed, BaseStats.ModType.ADDED); } } // find the parent's speed manager if (percentageSpeed != 0) { if (!parentBaseStats) { parentBaseStats = parent.GetComponent <BaseStats>(); } parentSpeedManager = parent.GetComponent <SpeedManager>(); if (parentSpeedManager != null && parentBaseStats != null) { parentBaseStats.ChangeStatModifier(Tags.Properties.Movespeed, percentageSpeed, BaseStats.ModType.INCREASED); } } if (reducedStunDuration != 0) { parentStunnedState = parent.gameObject.GetComponent <Stunned>(); if (parentStunnedState != null) { parentStunnedState.baseStunDuration -= reducedStunDuration; } } // apply taggedStats parentBaseStats = parent.GetComponent <BaseStats>(); if (parentBaseStats) { foreach (TaggedStatsHolder.TaggableStat stat in taggedStats) { parentBaseStats.ChangeStatModifier(stat.property, stat.addedValue, BaseStats.ModType.ADDED, stat.tagList); parentBaseStats.ChangeStatModifier(stat.property, stat.increasedValue, BaseStats.ModType.INCREASED, stat.tagList); foreach (float value in stat.moreValues) { parentBaseStats.ChangeStatModifier(stat.property, value, BaseStats.ModType.MORE, stat.tagList); } foreach (float value in stat.quotientValues) { parentBaseStats.ChangeStatModifier(stat.property, value, BaseStats.ModType.QUOTIENT, stat.tagList); } } parentBaseStats.UpdateStats(); } // update protection totals if (parentProtection) { parentProtection.UpdateProtectionTotals(); } // subscribe to a death event to remove the buffs if (GetComponent <SelfDestroyer>()) { GetComponent <SelfDestroyer>().deathEvent += removeBuffs; } }
public void Summon() { for (int i = 0; i < numberToSummon; i++) { // get a reference to this objects creation references CreationReferences myReferences = GetComponent <CreationReferences>(); // remove previous summons if necessary if (limitNumber && myReferences && attachCreationReferences && entity.GetComponent <Prefabs>()) { abilitiesThatCountForLimit.Add(myReferences.thisAbility); List <GameObject> existingSummons = new List <GameObject>(); foreach (Summoned summoned in Summoned.all) { if (abilitiesThatCountForLimit.Contains(summoned.references.thisAbility)) { if (summoned.references.creator = myReferences.creator) { existingSummons.Add(summoned.gameObject); } } } // components for removing summons SelfDestroyer selfDestroyer = null; Dying dying = null; while (existingSummons.Count >= limit) { GameObject SummonToKill = getLowestPriority(existingSummons); existingSummons.Remove(SummonToKill); selfDestroyer = SummonToKill.GetComponent <SelfDestroyer>(); dying = SummonToKill.GetComponent <Dying>(); // death events if (dying && dying.getController()) { dying.unsummoned = true; dying.die(); } // self destroyer events if (selfDestroyer) { selfDestroyer.die(); } // if neither exist, resort to destroying the game object if (!dying && !selfDestroyer) { Destroy(SummonToKill); } } } // decide the position Vector3 pos = displacement; if (distance > 0) { float angle = Random.Range(0, Mathf.PI * 2); pos = new Vector3(distance * Mathf.Cos(angle), displacement.y, distance * Mathf.Sin(angle)); } pos = transform.position + pos; pos = new Vector3(pos.x, getY(pos), pos.z); // create the entity GameObject summon = Instantiate(entity, pos, Quaternion.Euler(0, 0, 0)); // adapt the entity foreach (EntityAdapter adapter in GetComponents <EntityAdapter>()) { summon = adapter.adapt(summon); } // attach creation references if necessary, if not then update them CreationReferences references = null; if (attachCreationReferences && myReferences != null) { if (!summon.GetComponent <CreationReferences>()) { references = summon.AddComponent <CreationReferences>(); } else { references = summon.GetComponent <CreationReferences>(); } references.creator = myReferences.creator; references.thisAbility = myReferences.thisAbility; } // add a summoned component Summoned summonedComponent = summon.AddComponent <Summoned>(); summonedComponent.singeCardForAllMinions = singeCardForAllMinions; // initialise the summoned component summonedComponent.references = references; summonedComponent.initialise(); //adds recent events tracker summon.AddComponent <CharacterStatusTracker>(); // get a reference to the minion's stats BaseStats stats = summon.GetComponent <BaseStats>(); // give it damage bonuses based on a tagged stats holder if (GetComponent <TaggedStatsHolder>() && stats) { TaggedStatsHolder holder = GetComponent <TaggedStatsHolder>(); foreach (TaggedStatsHolder.TaggableStat ts in holder.taggedStats) { List <Tags.AbilityTags> newTagList = new List <Tags.AbilityTags>(); newTagList.AddRange(ts.tagList); if (newTagList.Contains(Tags.AbilityTags.Minion)) { newTagList.Remove(Tags.AbilityTags.Minion); stats.ChangeStatModifier(ts.property, ts.addedValue, BaseStats.ModType.ADDED, newTagList); stats.ChangeStatModifier(ts.property, ts.increasedValue, BaseStats.ModType.INCREASED, newTagList); foreach (float value in ts.moreValues) { stats.ChangeStatModifier(ts.property, value, BaseStats.ModType.MORE, newTagList); } foreach (float value in ts.quotientValues) { stats.ChangeStatModifier(ts.property, value, BaseStats.ModType.QUOTIENT, newTagList); } } } } // make it follow the creator if necessary if (followsCreator) { if (GetComponent <CreationReferences>()) { // if no follow ranges have been defined then use the defaults if (followRangesAndPriorities.Count <= 0) { summon.AddComponent <Following>().leader = myReferences.creator; } // otherwise create follow states for each entry in the list Following following; foreach (FollowRangeAndPriority frar in followRangesAndPriorities) { following = summon.AddComponent <Following>(); following.leader = myReferences.creator; following.startFollowingRange = frar.range; following.priority = frar.priority; } } } // make it move away from the creator when close if necessary if (movesAwayFromSummonerWhenClose) { if (myReferences) { summon.AddComponent <MovingAwayFromSummoner>().summoner = myReferences.creator; } } // if necessary limit the duration by adding a destroy after duration component if (limitDuration) { // use a self destroyer if it has ones, otherwise use the dying state if (summon.GetComponent <SelfDestroyer>()) { DestroyAfterDuration destroyer = summon.AddComponent <DestroyAfterDuration>(); destroyer.duration = duration; } else { DieAfterDelay destroyer = null; if (!summon.GetComponent <DieAfterDelay>()) { destroyer = summon.AddComponent <DieAfterDelay>(); destroyer.timeUntilDeath = duration; } // if there is already a destroy after duration component, lower the duration if this component's duration is lower than the one already there else { destroyer = summon.GetComponent <DieAfterDelay>(); destroyer.timeUntilDeath = Mathf.Min(destroyer.timeUntilDeath, duration); } // make the destroyer unsummon rather than kill if (destroyer) { destroyer.countsAsUnsummoned = true; } } } // pass on alignment if necessary, may require an alignment manager to be added to the entity if (passOnAlignment && GetComponent <AlignmentManager>()) { AlignmentManager alignmentManager = null; if (!summon.GetComponent <AlignmentManager>()) { alignmentManager = summon.AddComponent <AlignmentManager>(); } else { alignmentManager = summon.GetComponent <AlignmentManager>(); } alignmentManager.alignment = GetComponent <AlignmentManager>().alignment; } // give the entity a custom name if necessary, may require a display information component to be added to the entity if (giveCustomName && customNames.Count > 0) { DisplayInformation displayInformation = null; if (!summon.GetComponent <DisplayInformation>()) { displayInformation = summon.AddComponent <DisplayInformation>(); } else { displayInformation = summon.GetComponent <DisplayInformation>(); } int nameIndex = Random.Range(0, customNames.Count); displayInformation.displayName = customNames[nameIndex]; } // add stats if (statList != null && statList.Count > 0) { if (stats) { foreach (TaggedStatsHolder.TaggableStat stat in statList) { stats.addStat(stat); } stats.UpdateStats(); stats.myHealth.currentHealth = stats.myHealth.maxHealth; } } // give the entity a custom tag if necessary if (giveCustomTag) { summon.tag = customTag; } if (stats) { stats.UpdateStats(); if (stats.myHealth) { stats.myHealth.currentHealth = stats.myHealth.maxHealth; } } // pass on this summon information to a summonChangeTracker SummonChangeTracker sct = summon.AddComponent <SummonChangeTracker>(); sct.statList.AddRange(statList); sct.limitDuration = limitDuration; sct.followsCreator = followsCreator; sct.followRangesAndPriorities = new List <FollowRangeAndPriority>(); sct.followRangesAndPriorities.AddRange(followRangesAndPriorities); sct.limitDuration = limitDuration; sct.duration = duration; } }
void removeBuffs() { if (buffsRemoved) { return; } if (!initialised) { return; } buffsRemoved = true; if (parentProtection) { parentProtection.wardRegen -= wardRegen; } if (increasedSize != 0 && parent) { SizeManager sizeManager = parent.GetComponent <SizeManager>(); if (sizeManager) { sizeManager.increaseSize(-increasedSize); } } if (parentHealth && lifeRegen != 0) { parentHealth.addedHealthRegenPerSecond -= lifeRegen; } if (parentMana && manaCostDivider != 0) { parentMana.addedManaCostDivider -= manaCostDivider; } if (parentBaseStats != null) { parentBaseStats.ChangeStatModifier(Tags.Properties.Movespeed, -speed, BaseStats.ModType.ADDED); if (parentSpeedManager != null) { parentBaseStats.ChangeStatModifier(Tags.Properties.Movespeed, -percentageSpeed, BaseStats.ModType.INCREASED); } } if (parentStunnedState != null) { parentStunnedState.baseStunDuration += reducedStunDuration; } // remove taggedStats if (parentBaseStats) { foreach (TaggedStatsHolder.TaggableStat stat in taggedStats) { parentBaseStats.ChangeStatModifier(stat.property, -stat.addedValue, BaseStats.ModType.ADDED, stat.tagList); parentBaseStats.ChangeStatModifier(stat.property, -stat.increasedValue, BaseStats.ModType.INCREASED, stat.tagList); foreach (float value in stat.moreValues) { parentBaseStats.ChangeStatModifier(stat.property, value, BaseStats.ModType.QUOTIENT, stat.tagList); } foreach (float value in stat.quotientValues) { parentBaseStats.ChangeStatModifier(stat.property, value, BaseStats.ModType.MORE, stat.tagList); } } parentBaseStats.UpdateStats(); } }