// Use this for initialization void Start() { mutatorManager = GetComponent <AbilityMutatorManager>(); myAlignmentManager = GetComponent <AlignmentManager>(); myTaggedStatsHolder = GetComponent <TaggedStatsHolder>(); myCreationReferences = GetComponent <CreationReferences>(); myHitDetector = GetComponent <HitDetector>(); }
public InGameState() { bg = new Sprite(AssetManager.getTexture(AssetManager.TextureName.InGameBackground)); bg.Origin = (Vector2) bg.Texture.Size / 2F; bg.Scale = Vector2.One * 0.08F; resetView = true; this.Map = new Map(); ParticleManager = new ParticleManager(Map); Player = new Player(ParticleManager, Map); EnemyManager = new EnemyManager(Player); AlignmentManager = new AlignmentManager(Player, Map); }
private void Awake() { Instance = this; SturfeeEventManager.Instance.OnSessionReady += OnSessionReady; SturfeeEventManager.Instance.OnSessionFailed += OnSessionFailed; SturfeeEventManager.Instance.OnCoverageCheckComplete += OnCoverageCheckComplete; SturfeeEventManager.Instance.OnLocalizationComplete += OnLocalizationComplete; SturfeeEventManager.Instance.OnLocalizationLoading += OnLocalizationLoading; LookUpTrigger.OnUserLookedUp += HandleOnLookUpComplete; ScanButton.SetActive(false); BackButton.SetActive(false); Cursor.SetActive(false); Arrow.SetActive(false); ScanAnimation.SetActive(false); }
// Use this for initialization void Start() { abilityMover = GetComponent <AbilityMover>(); locationDetector = GetComponent <LocationDetector>(); AlignmentManager alignmentManager = GetComponent <AlignmentManager>(); if (locationDetector && alignmentManager) { Alignment alignment = alignmentManager.alignment; if (alignment) { List <Transform> possibleTargets = new List <Transform>(); foreach (BaseHealth health in BaseHealth.all) { if (health.alignmentManager && alignment.foes.Contains(health.alignmentManager.alignment) && health.currentHealth > 0) { possibleTargets.Add(health.transform); } } Vector3 position = locationDetector.targetLocation; targetPosition = position; float distance = 0f; float targetDistance = 0f; foreach (Transform possibleTarget in possibleTargets) { distance = Vector3.Distance(position, possibleTarget.position); targetDistance = Vector3.Distance(position, targetPosition); if ((target == null || distance < targetDistance) && distance < maxDistanceFromTarget) { targetPosition = possibleTarget.position; target = possibleTarget; } } if (target) { targetGo = target.gameObject; } } } }
private void Awake() { AlignSubtree subTree = FindObjectOfType <AlignSubtree>(); if (subTree != null) { if (subTree.AlignmentManager == null) { subTree.OnAlignManagerCreated += (sender, manager) => { this.alignmentManager = manager; alignmentManager.OnTriangulationBuilt += OnNewTriangulationWasBuilt; }; } else { this.alignmentManager = subTree.AlignmentManager; alignmentManager.OnTriangulationBuilt += OnNewTriangulationWasBuilt; } } }
void Start() { AlignmentManager alignmentManager = GetComponent <AlignmentManager>(); if (alignmentManager && alignmentManager.alignment) { Vector3 position = transform.position; foreach (Dying dying in Dying.all) { if (dying.isDying() && dying.myHealth && dying.myHealth.alignmentManager && dying.myHealth.alignmentManager.alignment && alignmentManager.alignment.foes.Contains(dying.myHealth.alignmentManager.alignment)) { if (Vector3.Distance(position, dying.transform.position) <= radius) { createAbilityObject(dying.gameObject); if (eraseCorpses) { dying.setDelays(0f, 0f); } } } } } }
// Use this for initialization public override void onCreation() { Alignment alignment = GetComponent <AlignmentManager>().alignment; if (alignment == null) { Debug.LogError("AttachToNearestAllyOnCreation component on " + gameObject.name + " cannot function as alignment is null"); return; } // find a lit of alignment objects that belong to allies List <AlignmentManager> alignments = new List <AlignmentManager>(); foreach (BaseHealth healthObject in BaseHealth.all) { if (alignment.isSameOrFriend(healthObject.GetComponent <AlignmentManager>().alignment)) { alignments.Add(healthObject.GetComponent <AlignmentManager>()); } } // remove dying objects from the list for (int i = alignments.Count - 1; i >= 0; i--) { if (alignments[i].GetComponent <Dying>() != null) { if (alignments[i].GetComponent <StateController>().currentState == alignments[i].GetComponent <StateController>().dying) { alignments.Remove(alignments[i]); } } } if (alignments.Count == 0) { return; } else { // find the nearest alignment object that is an ally AlignmentManager nearestAlignment = alignments[0]; float distance = Vector3.Distance(transform.position, nearestAlignment.transform.position); foreach (AlignmentManager alignmentManager in alignments) { if (Vector3.Distance(transform.position, alignmentManager.transform.position) < distance) { nearestAlignment = alignmentManager; distance = Vector3.Distance(transform.position, alignmentManager.transform.position); } } // if the nearest one already has a buff of this type then remove it if necessary if (replaceExistingBuff && GetComponent <CreationReferences>()) { CreationReferences[] references = nearestAlignment.transform.GetComponentsInChildren <CreationReferences>(); Ability thisAbility = GetComponent <CreationReferences>().thisAbility; for (int i = 0; i < references.Length; i++) { // check if the ability if the same as this one if (references[i].thisAbility == thisAbility) { // destroy the existing buff if (references[i].gameObject.GetComponent <SelfDestroyer>()) { references[i].gameObject.GetComponent <SelfDestroyer>().die(); } else { Destroy(references[i].gameObject); } } } } // attach to the nearest one transform.parent = nearestAlignment.transform; // move to the ally's location transform.localPosition = displacement; // change to the ally's rotation transform.rotation = transform.parent.rotation; } }
public void Apply(GameObject hitObject) { GameObject effect = Instantiate(statusEffect.effectObject, hitObject.transform); StatusDamage statusDamage = effect.GetComponent <StatusDamage>(); TaggedStatsHolder myTaggedStatsHolder = GetComponent <TaggedStatsHolder>(); ProtectionClass protection = hitObject.GetComponent <ProtectionClass>(); if (protection) { if (statusDamage && myTaggedStatsHolder) { TaggedStatsHolder taggedStatsHolder = effect.AddComponent <TaggedStatsHolder>(); taggedStatsHolder.simpleStats.AddRange(myTaggedStatsHolder.simpleStats); taggedStatsHolder.taggedStats.AddRange(myTaggedStatsHolder.taggedStats); // apply DoT damage foreach (TaggedStatsHolder.TaggableStat taggableStat in taggedStatsHolder.taggedStats) { if (taggableStat.tagList.Contains(Tags.AbilityTags.DoT)) { taggableStat.tagList.Remove(Tags.AbilityTags.DoT); } } // build damage stats if necessary foreach (DamageStatsHolder holder in effect.GetComponents <DamageStatsHolder>()) { holder.damageStats = DamageStats.buildDamageStats(holder, taggedStatsHolder); } } // add creation reference CreationReferences myReferences = GetComponent <CreationReferences>(); if (myReferences) { CreationReferences references = effect.AddComponent <CreationReferences>(); references.creator = myReferences.creator; references.thisAbility = myReferences.thisAbility; } // add alignment AlignmentManager myAlignmentManager = GetComponent <AlignmentManager>(); if (myAlignmentManager) { AlignmentManager alignmentManager = effect.AddComponent <AlignmentManager>(); alignmentManager.alignment = myAlignmentManager.alignment; } // apply shock effect if (statusEffect.effectID == 13) { TaggedStatsHolder tsh = GetComponent <TaggedStatsHolder>(); if (tsh) { float shockEffect = tsh.GetStatValue(Tags.Properties.IncreasedShockEffect); BuffParent pb = effect.GetComponent <BuffParent>(); if (shockEffect != 0 && pb) { foreach (TaggedStatsHolder.TaggableStat stat in pb.taggedStats) { stat.addedValue *= (1 + shockEffect); stat.increasedValue *= (1 + shockEffect); } } } } // apply protection.effectControl.AddEffect(effect, effect.GetComponent <StatusEffect>()); } }
void OnTriggerEnter(Collider hitObject) { // if the other object is an interactable then don't interact with it if (hitObject.gameObject.layer == 14) { return; } // if the other object is an ability object, e.g. another projectile, then don't interact with it if (hitObject.GetComponent <AbilityObjectIndicator>()) { return; } // get the shared hit detector's lists if (sharedHitDetector != null) { enemiesHit = sharedHitDetector.enemiesHit; alliesHit = sharedHitDetector.alliesHit; } // if the other object is dead, then don't interact with it StateController otherStateController = hitObject.GetComponent <StateController>(); if (otherStateController && otherStateController.currentState == otherStateController.dying) { return; } // if this is an enemy that has already been hit then invoke an enemy hit again event if (enemiesHit.Contains(hitObject.gameObject)) { if (enemyHitAgainEvent != null) { if (TryToHitEnemy(hitObject.gameObject)) { enemyHitAgainEvent.Invoke(hitObject.gameObject); if (afterEnemyHitEvent != null) { afterEnemyHitEvent.Invoke(hitObject.gameObject); } } } return; } // if this is an ally that has already been hit then invoke an ally hit again event if (alliesHit.Contains(hitObject.gameObject)) { if (allyHitAgainEvent != null) { allyHitAgainEvent.Invoke(hitObject.gameObject); if (afterAllyHitEvent != null) { afterAllyHitEvent.Invoke(hitObject.gameObject); } } return; } // check if the object hit is damageable AlignmentManager alignmentManager = GetComponent <AlignmentManager>(); if (hitObject.GetComponent <BaseHealth>() != null && alignmentManager != null && alignmentManager.alignment != null) { // check that the object hit is a friend if (alignmentManager.alignment.isSameOrFriend(hitObject.GetComponent <AlignmentManager>().alignment)) { // this is an enemy and this was not in the enemiesHit list so it is a new enemy alliesHit.Add(hitObject.gameObject); if (sharedHitDetector != null) { sharedHitDetector.alliesHit.Add(hitObject.gameObject); } if (newAllyHitEvent != null) { newAllyHitEvent.Invoke(hitObject.gameObject); if (afterAllyHitEvent != null) { afterAllyHitEvent.Invoke(hitObject.gameObject); } } return; } // if it is not with me, then it is against me.... else { // this is an enemy and this was not in the enemiesHit list so it is a new enemy enemiesHit.Add(hitObject.gameObject); if (sharedHitDetector != null) { sharedHitDetector.enemiesHit.Add(hitObject.gameObject); } if (newEnemyHitEvent != null) { if (TryToHitEnemy(hitObject.gameObject)) { newEnemyHitEvent.Invoke(hitObject.gameObject); if (afterEnemyHitEvent != null) { afterEnemyHitEvent.Invoke(hitObject.gameObject); } } } return; } } // if it's got to this point, the thing being hit shows no signs of life if (inanimateHitEvent != null) { inanimateHitEvent.Invoke(hitObject.gameObject); } }
// Use this for initialization public override void onCreation() { bool attached = false; Alignment alignment = GetComponent <AlignmentManager>().alignment; if (alignment == null) { Debug.LogError("AttachToNearestAllyOnCreation component on " + gameObject.name + " cannot function as alignment is null"); if (destroyIfFailedToAttach) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.die(); } return; } // find a list of alignment objects that belong to enemies List <AlignmentManager> alignments = new List <AlignmentManager>(); foreach (BaseHealth healthObject in BaseHealth.all) { if (healthObject.alignmentManager && !alignment.isSameOrFriend(healthObject.alignmentManager.alignment)) { alignments.Add(healthObject.alignmentManager); } } // remove inactive objects from the list for (int i = alignments.Count - 1; i >= 0; i--) { if (!alignments[i].gameObject.activeSelf) { alignments.Remove(alignments[i]); } } // remove dying objects from the list if (requiredLifeState == lifeState.alive) { for (int i = alignments.Count - 1; i >= 0; i--) { if (alignments[i].GetComponent <Dying>() != null) { if (alignments[i].GetComponent <StateController>().currentState == alignments[i].GetComponent <StateController>().dying) { alignments.Remove(alignments[i]); } } } } // or remove living objects from the list else if (requiredLifeState == lifeState.dead) { for (int i = alignments.Count - 1; i >= 0; i--) { if (alignments[i].GetComponent <Dying>() != null) { if (alignments[i].GetComponent <StateController>().currentState != alignments[i].GetComponent <StateController>().dying) { alignments.Remove(alignments[i]); } } else { alignments.Remove(alignments[i]); } } } // slightly different to dead as it will include things that died this step, but also things without a dying state else if (requiredLifeState == lifeState.zeroHealth) { BaseHealth bh = null; for (int i = alignments.Count - 1; i >= 0; i--) { bh = alignments[i].GetComponent <BaseHealth>(); if (bh && bh.currentHealth > 0) { alignments.Remove(alignments[i]); } } } if (alignments.Count == 0) { if (destroyIfFailedToAttach) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.die(); } return; } else { // find the nearest alignment object that is an enemy AlignmentManager nearestAlignment = alignments[0]; float distance = Vector3.Distance(transform.position, nearestAlignment.transform.position); foreach (AlignmentManager alignmentManager in alignments) { if (Vector3.Distance(transform.position, alignmentManager.transform.position) < distance) { nearestAlignment = alignmentManager; distance = Vector3.Distance(transform.position, alignmentManager.transform.position); } } // return if it is not close enough if (useRangeLimit && distance > rangeLimit) { if (destroyIfFailedToAttach) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.die(); } return; } // if the nearest one already has a buff of this type then remove it if necessary if (replaceExistingDebuff && GetComponent <CreationReferences>()) { CreationReferences[] references = nearestAlignment.transform.GetComponentsInChildren <CreationReferences>(); Ability thisAbility = GetComponent <CreationReferences>().thisAbility; for (int i = 0; i < references.Length; i++) { // check if the ability if the same as this one if (references[i].thisAbility == thisAbility) { // destroy the existing buff if (references[i].gameObject.GetComponent <SelfDestroyer>()) { references[i].gameObject.GetComponent <SelfDestroyer>().die(); } else { Destroy(references[i].gameObject); } } } } attached = true; // attach to the nearest one transform.parent = nearestAlignment.transform; // move to the ally's location transform.localPosition = displacement; // change to the ally's rotation transform.rotation = transform.parent.rotation; if (eraseInsteadOfAttaching) { BaseHealth bh = nearestAlignment.GetComponent <BaseHealth>(); if (bh) { bh.HealthDamagePercent(1000); } Dying dying = nearestAlignment.GetComponent <Dying>(); if (dying && !dying.delaysCannotBeChanged) { dying.destructionDelay = 0.02f; dying.sinkingDelay = 0.01f; } transform.parent = null; } } if (destroyIfFailedToAttach && !attached) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.die(); } }
public GameObject constructAbilityObject(Ability ability, Vector3 location, Vector3 targetLocation, GameObject overridePrefab = null, bool InheritSharedHitDetector = true) { // create the ability object GameObject abilityObject = null; if (overridePrefab == null) { // if there is no override prefab instantiate the ability's ability prefab abilityObject = Instantiate(ability.abilityPrefab, location, Quaternion.Euler(targetLocation - location)); } else // othewise instrantiate the override prefab { abilityObject = Instantiate(overridePrefab, location, Quaternion.Euler(targetLocation - location)); } // apply the relevant mutator if this entity has one if (mutatorManager) { mutators = mutatorManager.getMutators(ability); if (mutators != null) { foreach (AbilityMutator mutator in mutators) { abilityObject = mutator.Mutate(abilityObject, location, targetLocation); if (mutator.changeLocation) { targetLocation = mutator.newLocation; } if (mutator.changeTargetLocation) { targetLocation = mutator.newTargetLocation; } } } } // move the ability object if necessary foreach (DefineStartLocation defineStartLocation in abilityObject.GetComponents <DefineStartLocation>()) { if (defineStartLocation.active) { defineStartLocation.setLocation(location, targetLocation); // the direction from the cast point needs to be maintained if (defineStartLocation.maintainDirectionFromCastPoint()) { targetLocation = abilityObject.transform.position + targetLocation - location; } } } // initialise a location detector if necessary LocationDetector locationDetector = abilityObject.GetComponent <LocationDetector>(); if (locationDetector) { locationDetector.startLocation = abilityObject.transform.position; locationDetector.targetLocation = targetLocation; } // rotate the ability object abilityObject.transform.LookAt(targetLocation); // give the ability object its alignment AlignmentManager abilityAlignmentManager = abilityObject.GetComponent <AlignmentManager>(); if (!abilityAlignmentManager) { abilityAlignmentManager = abilityObject.AddComponent <AlignmentManager>(); } abilityAlignmentManager.alignment = myAlignmentManager.alignment; // give the ability object its creation references CreationReferences abilityCreationReferences = abilityObject.GetComponent <CreationReferences>(); if (!abilityCreationReferences) { abilityCreationReferences = abilityObject.AddComponent <CreationReferences>(); } abilityCreationReferences.thisAbility = ability; abilityCreationReferences.locationCreatedFrom = location; // if this an ability object then the creator is this objects creator, otherwise the creator is this object if (myCreationReferences && GetComponent <AbilityObjectIndicator>()) { abilityCreationReferences.creator = myCreationReferences.creator; } else { abilityCreationReferences.creator = gameObject; } // check whether there should be a shared hit detector HitDetector abilityHitDetector = abilityObject.GetComponent <HitDetector>(); if (abilityHitDetector) { SharedHitDetector sharedHitDetector = null; if (myHitDetector && myHitDetector.sharedHitDetector && InheritSharedHitDetector) { sharedHitDetector = myHitDetector.sharedHitDetector; } // create a shared hit detector else if (ability.sharedHitDetector) { GameObject newGameObject = new GameObject(); sharedHitDetector = newGameObject.AddComponent <SharedHitDetector>(); sharedHitDetector.gameObject.AddComponent <SelfDestroyer>(); sharedHitDetector.name = abilityObject.name + "'s shared hit detector"; } if (sharedHitDetector != null && !abilityHitDetector.cannotHaveSharedhitDetector) { abilityHitDetector.sharedHitDetector = sharedHitDetector; } } // build the damage stats for each damage stats holder foreach (DamageStatsHolder damageStatsHolder in abilityObject.GetComponents <DamageStatsHolder>()) { damageStatsHolder.damageStats = DamageStats.buildDamageStats(damageStatsHolder, GetComponent <TaggedStatsHolder>()); } // attach any on hit status appliers if this ability deals damage on hit if (myTaggedStatsHolder && abilityObject.GetComponent <DamageEnemyOnHit>() && !abilityObject.GetComponent <CannotApplyAdditionalStatuses>()) { ChanceToApplyStatusOnEnemyHit applier; float poisonChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.PoisonChance, ability.useTags); if (poisonChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Poison); applier.chance = poisonChance; applier.canApplyToSameEnemyAgain = false; } float igniteChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.IgniteChance, ability.useTags); if (igniteChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Ignite); applier.chance = igniteChance; applier.canApplyToSameEnemyAgain = false; } float chillChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.ChillChance, ability.useTags); if (chillChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Chill); applier.chance = chillChance; applier.canApplyToSameEnemyAgain = false; } float slowChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.SlowChance, ability.useTags); if (slowChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Slow); applier.chance = slowChance; applier.canApplyToSameEnemyAgain = false; } float blindChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.BlindChance, ability.useTags); if (blindChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Blind); applier.chance = blindChance; applier.canApplyToSameEnemyAgain = false; } float bleedChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.BleedChance, ability.useTags); if (bleedChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Bleed); applier.chance = bleedChance; applier.canApplyToSameEnemyAgain = false; } float shockChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.ShockChance, ability.useTags); if (shockChance > 0) { applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); applier.statusEffect = StatusEffectList.getEffect(StatusEffectID.Shock); applier.chance = shockChance; applier.canApplyToSameEnemyAgain = false; } } // if the ability has an ability object constructor give it a tagged stats holder with your tagged stats if (myTaggedStatsHolder && abilityObject.GetComponent <RequiresTaggedStats>()) { TaggedStatsHolder holder = abilityObject.GetComponent <TaggedStatsHolder>(); if (holder == null) { holder = abilityObject.AddComponent <TaggedStatsHolder>(); } holder.simpleStats.AddRange(myTaggedStatsHolder.simpleStats); holder.taggedStats.AddRange(myTaggedStatsHolder.taggedStats); } // set the direction if there is an ability mover if (abilityObject.GetComponent <AbilityMover>()) { abilityObject.GetComponent <AbilityMover>().positionDelta = Vector3.Normalize(targetLocation - location); // if the ability object defines its own start direction then let it if (abilityObject.GetComponent <DefineStartDirection>()) { abilityObject.GetComponent <DefineStartDirection>().setDirection(); } } // run any on creation methods foreach (OnCreation component in abilityObject.GetComponents <OnCreation>()) { if (component.runOnCreation) { component.onCreation(); } } // invoke the event if (abilityObjectCreatedEvent != null) { abilityObjectCreatedEvent.Invoke(ability, abilityObject); } return(abilityObject); }
// Use this for initialization public override void onCreation() { Alignment alignment = GetComponent <AlignmentManager>().alignment; if (alignment == null) { Debug.LogError("AttachToNearestAllyOnCreation component on " + gameObject.name + " cannot function as alignment is null"); return; } // find a lit of alignment objects that belong to enemies List <AlignmentManager> alignments = new List <AlignmentManager>(); if (moveToAllyInstead) { foreach (BaseHealth healthObject in BaseHealth.all) { if (alignment.friends.Contains(healthObject.GetComponent <AlignmentManager>().alignment)) { alignments.Add(healthObject.GetComponent <AlignmentManager>()); } } } else { foreach (BaseHealth healthObject in BaseHealth.all) { if (alignment.foes.Contains(healthObject.GetComponent <AlignmentManager>().alignment)) { alignments.Add(healthObject.GetComponent <AlignmentManager>()); } } } // remove dying objects from the list for (int i = alignments.Count - 1; i >= 0; i--) { if (alignments[i].GetComponent <Dying>() != null) { if (alignments[i].GetComponent <StateController>().currentState == alignments[i].GetComponent <StateController>().dying) { alignments.Remove(alignments[i]); } } } if (alignments.Count == 0) { return; } else { // find the nearest alignment object that is an enemy AlignmentManager nearestAlignment = alignments[0]; float distance = Vector3.Distance(transform.position, nearestAlignment.transform.position); foreach (AlignmentManager alignmentManager in alignments) { if (Vector3.Distance(transform.position, alignmentManager.transform.position) < distance) { nearestAlignment = alignmentManager; distance = Vector3.Distance(transform.position, alignmentManager.transform.position); } } // only move if the nearest one is within range if (distance < maxRange) { // move to the enemy's location transform.position = nearestAlignment.transform.position + offset; //// change to the ally's rotation //transform.rotation = transform.parent.rotation; } } }
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; } }
public void chain(GameObject hit) { // make sure this specific ability object only creates one chain if (hasChained) { return; } else { hasChained = true; } // check that there are chains remaining if (limitNumberOfChains) { if (chainsRemaining <= 0) { if (destroyAfterChainAttempt) { SelfDestroyer destroyer = GetComponent <SelfDestroyer>(); if (destroyer) { destroyer.die(); } } return; } } // find potential enemies to hit TargetFinder targetFinder = GetComponent <TargetFinder>(); AlignmentManager am = GetComponent <AlignmentManager>(); BaseHealth[] potentialTargetArray = targetFinder.getPotentialTargets(am.alignment, abilityToChain.targetsAllies, null, new LifeStateHolder(abilityToChain.requiredLifeState)); // exclude the object hit List <GameObject> potentialTargets = new List <GameObject>(); foreach (BaseHealth health in potentialTargetArray) { if (health.gameObject != hit) { potentialTargets.Add(health.gameObject); } } // if there is a shared hit detector remove objects that have already been hit bool hasSharedHitDetector = (detector.sharedHitDetector != null); if (hasSharedHitDetector) { foreach (GameObject removeObj in detector.sharedHitDetector.enemiesHit) { potentialTargets.Remove(removeObj); } } // get the positions of targets in range List <GameObject> outOfRangeObjects = new List <GameObject>(); Vector3 position = transform.position; foreach (GameObject target in potentialTargets) { if (Vector3.Distance(position, target.transform.position) > range) { outOfRangeObjects.Add(target); } } foreach (GameObject removeObject in outOfRangeObjects) { potentialTargets.Remove(removeObject); } // if there are no targets remaining return if (potentialTargets.Count <= 0) { if (destroyAfterChainAttempt) { SelfDestroyer destroyer = GetComponent <SelfDestroyer>(); if (destroyer) { destroyer.die(); } } return; } // if there is just one target chain to that else if (potentialTargets.Count == 1) { chainTo(potentialTargets[0], hit); if (destroyAfterSuccessfulChainAttempt) { SelfDestroyer destroyer = GetComponent <SelfDestroyer>(); if (destroyer) { destroyer.die(); } } } // if there are multiple targets, pick a random one else { int randTarget = Random.Range(0, potentialTargets.Count - 1); chainTo(potentialTargets[randTarget], hit); if (destroyAfterSuccessfulChainAttempt) { SelfDestroyer destroyer = GetComponent <SelfDestroyer>(); if (destroyer) { destroyer.die(); } } } if (destroyAfterChainAttempt) { SelfDestroyer destroyer = GetComponent <SelfDestroyer>(); if (destroyer) { destroyer.die(); } } }