using System; using System.Collections; using System.Collections.Generic; using DarkTonic.MasterAudio; using Pathfinding; using UnityEngine; // Token: 0x02000014 RID: 20 public class AttackAI : MonoBehaviour { // Token: 0x06000198 RID: 408 RVA: 0x0001FD24 File Offset: 0x0001DF24 private void Start() { } // Token: 0x06000199 RID: 409 RVA: 0x0001FD28 File Offset: 0x0001DF28 public void StartCombat() { this.seenCount = -1; this.GetLists(); this.pickups = Links.x.cellar.pickups; this.maxCrowdRadiusFromAbilities = this.character.stats.GetMaxRadiusFromAbilities(); this.character.stats.CheckForAbilityBooleans(); this.projectiles = Links.x.combat.projectiles; this.groundItems = Links.x.inventory.groundBag.hitScreenItems; this.party = Links.x.party; this.lastAction = ""; this.startingPosition = this.character.currentPosition; if (this.character.stats.canCastSpells) { this.character.stats.CombatStartSpells(); this.spellDifficulties = this.character.stats.spellDifficulties; this.spellAvgDifficulty = 0; int num = 0; int num2 = 1000; this.spellMeanDifficulty = 0; int num3 = 0; this.paganRows.Clear(); int num4 = 0; for (int i = 0; i < this.spellDifficulties.Count; i++) { Library.Pagan paganRow = Links.x.library.GetPaganRow(this.abilityNames[i]); this.paganRows.Add(paganRow); if (this.spellDifficulties[i] > 0) { if (this.spellDifficulties[i] > num) { num = this.spellDifficulties[i]; } if (this.spellDifficulties[i] < num2) { num2 = this.spellDifficulties[i]; } num3 += this.spellDifficulties[i]; num4++; } } this.spellMeanDifficulty = Mathf.RoundToInt((float)num3 / (float)num4); this.spellAvgDifficulty = Mathf.RoundToInt(((float)num - (float)num2) / 2f); } this.currentTileEffects = Links.x.cellar.currentTileEffects; this.timedBreakables = Links.x.cellar.combatBreakables; this.diaBreakables = Links.x.diorama.breakableActions; if (!this.character.npc) { this.circleTiles = Links.x.fellowship.circleTiles; } else if (this.character.inCircle) { this.circleTiles = this.character.group.circleTiles; } this.canMeleeRangeAttack = true; if (this.character.stats.hasCustomAI) { if (this.character.stats.xmlName.Contains("JumpingFrogs") || this.character.stats.xmlName == "JumpFrog") { this.canMeleeRangeAttack = false; this.onlySpecialAttack = true; } if (this.character.stats.customAI == "SpellsOnly") { this.canMeleeRangeAttack = false; } } } // Token: 0x0600019A RID: 410 RVA: 0x00020011 File Offset: 0x0001E211 private void OnDestroy() { if (this.chargeLoop) { Links.x.cellar.ReturnPooledGameObject(120, this.chargeLoop); } } // Token: 0x0600019B RID: 411 RVA: 0x00020038 File Offset: 0x0001E238 public void ClearCoroutines() { if (this.resurrectCorout != null) { this.EndResurrect(); this.resurrectCorout = null; this.busy = false; } if (this.findPathCoroutine != null) { base.StopCoroutine(this.findPathCoroutine); this.findPathCoroutine = null; } if (this.findTargetCoroutine != null) { base.StopCoroutine(this.findTargetCoroutine); this.findTargetCoroutine = null; } if (this.groundItemCoroutine != null) { base.StopCoroutine(this.groundItemCoroutine); this.groundItemCoroutine = null; } if (this.pickupCoroutine != null) { base.StopCoroutine(this.pickupCoroutine); this.pickupCoroutine = null; } if (this.spellNodesCoroutine != null) { base.StopCoroutine(this.spellNodesCoroutine); this.spellNodesCoroutine = null; } if (this.friendCoroutine != null) { base.StopCoroutine(this.friendCoroutine); this.friendCoroutine = null; } if (this.kitingCoroutine != null) { base.StopCoroutine(this.kitingCoroutine); this.kitingCoroutine = null; } if (this.songMoveCoroutine != null) { base.StopCoroutine(this.songMoveCoroutine); this.songMoveCoroutine = null; } if (this.spellCoroutine != null) { base.StopCoroutine(this.spellCoroutine); this.spellCoroutine = null; } if (this.wanderCoroutine != null) { base.StopCoroutine(this.wanderCoroutine); this.wanderCoroutine = null; } if (this.orbitRoutine != null) { base.StopCoroutine(this.orbitRoutine); this.orbitRoutine = null; } this.busy = false; } // Token: 0x0600019C RID: 412 RVA: 0x00020191 File Offset: 0x0001E391 public void StopLookingForAction() { if (this.character.npc) { return; } this.ClearCoroutines(); this.findingAction = false; } // Token: 0x0600019D RID: 413 RVA: 0x000201AE File Offset: 0x0001E3AE public void StopAI() { this.ClearCoroutines(); this.findingAction = false; } // Token: 0x0600019E RID: 414 RVA: 0x000201C0 File Offset: 0x0001E3C0 public void DoSomething1() { this.ClearCoroutines(); if (this.tactics.Count > 1000) { string text = this.tactics[this.tactics.Count - 1]; Character character = this.targets[this.targets.Count - 1]; this.tactics.Clear(); this.targets.Clear(); this.tactics.Add(text); this.targets.Add(character); } this.actionCount++; this.orderedTargets = false; this.actions.ResetAction(); this.actions.targetMovePosition = null; this.astarDebugging = Records.x.astarDebugging; if (!this.character.mainSelected) { this.astarDebugging = false; } this.debugging = Records.x.combatConsoleDebugging; this.quipDebugging = Records.x.combatQuipDebugging; if (this.debugging) { this.str.Clear(); this.str.Append("\nPrevious action: "); this.str.Append(this.lastAction); } if (this.debugging) { this.str.Append("\nIn circle: "); this.str.Append(this.character.inCircle); this.str.Append(", buff "); this.str.Append(this.character.hasCreatureBuff); } this.findingAction = true; this.findingActionTime = Links.x.gameplay.seconds; this.stayOutOfRange = false; this.switchedWeapon = false; int combatLevel = this.character.stats.characterRow._CombatLevel; this.startWeaponRow = this.character.invRow1; if (!Links.x.gaia.pathfindingReady) { this.Skip(); return; } if (this.character.ambushing) { this.Skip(); return; } this.actions.targetMovePosition = null; if (this.character.node != null && Links.x.hasMain) { bool flag = true; if (this.character.inCircle && this.character.npc && (this.character.group.inSwarm || this.character.group.inSwarmWait)) { flag = false; } if (flag) { float sqrMagnitude = ((Vector3)this.character.node.position - this.character.currentPosition).sqrMagnitude; float sqrMagnitude2 = (this.character.currentPosition - Links.x.main.currentPosition).sqrMagnitude; float num = Records.x.nodeSize * Records.x.nodeSize; if (sqrMagnitude > num || sqrMagnitude2 < 1f) { this.character.CheckInTile(); } } } if (!Links.x.combat.npcOnlyCombat || this.character.mainSelected) { this.character.animator.SetBool("Combat", true); } bool flag2 = false; float num2 = (float)this.character.stats.HealthCurrent() / (float)this.character.stats.HealthMax(); bool flag3 = false; this.GetLastKnownLists(); this.seenCount = 0; for (int i = 0; i < this.lkPlayerAI.Count; i++) { if (this.CanAttack(this.lkPlayerAI[i]) && this.lkBoolAI[i]) { this.seenCount++; } } if (!this.character.npc && !this.character.mainSelected && (this.character.vipFollow || this.character.party) && !this.character.inCircle && !this.character.sailing) { if (Vector3.Distance(this.character.currentPosition, Links.x.main.currentPosition) > 25f && !Records.x.partyWait) { if (this.debugging) { this.str.Append("\nMove to main"); } if (this.MovetoMain()) { return; } } else if (Records.x.partyWait && Vector3.Distance(this.character.currentPosition, this.character.waitPosition) > 25f) { this.moveToMainTries = 0; if (this.debugging) { this.str.Append("\nMove to main"); } if (this.MovetoWait()) { return; } } else { this.moveToMainTries = 0; if (this.debugging) { this.str.Append("\nDistance to main: "); this.str.Append(Vector3.Distance(this.character.currentPosition, Links.x.main.currentPosition)); } } } if ((!this.character.npc || (this.character.npc && this.character.vipFollow)) && this.lkPlayerAI.Count == 0 && !this.actions.hasTarget) { if (!this.character.mainSelected) { this.character.TransferLKP(Links.x.main); } if (!Records.x.partyWait && !this.character.inCircle) { float num3 = Vector3.Distance(this.character.currentPosition, Links.x.main.currentPosition); if ((this.character.stats.formationGroup <= 6 && num3 > 10f) || num3 > 16f) { this.SkipWatch(); return; } this.moveToMainTries = 0; } if (this.LookForBreakables()) { return; } if (!this.character.inCircle) { this.Skip(); return; } } if (this.character.party && this.character.commandMove != null) { if (((Vector3)this.character.commandMove.position - this.character.currentPosition).sqrMagnitude >= 9f) { this.MovetoCommandPosition(); return; } this.character.commandMove = null; } this.earlyActions = this.ActionTacticsCount(); if (this.runBackToFriends) { this.runBackToFriends = false; if (this.RunToFriends()) { return; } } this.spread = true; this.stayNearCharacter = null; this.stayNearPosition = Vector3.zero; this.spreadStrong = false; if (this.character.stats.defendMainInCombat && !this.character.ghost) { if (this.character.stats.defendingCharacter && !this.character.stats.isLeader && this.character != this.character.stats.defendingCharacter) { this.spread = false; this.stayNearCharacter = this.character.stats.defendingCharacter; this.stayNearPosition = this.stayNearCharacter.currentPosition; this.stayNearNode = this.stayNearCharacter.node; this.spreadStrong = true; } if (this.character.stats.defendingCharacter && this.character.stats.isLeader && Random.Range(0, 10) == 0) { this.actions.savedEnemy = null; } if (this.character.creatures && this.character.creatures.creatures.pickOneLeader) { this.justAttackWithLeader = true; this.spread = true; } this.checkCircleID = 0; } else if (this.character.stats.stayNearPatrol) { this.spread = false; this.stayNearCharacter = null; this.stayNearPosition = (Vector3)this.character.stats.stayNearPoint.position; this.stayNearNode = this.character.stats.stayNearPoint; this.spreadStrong = true; } else { if (!this.character.npc) { if (this.character.inFriendGroup && !this.character.inCircle) { if (!this.character.isFriendGroupLeader) { this.spread = false; this.spreadStrong = true; this.stayNearCharacter = this.character.friendLeader; this.stayNearPosition = this.stayNearCharacter.currentPosition; this.stayNearNode = this.stayNearCharacter.node; if (this.MovetoFriend(36f)) { return; } } } else if (!this.character.inCircle && this.character.party) { Character character2 = this.NearestFriendSpread(); if (character2) { this.spread = false; this.spreadStrong = false; this.stayNearCharacter = character2; this.stayNearPosition = this.stayNearCharacter.currentPosition; this.stayNearNode = this.stayNearCharacter.node; if (this.MovetoFriend(225f)) { return; } } else { this.moveToFriendTries = 0; } } } if (this.character.inCircle) { this.moveToFriendTries = 0; if (!this.character.npc) { this.checkCircleID = 1; if (Links.x.fellowship.CheckCirclePositionAndMove(this.character) && this.circleMoveTries < 8) { this.circleMoveTries++; this.Skip(); return; } if (this.lkPlayerAI.Count == 0 && !this.actions.hasTarget) { this.circleMoveTries = 0; this.Skip(); return; } } if (this.character.npc && this.character.group && this.character.group.AnyoneHasLKP()) { this.checkCircleID = this.character.group.groupID; if ((this.character.group.inFormationMovement && this.circleMovement) || (this.character.group.inSwarm && this.circleMovement)) { this.Skip(); return; } if (!this.character.group.inSwarm && !this.character.group.inSwarmWait && this.character.group.CheckCirclePositionAndMove(this.character) && this.circleMoveTries < 8) { this.circleMoveTries++; this.Skip(); return; } } this.circleMoveTries = 0; this.spread = false; this.spreadStrong = true; this.stayNearCharacter = this.character; this.stayNearPosition = this.stayNearCharacter.currentPosition; this.stayNearNode = this.stayNearCharacter.node; if (this.character.npc && this.character.group && (this.character.group.inSwarm || this.character.group.inSwarmWait) && !this.circleMovement) { this.spread = true; this.stayNearCharacter = null; this.stayNearNode = null; } if (this.character.summoned && !this.character.npc && !Links.x.main.hasCircleBuff) { this.spread = true; this.stayNearCharacter = null; this.stayNearNode = null; } } else { this.checkCircleID = 0; this.circleMoveTries = 0; } } if (this.character.stats.formationGroup >= 7 || (this.character.stats.formationGroup > 3 && Random.Range(0, 5) == 0)) { bool flag4 = true; if (!this.IsPointAwayFromEnemies(this.character.currentPosition, false, flag4)) { flag3 = true; } } if (!this.actions.hasTarget && (flag2 || num2 * 100f < (float)this.character.stats.useItemsAI) && !this.character.summoned && !this.character.charmed && this.character.attackTime >= 1f) { if (this.debugging) { this.str.Append("\nHealth is low, look for potion: "); this.str.Append(num2); } if (this.LookForHealthItem(num2)) { return; } } if (this.character.fleeing && this.character.stats.Stuck() == 0 && (this.character.boatNavigator || !this.character.sailing)) { if (this.debugging) { this.str.Append("\nContinuing flee"); } this.SkipWatch(); return; } if (this.seenCount == 0 && this.character.npc) { bool flag5 = true; bool flag6 = true; if (this.character.inCircle && this.character.group) { if (this.character.group.staminaFilling || this.character.group.aggressive || this.character.group.movingTogether || !this.character.group.AnyoneHasLKP()) { flag5 = true; } else { flag5 = false; flag6 = false; } } if (this.character.vipFollow) { flag6 = false; } if (this.timeSinceSearchStarted > 0f) { if (this.character.stats.animal) { if (Links.x.gameplay.seconds > this.timeSinceSearchStarted + 72f) { if (Records.x.editor) { string text2 = "Search too long "; Character character3 = this.character; Debug.Log(text2 + ((character3 != null) ? character3.ToString() : null)); } flag6 = false; } } else { this.timeSinceSearchStarted = 0f; } } if (this.lkPlayerAI.Count > 0 && flag6) { if ((!this.character.sailing || (this.character.sailing && this.character.boatNavigator)) && this.Search()) { if (this.timeSinceSearchStarted == 0f) { this.timeSinceSearchStarted = Links.x.gameplay.seconds; } return; } } else { if (this.lkPlayerAI.Count == 0 && flag5) { this.findingAction = false; this.actions.EndActions(); return; } this.Skip(); return; } } else if (this.seenCount > 0) { this.timeSinceSearchStarted = 0f; } if (this.actions.spellWaveFX) { this.Skip(); return; } if (this.character.jumping) { this.Skip(); return; } if (this.character.invRow1 == null) { this.character.CreateEquippedItems(0, 0, Vector3.zero, Vector3.zero, 0, true); this.character.invRow1 = Links.x.library.GetInvRow(1); string text3 = "No inv row "; Character character4 = this.character; Debug.Log(text3 + ((character4 != null) ? character4.ToString() : null)); } if (this.character.npc && Records.x.noCombat && (Records.x.editor || Records.x.secrets)) { this.SkipLong(); return; } if (this.character.node == null) { this.character.FindCurrentNode(true); this.Skip(); return; } this.allyIsPinning = false; if (this.character.attackTime >= 1f) { if (this.character.party) { this.allyIsPinning = Links.x.fellowship.AnyonePinning(); } else { int num4; Character character5; this.allyIsPinning = this.AnyonePinning(out num4, out character5); if (this.allyIsPinning && character5 && (character5.currentPosition - this.character.currentPosition).sqrMagnitude < 144f) { this.actions.savedEnemy = character5; } } } if (this.character.stats.formationGroup >= 4 && !this.character.mainSelected && flag3 && ((Random.Range(0, 10 - this.character.stats.formationGroup) == 0 && this.character.attackTime >= 1f) || this.character.attackTime < 0.25f || this.character.stats.formationGroup >= 7) && !this.character.sailing && !this.allyIsPinning && flag3) { if (this.debugging) { this.str.Append("\nHealth is low or is a squishie, kite: "); this.str.Append(num2); } this.LookForKitingPlace(1); return; } this.needToKite = false; if ((this.character.party || (this.character.npc && this.character.vipFollow)) && this.character.stats.formationGroup >= 7 && !this.character.mainSelected && !this.allyIsPinning && !this.character.sailing && !this.IsPointAwayFromEnemies(this.character.currentPosition, false, true)) { this.needToKite = true; } if (this.character.evading || (this.character.stats.formationGroup < 7 && this.character.dodging && !this.allyIsPinning && (this.character.attackTime < 1f || Links.x.gameplay.seconds < this.character.blockDodgeStartTime + 7f)) || !this.character.IsSentient()) { this.Skip(); return; } this.hasNearbyAttackingEnemy = null; this.hasNearbyProjectile = null; bool flag7 = false; int num5; if (this.character.stats.Stat("Agility", false, out num5) >= 70f) { flag7 = true; } bool flag8 = this.character.party; if (this.character.npc && Random.Range(0, combatLevel * 2) > 0) { flag8 = true; } if (Random.Range(0, 4) > 0 && this.character.stats.formationGroup > 3 && flag8 && !this.character.sailing) { this.hasNearbyAttackingEnemy = this.NearbyAttackingEnemy(); this.hasNearbyProjectile = null; if (!this.hasNearbyAttackingEnemy) { this.hasNearbyProjectile = this.NearbyAttackingProjectile(); } if (this.hasNearbyAttackingEnemy || this.hasNearbyProjectile) { if (this.debugging) { this.str.Append("\nLooking for incoming attack, trying to move"); } if (this.hasNearbyAttackingEnemy && this.character.IsSentient()) { GraphNode graphNode = this.character.FindSlideNode(this.character, this.hasNearbyAttackingEnemy.currentPosition, false, true); if (graphNode != null && graphNode != this.character.node && this.character.stats.Stuck() == 0 && ((Vector3)graphNode.position - this.character.currentPosition).sqrMagnitude < 16f) { this.character.Slide(graphNode, false); this.character.body.lookAtController.SetNewTarget(this.hasNearbyAttackingEnemy.body.headBone, 0f, 0f, false); this.character.SetAnimatorSpeed(1f); this.Skip(); return; } } } } if (this.character.npc) { if (this.lastAction.Contains("Skip") && !flag7 && !this.character.vipFollow && !this.allyIsPinning) { int num6 = 1; int count = this.tactics.Count; if (count > 1) { if (this.tactics[count - 1].Contains("Skip")) { num6++; } if (count > 2 && this.tactics[count - 2].Contains("Skip")) { num6++; } if (count > 3 && this.tactics[count - 3].Contains("Skip")) { num6++; } } if ((num6 < 3 && this.character.attackTime < 1f) || num6 <= 1) { this.Skip(); return; } } if (this.lastAction.Contains("Wander") && !flag7 && !this.allyIsPinning && combatLevel <= 5 && Random.Range(0, 5) != 0) { this.Skip(); return; } if (this.lastAction.Contains("Attack") || this.lastAction.Contains("Spell") || (this.lastAction.Contains("Elixir") && !flag7 && this.character.attackTime < 1f && !this.allyIsPinning && !flag7)) { if (Random.Range(0, 2) == 0) { this.orbitRight = true; } else { this.orbitRight = false; } if (combatLevel <= 4 && !this.character.oar && Random.Range(0, 5) == 0) { this.TurnToEnemy(false, null); this.Skip(); return; } } } if (!this.character.npc && !this.actions.hasTarget && Records.x.ai == 0) { this.Skip(); return; } bool flag9 = false; if (this.actions.hasTarget && this.character.attackTime >= 1f) { if (!this.actions.selectedTarget && !this.actions.selectedTargetInteractive) { this.actions.SetSelectedTarget(false, null, null, null); this.CheckWeapons(false); return; } if (this.actions.selectedAITargetInteractive) { if (!this.actions.selectedAITargetInteractive.activeSelf) { this.actions.SetSelectedTarget(false, null, null, null); } if (this.LookForBreakables()) { return; } } bool flag10 = false; for (int j = 0; j < this.party.Count; j++) { if (this.party[j] && this.party[j].stats.pinning) { flag10 = true; } } if (this.actions.selectedTarget || this.actions.selectedTargetInteractive || flag10) { this.CheckWeapons(true); return; } } if (!flag9) { this.CheckWeapons(false); } } // Token: 0x0600019F RID: 415 RVA: 0x0002188C File Offset: 0x0001FA8C public void DoSomething2() { if (!Links.x.gaia.pathfindingReady) { this.Skip(); return; } if (this.character.stats.hasBuffItem && this.character.npc && this.character.attackTime >= 1f && !this.allyIsPinning) { if (this.debugging) { this.str.Append("\nHas buff item"); } if (this.UsingBuff(-1)) { return; } } if (this.character.party && this.character.attackTime >= 1f && this.character.stats.autoBuffsAI < 3 && !this.allyIsPinning) { int num = this.character.HasBuffItem(); if (num > -1) { float num2 = (float)(Links.x.combat.ChallengeLevel(false) * 2) / (float)Links.x.fellowship.GroupLevel(); bool flag = false; float num3 = 2f; float num4 = 4f; float num5 = 6f; if (this.character.stats.autoBuffsAI == 0 && num2 >= num3) { flag = true; } if (this.character.stats.autoBuffsAI == 1 && num2 >= num4) { flag = true; } if (this.character.stats.autoBuffsAI == 2 && num2 >= num5) { flag = true; } if (flag) { if (this.debugging) { this.str.Append("\nHas buff item"); } if (this.UsingBuff(num)) { return; } } } } bool flag2 = false; if (!this.character.npc || (!flag2 && Random.Range(0, 3) != 0) || this.character.attackTime < 1f || this.onlySpecialAttack || this.allyIsPinning) { this.DoSomething3(); return; } int num6 = this.character.HasHealthItem(); if (num6 > -1) { if (this.debugging) { this.str.Append("\nHelp friend, has healing item "); this.str.Append(num6); } this.LookForFriend(false); return; } this.DoSomething3(); } // Token: 0x060001A0 RID: 416 RVA: 0x00021AA4 File Offset: 0x0001FCA4 public void DoSomething3() { if (!Links.x.gaia.pathfindingReady) { this.Skip(); return; } if (this.character.stats.canCharm && !this.allyIsPinning && this.TryToCharm()) { return; } bool flag = false; bool flag2 = false; if (!Records.x.editor) { flag = false; } if (this.character.stats.canCastSpells && ((this.character.party && this.character.stats.autoCastAI) || !this.character.party) && this.character.attackTime >= 1f && !this.onlySpecialAttack && !this.allyIsPinning && this.TryToCastSpell(1, 4)) { return; } if (this.SpecialAttack(false)) { return; } if (!this.character.ghost && !this.character.sailing && !this.character.summoned && ((this.character.npc && Random.Range(0, 3) == 0) || !this.character.npc) && !this.onlySpecialAttack && !flag && !this.allyIsPinning) { if (this.debugging) { this.str.Append("\nLooking for breakable"); } if (this.LookForBreakables()) { return; } } if (flag2 || (!this.character.ghost && !this.character.sailing && !this.character.summoned && ((this.character.npc && (this.character.stats.canCastSpells || Random.Range(0, 3) == 0)) || (!this.character.npc && Random.Range(0, 2) == 0)) && this.character.attackTime < 1f && !this.onlySpecialAttack && !flag && !this.allyIsPinning)) { if (this.debugging) { this.str.Append("\nLooking for pickup"); } this.LookForPickups(); return; } if (flag || (!this.character.ghost && !this.character.sailing && !this.character.summoned && !this.character.charmed && ((this.character.npc && Random.Range(0, 4) == 0) || (!this.character.npc && Random.Range(0, 7) == 0 && !this.needToKite)) && !this.onlySpecialAttack && !this.allyIsPinning)) { if (this.debugging) { this.str.Append("\nLooking for item"); } this.LookForGroundItem(); return; } this.DoSomething4(); } // Token: 0x060001A1 RID: 417 RVA: 0x00021D50 File Offset: 0x0001FF50 public void DoSomething4() { if (!Links.x.gaia.pathfindingReady) { this.Skip(); return; } bool flag = false; bool flag2 = false; if (this.character.stats.semizenMagic) { flag2 = true; if ((float)this.character.stats.characterRow._MaxMP == 222222f) { flag2 = false; } } if (!flag && !flag2 && this.character.attackTime >= 1f && !this.needToKite && this.canMeleeRangeAttack && !this.onlySpecialAttack && Links.x.gaia.pathfindingReady) { if (this.findTargetCoroutine != null) { base.StopCoroutine(this.findTargetCoroutine); } this.findTargetCoroutine = this.FindTarget(); base.StartCoroutine(this.findTargetCoroutine); return; } this.DoSomething5(); } // Token: 0x060001A2 RID: 418 RVA: 0x00021E20 File Offset: 0x00020020 public void DoSomething5() { if (!Links.x.gaia.pathfindingReady) { this.Skip(); return; } if (this.debugging) { this.str.Append("\nAttacking failed, attack time was "); this.str.Append(this.character.attackTime); } if (Links.x.combat.preDome) { this.Skip(); return; } if ((this.stayNearCharacter || this.stayNearNode != null) && !this.character.sailing && !this.character.inCircle && this.spreadStrong && !this.character.party) { float num = 49f; if (this.spread) { num = 100f; } if ((this.character.currentPosition - this.stayNearPosition).sqrMagnitude > num && !this.needToKite) { GraphNode graphNode = this.character.NearNode(this.stayNearPosition, true, 0, -1, this.checkCircleID); if (graphNode != null) { if (((Vector3)graphNode.position - this.stayNearPosition).sqrMagnitude < num) { this.findPathCoroutine = this.FindPath(graphNode, 0f, num, 50, false, false, false, false, false, "Move"); } else { this.findPathCoroutine = this.FindPath(graphNode, 0f, num, 50, false, false, false, false, false, "MoveTargetFar"); } base.StartCoroutine(this.findPathCoroutine); if (this.debugging) { this.str.Append("\nStaying near buddy character"); } return; } } } if (this.character.stats.hasBuffItem && this.character.npc && this.character.attackTime >= 1f) { if (this.debugging) { this.str.Append("\nLooking for buffs"); } if (this.UsingBuff(-1)) { return; } } if (this.character.party && !Links.x.qte.resurrecting && Links.x.PartyMembersAlive() < 4 && !Links.x.fellowship.AnyoneResurrecting(null)) { this.LookForFriend(true); return; } if (this.character.stats.canCastSpells && ((this.character.party && this.character.stats.autoCastAI) || !this.character.party) && this.character.attackTime >= 1f) { this.TryToCastSpell(2, 6); return; } this.DoSomething6(); } // Token: 0x060001A3 RID: 419 RVA: 0x000220C8 File Offset: 0x000202C8 public void DoSomething6() { if (!Links.x.gaia.pathfindingReady) { this.Skip(); return; } bool flag = false; int num; if (this.character.stats.Stat("Agility", false, out num) > 50f) { flag = true; } if (!this.stayOutOfRange && !this.character.sailing && this.character.stats.Stuck() == 0 && !this.character.dodging && !this.needToKite) { bool flag2 = true; int num2 = 2; if (this.character.npc) { num2 = 6; } if (this.character.inCircle) { flag2 = false; } if (this.character.party) { flag2 = false; if (Random.Range(0, Mathf.RoundToInt((float)this.character.stats.formationGroup / 2f)) == 0) { flag2 = true; } } if (this.justAttackWithLeader) { flag2 = false; } if (this.character.stats.stayNearPatrol) { flag2 = false; } if (this.character.sailing) { flag2 = false; } if (flag2 && (flag || (((this.character.stats.formationGroup <= 6 && this.earlyActions < 2 && Random.Range(0, 100) == 0) || (Random.Range(0, num2) != 0 && (this.character.npc || this.character.stats.formationGroup <= 6))) && this.character.stats.formationGroup != 0))) { if (this.character.invRow1._MeleeRangeEnd < 5f) { if (this.OrbitEnemy(true)) { return; } } else if (Random.Range(0, 3 + this.character.stats.formationGroup) == 0 && this.character.attackTime < 0.3f && this.OrbitEnemy(false)) { return; } } if (!this.character.turning && !flag && !this.character.party) { if (!this.character.inCircle && !this.character.oar) { this.TurnToEnemy(false, null); } this.SkipWatch(); return; } } if ((!this.IsPointAwayFromEnemies(this.character.currentPosition, false, true) && !this.noKiting && !this.character.sailing && !this.character.inCircle && ((Random.Range(0, 15) == 0 && this.character.npc && this.character.stats.formationGroup != 0) || this.character.stats.formationGroup >= 7)) || (this.character.stats.formationGroup >= 4 && Random.Range(0, 10) == 0)) { this.LookForKitingPlace(3); return; } if (this.character.party && !this.character.dodging && !this.character.turning) { if (!Records.x.partyWait && !this.character.inCircle) { float num3 = Vector3.Distance(this.character.currentPosition, Links.x.main.currentPosition); if ((this.character.stats.formationGroup <= 6 && num3 > 10f) || num3 > 16f) { if (this.MovetoMain()) { return; } } else { this.moveToMainTries = 0; } } if (!this.character.oar) { this.TurnToEnemy(false, null); } this.SkipWatch(); return; } if (flag && !this.character.inCircle && !this.character.sailing) { this.Wander(); } else { this.Skip(); } this.findingAction = false; } // Token: 0x060001A4 RID: 420 RVA: 0x00022478 File Offset: 0x00020678 public void FinishFindingAction(string pickedAction, Character target) { this.lastAction = pickedAction; this.tactics.Add(pickedAction); this.targets.Add(target); if (!pickedAction.Contains("Target") && !pickedAction.Contains("Attack") && this.character.invRow1 != this.startWeaponRow) { this.SwitchWeapons(); } this.character.CircleColor(this.character.fleeing); if (this.debugging) { Debug.Log(string.Concat(new string[] { this.character.gameObject.name, ": ", pickedAction, " ", this.str.ToString() })); } if (this.switchedWeapon && this.character.invRow1 != this.startWeaponRow) { this.character.UpdateWeaponVisuals(); } } // Token: 0x060001A5 RID: 421 RVA: 0x00022560 File Offset: 0x00020760 public void TriggerTimeline(float actionSpeed, bool skipReset) { if (!Records.x.turnBased && this.character.timelineIcon) { this.character.timelineIcon.WaitForAction(actionSpeed, false, skipReset); } } // Token: 0x060001A6 RID: 422 RVA: 0x00022594 File Offset: 0x00020794 public void ShowDebug() { if (this.debugging) { Debug.Log(string.Concat(new string[] { this.character.gameObject.name, " is finding action: ", this.findingAction.ToString(), " ", this.str.ToString() })); } } // Token: 0x060001A7 RID: 423 RVA: 0x000225F8 File Offset: 0x000207F8 public Character FindNearTarget(Character currentTarget) { if (!this.character) { return null; } float num = float.PositiveInfinity; Character character = null; this.combatCharacters = Links.x.combat.characters; for (int i = 0; i < this.combatCharacters.Count; i++) { Character character2 = this.combatCharacters[i]; if (character2 && this.CanAttack(character2) && !this.actions.ActionTargetsContains(character2)) { float sqrMagnitude = (character2.currentPosition - currentTarget.currentPosition).sqrMagnitude; if (sqrMagnitude <= num) { num = sqrMagnitude; character = character2; } } } return character; } // Token: 0x060001A8 RID: 424 RVA: 0x000226A4 File Offset: 0x000208A4 public Character NearestFriend() { if (!this.character) { return null; } float num = float.PositiveInfinity; Character character = null; this.combatCharacters = Links.x.combat.characters; for (int i = 0; i < this.combatCharacters.Count; i++) { Character character2 = this.combatCharacters[i]; if (character2 && !this.CanAttack(character2) && !character2.summoned && !character2.dead && character2 != this.character) { float sqrMagnitude = (character2.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; character = character2; } } } return character; } // Token: 0x060001A9 RID: 425 RVA: 0x00022768 File Offset: 0x00020968 public Character NearestFriendSpread() { if (!this.character) { return null; } float num = float.PositiveInfinity; Character character = null; this.factionCharacters.Clear(); for (int i = 0; i < this.party.Count; i++) { Character character2 = this.party[i]; if (character2 && character2 != this.character && character2.IsSentient() && character2.party && character2.actions) { if (this.rangeWeaponIndex == 0 || this.meleeWeaponIndex == -1) { if (character2.actions.ai.rangeWeaponIndex == 0 && this.earlyActions > 1) { this.factionCharacters.Add(character2); } } else if (character2.actions.ai.meleeWeaponIndex == 0 && character2.actions.ai.HasTargetInRange() && this.earlyActions > 2) { this.factionCharacters.Add(character2); } } } if (this.factionCharacters.Count > 0) { if (this.factionCharacters.Count == 1) { int portraitOrder = Links.x.GetPortraitOrder(this.character); int portraitOrder2 = Links.x.GetPortraitOrder(this.factionCharacters[0]); if (portraitOrder > portraitOrder2) { return this.factionCharacters[0]; } } else { int portraitOrder3 = Links.x.GetPortraitOrder(this.character); for (int j = 0; j < this.factionCharacters.Count; j++) { Character character3 = this.factionCharacters[j]; int portraitOrder4 = Links.x.GetPortraitOrder(character3); if (portraitOrder3 < portraitOrder4) { float sqrMagnitude = (character3.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; character = character3; } } } } } return character; } // Token: 0x060001AA RID: 426 RVA: 0x00022958 File Offset: 0x00020B58 public Character NearestFriendRally() { if (!this.character) { return null; } float num = float.PositiveInfinity; Character character = null; for (int i = 0; i < this.party.Count; i++) { Character character2 = this.party[i]; if (character2 && !character2.summoned && !character2.inAction && character2.IsSentient() && !character2.inQueuedAbility && character2.actions && character2 != this.character && !character2.actions.ai.busy) { float sqrMagnitude = (character2.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < num && sqrMagnitude < 64f) { num = sqrMagnitude; character = character2; } } } return character; } // Token: 0x060001AB RID: 427 RVA: 0x00022A40 File Offset: 0x00020C40 public Character NearestEnemy() { Character character; if (this.actions.savedEnemy) { if (this.GetRow()._MeleeRangeEnd <= 5f) { if ((this.actions.savedEnemy.currentPosition - this.character.currentPosition).sqrMagnitude > 144f || this.actions.savedEnemy.stunned || this.actions.savedEnemy.dead) { if (this.actions.currentlyTargeting) { if (!this.actions.currentlyTargeting.dead && !this.actions.currentlyTargeting.stunned && (this.actions.currentlyTargeting.currentPosition - this.character.currentPosition).sqrMagnitude < 64f) { character = this.actions.currentlyTargeting; } else { character = this.GetNearestEnemy(this.character.currentPosition); } } else { character = this.GetNearestEnemy(this.character.currentPosition); } if (!character) { character = this.actions.savedEnemy; } } else { character = this.actions.savedEnemy; } } else { character = this.actions.savedEnemy; } } else { character = this.GetNearestEnemy(this.character.currentPosition); } return character; } // Token: 0x060001AC RID: 428 RVA: 0x00022BB0 File Offset: 0x00020DB0 public Character GetNearestEnemy(Vector3 from) { float num = float.PositiveInfinity; Character character = null; this.combatCharacters = Links.x.combat.characters; for (int i = 0; i < this.combatCharacters.Count; i++) { Character character2 = this.combatCharacters[i]; if (character2 && this.CanAttack(character2)) { float sqrMagnitude = (character2.currentPosition - from).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; character = character2; } } } return character; } // Token: 0x060001AD RID: 429 RVA: 0x00022C38 File Offset: 0x00020E38 public bool CanAttack(Character target) { if (!this.character.hasActions) { return false; } if (target.npc && target.hostility != 2 && !this.character.npc) { if (this.character.actions.hasTarget) { if (this.character.actions.selectedTargetInteractive) { return target == this.character.actions.selectedTargetInteractive.GetComponent(); } if (this.character.actions.selectedAITargetInteractive) { return target == this.character.actions.selectedAITargetInteractive.GetComponent(); } if (this.character.actions.selectedTarget == target) { return true; } } return !target.vipFollow && target.attackingUntilBribe; } if (this.character.npc && target.npc && !target.interactiveObject) { return this.character.stats.IsTargetAnEnemy(target.stats.allegiance) || (this.character.stats.isGuard && target.hostility == 2 && this.character.hostility == 1); } if (target.dead || (this.character.stats.ShouldStun(target) && target.stunned)) { return false; } if (!this.character.npc && !target.npc) { return false; } if (this.character.npc && !target.npc) { if (this.character.vipFollow) { return false; } if (this.character.hostility == 1 && !this.character.attackingUntilBribe) { return false; } } return true; } // Token: 0x060001AE RID: 430 RVA: 0x00022E18 File Offset: 0x00021018 public bool CheckSight(Vector3 from, Vector3 to, bool interactiveTarget) { if (!interactiveTarget) { return Physics.Linecast(from, this.character.AddVectorY(to, 2.5f), Links.x.sightBlockers); } float num = Vector3.Distance(from, to); RaycastHit raycastHit; bool flag = Physics.SphereCast(from, 0.25f, this.character.AddVectorY(to, 2.5f) - from, out raycastHit, num, Links.x.sightBlockers); if (flag) { if (raycastHit.collider.gameObject == this.actions.selectedTargetInteractive || raycastHit.collider.gameObject == this.actions.selectedAITargetInteractive) { flag = false; } else if (raycastHit.collider.gameObject.transform.parent && (raycastHit.collider.gameObject.transform.parent.gameObject == this.actions.selectedTargetInteractive || raycastHit.collider.gameObject.transform.parent.gameObject == this.actions.selectedAITargetInteractive)) { flag = false; } } return flag; } // Token: 0x060001AF RID: 431 RVA: 0x00022F4C File Offset: 0x0002114C private IEnumerator FindTarget() { int c = this.lkPlayerAI.Count; Vector3 center = this.GetPosition(this.character); float num = 0f; float num2 = float.PositiveInfinity; float maxDistance = 0f; float minDistance = 0f; float bestDistance = 0f; int selected = -1; Character target = null; this.OrderTargets(); bool stop = false; if (this.rangeWeaponIndex == -1 && this.meleeWeaponIndex == -1) { stop = true; } if (this.rangeWeaponIndex == -1 && this.meleeWeaponIndex == -1) { stop = true; if (this.debugging) { this.str.Append("\nNo weapons"); } } if (!this.findingAction) { stop = true; } bool sightBlocked = false; ConstantPath constPath = null; bool hasPowerDraw = false; bool usingRangeWeapon = false; if (this.GetRow()._MeleeRangeEnd >= 5f) { usingRangeWeapon = true; hasPowerDraw = this.character.stats.HasPowerDraw(); } c = this.lkPlayerTemp.Count; if (this.lkPlayerAI.Count == 0) { stop = true; } if (this.meleeWeaponIndex > -1 && this.meleeWeaponIndex2 > -1 && this.character.npc && this.canSwitchWeapons && !stop && Random.Range(0, 2) == 0 && this.character.GetInvNum(0) != this.character.GetInvNum(32) && this.character.GetInvNum(32) > 1) { this.SwitchWeapons(); if (this.debugging) { this.str.Append("\nSwitching random to other melee"); } } if (this.meleeWeaponIndex > -1 && this.GetRow()._MeleeRangeEnd >= 5f && this.canSwitchWeapons && this.character.stats.formationGroup < 4 && !stop) { this.SwitchWeapons(); if (this.debugging) { this.str.Append("\nSwitching back to melee because of formation group"); } } bool interactiveTarget = false; if (!this.character.npc && this.actions.hasTarget && (this.actions.selectedTargetInteractive || this.actions.selectedAITargetInteractive)) { interactiveTarget = true; } bool movedOn = false; if (this.debugging) { this.str.Append("\nLooking for target, "); this.str.Append(this.lkPlayerAI.Count); this.str.Append(" in list"); } if (!stop) { for (int k = 0; k < c; k++) { if (this.lkPlayerAI.Count == 0) { stop = true; string[] array = new string[5]; int num3 = 0; Character character = this.character; array[num3] = ((character != null) ? character.ToString() : null); array[1] = " last known player lists don't match "; array[2] = this.lkPlayerAI.Count.ToString(); array[3] = " "; array[4] = this.lkPlayerTemp.Count.ToString(); Debug.Log(string.Concat(array)); } else { int num4 = this.lkPlayerTemp[k]; if (num4 >= this.lkPlayerAI.Count || num4 < 0) { string[] array2 = new string[7]; int num5 = 0; Character character2 = this.character; array2[num5] = ((character2 != null) ? character2.ToString() : null); array2[1] = " "; array2[2] = num4.ToString(); array2[3] = " "; array2[4] = this.lkPlayerTemp.Count.ToString(); array2[5] = " "; array2[6] = this.lkPlayerAI.Count.ToString(); Debug.Log(string.Concat(array2)); } else { target = this.lkPlayerAI[num4]; if (this.CanAttack(target) && selected == -1 && this.lkBoolAI[num4]) { this.GetPosition(target); if (!this.lkBoolAI[num4]) { (Vector3)this.lkPositionAI[num4].position; } bestDistance = 0f; minDistance = 0f; maxDistance = 0f; this.GetDistances(this.character, target, out bestDistance, out maxDistance, out minDistance, hasPowerDraw, false); num = this.SubtractVectors(this.GetPosition(target), center).sqrMagnitude; if (this.debugging) { this.str.Append("\nTesting target: "); this.str.Append(target); this.str.Append(" current distance is "); this.str.Append(num); this.str.Append(" max is "); this.str.Append(maxDistance); } if (num <= maxDistance && num >= minDistance) { sightBlocked = this.CheckSight(this.character.raycastPosition, this.GetPosition(target), interactiveTarget); if (hasPowerDraw || !sightBlocked) { if (this.findingAction && this.targets.Count > 0) { if (this.targets[this.targets.Count - 1] == target) { this.actions.readyToAttack = true; } else { this.actions.readyToAttack = false; } } if (this.debugging) { this.str.Append("\nFound target: "); this.str.Append(target); } if (this.quipDebugging && target.stats) { this.character.StartQuip("Attacking " + target.stats.displayName); } if (usingRangeWeapon && hasPowerDraw && this.findingAction) { float meleeRangeEnd = this.GetRow()._MeleeRangeEnd; sightBlocked = this.CheckSight(this.character.raycastPosition, this.GetPosition(target), interactiveTarget); hasPowerDraw = num > (meleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + target.attackRadius) * (meleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + target.attackRadius) || sightBlocked; this.actions.hasPowerDraw = hasPowerDraw; } if (target) { if (!target.dead && target.node != null) { if (this.character.attackTime >= 1f) { this.actions.AddTarget(target); this.actions.savedEnemy = target; this.actions.QueueIcon(true); selected = num4; if (this.findingAction) { this.actions.StartAction("Attack"); } this.FinishFindingAction("Attack", target); movedOn = true; this.findingAction = false; } else { selected = num4; stop = true; } } else { selected = -1; } } else { selected = -1; } } else { selected = -1; } } } } } } } bool flag = false; if (this.rangeWeaponIndex > -1 && selected == -1 && this.GetRow()._MeleeRangeEnd < 5f && this.canSwitchWeapons && (this.character.npc || (this.character.party && Records.x.ai == 1 && this.character.stats.formationGroup > 3)) && !stop && this.findingAction) { if (this.debugging) { StringFast stringFast = this.str; string text = "\nChecking to switch to range weapon from "; Library.Inventory row = this.GetRow(); stringFast.Append(text + ((row != null) ? row.ToString() : null)); } this.SwitchWeapons(); flag = true; if (this.debugging) { StringFast stringFast2 = this.str; string text2 = " to "; Library.Inventory row2 = this.GetRow(); stringFast2.Append(text2 + ((row2 != null) ? row2.ToString() : null)); } if (this.GetRow()._MeleeRangeEnd >= 5f) { usingRangeWeapon = true; hasPowerDraw = this.character.stats.HasPowerDraw(); c = this.lkPlayerTemp.Count; for (int l = 0; l < c; l++) { if (selected == -1) { if (this.lkPlayerAI.Count == 0) { stop = true; Character character3 = this.character; Debug.Log(((character3 != null) ? character3.ToString() : null) + " last known player lists don't match " + this.lkPlayerAI.Count.ToString()); } else { int num6 = this.lkPlayerTemp[l]; target = this.lkPlayerAI[num6]; if (this.lkBoolAI[num6] && this.CanAttack(target)) { bestDistance = 0f; minDistance = 0f; maxDistance = 0f; this.GetDistances(this.character, target, out bestDistance, out maxDistance, out minDistance, hasPowerDraw, false); num = this.SubtractVectors(this.GetPosition(target), center).sqrMagnitude; if (num < num2 && num <= maxDistance && num >= minDistance) { sightBlocked = this.CheckSight(this.character.raycastPosition, this.GetPosition(target), interactiveTarget); this.friendlyFire = false; this.character.GetSocketNum(0); if (!this.friendlyFire && (hasPowerDraw || !sightBlocked)) { selected = l; num2 = num; } } } } if (selected > -1 && this.findingAction) { target = this.lkPlayerAI[selected]; if (this.debugging) { this.str.Append("\nFound range target: "); this.str.Append(target); } if (this.quipDebugging) { this.character.StartQuip("Attacking " + target.stats.displayName); } if (hasPowerDraw) { sightBlocked = this.CheckSight(this.character.raycastPosition, target.currentPosition, interactiveTarget); hasPowerDraw = num > this.GetRow()._MeleeRangeEnd * Records.x.nodeSize * (this.GetRow()._MeleeRangeEnd * Records.x.nodeSize) || sightBlocked; this.actions.hasPowerDraw = hasPowerDraw; } if (target) { if (this.character.attackTime >= 1f) { this.actions.AddTarget(target); this.actions.savedEnemy = target; this.actions.QueueIcon(true); if (this.findingAction) { this.actions.StartAction("Attack"); } this.FinishFindingAction("Attack", target); movedOn = true; this.findingAction = false; } else { stop = true; } } else { selected = -1; } } } } } } if (!stop && selected == -1 && this.character.node != null) { if (flag && this.character.stats.formationGroup < 7 && selected == -1) { this.SwitchWeapons(); } int num26; for (int i = 0; i < c; i = num26 + 1) { if (this.lkPlayerAI.Count == 0) { stop = true; string[] array3 = new string[5]; int num7 = 0; Character character4 = this.character; array3[num7] = ((character4 != null) ? character4.ToString() : null); array3[1] = " last known player lists don't match "; array3[2] = this.lkPlayerAI.Count.ToString(); array3[3] = " "; array3[4] = this.lkPlayerTemp.Count.ToString(); Debug.Log(string.Concat(array3)); } else { int index = this.lkPlayerTemp[i]; if (index >= this.lkPlayerAI.Count || index < 0) { string[] array4 = new string[7]; int num8 = 0; Character character5 = this.character; array4[num8] = ((character5 != null) ? character5.ToString() : null); array4[1] = " "; array4[2] = index.ToString(); array4[3] = " "; array4[4] = this.lkPlayerTemp.Count.ToString(); array4[5] = " "; array4[6] = this.lkPlayerAI.Count.ToString(); Debug.Log(string.Concat(array4)); } target = this.lkPlayerAI[index]; if (this.CanAttack(target) && selected == -1 && this.lkBoolAI[index]) { Vector3 targetPosition = this.GetPosition(target); if (!this.lkBoolAI[index]) { targetPosition = (Vector3)this.lkPositionAI[index].position; } bestDistance = 0f; minDistance = 0f; maxDistance = 0f; this.GetDistances(this.character, target, out bestDistance, out maxDistance, out minDistance, hasPowerDraw, false); num = this.SubtractVectors(this.GetPosition(target), center).sqrMagnitude; if (this.debugging) { this.str.Append("\nTesting target: "); this.str.Append(target); this.str.Append(" current distance is "); this.str.Append(num); this.str.Append(" max is "); this.str.Append(maxDistance); this.str.Append(" min is "); this.str.Append(minDistance); this.str.Append(" best is "); this.str.Append(bestDistance); this.str.Append(" with "); this.str.Append(this.GetRow()._Name); } if (!stop && !this.stayOutOfRange && (!this.character.sailing || (this.character.sailing && this.character.boatNavigator && this.character.stats.Stuck() == 0)) && Links.x.gaia.pathfindingReady && target.node != null) { bestDistance = 0f; minDistance = 0f; maxDistance = 0f; this.GetDistances(this.character, target, out bestDistance, out maxDistance, out minDistance, hasPowerDraw, this.character.boatNavigator); float radius = maxDistance; GraphNode graphNode = target.node; this.SetNodeConstraint(null, false, false, 0, -1, 0); if (!target.node.Walkable || target.node.Area != this.character.node.Area) { this.nodeConstraint.constrainWalkability = true; this.nodeConstraint.walkable = true; this.nodeConstraint.constrainTags = false; this.nodeConstraint.passID = 0; this.nodeConstraint.passID2 = 0; this.nodeConstraint.checkConnections = 0; this.nodeConstraint.constrainPenalty = 0; this.nodeConstraint.constrainToArea = (int)this.character.node.Area; if (this.character.node.GraphIndex == 0U) { graphNode = Links.x.gaia.exteriorGraph.GetNearestForce((Vector3)target.node.position, this.nodeConstraint).node; } else { graphNode = Links.x.gaia.interiorGraph.GetNearestForce((Vector3)target.node.position, this.nodeConstraint).node; } } if (graphNode != null) { this.nodeConstraint.constrainWalkability = false; constPath = ConstantPath.ConstructFast(graphNode, Records.x.GetConstantPathRadius((int)radius), null); constPath.nnConstraint = this.nodeConstraint; AstarPath.StartPath(constPath, false); yield return base.StartCoroutine(constPath.WaitForPath()); constPath.Claim(this); this.allNodes = constPath.allNodes; if (this.debugging) { this.str.Append("\nMade constant path for targets, nodes: "); this.str.Append(this.allNodes.Count); this.str.Append(", radius was "); this.str.Append(radius); } int x = this.allNodes.Count; this.targetingNodes.Clear(); this.nearNodes.Clear(); bool flag2 = true; if (this.character.ignoreNodeIDs) { flag2 = false; } this.SetNodeConstraint(this.character, flag2, false, 0, -1, this.checkCircleID); Vector3 vector = Vector3.zero; x = this.allNodes.Count; for (int m = 0; m < x; m++) { GraphNode graphNode2 = this.allNodes[m]; if (this.nodeConstraint.Suitable(graphNode2)) { vector = (Vector3)graphNode2.position; float sqrMagnitude = this.SubtractVectors(vector, targetPosition).sqrMagnitude; if (sqrMagnitude <= maxDistance && sqrMagnitude >= minDistance) { if (sqrMagnitude >= bestDistance || (usingRangeWeapon && hasPowerDraw)) { bool flag3 = false; if (usingRangeWeapon && hasPowerDraw) { flag3 = true; } if (this.character.mainSelected) { flag3 = true; } if (!flag3) { sightBlocked = this.CheckSight(vector, targetPosition, interactiveTarget); if (!sightBlocked) { flag3 = true; } } if (flag3) { if (!this.NodeTaken(graphNode2)) { this.targetingNodes.Add(graphNode2); } else { this.nearNodes.Add(graphNode2); } } } else { bool flag4 = false; if (usingRangeWeapon && hasPowerDraw) { flag4 = true; } if (this.character.mainSelected) { flag4 = true; } if (!flag4) { this.CheckSight(vector, targetPosition, interactiveTarget); if (!sightBlocked) { flag4 = true; } } if (flag4) { if (!this.NodeTaken(graphNode2)) { this.targetingNodes.Add(graphNode2); } else { this.nearNodes.Add(graphNode2); } } } } } } this.distanceCheckNodes.Clear(); this.used.Clear(); x = this.targetingNodes.Count; for (int n = 0; n < x; n++) { GraphNode graphNode2 = this.targetingNodes[n]; this.used.Add(false); } Vector3 currentPosition = this.character.currentPosition; if (this.targetingNodes.Count < 10) { int count = this.targetingNodes.Count; } for (int num9 = 0; num9 < 10; num9++) { float num10 = 100000f; int num11 = -1; for (int num12 = 0; num12 < x; num12++) { GraphNode graphNode2 = this.targetingNodes[num12]; vector = (Vector3)graphNode2.position; if (!this.used[num12]) { float num13 = this.SubtractVectors(vector, currentPosition).sqrMagnitude; if (num13 < num10) { num10 = num13; num11 = num12; } } } if (num11 > -1) { this.distanceCheckNodes.Add(this.targetingNodes[num11]); this.used[num11] = true; } } for (int num14 = 0; num14 < x; num14++) { if (!this.used[num14]) { this.distanceCheckNodes.Add(this.targetingNodes[num14]); } } this.targetingNodes.Clear(); for (int num15 = 0; num15 < x; num15++) { this.targetingNodes.Add(this.distanceCheckNodes[num15]); } x = this.nearNodes.Count; this.distanceCheckNodes.Clear(); this.used.Clear(); if (this.nearNodes.Count < 10) { int count2 = this.nearNodes.Count; } for (int num16 = 0; num16 < x; num16++) { GraphNode graphNode2 = this.nearNodes[num16]; this.used.Add(false); } for (int num17 = 0; num17 < 10; num17++) { float num18 = 100000f; int num19 = -1; for (int num20 = 0; num20 < x; num20++) { GraphNode graphNode2 = this.nearNodes[num20]; vector = (Vector3)graphNode2.position; if (!this.used[num20]) { float num13 = this.SubtractVectors(vector, currentPosition).sqrMagnitude; if (num13 < num18) { num18 = num13; num19 = num20; } } } if (num19 > -1) { this.distanceCheckNodes.Add(this.nearNodes[num19]); this.used[num19] = true; } } for (int num21 = 0; num21 < x; num21++) { if (!this.used[num21]) { this.distanceCheckNodes.Add(this.nearNodes[num21]); } } this.nearNodes.Clear(); for (int num22 = 0; num22 < x; num22++) { this.nearNodes.Add(this.distanceCheckNodes[num22]); } constPath.Release(this, false); x = this.targetingNodes.Count; int y = this.nearNodes.Count; GraphNode cnode = this.character.node; if (this.debugging) { this.str.Append("\nChecking paths for "); this.str.Append(x); this.str.Append("/"); this.str.Append(y); this.str.Append(" nodes for "); this.str.Append(target); } for (int j = 0; j < x + y; j = num26 + 1) { if (selected == -1 && cnode != null) { GraphNode waypoint = null; if (j < x) { if (j >= this.targetingNodes.Count) { Debug.Log(j.ToString() + " array out of index "); } waypoint = this.targetingNodes[j]; } else { waypoint = this.nearNodes[j - x]; } bool flag5 = true; float num23 = 8f; if (!this.spreadStrong) { num23 = 20f; } if (!this.spread) { if (this.character.inCircle) { flag5 = this.InCircle(waypoint, true); } else if (((Vector3)waypoint.position - this.stayNearPosition).sqrMagnitude > num23 * num23) { flag5 = false; } } if (!this.noKiting && !this.IsPointAwayFromEnemies((Vector3)waypoint.position, true, true)) { flag5 = false; } this.character.GetSocketNum(0); if (flag5 && Links.x.gaia.pathfindingReady) { ABPath p = ABPath.ConstructFast(cnode, waypoint, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); bool flag6 = false; if (!p.error) { flag6 = true; } if (flag6) { this.tempPath = p.path; if (this.debugging) { this.str.Append("\nFind path to target "); this.str.Append(target); this.str.Append(" path count is "); this.str.Append(this.tempPath.Count); this.str.Append(" walk count is "); } bool flag7 = true; if (this.character.party && this.character.node != null) { uint area = this.character.node.Area; Vector3 currentPosition2 = Links.x.main.currentPosition; for (int num24 = 0; num24 < this.tempPath.Count; num24++) { if (flag7) { if (this.tempPath[num24].Area != area) { flag7 = false; } if (flag7) { if (this.character.npc || !Records.x.partyWait || this.character.mainSelected) { if (((Vector3)this.tempPath[num24].position - currentPosition2).sqrMagnitude > 2500f) { flag7 = false; } } else if (Records.x.partyWait && !this.character.mainSelected && ((Vector3)this.tempPath[num24].position - this.character.waitPosition).sqrMagnitude > 100f) { flag7 = false; } if (this.character.inCircle && !this.InCircle(this.tempPath[num24], true)) { flag7 = false; } } } } } if (this.debugging) { this.str.Append("\nFound path, meetsFormationConditions is "); this.str.Append(flag7); this.str.Append(" "); this.str.Append("path count"); this.str.Append(this.tempPath.Count); } if (this.findingAction && flag7) { selected = index; this.actions.QueueIcon(true); int num25 = 20; if (this.character.sailing) { num25 = 10; } if (target) { this.actions.AddTarget(target); this.actions.savedEnemy = target; if (this.targets.Count > 0) { if (this.targets[this.targets.Count - 1] == target) { this.actions.readyToAttack = true; } else { this.actions.readyToAttack = false; } } this.SetMoveBack(target, (Vector3)waypoint.position); this.MakePath(waypoint, num25, false, false, true, false, false, "MoveTarget"); } if (this.debugging) { this.str.Append("\nMoving to target: "); this.str.Append(target); } if (this.quipDebugging && target.stats) { this.character.StartQuip("Moving to " + target.stats.displayName); } this.character.lookTarget = null; movedOn = true; } } else if (this.debugging) { this.str.Append("\nNo path to target "); this.str.Append(target); } p.Release(this, false); p = null; } waypoint = null; } num26 = j; } cnode = null; } } targetPosition = default(Vector3); } } num26 = i; } } bool restarting = false; if (this.character.stats.Stuck() > 0) { stop = true; if (this.debugging) { this.str.Append("\nStuck"); } } if (this.debugging) { this.str.Append("\nTargets count: "); this.str.Append(this.lkPlayerAI.Count); this.str.Append(" last action "); this.str.Append(this.lastAction); this.str.Append(" spread "); this.str.Append(this.spread); this.str.Append(" stuck "); this.str.Append(this.character.stats.Stuck()); this.str.Append(" selected index "); this.str.Append(selected); this.str.Append(" stayOutOfRange "); this.str.Append(this.stayOutOfRange); this.str.Append(" stop "); this.str.Append(stop); this.str.Append(" findingAction "); this.str.Append(this.findingAction); } hasPowerDraw = false; if (selected == -1 && !stop && this.findingAction) { if (!this.character.sailing || (this.character.sailing && this.character.boatNavigator)) { if (this.spread) { c = this.lkPlayerTemp.Count; int num26; for (int i = 0; i < c; i = num26 + 1) { if (this.lkPlayerAI.Count == 0 || (this.character.party && this.lastAction.Contains("Far"))) { stop = true; } else { int num27 = this.lkPlayerTemp[i]; target = this.lkPlayerAI[num27]; if (this.CanAttack(target) && selected == -1 && this.findingAction) { if (this.debugging) { this.str.Append("\nTrying to make path to target "); this.str.Append(target); } bestDistance = 0f; minDistance = 0f; maxDistance = 0f; this.GetDistances(this.character, target, out bestDistance, out maxDistance, out minDistance, hasPowerDraw, false); float num28 = this.GetRow()._MeleeRangeEnd * Records.x.nodeSize; if (this.GetRow()._MeleeRangeEnd < 5f) { num28 *= 2f; } this.findPathCoroutine = this.FindPath(this.lkPositionAI[num27], 1f, this.GetRow()._MeleeRangeEnd, 10, false, false, false, false, false, "MoveTargetFar"); base.StartCoroutine(this.findPathCoroutine); while (this.findPathCoroutine != null) { yield return null; } if (!this.findingAction) { movedOn = true; selected = 1; } } } num26 = i; } } } else { stop = true; } } if (this.character.npc) { this.actions.SetSelectedTarget(false, null, null, null); } this.findTargetCoroutine = null; if ((selected == -1 || stop) && !restarting) { if (this.character.attackTime >= 1f && !this.character.npc && this.character.actions.hasTarget) { this.Skip(); movedOn = true; } else { this.DoSomething5(); movedOn = true; } } if (restarting) { this.DoSomething1(); movedOn = true; } if (!movedOn) { this.DoSomething5(); } yield break; } // Token: 0x060001B0 RID: 432 RVA: 0x00022F5C File Offset: 0x0002115C public bool RunToFriends() { if (this.diaCharacters == null) { this.diaCharacters = Links.x.diorama.characters; } if (this.character.inCircle) { return false; } if (!this.character.HasPartyLKP()) { return false; } Character character = null; Character character2 = null; Character character3 = null; float num = 1600f; Character nearestParty = Links.x.GetNearestParty(this.character.currentPosition); if (nearestParty) { for (int i = 0; i < this.diaCharacters.Count; i++) { Character character4 = this.diaCharacters[i]; if (character4 && !character4.inactive && character4.npc && character4.IsSentient() && !character4.inCircle && !character4.enraged && !character4.hasActions && !character4.ambushing && (character4.hostility == 2 || character4.attackingUntilBribe) && character4.stats.race == this.character.stats.race) { Vector3 vector = Quaternion.LookRotation(nearestParty.currentPosition - this.character.currentPosition) * Vector3.forward; Vector3 vector2 = Vector3.Normalize(character4.currentPosition - this.character.currentPosition); if (Vector3.Dot(vector, vector2) < 0.25f) { float sqrMagnitude = (character4.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; character = character4; if (!character2) { character2 = character4; } else if (!character3) { character3 = character4; } } } } } if (character) { GraphNode graphNode = this.character.NearNode(Vector3.Lerp(this.character.currentPosition, character.currentPosition, 0.5f), true, 0, -1, this.checkCircleID); if (graphNode == null) { graphNode = this.character.NearNode(Vector3.Lerp(this.character.currentPosition, character2.currentPosition, 0.5f), true, 0, -1, this.checkCircleID); character = character2; } if (graphNode == null) { graphNode = this.character.NearNode(Vector3.Lerp(this.character.currentPosition, character3.currentPosition, 0.5f), true, 0, -1, this.checkCircleID); character = character3; } if (graphNode != null) { if (!character.inCombat) { Character character5 = this.character.GetNearestPartyLKP(this.character.currentPosition); if (!character5) { character5 = Links.x.main; } character.UpdateLKP(character5, character5.node, "Heard", false); Links.x.sensory.AddPlayerToCombat(character, character5, false, true, true); } this.character.running = true; this.character.MoveBackEmpty(); this.character.running = true; this.MakePath(graphNode, 200, false, false, true, false, false, "MoveFriend"); return true; } } } return false; } // Token: 0x060001B1 RID: 433 RVA: 0x00023284 File Offset: 0x00021484 public bool MovetoMain() { GraphNode graphNode = this.character.NearNode(Vector3.Lerp(this.character.currentPosition, Links.x.main.currentPosition, 0.3f), true, 0, -1, this.checkCircleID); if (graphNode != null && this.moveToMainTries < 15) { this.moveToMainTries++; this.character.running = true; this.character.MoveBackEmpty(); this.MakePath(graphNode, 200, false, false, true, false, false, "Move"); return true; } return false; } // Token: 0x060001B2 RID: 434 RVA: 0x00023318 File Offset: 0x00021518 public void MovetoCommandPosition() { this.character.running = true; this.character.MoveBackEmpty(); this.MakePath(this.character.commandMove, 200, false, false, true, false, false, "Move"); } // Token: 0x060001B3 RID: 435 RVA: 0x0002335C File Offset: 0x0002155C public bool MovetoFriend(float max) { if ((this.character.currentPosition - this.stayNearPosition).sqrMagnitude > max) { if (this.moveToFriendTries < 15) { GraphNode graphNode = this.character.NearNode(Vector3.Lerp(this.character.currentPosition, this.stayNearPosition, 0.5f), true, 0, -1, this.checkCircleID); if (graphNode != null) { if (this.debugging) { this.str.Append("\nStaying near buddy character "); this.str.Append(this.stayNearCharacter); } this.moveToFriendTries++; this.character.running = true; this.character.MoveBackEmpty(); this.MakePath(graphNode, 200, false, false, true, false, false, "Move"); return true; } } } else { this.moveToFriendTries = 0; } return false; } // Token: 0x060001B4 RID: 436 RVA: 0x00023440 File Offset: 0x00021640 public bool MovetoWait() { GraphNode graphNode = this.character.NearNode(this.character.waitPosition, true, 0, -1, this.checkCircleID); if (graphNode != null) { this.character.running = true; this.character.MoveBackEmpty(); this.MakePath(graphNode, 200, false, false, true, false, false, "Move"); return true; } return false; } // Token: 0x060001B5 RID: 437 RVA: 0x000234A0 File Offset: 0x000216A0 public void SetMoveTargetAsAttack() { if (this.lastAction.Contains("MoveTarget")) { this.lastAction = "Attack"; } } // Token: 0x060001B6 RID: 438 RVA: 0x000234C0 File Offset: 0x000216C0 public bool NodeTaken(GraphNode n) { if (this.character.npc) { return Links.x.combat.NodeCalled(n); } Character character = this.character; for (int i = 0; i < this.party.Count; i++) { character = this.party[i]; if (character && character != this.character && character.hasActions && n != character.actions.targetMovePosition) { return true; } } return false; } // Token: 0x060001B7 RID: 439 RVA: 0x00023544 File Offset: 0x00021744 public void OrderTargets() { if (this.orderedTargets || !Links.x.gaia.pathfindingReady) { return; } this.orderedTargets = true; int num = -1; int num2 = -1; int num3 = -1; int num4 = -1; int num5 = -1; int num6 = -1; this.lkPlayerTemp.Clear(); int num7 = this.lkPlayerAI.Count; Vector3 position = this.GetPosition(this.character); bool flag = false; Character character = null; if (!this.character.npc) { for (int i = 0; i < this.party.Count; i++) { if (this.party[i] && this.party[i].stats.pinning && this.party[i].actions) { character = this.party[i].actions.ai.pinnedTarget; if (character) { flag = true; } } } } else if (Random.Range(0, 3) == 0) { for (int j = 0; j < this.lkPlayer.Count; j++) { if (this.lkPlayer[j] && !this.CanAttack(this.lkPlayer[j]) && this.lkPlayer[j].stats.pinning && this.lkPlayer[j].actions) { character = this.lkPlayer[j].actions.ai.pinnedTarget; if (character) { flag = true; } } } } if (flag || this.actions.hasTarget) { if (this.actions.selectedTargetInteractive) { Character component = this.actions.selectedTargetInteractive.GetComponent(); int num8 = this.lkPlayerAI.IndexOf(component); if (num8 > -1) { if (!this.lkPlayerTemp.Contains(num8)) { this.lkPlayerTemp.Add(num8); } return; } if (num8 == -1 && this.actions.selectedTargetInteractive) { this.lkPlayerTemp.Insert(0, 0); num4 = 0; this.lkPlayerAI.Insert(0, component); this.lkBoolAI.Insert(0, true); this.lkPositionAI.Insert(0, component.node); } } else if (this.actions.selectedAITargetInteractive) { Character component2 = this.actions.selectedAITargetInteractive.GetComponent(); int num9 = this.lkPlayerAI.IndexOf(component2); if (num9 > -1) { if (!this.lkPlayerTemp.Contains(num9)) { this.lkPlayerTemp.Add(num9); } return; } if (num9 == -1 && this.actions.selectedAITargetInteractive) { this.lkPlayerTemp.Insert(0, 0); num4 = 0; this.lkPlayerAI.Insert(0, component2); this.lkBoolAI.Insert(0, true); this.lkPositionAI.Insert(0, component2.node); } } else { Character character2 = this.actions.selectedTarget; if (character) { character2 = character; } int num10 = this.lkPlayerAI.IndexOf(character2); if (num10 > -1) { if (!this.lkPlayerTemp.Contains(num10)) { this.lkPlayerTemp.Add(num10); } return; } if (num10 == -1 && character2 && !character2.dead && (!character2.stunned || (character2.stunned && Records.x.kill))) { this.character.UpdateLKPSpecial(character2, character2.node, "Attack", true); this.lkPlayerTemp.Insert(0, 0); this.lkPlayerAI.Insert(0, character2); this.lkBoolAI.Insert(0, true); this.lkPositionAI.Insert(0, character2.node); return; } } } num7 = this.lkPlayerAI.Count; if (this.stayNearCharacter && this.stayNearCharacter.actions && (this.stayNearCharacter.actions.currentlyTargeting || this.stayNearCharacter.actions.savedEnemy)) { Character character3 = this.stayNearCharacter.actions.currentlyTargeting; if (!character3) { character3 = this.stayNearCharacter.actions.savedEnemy; } if (this.CanAttack(character3)) { if (this.stayNearCharacter.party) { int num11 = this.lkPlayerAI.IndexOf(character3); if (num11 > -1) { this.lkPlayerTemp.Insert(0, 0); this.lkPlayerAI.Insert(0, character3); this.lkBoolAI.Insert(0, true); this.lkPositionAI.Insert(0, character3.node); num5 = num11; if (this.character.inFriendGroup || this.character.stats.defendMainInCombat) { return; } } } else { int num12 = this.lkPlayerAI.IndexOf(character3); if (!this.lkPlayerTemp.Contains(num12) && num12 > -1) { this.lkPlayerTemp.Add(num12); } num5 = num12; if (this.justAttackWithLeader) { return; } } } } if (!this.character.npc && !this.actions.hasTarget) { for (int k = 0; k < this.lkPlayerAI.Count; k++) { Character character4 = this.lkPlayerAI[k]; if (character4 && character4.stats.pinned) { this.lkPlayerTemp.Insert(0, 0); this.lkPlayerAI.Insert(0, character4); this.lkBoolAI.Insert(0, true); this.lkPositionAI.Insert(0, character4.node); return; } } } if (!this.character.npc && !this.actions.hasTarget) { for (int l = 0; l < this.lkPlayerAI.Count; l++) { Character character4 = this.lkPlayerAI[l]; if (character4 && character4.node != null && character4.node.circle == 1) { this.lkPlayerTemp.Insert(0, 0); this.lkPlayerAI.Insert(0, character4); this.lkBoolAI.Insert(0, true); this.lkPositionAI.Insert(0, character4.node); return; } } } if (this.previouslyAttacked || this.actions.savedEnemy) { if (this.actions.savedEnemy) { this.previouslyAttacked = this.actions.savedEnemy; } if (this.CanAttack(this.previouslyAttacked)) { int num13 = this.lkPlayerAI.IndexOf(this.previouslyAttacked); if (num13 > -1) { if (!this.lkPlayerTemp.Contains(num13)) { this.lkPlayerTemp.Add(num13); } num6 = num13; } } } if (this.hitBy && Random.Range(0, 2) == 0 && num5 == -1) { int num14 = this.lkPlayerAI.IndexOf(this.hitBy); if (num14 > -1) { if (!this.lkPlayerTemp.Contains(num14)) { this.lkPlayerTemp.Add(num14); } num5 = num14; } } bool flag2 = false; if (this.character.party && this.earlyActions > 1) { flag2 = true; } int num15 = 3; if (this.lkPlayerAI.Count < 3) { num15 = this.lkPlayerAI.Count; } for (int m = 0; m < num15; m++) { float num16 = float.PositiveInfinity; int num17 = -1; for (int n = 0; n < num7; n++) { if (n != num && n != num2 && n != num3 && n != num4 && n != num5 && n != num6) { Character character4 = this.lkPlayerAI[n]; if (!character4.dead && (!character4.stunned || (character4.stunned && this.character.stats.ShouldStun(character4)))) { if (character4.node == null) { character4.FindCurrentNode(false); } if (character4.node != null && this.PartyInRange(character4.currentPosition)) { Vector3 vector = this.GetPosition(character4); if (!this.lkBoolAI[n]) { vector = (Vector3)this.lkPositionAI[n].position; } if (!flag2) { if (this.lkBoolAI[n]) { float sqrMagnitude = this.SubtractVectors(vector, position).sqrMagnitude; if (sqrMagnitude < num16) { num17 = n; num16 = sqrMagnitude; } } } else if (character4.stats) { float num18 = character4.stats.StaminaPercent(); if (num18 < num16) { num17 = n; num16 = num18; } } } } } } if (num17 > -1) { if (m == 0) { num = num17; } if (m == 1) { num2 = num17; } if (m == 2) { num3 = num17; } if (!this.lkPlayerTemp.Contains(num17)) { this.lkPlayerTemp.Add(num17); } } } for (int num19 = 0; num19 < num7; num19++) { if (!this.lkPlayerTemp.Contains(num19)) { this.lkPlayerTemp.Add(num19); } } } // Token: 0x060001B8 RID: 440 RVA: 0x00023F04 File Offset: 0x00022104 private bool PartyInRange(Vector3 pt) { return (this.character.npc && !this.character.vipFollow) || this.character.mainSelected || (Records.x.partyWait && (pt - this.character.waitPosition).sqrMagnitude < 225f) || (pt - Links.x.main.currentPosition).sqrMagnitude < 625f; } // Token: 0x060001B9 RID: 441 RVA: 0x00023F94 File Offset: 0x00022194 private void CheckWeapons(bool findTargetAfter) { this.hasAlternativeWeapons = true; this.meleeWeaponIndex = -1; this.meleeWeaponIndex2 = -1; this.rangeWeaponIndex = -1; this.rangeWeaponIndex2 = -1; this.rangeWeaponSkill = 0f; this.meleeWeaponSkill = 0f; this.doingMeleeAttack = true; bool flag = false; this.canSwitchWeapons = false; if (this.character.invRow1 == null) { this.character.invRow1 = Links.x.library.GetInvRowFromName("Fist"); } if (this.character.altInvRow1 != null) { if (this.character.stats.animal && this.character.altInvRow1._ID <= 1) { this.hasAlternativeWeapons = false; } } else { this.character.altInvRow1 = Links.x.library.GetInvRowFromName("Fist"); if (this.character.stats.animal) { this.hasAlternativeWeapons = false; } } if (this.character.npc || (!this.character.npc && !this.character.actions.selectedWeapon && !this.character.mainSelected)) { this.canSwitchWeapons = true; if (this.character.stats.formationGroup >= 7) { flag = true; } else if (this.character.stats.formationGroup >= 4 && this.character.stats.formationGroup < 7) { flag = true; if (Random.Range(0, 2) != 0) { flag = false; } } else { flag = false; } } if (this.GetRow()._MeleeRangeEnd < 5f) { this.meleeWeaponIndex = this.GetHand(); if (this.character.stats.canCastSpells) { this.meleeWeaponSkill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(this.GetRow()._MainSkill)); } if (this.GetRow()._ID == 1) { if (this.character.altInvRow1 != null && !this.character.party && this.character.altInvRow1._ID != 1 && this.character.stats.GetSkill(13) < 60f) { this.meleeWeaponIndex = -1; } if (this.character.party && !this.character.mainSelected && this.character.stats.GetSkill(13) < 50f && (this.character.stats.formationGroup >= 7 || this.character.altInvRow1._ID != 1)) { this.meleeWeaponIndex = -1; } } } else if (this.GetRow()._MeleeRangeEnd >= 5f) { this.rangeWeaponIndex = 0; if (this.character.stats.canCastSpells) { this.rangeWeaponSkill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(this.GetRow()._MainSkill)); } } if (this.character.altInvRow1 != null && this.hasAlternativeWeapons) { if (this.character.altInvRow1._MeleeRangeEnd < 5f) { if (this.meleeWeaponIndex == -1) { this.meleeWeaponIndex = 16; if (this.character.stats.canCastSpells) { this.meleeWeaponSkill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(this.character.altInvRow1._MainSkill)); } if (this.character.altInvRow1._ID == 1 && (this.character.npc || !this.character.npc) && this.character.stats.GetSkill(13) < 50f) { this.meleeWeaponIndex = -1; } } else { this.meleeWeaponIndex2 = 16; if (this.character.altInvRow1._ID == 1 && (this.character.npc || !this.character.npc) && this.character.stats.GetSkill(13) < 50f) { this.meleeWeaponIndex2 = -1; } } } else if (this.rangeWeaponIndex == -1) { this.rangeWeaponIndex = 16; if (this.character.stats.canCastSpells) { this.rangeWeaponSkill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(this.character.altInvRow1._MainSkill)); } } else { this.rangeWeaponIndex2 = 16; if (this.character.stats.canCastSpells) { this.rangeWeaponSkill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(this.character.altInvRow1._MainSkill)); } } } bool flag2 = false; int num = -1; if (this.rangeWeaponIndex > -1) { bool flag3 = true; Library.Inventory inventory = this.character.invRow1; if (this.rangeWeaponIndex == 16) { inventory = this.character.altInvRow1; } num = this.character.GetAmmoIndex(inventory); if (num == -1) { if (this.character.npc) { this.character.LookForAmmoInBag(-1, inventory._MainSkill, inventory); num = this.character.GetAmmoIndex(inventory); if (num == -1) { flag3 = false; } } else { flag3 = false; } } if (this.debugging) { this.str.Append("\nRange weapon has ammo? "); this.str.Append(flag3); } if (!flag3) { this.rangeWeaponIndex = -1; this.rangeWeaponSkill = 0f; flag2 = true; } } if (this.rangeWeaponIndex2 > -1 && (!this.character.party || this.rangeWeaponIndex == -1)) { if (this.debugging) { this.str.Append("\nChecking range weapon 2 for ammo"); } this.rangeWeaponIndex = this.rangeWeaponIndex2; bool flag4 = true; Library.Inventory inventory2 = this.character.invRow1; if (this.rangeWeaponIndex2 == 16) { inventory2 = this.character.altInvRow1; } int num2 = this.character.GetAmmoIndex(inventory2); if (num2 == -1) { if (this.character.npc) { this.character.LookForAmmoInBag(-1, inventory2._MainSkill, inventory2); num2 = this.character.GetAmmoIndex(inventory2); if (num2 == -1) { flag4 = false; } } else { flag4 = false; } } if (this.debugging) { this.str.Append("\nRange weapon 2 has ammo? "); this.str.Append(flag4); } if (!flag4) { this.rangeWeaponIndex2 = -1; this.rangeWeaponIndex = -1; this.rangeWeaponSkill = 0f; flag2 = true; if (this.character.party) { this.character.OutOfAmmoMessage(); } } else if (this.rangeWeaponIndex == -1) { this.SwitchWeapons(); this.rangeWeaponIndex = 0; this.rangeWeaponIndex2 = -1; num = num2; if (this.character.stats.canCastSpells) { this.rangeWeaponSkill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory2._MainSkill)); } if (this.debugging) { this.str.Append("\nSwitching to other range weapon, can't use equipped range weapon"); } } } if (this.debugging) { this.str.Append("\nMelee weapon is "); this.str.Append(this.meleeWeaponIndex); this.str.Append(", Range weapon is "); this.str.Append(this.rangeWeaponIndex); } bool flag5 = false; if (this.character.npc && this.rangeWeaponIndex > -1) { int num3 = 0; int num4 = 0; int num5 = 0; this.character.GetAmmoSlotsNPC(out num3, out num4, out num5, this.GetRow()); if (num3 > 1 && num4 <= 1 && num5 <= 1) { this.character.selectedAmmoIndex = 0; } if (num4 > 1) { if (num5 <= 1) { if (Random.Range(0, 3) != 0) { this.character.selectedAmmoIndex = 1; } } else if (Random.Range(0, 3) != 0) { this.character.selectedAmmoIndex = 2; } else if (Random.Range(0, 3) != 0) { this.character.selectedAmmoIndex = 1; } } } if (this.character.party && this.meleeWeaponIndex == -1 && this.rangeWeaponIndex == -1 && this.actions.hasTarget && this.GetRow()._ID == 1) { this.meleeWeaponIndex = 0; } if (this.hasAlternativeWeapons && !flag5) { if (this.GetRow()._MeleeRangeEnd >= 5f && this.rangeWeaponIndex == -1 && this.meleeWeaponIndex > -1) { if (this.debugging) { this.str.Append("\nRemoving range weapon bc out of ammo"); } if (this.meleeWeaponIndex > 0 && this.canSwitchWeapons && (this.character.npc || (Records.x.ai == 1 && !this.character.npc && this.character.stats.formationGroup < 7))) { this.SwitchWeapons(); if (this.debugging) { this.str.Append("\nSwitching to melee, can't use range weapon"); } flag5 = true; } } if (this.GetRow()._MeleeRangeEnd < 5f && flag && this.canSwitchWeapons && (this.character.npc || Records.x.ai == 1) && this.rangeWeaponIndex > -1 && !flag5 && Random.Range(0, 5) > 0) { this.SwitchWeapons(); if (this.debugging) { this.str.Append("\nSwitching to range, is preferred by formation group"); } flag5 = true; } if (this.meleeWeaponIndex == 16 && this.rangeWeaponIndex == -1 && this.meleeWeaponIndex2 == -1 && !flag5) { this.SwitchWeapons(); if (this.debugging) { this.str.Append("\nSwitching to alternative melee weapon, main hand is missing usable weapon"); } flag5 = true; } bool flag6 = false; if (!this.character.party && this.character.stats.animal && num > -1 && this.meleeWeaponIndex > -1) { Library.Inventory invRowByIndex = Links.x.library.GetInvRowByIndex(this.character.GetInvNum(num)); if (invRowByIndex._DmgMax <= 0 && invRowByIndex._Effect != "" && Random.Range(0, 6) != 0) { flag6 = true; this.rangeWeaponIndex = -1; } } if ((flag6 || !flag) && this.GetRow()._MeleeRangeEnd >= 5f && this.meleeWeaponIndex > -1 && this.canSwitchWeapons) { this.SwitchWeapons(); flag5 = true; if (this.debugging) { this.str.Append("\nSwitching to alternative melee weapon because formation group prefers melee"); } } if (this.character.npc && this.rangeWeaponIndex > -1 && this.meleeWeaponIndex > -1 && this.GetRow()._MeleeRangeEnd >= 5f && !flag5 && this.canSwitchWeapons) { this.SwitchWeapons(); if (this.HasTargetInRange()) { if (this.debugging) { this.str.Append("\nSwitching to alternative melee weapon because a target should be nearby"); } } else { this.SwitchWeapons(); } } } if (this.character.party && this.meleeWeaponIndex == -1 && this.rangeWeaponIndex == -1 && this.rangeWeaponIndex2 == -1 && flag2) { this.character.OutOfAmmoMessage(); } if (this.character.party && this.character.stats.canCastSpells) { this.hasGreatWeapon = false; if (this.rangeWeaponIndex > -1 && this.rangeWeaponSkill > 90f + (float)this.character.stats.level * 5f) { this.hasGreatWeapon = true; } if (this.meleeWeaponIndex > -1 && this.meleeWeaponSkill > 90f + (float)this.character.stats.level * 5f) { this.hasGreatWeapon = true; } } if (findTargetAfter) { if (this.debugging) { this.str.Append("\nHas target: "); if (this.actions.selectedTarget) { this.str.Append(this.actions.selectedTarget); } else if (this.actions.selectedTargetInteractive) { this.str.Append(this.actions.selectedTargetInteractive); } else if (this.actions.selectedAITargetInteractive) { this.str.Append(this.actions.selectedAITargetInteractive); } } this.actions.ClearTargetCharacters(); if (this.findTargetCoroutine != null) { base.StopCoroutine(this.findTargetCoroutine); } this.findTargetCoroutine = this.FindTarget(); base.StartCoroutine(this.findTargetCoroutine); return; } if (this.findingAction) { this.DoSomething2(); } } // Token: 0x060001BA RID: 442 RVA: 0x00024CA0 File Offset: 0x00022EA0 private bool HasTargetInRange() { for (int i = 0; i < this.lkPlayerAI.Count; i++) { Character character = this.lkPlayerAI[i]; if (this.CanAttack(this.lkPlayerAI[i])) { float num; float num2; float num3; this.GetDistances(this.character, character, out num, out num2, out num3, false, false); float sqrMagnitude = this.SubtractVectors(character.currentPosition, this.character.currentPosition).sqrMagnitude; if (sqrMagnitude <= num2 && sqrMagnitude >= num3) { return true; } } } return false; } // Token: 0x060001BB RID: 443 RVA: 0x00024D29 File Offset: 0x00022F29 private void SwitchWeapons() { this.SwitchItem(16, 0); this.SwitchItem(17, 1); this.SwitchItem(18, 2); this.SwitchItem(15, 3); this.character.SwitchWeaponsRows(); } // Token: 0x060001BC RID: 444 RVA: 0x00024D5C File Offset: 0x00022F5C public void MakePath(GraphNode node, int maxCount, bool toDirection, bool fleeing, bool nothing, bool clearTargets, bool canOverlap, string type) { if (!this.findingAction) { return; } if (!toDirection) { this.actions.targetMovePosition = node; } else { this.actions.targetMovePosition = null; } if (clearTargets) { this.actions.ClearTargetCharacters(); this.previouslyAttacked = null; } this.character.ClearPathUpdates(); if (this.character.npc && canOverlap && Records.x.turnBased) { this.character.overlapping = true; } if (this.debugging) { this.str.Append("\nMaking path "); this.str.Append((Vector3)node.position); } this.character.MakePath(node, maxCount, false, toDirection, true); if (this.character.npc && canOverlap && Records.x.turnBased) { Links.x.combat.TriggerNextEnemy(this.character); } if (this.character.party) { this.character.portrait.QueueIcon(false); } this.FinishFindingAction(type, this.actions.GetTarget()); this.findingAction = false; } // Token: 0x060001BD RID: 445 RVA: 0x00024E88 File Offset: 0x00023088 private IEnumerator FindPath(GraphNode n, float minDistance, float maxDistance, int maxCount, bool toDirection, bool fleeing, bool partial, bool clearTargets, bool canOverlap, string type) { GraphNode checkNode = n; GraphNode foundNode = null; bool enoughNodes = false; bool stop = false; if (checkNode != null && Links.x.gaia.pathfindingReady) { Vector3 moveToNodePosition = (Vector3)checkNode.position; float stayNearMax = 64f; if (!this.spreadStrong) { stayNearMax = 1600f; } int num = 7; bool forRangePath = false; bool forMeleePath = false; if (type == "MoveTargetFar") { if (maxDistance >= 7f) { num = Mathf.RoundToInt(maxDistance); float num2 = maxDistance * Records.x.nodeSize * (maxDistance * Records.x.nodeSize); maxDistance = num2; minDistance = 0f; forRangePath = true; } else if (maxDistance < 7f) { maxDistance = 64f; minDistance = 0f; forMeleePath = true; } else { maxDistance = 400f; minDistance = 0f; forMeleePath = true; } } Character canGoNearCharacter = null; bool excludeCharacter = false; if (type == "MovePin") { canGoNearCharacter = this.actions.pinTarget; if (canGoNearCharacter) { excludeCharacter = true; } } if (Links.x.gaia.pathfindingReady) { this.interactConstraint.constrainWalkability = false; this.interactConstraint.constrainTags = false; this.interactConstraint.checkCircleID = 0; this.interactConstraint.passID = 0; this.interactConstraint.passID2 = 0; this.interactConstraint.checkConnections = 0; this.interactConstraint.constrainToEnvironment = 1; if (this.character.ghost) { this.interactConstraint.constrainToEnvironment = 0; } if ((this.character.sailing && this.character.boatNavigator) || this.character.movesOnWater) { this.interactConstraint.constrainToEnvironment = 2; } this.interactConstraint.constrainToArea = -1; if (this.character.ghost && !this.interactConstraint.Suitable(checkNode)) { checkNode = this.character.NearNode((Vector3)checkNode.position, false, 0, -1, this.checkCircleID); } if (checkNode != null && Links.x.gaia.pathfindingReady) { ConstantPath constPath = ConstantPath.ConstructFast(checkNode, Records.x.GetConstantPathRadius(num), null); if (this.debugging) { this.str.Append("\nStarting find path coroutine"); } constPath.nnConstraint = this.interactConstraint; this.interactConstraint.constrainWalkability = false; AstarPath.StartPath(constPath, false); float t = Time.timeSinceLevelLoad + 2f; while (constPath.PipelineState != PathState.Returned && Time.timeSinceLevelLoad < t) { yield return null; } if (Time.timeSinceLevelLoad >= t) { this.findPathCoroutine = null; this.Skip(); Debug.LogWarning("Constant path failed"); if (this.debugging) { this.str.Append("\nPath failure!"); } } else { constPath.Claim(this); this.allNodes = constPath.allNodes; int x = this.allNodes.Count; int y = x - 1; Vector3 zero = Vector3.zero; Vector3 thisPosition = this.character.currentPosition; moveToNodePosition = (Vector3)checkNode.position; Vector3 vector = Vector3.zero; this.interactConstraint.constrainTags = true; this.interactConstraint.checkCircleID = this.checkCircleID; this.interactConstraint.constrainDistance = false; this.interactConstraint.passID = this.character.nodeMovingID; this.interactConstraint.passID2 = this.character.nodeStationaryID; this.interactConstraint.constrainWalkability = true; this.interactConstraint.constrainToArea = -1; this.interactConstraint.walkable = true; if (this.character.npc) { this.interactConstraint.constrainPenalty = 1; } else { this.interactConstraint.constrainPenalty = 2; } this.interactConstraint.constrainToEnvironment = 1; if (this.character.ghost) { this.interactConstraint.constrainToEnvironment = 0; } if (this.character.sailing && this.character.boatNavigator) { this.interactConstraint.constrainToEnvironment = 2; this.interactConstraint.passID = this.character.boat.nodeMovingID; this.interactConstraint.passID2 = this.character.boat.nodeStationaryID; this.interactConstraint.checkConnections = this.character.boat.ConnectionNumber(); } else { this.interactConstraint.checkConnections = this.character.ConnectionNumber(); if (this.character.movesOnWater) { this.interactConstraint.constrainToEnvironment = 2; } } int count = 0; this.suitableNodes.Clear(); this.bestNodes.Clear(); this.pathNodes.Clear(); if (!toDirection) { for (int j = 0; j < x; j++) { GraphNode graphNode = this.allNodes[j]; if (((Vector3)graphNode.position - (Vector3)checkNode.position).sqrMagnitude < maxDistance && this.interactConstraint.Suitable(graphNode)) { vector = (Vector3)graphNode.position; bool flag = true; if (!this.spread && !this.character.inCircle && (vector - this.stayNearPosition).sqrMagnitude > stayNearMax) { flag = false; } if (this.character.stats.formationGroup >= 7 && !this.character.inCircle && !this.noKiting) { if (excludeCharacter) { if (!this.IsPointAwayFromEnemiesExcept(vector, true, false, canGoNearCharacter)) { flag = false; } } else if (!this.IsPointAwayFromEnemies(vector, true, true)) { flag = false; } } if (this.character.inCircle) { flag = this.InCircle(graphNode, true); } if (flag) { this.suitableNodes.Add(graphNode); } } } } else { for (int k = y; k >= 0; k--) { GraphNode graphNode = this.allNodes[k]; if (((Vector3)graphNode.position - (Vector3)checkNode.position).sqrMagnitude < maxDistance && this.interactConstraint.Suitable(graphNode)) { bool flag2 = true; if (!this.spread && !this.character.inCircle && (vector - this.stayNearPosition).sqrMagnitude > stayNearMax) { flag2 = false; } if (this.character.stats.formationGroup >= 7 && !this.character.inCircle && !this.noKiting) { if (excludeCharacter) { if (!this.IsPointAwayFromEnemiesExcept(vector, true, false, canGoNearCharacter)) { flag2 = false; } } else if (!this.IsPointAwayFromEnemies(vector, true, true)) { flag2 = false; } } if (this.character.inCircle) { flag2 = this.InCircle(graphNode, true); } if (flag2) { this.suitableNodes.Add(graphNode); } } } } x = this.suitableNodes.Count; y = x - 1; this.used.Clear(); for (int l = 0; l < x; l++) { this.used.Add(false); } int num6; for (int i = 0; i < x; i = num6 + 1) { if (!enoughNodes && !stop) { float num3 = 100000f; int num4 = -1; for (int m = y; m >= 0; m--) { if (!enoughNodes && !stop && !this.used[m]) { vector = (Vector3)this.suitableNodes[m].position; float sqrMagnitude = this.SubtractVectors(new Vector3(moveToNodePosition.x, vector.y, moveToNodePosition.z), vector).sqrMagnitude; if (sqrMagnitude < num3 && sqrMagnitude < maxDistance && sqrMagnitude > minDistance) { num4 = m; num3 = sqrMagnitude; } } } if (num4 > -1) { this.used[num4] = true; this.bestNodes.Add(this.suitableNodes[num4]); } if (count > 10000) { count = 0; yield return new WaitForEndOfFrame(); } int num5 = 200; if (forRangePath) { num5 = 500; } if (this.bestNodes.Count >= num5) { enoughNodes = true; break; } if (!this.findingAction) { stop = true; } } num6 = i; } x = this.bestNodes.Count; this.used.Clear(); for (int num7 = 0; num7 < x; num7++) { this.used.Add(false); } Vector3 forward = Quaternion.LookRotation(moveToNodePosition - new Vector3(this.character.currentPosition.x, moveToNodePosition.y, this.character.currentPosition.z)) * Vector3.forward; Vector3 vector2 = Vector3.zero; bool flag3 = false; bool flag4 = false; if (type == "MoveTargetFar") { flag4 = true; } if (flag3) { for (int i = 0; i < x; i = num6 + 1) { float num3 = -100f; int num4 = -1; for (int num8 = 0; num8 < x; num8++) { if (!this.used[num8]) { vector = (Vector3)this.bestNodes[num8].position; vector2 = Vector3.Normalize(moveToNodePosition - new Vector3(vector.x, moveToNodePosition.y, vector.z)); float num9 = Vector3.Dot(forward, vector2); if (num9 > num3) { num4 = num8; num3 = num9; } } } if (num4 > -1) { this.used[num4] = true; this.pathNodes.Add(this.bestNodes[num4]); } if (count > 10000) { count = 0; yield return new WaitForEndOfFrame(); } if (!this.findingAction) { stop = true; } num6 = i; } } else if (flag4) { Vector3 idealPosition = thisPosition; if (forMeleePath) { idealPosition = (Vector3)checkNode.position + forward * -4f; } if (forRangePath) { idealPosition = (Vector3)checkNode.position + forward * -10f; } for (int i = 0; i < x; i = num6 + 1) { float num3 = 1000000f; int num4 = -1; for (int num10 = 0; num10 < x; num10++) { if (!this.used[num10]) { float sqrMagnitude2 = this.SubtractVectors(idealPosition, (Vector3)this.bestNodes[num10].position).sqrMagnitude; if (sqrMagnitude2 < num3) { num4 = num10; num3 = sqrMagnitude2; } } } if (num4 > -1) { this.used[num4] = true; this.pathNodes.Add(this.bestNodes[num4]); } if (count > 10000) { count = 0; yield return new WaitForEndOfFrame(); } if (!this.findingAction) { stop = true; } num6 = i; } idealPosition = default(Vector3); } else { for (int num11 = 0; num11 < x; num11++) { this.pathNodes.Add(this.bestNodes[num11]); } } x = this.pathNodes.Count; bool flag5 = this.pathNodes.Count != 0 && !stop; if (this.debugging) { this.str.Append("\nFinding path with constant path for move type "); this.str.Append(type); this.str.Append(", const path nodes: "); this.str.Append(this.allNodes.Count); this.str.Append(", suitable nodes: "); this.str.Append(this.suitableNodes.Count); this.str.Append(", best nodes: "); this.str.Append(this.bestNodes.Count); } if (flag5 && x > 0 && this.character.node != null && Links.x.gaia.pathfindingReady) { bool foundPath = false; uint nodeArea = this.character.node.Area; for (int i = 0; i < x; i = num6 + 1) { if (!foundPath && !stop && i < 20 && i < this.pathNodes.Count) { GraphNode destination = this.pathNodes[i]; ABPath p = ABPath.ConstructFast(this.character.node, destination, null); p.nnConstraint = this.interactConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); if (this.debugging) { this.str.Append("\nCheck path for index "); this.str.Append(i); this.str.Append(", error? "); this.str.Append(p.error); } if (!p.error) { this.tempPath = p.path; bool flag6 = false; if (type == "MoveKite") { flag6 = true; } bool flag7 = true; Vector3 currentPosition = Links.x.main.currentPosition; for (int num12 = 0; num12 < this.tempPath.Count; num12++) { if (flag7) { if (!this.noKiting && !flag6 && !this.character.inCircle) { if (excludeCharacter) { if (!this.IsPointAwayFromEnemiesExcept((Vector3)this.tempPath[num12].position, true, true, canGoNearCharacter)) { flag7 = false; } } else if (!this.IsPointAwayFromEnemies((Vector3)this.tempPath[num12].position, true, true)) { flag7 = false; } } if (this.character.party && !Records.x.partyWait && !this.character.inCircle) { if (this.tempPath[num12].Area != nodeArea) { flag7 = false; } if (flag7 && ((Vector3)this.tempPath[num12].position - currentPosition).sqrMagnitude > 1600f) { flag7 = false; } } if (this.character.inCircle && !this.InCircle(this.tempPath[num12], true)) { flag7 = false; } } } if (this.debugging) { this.str.Append("\nFound path, meetsFormationConditions is "); this.str.Append(flag7); this.str.Append(" for "); this.str.Append(type); this.str.Append(" "); this.str.Append("path count"); this.str.Append(this.tempPath.Count); } if (flag7) { foundPath = true; foundNode = destination; } } p.Release(this, false); destination = null; p = null; } if (!this.findingAction) { stop = true; } num6 = i; } } if (this.findingAction) { if (foundNode != null) { if (type == "MoveTargetFar") { this.actions.ClearTargetCharacters(); } if (type == "MovePin") { this.actions.movingToPin = true; } this.character.MoveBackEmpty(); this.MakePath(foundNode, maxCount, false, fleeing, partial, clearTargets, canOverlap, type); } else { this.Skip(); } } constPath.Release(this, false); this.findPathCoroutine = null; thisPosition = default(Vector3); forward = default(Vector3); } constPath = null; } else { this.Skip(); } } else { this.Skip(); } moveToNodePosition = default(Vector3); canGoNearCharacter = null; } else { this.Skip(); } yield break; } // Token: 0x060001BE RID: 446 RVA: 0x00024EF0 File Offset: 0x000230F0 public bool OrbitEnemy(bool either) { Character character = this.NearestEnemy(); if (character && Links.x.gaia.pathfindingReady) { if (this.debugging && this.character.npc) { this.str.Append("\nOrbit"); } if ((character.currentPosition - this.character.currentPosition).sqrMagnitude >= 49f && either) { this.orbitRoutine = this.OrbitRoutine(character, false); } else { this.orbitRoutine = this.OrbitRoutine(character, false); } base.StartCoroutine(this.orbitRoutine); return true; } if (this.debugging && this.character.npc) { this.str.Append("\nCan't Orbit"); if (!character) { this.str.Append(", no enemy"); } } return false; } // Token: 0x060001BF RID: 447 RVA: 0x00024FDF File Offset: 0x000231DF private IEnumerator OrbitRoutine(Character nearestEnemy, bool goSideways) { ConstantPath constPath = ConstantPath.ConstructFast(this.character.node, Records.x.GetConstantPathRadius(5), null); int environment = 1; if (this.character.sailing) { environment = 2; } this.SetNodeConstraint(null, false, false, 0, environment, 0); this.nodeConstraint.constrainWalkability = false; constPath.nnConstraint = this.nodeConstraint; AstarPath.StartPath(constPath, false); yield return base.StartCoroutine(constPath.WaitForPath()); constPath.Claim(this); this.allNodes = constPath.allNodes; int x = 0; Vector3 vector = Quaternion.LookRotation(this.character.currentPosition - nearestEnemy.currentPosition) * Vector3.forward; float num = Vector3.Distance(this.character.currentPosition, nearestEnemy.currentPosition); float num2 = Random.Range(2.5f, 5f); float max = (num2 + 1f) * (num2 + 1f); this.character.stats.SightRadius(false, false, false); this.character.stats.SightRadius(false, false, false); Vector3 desiredPointRight = this.character.currentPosition + vector * num2; Vector3 desiredPointLeft = this.character.currentPosition + vector * num2; if (this.GetRow()._MeleeRangeEnd < 5f && num > 10f) { desiredPointRight = nearestEnemy.currentPosition + vector * num2; desiredPointLeft = nearestEnemy.currentPosition + vector * num2; } if (goSideways) { if (num2 <= 2f) { num2 = 1f; } if (num2 >= 2f && num2 < 4f) { num2 = 2f; } if (num2 >= 4f && num2 < 6f) { num2 = 3f; } if (num2 >= 6f) { num2 = 4f; } max = (num2 + 1f) * (num2 + 1f); desiredPointRight = nearestEnemy.currentPosition + vector * num2 + Quaternion.LookRotation(this.character.currentPosition - nearestEnemy.currentPosition) * Vector3.right * 5f; desiredPointLeft = nearestEnemy.currentPosition + vector * num2 + Quaternion.LookRotation(this.character.currentPosition - nearestEnemy.currentPosition) * Vector3.right * -5f; } bool foundPath = false; GraphNode moveNode = null; this.SetNodeConstraint(this.character, true, false, 0, environment, this.checkCircleID); int num9; for (int i = 0; i < 1; i = num9 + 1) { if (!foundPath) { this.orbitNodes.Clear(); this.targetingNodes.Clear(); Vector3 vector2 = desiredPointRight; if (i == 1) { vector2 = desiredPointLeft; } if (!this.orbitRight) { vector2 = desiredPointLeft; if (i == 1) { vector2 = desiredPointRight; } } x = this.allNodes.Count; for (int k = x - 1; k >= 0; k--) { float sqrMagnitude = this.SubtractVectors((Vector3)this.allNodes[k].position, vector2).sqrMagnitude; if (this.SubtractVectors((Vector3)this.allNodes[k].position, this.character.currentPosition).sqrMagnitude < max && sqrMagnitude < 11f && this.nodeConstraint.Suitable(this.allNodes[k]) && this.allNodes[k] != this.character.node) { this.targetingNodes.Add(this.allNodes[k]); } } int num3 = -1; int num4 = -1; int num5 = -1; int num6 = -1; for (int l = 0; l < 4; l++) { int num7 = -1; float num8 = 100000f; if (l <= 3) { for (int m = 0; m < this.targetingNodes.Count; m++) { if (m != num3 && m != num4 && m != num5 && m != num6) { float sqrMagnitude2 = this.SubtractVectors((Vector3)this.targetingNodes[m].position, vector2).sqrMagnitude; if (sqrMagnitude2 < num8) { num8 = sqrMagnitude2; num7 = m; } } } if (num7 > -1) { if (l == 0) { num3 = num7; } if (l == 1) { num4 = num7; } if (l == 2) { num5 = num7; } if (l == 3) { num6 = num7; } this.orbitNodes.Add(this.targetingNodes[num7]); } } else { for (int n = 0; n < this.targetingNodes.Count; n++) { if (n != num3 && n != num4 && n != num5 && n != num6) { this.orbitNodes.Add(this.targetingNodes[n]); } } } } x = this.orbitNodes.Count; GraphNode g = null; for (int j = 0; j < x; j = num9 + 1) { if (!foundPath) { g = this.orbitNodes[j]; ABPath p = ABPath.ConstructFast(this.character.node, g, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); if (!p.error) { bool flag = true; this.tempPath = p.path; if (this.character.inCircle) { foreach (GraphNode graphNode in this.tempPath) { if (flag && !this.InCircle(graphNode, true)) { flag = false; } } } if (flag) { moveNode = g; p.Release(this, false); foundPath = true; break; } } p.Release(this, false); p = null; } num9 = j; } g = null; } num9 = i; } if (foundPath) { this.character.MoveBackEmpty(); if (nearestEnemy) { this.SetMoveBack(nearestEnemy, (Vector3)moveNode.position); } this.MakePath(moveNode, 8, false, false, false, false, false, "MoveWander"); if (this.quipDebugging) { this.character.StartQuip("Orbit"); } this.character.lookTarget = nearestEnemy; this.actions.savedEnemy = nearestEnemy; } else { bool flag2 = false; if (this.character.party && this.earlyActions < 4 && this.character.stats.formationGroup <= 6) { if (Records.x.partyWait) { flag2 = this.MovetoWait(); } else if (!this.character.inCircle) { flag2 = this.MovetoMain(); } } if (!flag2) { if (this.actions.savedEnemy && !this.character.turning && !this.character.Pivoting()) { this.TurnToEnemy(false, null); } this.SkipWatch(); } } constPath.Release(this, false); this.orbitRoutine = null; yield break; } // Token: 0x060001C0 RID: 448 RVA: 0x00024FFC File Offset: 0x000231FC public void TurnToEnemy(bool instant, Character knownEnemy) { if (Links.x.gameplay.seconds > this.timeSinceTurn + 25f || this.timeSinceTurn == 0f) { Character character = knownEnemy; if (!character) { character = this.NearestEnemy(); } if (character) { this.actions.savedEnemy = character; Vector3 currentPosition = this.actions.savedEnemy.currentPosition; if (this.character.GetRotationAngle(Quaternion.LookRotation(currentPosition - new Vector3(this.character.currentPosition.x, currentPosition.y, this.character.currentPosition.z)), this.character.body.tr.rotation) > 40f) { this.character.alwaysTurn = true; this.character.SetRotation(Quaternion.LookRotation(currentPosition - new Vector3(this.character.currentPosition.x, currentPosition.y, this.character.currentPosition.z)), false, instant); this.timeSinceTurn = Links.x.gameplay.seconds; return; } if (instant) { this.character.SetRotation(Quaternion.LookRotation(currentPosition - new Vector3(this.character.currentPosition.x, currentPosition.y, this.character.currentPosition.z)), false, instant); } } } } // Token: 0x060001C1 RID: 449 RVA: 0x00025178 File Offset: 0x00023378 public void Wander() { if (!this.findingAction) { return; } if (!Links.x.gaia.pathfindingReady) { return; } if (this.character.party) { this.character.portrait.QueueIcon(false); } if (this.quipDebugging) { this.character.StartQuip("Wander"); } this.character.MoveBackEmpty(); this.MakePath(this.character.node, Random.Range(2, 3), true, false, false, true, true, "MoveWander"); } // Token: 0x060001C2 RID: 450 RVA: 0x00025204 File Offset: 0x00023404 public void Flee() { if (!this.findingAction) { return; } if (this.character.party) { this.character.portrait.QueueIcon(false); } if (this.quipDebugging) { this.character.StartQuip("Flee"); } GraphNode graphNode = this.NearestEnemyNode(); this.MakePath(graphNode, Random.Range(3, 6), true, true, false, true, true, "MoveFlee"); } // Token: 0x060001C3 RID: 451 RVA: 0x00025270 File Offset: 0x00023470 private GraphNode NearestEnemyNode() { GraphNode graphNode = null; float num = float.PositiveInfinity; for (int i = 0; i < this.lkPlayerAI.Count; i++) { if (this.lkPlayerAI[i] && this.CanAttack(this.lkPlayerAI[i]) && this.lkPlayerAI[i].node != null) { float sqrMagnitude = (this.character.currentPosition - this.lkPlayerAI[i].currentPosition).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; graphNode = this.lkPlayerAI[i].node; } } } if (graphNode == null) { graphNode = this.character.node; } return graphNode; } // Token: 0x060001C4 RID: 452 RVA: 0x00025334 File Offset: 0x00023534 public bool CheckOpenSpace(Item item) { return this.character.npc || !this.character.inventoryBag || Links.x.inventory.CheckGrid(false, item, Vector3.zero, new Vector4(0f, 0f, 0f, 0f), Links.x.inventory.mainBagX, Links.x.inventory.mainBagY, "Hidden"); } // Token: 0x060001C5 RID: 453 RVA: 0x000253BB File Offset: 0x000235BB public float WalkRadius(Character c) { return 28f; } // Token: 0x060001C6 RID: 454 RVA: 0x000253C4 File Offset: 0x000235C4 public void LookForGroundItem() { bool flag = false; this.pickupItems.Clear(); if (this.character.invRow1._MeleeRangeEnd >= 5f) { flag = true; } int count = this.groundItems.Count; float num = this.WalkRadius(this.character) * 2f + this.character.attackRadius; if (!Records.x.turnBased) { num = this.WalkRadius(this.character) + this.character.attackRadius; } float num2 = num * num; if (this.character.inventoryBag) { Links.x.inventory.GetBagLists(this.character); } for (int i = 0; i < count; i++) { Item item = this.groundItems[i]; if (item && !item.forSale && this.SubtractVectors(item.tr.position, this.character.currentPosition).sqrMagnitude < num2) { if (item.edible && this.CheckOpenSpace(item)) { this.pickupItems.Add(item); } if (flag && item.ammo && item.invRow._MainSkill == this.character.invRow1._MainSkill && this.CheckOpenSpace(item)) { this.pickupItems.Add(item); } if (this.character.invRow1._MainSkill.Contains("Sling") && item.spellItem && this.CheckOpenSpace(item)) { this.pickupItems.Add(item); } } } if (this.debugging) { this.str.Append("\nPickup item count: "); this.str.Append(this.pickupItems.Count); } if (this.pickupItems.Count > 0) { this.groundItemCoroutine = this.GroundItems(); base.StartCoroutine(this.groundItemCoroutine); return; } this.DoSomething4(); } // Token: 0x060001C7 RID: 455 RVA: 0x000255D1 File Offset: 0x000237D1 private IEnumerator GroundItems() { bool foundItem = false; bool inRange = false; Item itemToPickup = null; GraphNode moveToNode = null; bool needsPath = false; float pickupRange = 2.5f; for (int j = 0; j < this.pickupItems.Count; j++) { Item item2 = this.pickupItems[j]; if (!foundItem) { float num = pickupRange + this.character.attackRadius; float num2 = num * num; Vector3 currentPosition = this.character.currentPosition; currentPosition.y = item2.tr.position.y; float num3 = this.SubtractVectors(item2.tr.position, currentPosition).sqrMagnitude; if (num3 <= num2) { foundItem = true; itemToPickup = item2; inRange = true; } } } if (!foundItem && !this.stayOutOfRange && (!this.character.sailing || (this.character.sailing && this.character.boatNavigator))) { int num7; for (int i = 0; i < this.pickupItems.Count; i = num7 + 1) { if (!foundItem) { Item item = this.pickupItems[i]; GraphNode dropNode = item.dropNode; if (dropNode != null) { bool flag = true; float num4 = 7f; if (this.spread) { num4 = 10f; } if (!this.spreadStrong) { num4 = 13f; } if (!this.spread && !this.character.inCircle && ((Vector3)dropNode.position - this.stayNearPosition).sqrMagnitude > num4 * num4) { flag = false; } if (!this.noKiting && !this.character.inCircle && !this.IsPointAwayFromEnemies((Vector3)dropNode.position, true, true)) { flag = false; } if (this.character.inCircle && !this.InCircle(dropNode, true)) { flag = false; } if (flag) { ABPath p = ABPath.ConstructFast(this.character.node, dropNode, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); bool flag2 = false; if (!p.error) { flag2 = true; } if (this.debugging) { this.str.Append("\nLooking for item path: "); this.str.Append(p.error); } if (flag2) { this.tempPath = p.path; GraphNode graphNode = null; int num5 = 0; bool flag3 = true; for (int k = 0; k < this.tempPath.Count; k++) { graphNode = this.tempPath[k]; num5++; if (this.character.inCircle && flag3 && !this.InCircle(this.tempPath[k], true)) { flag3 = false; } } if (graphNode != null && flag3) { float num6 = pickupRange + this.character.attackRadius; float num2 = num6 * num6; Vector3 position = item.tr.position; Vector3 vector = (Vector3)graphNode.position; vector.y = position.y; float num3 = this.SubtractVectors(vector, position).sqrMagnitude; if (this.debugging) { this.str.Append("\nLooking for item path 2, path count:"); this.str.Append(this.tempPath.Count); this.str.Append(" , currentDistance: "); this.str.Append(num3); this.str.Append(", max distance: "); this.str.Append(num2); this.str.Append(", item pos: "); this.str.Append(item.tr.position); } if (num3 <= num2) { moveToNode = graphNode; needsPath = true; foundItem = true; itemToPickup = item; inRange = num3 <= num2; if (this.debugging) { this.str.Append("\nPicking up item"); break; } break; } } } p.Release(this, false); p = null; } } else { Item item3 = item; Debug.Log(((item3 != null) ? item3.ToString() : null) + " missing combat node"); } item = null; } num7 = i; } } if (this.debugging) { this.str.Append("\nFound item: "); this.str.Append(foundItem); this.str.Append(" kiting? "); this.str.Append(this.stayOutOfRange); if (itemToPickup) { this.str.Append(itemToPickup); } } if (foundItem) { if (needsPath) { this.actions.pickingUpItem = inRange; this.actions.pickupItem = itemToPickup; this.MakePath(moveToNode, 100, false, false, false, false, false, "Move"); if (this.debugging) { this.str.Append("\nGetting Item"); } if (this.quipDebugging) { this.character.StartQuip("Moving to item"); } } else { this.actions.pickingUpItem = true; this.actions.pickupItem = itemToPickup; this.actions.StartAction("Use"); this.findingAction = false; if (this.debugging) { this.str.Append("\nGetting Item"); } if (this.quipDebugging) { this.character.StartQuip("Picking up item"); } } } else { this.DoSomething4(); } yield break; } // Token: 0x060001C8 RID: 456 RVA: 0x000255E0 File Offset: 0x000237E0 public bool SpecialAttack(bool always) { if (always) { this.orderedTargets = false; this.actions.ResetAction(); this.actions.targetMovePosition = null; this.findingAction = true; this.findingActionTime = Links.x.gameplay.seconds; this.GetLastKnownLists(); } if (this.character.stats.hasCustomAI) { if (this.character.stats.customAI.Contains("Attack")) { int num = 9; float num2 = 1f; if (this.character.stats.customAI == "BoneBeamAttack") { num = 2; num2 = 0.5f; } if (this.character.stats.customAI.Contains("Beam") && this.character.attackTime >= num2 && Random.Range(0, num) == 0) { string text = ""; string text2 = ""; float num3 = 6f; if (this.character.stats.customAI == "PoisonBeamAttack") { text = "FishPoisonBeam"; text2 = "Poison Spray"; } if (this.character.stats.customAI == "BoneBeamAttack") { text = "BoneSpikes"; text2 = "Bones"; num3 = 10f; } int num4 = this.character.stats.SpellIndex(text); Vector3 currentPosition = this.character.currentPosition; if (this.character.node != null) { int count = this.lkPlayerTemp.Count; for (int i = 0; i < count; i++) { int num5 = this.lkPlayerTemp[i]; if (num5 < this.lkPlayerAI.Count && num5 > -1) { Character character = this.lkPlayerAI[num5]; if (character && character.hasActions) { bool flag = true; if (!this.character.npc) { flag = this.CanAttack(character); } if (character.IsSentient() && flag && character.node != null) { Vector3 currentPosition2 = character.currentPosition; float sqrMagnitude = (currentPosition - currentPosition2).sqrMagnitude; Quaternion.LookRotation(currentPosition2 - currentPosition) * Vector3.forward; float num6 = (num3 * Records.x.nodeSize + 0.1f) * (num3 * Records.x.nodeSize + 0.1f); if (sqrMagnitude < num6) { if (this.debugging) { this.str.Append("\nSpecial attack found "); this.str.Append(" "); this.str.Append(character); } this.FinishFindingAction("Spell", character); this.actions.RemoveAbility(); this.actions.ClearTargetCharacters(); this.actions.AddTarget(character); this.actions.spellNode = this.character.node; this.actions.spellIndex = num4; this.character.actions.paganRow = Links.x.library.GetPaganRow(text); this.actions.Ability(text, text2, false, true); this.actions.CastSpell(character, true, character.node, Vector3.zero, true, false); this.findingAction = false; return true; } } } } } } } return false; } if (this.character.stats.customAI.Contains("Charge")) { if (Random.Range(0, 15) == 0 && this.character.attackTime >= 1f) { if (!Links.x.combat.AnyoneCharging() && !this.character.inCircle && this.character.node != null && this.character.stats.Stuck() == 0) { int count2 = this.lkPlayerTemp.Count; for (int j = 0; j < count2; j++) { int num7 = this.lkPlayerTemp[j]; if (num7 < this.lkPlayerAI.Count && num7 > -1) { Character character2 = this.lkPlayerAI[num7]; if (character2 && character2.hasActions) { bool flag2 = true; if (!this.character.npc) { flag2 = this.CanAttack(character2); } if (character2.IsSentient() && flag2 && character2.node != null) { Quaternion quaternion = Quaternion.LookRotation(character2.currentPosition - this.character.currentPosition); Vector3 vector = quaternion * Vector3.forward * Records.x.nodeSize + this.character.currentPosition; GraphNode slideNode = this.character.GetSlideNode(vector, this.character.node, true, 0, 0); float num8 = (character2.attackRadius + this.character.attackRadius) * 0.75f; GraphNode graphNode = null; if (slideNode != null) { Vector3 vector2 = quaternion * Vector3.forward; vector = this.character.currentPosition + vector2 * 2.5f * 2f; GraphNode slideNode2 = this.character.GetSlideNode(vector, slideNode, true, 0, 0); if (slideNode2 != null) { vector = this.character.currentPosition + vector2 * 2.5f * 3f; GraphNode slideNode3 = this.character.GetSlideNode(vector, slideNode2, true, 0, 0); if (slideNode3 != null) { if (this.DistanceToLine(character2.currentPosition, this.character.currentPosition, (Vector3)slideNode3.position) < num8) { graphNode = slideNode3; } else { vector = this.character.currentPosition + vector2 * 2.5f * 4f; GraphNode slideNode4 = this.character.GetSlideNode(vector, slideNode3, true, 0, 0); if (slideNode4 != null) { if (this.DistanceToLine(character2.currentPosition, this.character.currentPosition, (Vector3)slideNode4.position) < num8) { graphNode = slideNode4; } else { vector = this.character.currentPosition + vector2 * 2.5f * 5f; GraphNode slideNode5 = this.character.GetSlideNode(vector, slideNode4, true, 0, 0); if (slideNode5 != null && this.DistanceToLine(character2.currentPosition, this.character.currentPosition, (Vector3)slideNode5.position) < num8) { graphNode = slideNode5; } } } } } } } if (graphNode != null) { if (this.debugging) { this.str.Append("\nSpecial attack found for charge "); this.str.Append(" "); this.str.Append(character2); } base.StartCoroutine(this.Jump(character2, graphNode, (Vector3)graphNode.position, "Charge", true, true)); return true; } } } } } } return false; } } else if (this.character.stats.customAI.Contains("Tiles")) { if (this.character.stats.customAI.Contains("MushroomWallTiles")) { bool flag3 = true; bool flag4 = Links.x.cellar.CharacterHasCastTileEffect(this.character, "MushroomWall"); if (!flag4) { flag3 = false; } if (flag3 && (this.tactics.Count > 4 && flag3)) { if (this.tactics[this.tactics.Count - 1].Contains("Attack")) { flag3 = false; } if (this.tactics[this.tactics.Count - 2].Contains("Attack")) { flag3 = false; } if (this.tactics[this.tactics.Count - 3].Contains("Attack")) { flag3 = false; } } if (flag4 && Random.Range(0, 10) != 0) { flag3 = true; } bool flag5 = false; if (this.character.node != null && !flag3) { if (this.party == null && this.character.npc) { this.party = Links.x.portraitOrder; } if (!this.character.npc && this.party == null) { this.party = Links.x.npcs; } for (int k = 0; k < this.party.Count; k++) { Character character3 = this.party[k]; if (character3 && character3.hasActions) { bool flag6 = true; if (!this.character.npc) { flag6 = this.CanAttack(character3); } if (character3.IsSentient() && flag6 && character3.node != null) { Vector3 vector3 = (Vector3)this.character.node.position; Vector3 vector4 = (Vector3)character3.node.position; vector4.y = vector3.y; if ((vector3 - vector4).sqrMagnitude < 25f) { bool flag7 = true; bool flag8 = true; for (int l = 0; l < 8; l++) { if (flag7) { GraphNode graphNode2 = character3.node.ConnectionFromIndex(l); if (graphNode2 != null && graphNode2.ID != 0 && graphNode2.ID != character3.nodeStationaryID && graphNode2.ID != character3.nodeMovingID) { Character nodeCharacter = character3.GetNodeCharacter(graphNode2.ID); if (nodeCharacter && !nodeCharacter.Knockback(character3.currentPosition, 1, true, false, false)) { flag7 = false; } } } } if (flag7) { for (int m = 0; m < 8; m++) { if (flag8) { GraphNode graphNode3 = this.character.node.ConnectionFromIndex(m); if (graphNode3 != null && graphNode3.ID != 0 && graphNode3.ID != this.character.nodeStationaryID && graphNode3.ID != this.character.nodeMovingID) { Character nodeCharacter2 = this.character.GetNodeCharacter(graphNode3.ID); if (nodeCharacter2 && nodeCharacter2 != character3 && nodeCharacter2 != this.character && !nodeCharacter2.Knockback(this.character.currentPosition, 1, true, false, false)) { flag8 = false; } } } } } if (flag8 && flag7 && this.character.actions) { this.Skip(); this.character.attackTime = 1f; this.findingAction = false; this.character.actions.SpellFromTrigger("MushroomWall", "Wall", character3); return true; } } } } } } if (!flag5) { return false; } } } else if (this.character.stats.customAI.Contains("Jump")) { if (this.character.stats.customAI.Contains("BakkaJump") && (!this.character.inCircle || always)) { float num9 = 7.5f; float num10 = 17.5f; if (Records.x.miniGame) { num10 = 35f; } if (always) { num10 = 75f; } if (this.character.node != null && this.character.stats.Stuck() == 0 && ((Records.x.miniGame && Random.Range(0, 2) == 0) || (this.character.attackTime > 0.5f && Random.Range(0, 4) == 0) || always)) { if (!this.canMeleeRangeAttack || always) { this.OrderTargets(); } int count3 = this.lkPlayerTemp.Count; for (int n = 0; n < count3; n++) { int num11 = this.lkPlayerTemp[n]; if (num11 < this.lkPlayerAI.Count && num11 > -1) { Character character4 = this.lkPlayerAI[num11]; if (character4 && character4.hasActions) { bool flag9 = true; if (!this.character.npc) { flag9 = this.CanAttack(character4); } if (character4.IsSentient() && flag9 && character4.node != null) { this.specialNodes.Clear(); Vector3 vector5 = (Vector3)this.character.node.position; Vector3 vector6 = (Vector3)character4.node.position; vector6.y = vector5.y; float num12 = (vector5 - vector6).sqrMagnitude; if (num12 < num10 * num10 && num12 > num9 * num9) { for (int num13 = 0; num13 < 8; num13++) { GraphNode graphNode4 = character4.node.ConnectionFromIndex(num13); if (graphNode4 != null && graphNode4 != character4.node && graphNode4.ID == 0 && ((Vector3)graphNode4.position - character4.currentPosition).sqrMagnitude < num10 * num10) { this.specialNodes.Add(graphNode4); } } float num14 = float.PositiveInfinity; int num15 = -1; for (int num16 = 0; num16 < this.specialNodes.Count; num16++) { num12 = (vector5 - (Vector3)this.specialNodes[num16].position).sqrMagnitude; if (num12 < num14) { num14 = num12; num15 = num16; } } if (num15 > -1) { if (this.debugging) { this.str.Append("\nSpecial attack found for jump "); this.str.Append(" "); this.str.Append(character4); } base.StartCoroutine(this.Jump(character4, this.specialNodes[num15], (Vector3)this.specialNodes[num15].position, "Jump", false, true)); return true; } } } } } } if (this.debugging) { this.str.Append("\nNo one in range for special attack "); } } } } else if (this.character.stats.customAI == "Dragoon") { float num17 = 7.5f; float num18 = 25f; if (this.character.node != null && ((this.character.attackTime >= 1f && this.character.CanAttack() && this.character.stats.Stuck() == 0 && (Links.x.gameplay.seconds > this.lastSpecialAttack + 250f || this.lastSpecialAttack == 0f)) || always)) { if (!this.canMeleeRangeAttack || always) { this.OrderTargets(); } int count4 = this.lkPlayerTemp.Count; if (this.specialCharacters == null) { this.specialCharacters = new List(); } this.specialNodes.Clear(); this.specialCharacters.Clear(); for (int num19 = 0; num19 < count4; num19++) { int num20 = this.lkPlayerTemp[num19]; if (num20 < this.lkPlayerAI.Count && num20 > -1) { Character character5 = this.lkPlayerAI[num20]; if (character5 && character5.hasActions) { bool flag10 = true; if (!this.character.npc) { flag10 = this.CanAttack(character5); } if (character5.IsSentient() && flag10 && character5.node != null) { Vector3 vector7 = (Vector3)this.character.node.position; Vector3 vector8 = (Vector3)character5.node.position; vector8.y = vector7.y; float sqrMagnitude2 = (vector7 - vector8).sqrMagnitude; if (sqrMagnitude2 < num18 * num18 && sqrMagnitude2 > num17 * num17) { for (int num21 = 0; num21 < 8; num21++) { GraphNode graphNode5 = character5.node.ConnectionFromIndex(num21); if (graphNode5 != null && graphNode5 != character5.node && graphNode5.ID == 0 && ((Vector3)graphNode5.position - (Vector3)character5.node.position).sqrMagnitude < 16f) { for (int num22 = 0; num22 < 8; num22++) { GraphNode graphNode6 = character5.node.ConnectionFromIndex(num22); if (graphNode6 != null && graphNode6 != character5.node && graphNode6 != graphNode5 && graphNode6.ID == 0 && ((Vector3)graphNode6.position - (Vector3)character5.node.position).sqrMagnitude < 16f) { this.specialNodes.Add(graphNode6); this.specialCharacters.Add(character5); } } } } } } } } } if (this.specialNodes.Count > 0) { int num23 = Random.Range(0, this.specialNodes.Count); if (num23 > -1) { this.lastSpecialAttack = Links.x.gameplay.seconds; if (this.debugging) { this.str.Append("\nSpecial attack found for jump "); this.str.Append(" "); this.str.Append(this.specialCharacters[num23]); } this.jumpNode = this.specialNodes[num23]; this.actions.StartMiniEvent(this.specialCharacters[num23], null, "Dragoon Bubble Evade", true); this.SkipWatch(); return true; } } if (this.debugging) { this.str.Append("\nNo one in range for special attack "); } } } else if (this.character.stats.customAI == "Egg" && Random.Range(0, 5) == 0 && Links.x.cellar.CombatBreakableCount() < Random.Range(3, 5) && Links.x.combat.GetNPCCount() < 30 && this.character.node != null && this.character.node.Walkable) { bool flag11 = false; GraphNode graphNode7 = null; for (int num24 = 0; num24 < 8; num24++) { GraphNode graphNode8 = this.character.node.ConnectionFromIndex(num24); if (graphNode8 != null && graphNode8 != this.character.node && graphNode8.ID == 0) { flag11 = true; graphNode7 = graphNode8; break; } } if (flag11) { GameObject gameObject = Object.Instantiate(Links.x.cellar.egg, this.character.body.transform.GetChild(0).transform.position, Quaternion.Euler(new Vector3(0f, Random.Range(-360f, 360f), 0f)), null); gameObject.GetComponent().node = this.character.node; Links.x.cellar.AddCombatBreakable(gameObject.GetComponent()); gameObject.GetComponent().source = this.character; gameObject.GetComponent().Fall(); this.character.node.Walkable = false; this.character.ClearNodePath(); this.character.Jump(graphNode7, (Vector3)graphNode7.position, false, false); this.Skip(); return true; } } } if (this.character.stats.canPin && !this.allyIsPinning && !this.character.sailing && this.character.node != null && this.character.attackTime >= 1f && this.character.stats.Stuck() == 0 && (this.character.npc || this.character.stats.stamina >= 15f)) { bool flag12 = false; int num25; Character character6; if (this.character.party) { if (!Links.x.fellowship.AnyonePinning() && Links.x.PartySummonsAlive() >= 2 && Random.Range(1, 101) <= this.character.stats.autoCritsAI && !this.character.summoned) { flag12 = true; } } else if ((Links.x.gameplay.seconds > Links.x.combat.lastPinTime + 250f || Links.x.combat.lastPinTime == 0f) && !this.AnyonePinning(out num25, out character6) && num25 > 0 && Random.Range(0, 3) == 0) { flag12 = true; } if (flag12) { int num26 = this.lkPlayerTemp.Count; this.factionCharacters.Clear(); float num27 = 400f; if (this.character.npc) { num27 = 144f; } for (int num28 = 0; num28 < num26; num28++) { int num29 = this.lkPlayerTemp[num28]; if (num29 < this.lkPlayerAI.Count && num29 > -1) { Character character7 = this.lkPlayerAI[num29]; if (character7 && character7.hasActions && character7.IsSentient() && this.CanAttack(character7) && !character7.stats.pinned && !character7.jumping && !character7.charging && character7.stats.Stuck() == 0 && character7.radius <= 2f && character7.stats.characterRow._Height < 3.5f && !character7.stats.flying && !character7.inCircle && this.IsPointAwayFromEnemiesExcept(character7.currentPosition, false, false, character7)) { float sqrMagnitude3 = (character7.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude3 < 25f) { if (this.debugging) { this.str.Append("\nPin "); this.str.Append(" "); this.str.Append(character7); } this.PinTarget(character7); return true; } if (sqrMagnitude3 < num27) { this.factionCharacters.Add(character7); } } } } num26 = this.factionCharacters.Count; float num30 = 100000f; Character character8 = null; for (int num31 = 0; num31 < num26; num31++) { Character character9 = this.factionCharacters[num31]; if (!character9.moving) { float sqrMagnitude4 = (character9.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude4 < num30) { character8 = character9; num30 = sqrMagnitude4; } } } if (!character8) { num30 = 100000f; for (int num32 = 0; num32 < num26; num32++) { Character character10 = this.factionCharacters[num32]; float sqrMagnitude5 = (character10.currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude5 < num30) { character8 = character10; num30 = sqrMagnitude5; } } } if (character8) { if (this.debugging) { this.str.Append("\nMove to pin "); this.str.Append(" "); this.str.Append(character8); } this.actions.pinTarget = character8; this.findPathCoroutine = this.FindPath(character8.node, 0f, 36f, 50, false, false, false, true, false, "MovePin"); base.StartCoroutine(this.findPathCoroutine); return true; } } } if (this.character.stats.canCharge && !this.character.sailing && ((this.character.stats.stamina > 15f && this.character.party) || (!this.character.party && (Links.x.combat.lastChargeTime == 0f || Links.x.gameplay.seconds > Links.x.combat.lastChargeTime + 300f))) && !this.allyIsPinning && this.character.stats.Stuck() == 0) { bool flag13 = false; if (!Records.x.editor) { flag13 = false; } if ((Random.Range(0, this.character.stats.formationGroup * 3) == 0 || (this.meleeWeaponIndex == -1 && this.rangeWeaponIndex == -1) || flag13) && this.character.node != null && (this.character.attackTime >= 1f || flag13)) { bool flag14 = false; int count5 = this.lkPlayerTemp.Count; for (int num33 = 0; num33 < 3; num33++) { for (int num34 = 0; num34 < count5; num34++) { int num35 = this.lkPlayerTemp[num34]; if (num35 < this.lkPlayerAI.Count && num35 > -1) { Character character11 = this.lkPlayerAI[num35]; if (character11 && character11.hasActions && (num33 == 2 || (num33 == 0 && character11.hasCreatureBuff) || (num33 == 1 && character11.inCircle))) { bool flag15 = true; if (!this.character.npc) { flag15 = this.CanAttack(character11); } if (character11.IsSentient() && flag15 && !character11.stats.pinned && character11.node != null) { Quaternion quaternion2 = Quaternion.LookRotation(character11.currentPosition - this.character.currentPosition); Vector3 vector9 = quaternion2 * Vector3.forward * Records.x.nodeSize + this.character.currentPosition; GraphNode slideNode6 = this.character.GetSlideNode(vector9, this.character.node, true, 0, 0); float num36 = (character11.attackRadius + this.character.attackRadius) * 0.75f; GraphNode graphNode9 = null; if (slideNode6 != null) { Vector3 vector10 = quaternion2 * Vector3.forward; vector9 = this.character.currentPosition + vector10 * 2.5f * 2f; GraphNode slideNode7 = this.character.GetSlideNode(vector9, slideNode6, true, 0, 0); if (slideNode7 != null) { vector9 = this.character.currentPosition + vector10 * 2.5f * 3f; GraphNode slideNode8 = this.character.GetSlideNode(vector9, slideNode7, true, 0, 0); if (slideNode8 != null) { if (this.DistanceToLine(character11.currentPosition, this.character.currentPosition, (Vector3)slideNode8.position) < num36) { graphNode9 = slideNode8; } else { vector9 = this.character.currentPosition + vector10 * 2.5f * 4f; GraphNode slideNode9 = this.character.GetSlideNode(vector9, slideNode8, true, 0, 0); if (slideNode9 != null) { if (this.DistanceToLine(character11.currentPosition, this.character.currentPosition, (Vector3)slideNode9.position) < num36) { graphNode9 = slideNode9; } else { vector9 = this.character.currentPosition + vector10 * 2.5f * 5f; GraphNode slideNode10 = this.character.GetSlideNode(vector9, slideNode9, true, 0, 0); if (slideNode10 != null && this.DistanceToLine(character11.currentPosition, this.character.currentPosition, (Vector3)slideNode10.position) < num36) { graphNode9 = slideNode10; } } } } } } } if (graphNode9 != null) { Links.x.combat.lastChargeTime = Links.x.gameplay.seconds; if (this.debugging) { this.str.Append("\nSpecial attack found for charge "); this.str.Append(" "); this.str.Append(character11); } if (this.character.party) { this.character.stats.AddStamina(-25f); } base.StartCoroutine(this.Jump(character11, graphNode9, (Vector3)graphNode9.position, "Charge", true, false)); return true; } } } } } } if (!flag14) { for (int num37 = 0; num37 < count5; num37++) { int num38 = this.lkPlayerTemp[num37]; if (num38 < this.lkPlayerAI.Count && num38 > -1) { Character character12 = this.lkPlayerAI[num38]; if (character12 && character12.hasActions && character12.IsSentient() && this.CanAttack(character12) && !character12.stats.pinned && (character12.currentPosition - this.character.currentPosition).sqrMagnitude < 14.0625f) { base.StartCoroutine(this.Jump(character12, character12.node, (Vector3)character12.node.position, "Kick", true, false)); return true; } } } } } } return false; } // Token: 0x060001C9 RID: 457 RVA: 0x00027458 File Offset: 0x00025658 public void ChargeTarget(Character c) { this.chargeTarget = c; if ((c.currentPosition - this.character.currentPosition).sqrMagnitude < 6.25f && !c.interactiveObject) { this.character.stats.AddStamina(-15f); base.StartCoroutine(this.Jump(c, c.node, (Vector3)c.node.position, "Kick", true, false)); return; } Quaternion quaternion = Quaternion.LookRotation(c.currentPosition - this.character.currentPosition); quaternion * Vector3.forward * Records.x.nodeSize + this.character.currentPosition; Vector3 vector = quaternion * Vector3.forward * 10f + this.character.currentPosition; GraphNode graphNode = this.character.NearNode(vector, false, 0, -1, 0); if (graphNode == null) { graphNode = this.character.node; } this.character.stats.AddStamina(-25f); base.StartCoroutine(this.Jump(c, graphNode, vector, "Charge", true, false)); } // Token: 0x060001CA RID: 458 RVA: 0x00027591 File Offset: 0x00025791 private IEnumerator Jump(Character c, GraphNode n, Vector3 nPosition, string type, bool knockback, bool hasChargeUpTime) { this.findingAction = true; bool canJump = true; this.chargeLoop = null; this.jumpNode = n; this.jumping = true; this.busy = true; bool charging = false; if (type == "Charge") { charging = true; } bool kicking = false; if (type == "Kick") { kicking = true; } while (this.character.body.IsHit()) { yield return null; } if (charging || kicking) { if (this.diaCharacters == null) { this.diaCharacters = Links.x.diorama.characters; } if (hasChargeUpTime) { this.actions.chargeUpNum = 114; if (!this.actions.chargeUpFX) { this.actions.chargeUpFX = Links.x.cellar.GetPooledGameObject(this.actions.chargeUpNum); } if (this.actions.chargeUpFX) { MasterAudio.PlaySound3DAtTransform("SpecialAttacks", this.character.tr, 1f, new float?(1f), 0f, "ChargeUp", null, false, false); this.actions.chargeUpFX.transform.SetParent(this.character.body.GetNeck(), true); this.actions.chargeUpFX.transform.localPosition = Vector3.zero; this.actions.chargeUpFX.SetActive(true); float timeToLerp = 0.75f; float percentage = 0f; float startTime = Time.time; while (percentage < 1f) { if (!this.actions.chargeUpFX) { break; } this.character.SetRotation(Quaternion.LookRotation((Vector3)n.position - this.character.currentPosition), false, false); percentage = (Time.time - startTime) / timeToLerp; yield return null; } while (Records.x.pocketPause) { yield return null; } if (!this.actions.chargeUpFX || !c.IsSentient()) { canJump = false; } if (this.actions.chargeUpFX) { Links.x.cellar.ReturnPooledGameObject(this.actions.chargeUpNum, this.actions.chargeUpFX); this.actions.chargeUpFX = null; } MasterAudio.StopSoundGroupOfTransform(this.character.tr, "SpecialAttacks"); } else { canJump = false; this.jumping = false; } } } else if (Records.x.miniGame) { this.chargeLoop = Links.x.cellar.GetPooledGameObject(120); this.chargeLoop.transform.position = (Vector3)n.position + new Vector3(0f, 0.1f, 0f); this.chargeLoop.SetActive(true); } if (canJump) { this.jumpDone = false; if (!kicking) { this.character.ClearNodePath(); this.character.ClaimNode(n, this.character.tr.position, false); this.character.charging = charging; if (Records.x.editor) { Character character = this.character; Debug.Log(((character != null) ? character.ToString() : null) + " " + charging.ToString()); } this.character.Jump(n, nPosition, false, false); } else { Quaternion look = Quaternion.LookRotation(c.tr.position - this.character.tr.position); while (this.character.moving) { yield return null; } this.character.alwaysTurn = true; this.character.SetRotation(look, false, this.character.mainSelected); if (this.character.GetRotationAngle(look, this.character.savedRot) >= 40f && !this.character.mainSelected) { yield return new WaitForSeconds(0.03f); while (this.character.turning) { yield return null; } } this.character.EndTurning(false); this.character.PlayAnimation("Kick", 0f); yield return new WaitForSeconds(0.25f); look = default(Quaternion); } this.character.PlaySoundFX(0, 7); Vector3 startPosition = this.character.currentPosition; Vector3 randomRot = Vector3.zero; randomRot.x = Random.Range(5f, 6f); if (Random.Range(0, 2) == 0) { randomRot.x *= -1f; } randomRot.y = Random.Range(5f, 6f); if (Random.Range(0, 2) == 0) { randomRot.y *= -1f; } randomRot.z = Random.Range(5f, 6f); if (Random.Range(0, 2) == 0) { randomRot.z *= -1f; } if (!kicking) { yield return new WaitForSeconds(0.1f); } if (!charging && !kicking) { int x = this.character.GetArcPoints(); while (this.CanJump()) { this.findingAction = true; if (this.character.currentArcIndex < 2) { this.character.SetRotation(Quaternion.LookRotation((Vector3)n.position - startPosition), false, false); } if (this.character.currentArcIndex > x - 3) { this.character.SetRotation(Quaternion.LookRotation((Vector3)n.position - startPosition), false, false); this.character.body.tr.rotation = Quaternion.Slerp(this.character.body.tr.rotation, Quaternion.Euler(Vector3.zero), Time.deltaTime * 15f); } if (this.character.stats.animal && this.character.currentArcIndex <= x - 3 && this.character.currentArcIndex >= 2) { this.character.tr.Rotate(randomRot * 80f * Time.deltaTime); this.character.rot = this.character.tr.rotation; } yield return null; } } else { this.factionCharacters.Clear(); int x = 0; if (this.character.party) { MasterAudio.PlaySoundAndForget("Feedback", 0.45f, new float?(1f), 0f, "Bff_Sounds_Charge", null); } bool hitTarget = false; while ((charging && this.character.moveNode == n) || (kicking && x == 0)) { bool flag = false; if (kicking) { flag = true; } for (int i = 0; i < this.diaCharacters.Count; i++) { Character character2 = this.diaCharacters[i]; if (character2 && !character2.dead && !character2.stunned && character2 != this.character) { float sqrMagnitude = this.SubtractVectors(this.character.currentPosition, character2.currentPosition).sqrMagnitude; if (sqrMagnitude < (this.character.attackRadius + character2.attackRadius) * 0.75f * ((this.character.attackRadius + character2.attackRadius) * 0.75f) || (kicking && character2 == c && sqrMagnitude < 16f)) { bool flag2 = true; if (flag) { Vector3 forward = this.character.tr.forward; Vector3 vector = Vector3.Normalize(c.tr.position - this.character.currentPosition); if (Vector3.Dot(forward, vector) < 0.25f) { flag2 = false; } } if (!this.factionCharacters.Contains(character2) && flag2) { bool flag3 = true; Effects existingEffect = character2.stats.GetExistingEffect("Impact"); if (existingEffect && existingEffect.source == this.character) { flag3 = false; } if (Records.x.miniGame) { flag3 = character2 == Links.x.main; } if (flag3) { bool flag4 = this.CanAttack(character2); if (knockback && flag4) { MasterAudio.PlaySound3DAtVector3AndForget(this.character.stats.characterRow._UnarmedAttackSound, character2.currentPosition, Random.Range(0.5f, 0.6f), new float?(1f), 0f, "", null); character2.Bounce(this.character, "Knockback", 0f); } if (flag4) { this.factionCharacters.Add(character2); if (!character2.body.IsHit() && character2.animID != 9) { character2.PlayAnimation("Hit", 0f); } character2.SetRotation(Quaternion.LookRotation(this.character.currentPosition - character2.currentPosition), false, true); Effects effects = character2.gameObject.AddComponent(); Links.x.cellar.AddEffects(effects); effects.gameObject.SetActive(true); effects.source = this.character; effects.target = character2; effects.fromLoad = false; effects.effectName = "Impact"; effects.sourceLevel = ((float)this.character.stats.level + 1f) * 1.5f + this.character.stats.ShieldAC(); effects.Inflicted(true); if (c == character2) { hitTarget = true; } } MasterAudio.PlaySound3DAtVector3AndForget(character2.stats.characterRow._UnarmedAttackSound, character2.currentPosition, Random.Range(0.4f, 0.5f), new float?(1f), 0f, "", null); } } } else if (Records.x.miniGame && character2 == Links.x.main && Links.x.minigame) { Links.x.minigame.AddScore(); } } } if (charging) { Vector3 currentPosition = this.character.currentPosition; int num = Mathf.RoundToInt(((float)this.character.stats.level + 1f) * 1.5f + this.character.stats.ShieldAC()); GameObject gameObject = null; if (c.interactiveObject) { gameObject = c.gameObject; } float num2 = 12f; for (int j = 0; j < this.timedBreakables.Count; j++) { TimedBreakable timedBreakable = this.timedBreakables[j]; if (timedBreakable && !timedBreakable.breakable.destroyed && this.SubtractVectorsNoY(timedBreakable.breakable.pt, currentPosition).sqrMagnitude < num2) { if (timedBreakable.gameObject == gameObject) { hitTarget = true; } if (timedBreakable.breakable.breakable.armor > 0) { timedBreakable.breakable.currentHealth -= num; } if (timedBreakable.breakable.currentHealth <= 0 || timedBreakable.breakable.breakable.armor == 0) { timedBreakable.breakable.ClickToBreak(this.character, false, false); } else { Links.x.cellar.GetAnimatedText("NPCDmg", num.ToString(), true).gameObject.transform.position = timedBreakable.gameObject.transform.position + new Vector3(0f, 2f, 0f); } } } for (int k = 0; k < this.currentTileEffects.Count; k++) { TileEffects tileEffects = this.currentTileEffects[k]; if (tileEffects && tileEffects.isWall) { this.breakies = tileEffects.breakables; foreach (BreakableActions breakableActions in this.breakies) { if (breakableActions && !breakableActions.destroyed && this.SubtractVectorsNoY(breakableActions.transform.position, currentPosition).sqrMagnitude < num2) { if (breakableActions.gameObject == gameObject) { hitTarget = true; } if (breakableActions.breakable.armor > 0) { breakableActions.currentHealth -= num; } if (breakableActions.currentHealth <= 0 || breakableActions.breakable.armor == 0) { breakableActions.ClickToBreak(this.character, false, false); } else { Links.x.cellar.GetAnimatedText("NPCDmg", num.ToString(), true).gameObject.transform.position = breakableActions.gameObject.transform.position + new Vector3(0f, 2f, 0f); } } } } } for (int l = 0; l < this.diaBreakables.Count; l++) { BreakableActions breakableActions2 = this.diaBreakables[l]; if (breakableActions2 && !breakableActions2.destroyed && this.SubtractVectorsNoY(breakableActions2.pt, currentPosition).sqrMagnitude < num2) { if (breakableActions2.gameObject == gameObject) { hitTarget = true; } if (breakableActions2.breakable.armor > 0) { breakableActions2.currentHealth -= num; } if (breakableActions2.currentHealth <= 0 || breakableActions2.breakable.armor == 0) { breakableActions2.ClickToBreak(this.character, false, false); } else { Links.x.cellar.GetAnimatedText("NPCDmg", num.ToString(), true).gameObject.transform.position = breakableActions2.gameObject.transform.position + new Vector3(0f, 2f, 0f); } } } } int num3 = x; x = num3 + 1; yield return null; } if (this.character.mainSelected && !hitTarget && c != this.character && !c.interactiveObject) { c.Bounce(this.character, "Knockback", 0f); } } if (!this.character.jumping && charging) { this.character.charging = false; if (Records.x.editor) { Debug.Log(((this != null) ? this.ToString() : null) + " charging false"); } } if (this.character.jumping && charging) { this.character.TargetReached(); } if (!charging) { Vector3 eulerAngles = this.character.tr.rotation.eulerAngles; eulerAngles.x = 0f; eulerAngles.z = 0f; this.character.SetRotation(Quaternion.Euler(eulerAngles), false, false); } if (this.character && this.character.IsSentient() && !charging && !kicking && !this.character.isHit) { if (this.chargeLoop) { Links.x.cellar.ReturnPooledGameObject(120, this.chargeLoop); } string text = "Cannonball"; if (Random.Range(0, 2) == 0) { text += "1"; } else { text += "2"; } MasterAudio.PlaySound3DAtVector3AndForget("SpecialAttacks", this.character.currentPosition, 1f, new float?(1f), 0f, text, null); GameObject pooledGameObject = Links.x.cellar.GetPooledGameObject(112); pooledGameObject.transform.position = this.character.currentPosition; pooledGameObject.SetActive(true); bool flag5 = true; if (!Records.x.miniGame && this.character.summoned) { flag5 = false; } for (int m = 0; m < 8; m++) { n = this.character.node.ConnectionFromIndex(m); if (n != null && n != this.character.node && n.ID != 0 && n.ID != this.character.nodeStationaryID && n.ID != this.character.nodeMovingID) { Character character3 = this.character.GetNodeCharacter(n.ID); if (Records.x.miniGame && character3 && !(character3 == Links.x.main)) { character3 = null; } if (character3 && character3.party && character3.mainSelected && Vector3.Distance((Vector3)n.position, character3.tr.position) > 2.6f) { character3 = null; } if (character3) { bool flag6 = this.CanAttack(character3); if (!character3.downed) { if (flag5) { character3.Knockback(this.character.currentPosition, 1, false, true, false); } else if (flag6) { character3.Knockback(this.character.currentPosition, 1, false, true, false); } } character3.PlayAnimation("Hit", 0f); if (flag6) { character3.SetRotation(Quaternion.LookRotation(this.character.currentPosition - character3.currentPosition), false, true); Effects effects2 = character3.gameObject.AddComponent(); Links.x.cellar.AddEffects(effects2); effects2.gameObject.SetActive(true); effects2.source = this.character; effects2.target = character3; effects2.fromLoad = false; effects2.effectName = "Impact"; effects2.sourceLevel = ((float)this.character.stats.level + 1f) * 2f; effects2.Inflicted(true); float num4 = Random.Range(0.3f, 0.4f); if (this.character.stats.xmlName.Contains("Frog")) { num4 = Random.Range(0.1f, 0.15f); } MasterAudio.PlaySound3DAtVector3AndForget(character3.stats.characterRow._UnarmedAttackSound, character3.currentPosition, num4, new float?(Random.Range(0.9f, 1f)), 0f, "", null); if (Records.x.miniGame) { character3.isHit = true; character3.downed = true; character3.PlayAnimation("Hit Down", 0f); } } } } } } this.busy = false; while (this.StillCharging(charging)) { yield return null; } if (charging && this.character) { this.character.charging = false; } this.jumping = false; this.actions.canEndAttackTime = true; this.actions.EndAttackTime(0f); this.actions.EndTurn(true); if (this.character && this.character.actions && !this.character.mainSelected) { this.Skip(); } if (!this.character.party) { this.character.attackTime = 0.25f; } else { this.character.inAction = false; } startPosition = default(Vector3); randomRot = default(Vector3); } this.jumping = false; this.findingAction = false; this.jumpDone = false; yield break; } // Token: 0x060001CB RID: 459 RVA: 0x000275CD File Offset: 0x000257CD private bool StillCharging(bool charging) { return charging && this.character && this.character.jumping; } // Token: 0x060001CC RID: 460 RVA: 0x000275F4 File Offset: 0x000257F4 private bool CanJump() { return !this.jumpDone && this.character && this.character.IsSentient() && this.character.actions && this.character.jumping; } // Token: 0x060001CD RID: 461 RVA: 0x00027650 File Offset: 0x00025850 public Vector3 GetClosestPointOnFiniteLine(Vector3 point, Vector3 start, Vector3 end) { Vector3 vector = end - start; float magnitude = vector.magnitude; vector.Normalize(); float num = Mathf.Clamp(Vector3.Dot(point - start, vector), 0f, magnitude); return start + vector * num; } // Token: 0x060001CE RID: 462 RVA: 0x0002769C File Offset: 0x0002589C private float DistanceToLine(Vector3 pt, Vector3 start, Vector3 end) { Vector3 closestPointOnFiniteLine = this.GetClosestPointOnFiniteLine(pt, start, end); Vector3 vector = Quaternion.LookRotation(end - start) * Vector3.forward; Vector3 vector2 = Vector3.Normalize(pt - closestPointOnFiniteLine); float num = Vector3.Dot(vector, vector2); if (num < -0.5f || num > 0.5f) { return 100f; } return Vector3.Distance(closestPointOnFiniteLine, pt); } // Token: 0x060001CF RID: 463 RVA: 0x000276FA File Offset: 0x000258FA public void PinTarget(Character c) { this.actions.pinTarget = c; base.StartCoroutine(this.PinWait(c)); } // Token: 0x060001D0 RID: 464 RVA: 0x00027716 File Offset: 0x00025916 private IEnumerator PinWait(Character c) { this.busy = true; this.pinLow = false; this.jumpDone = false; GraphNode node = c.node; this.character.ClearNodePath(); Quaternion quaternion = Quaternion.LookRotation(c.currentPosition - this.character.currentPosition); Vector3 vector = c.currentPosition + quaternion * Vector3.forward * -0.9f; this.character.ClaimNode(node, vector, false); this.character.charging = true; this.character.ignoreNodeIDs = true; this.jumping = true; this.character.Jump(node, c.tr.position, false, false); this.character.PlaySoundFX(0, 7); Vector3 currentPosition = this.character.currentPosition; yield return new WaitForSeconds(0.001f); yield return new WaitForSeconds(0.1f); float startTime = Time.timeSinceLevelLoad; this.character.charging = false; this.character.ignoreNodeIDs = false; this.character.jumpLanding = false; this.jumping = false; this.character.ClearNodePath(); int num = 1; if (this.character.npc) { num = this.FriendCount(15f); } if ((this.character.tr.position - c.tr.position).sqrMagnitude > 9f || c.stats.pinned || this.character.stats.pinned || num < 1) { this.actions.canEndAttackTime = true; this.busy = false; this.actions.EndAttackTime(0f); this.actions.EndTurn(true); if (this.character.mainSelected) { Links.x.cellar.GetAnimatedText("Evaded", "", Records.x.IsTextLeft(this.character, c)).gameObject.transform.position = c.body.HeadPosition(0f) + new Vector3(Random.Range(0f, 1f), Random.Range(0f, 1f), 0f); } this.actions.pinTarget = null; } else { if (this.character.body.sneaking) { this.character.EndSneak(false, false); } if (Records.x.pocketPause) { c.OverridePocketPause(); } if (!c.hasActions) { c.UpdateLKP(Links.x.main, Links.x.main.node, "Seen", true); Links.x.sensory.AddPlayerToCombat(c, this.character, true, false, true); if (!Records.x.combat) { Links.x.combat.StartCombat(null, this.character, true, true); } } Effects effects = c.gameObject.AddComponent(); Links.x.cellar.AddEffects(effects); effects.source = this.character; effects.target = c; effects.effectName = "Pinned"; effects.sourceLevel = 0f; effects.Inflicted(true); c.stats.pinned = true; Effects effects2 = this.character.gameObject.AddComponent(); Links.x.cellar.AddEffects(effects2); effects2.source = this.character; effects2.target = this.character; effects2.effectName = "Pinning"; effects2.sourceLevel = 0f; effects2.Inflicted(true); this.character.stats.pinning = true; this.character.stats.pinHitCount = 0; this.pinnedTarget = c; if (this.character.npc) { MasterAudio.PlaySoundAndForget("Feedback", 0.4f, new float?(1f), 0f, "Bff_Sounds_GotPinned", null); } if (c.npc) { MasterAudio.PlaySoundAndForget("Feedback", 1.25f, new float?(1f), 0f, "Bff_Sounds_PinningEnemy", null); } MasterAudio.PlaySound3DAtVector3AndForget("Body Fall", this.character.currentPosition, 1f, new float?(1f), 0.5f, "", null); Vector3 characterPosition = this.character.tr.position; if (c.stats.xmlName.Contains("ImpRat") || c.stats.xmlName.Contains("Fox") || c.stats.xmlName.Contains("PaduriiChild") || c.stats.xmlName.Contains("Brisska")) { this.pinLow = true; } if (c.jumping) { c.ForceEndJump(); } if (c.dodging) { c.EndDodge(); } if (c.evading) { c.StopEvading(); } if (c.NodesCount() > 0) { c.ClearNodePath(); } if (c.actions) { c.actions.Interrupt(); } this.character.PlayAnimation("Pinning", 0f); if (this.character.mainSelected) { this.actions.canEndAttackTime = true; this.busy = false; this.actions.EndAttackTime(0f); this.actions.EndTurn(true); } this.character.StartQuip("Over here!"); float timeToLerp = 150f; float percentage = 0f; startTime = Links.x.gameplay.seconds; float savedPercentage = 0f; float rotatePercentage = 0f; Character savedFriend = null; if (Records.x.banquetIsle && c.party && Links.x.GetPartyCount() == 1) { timeToLerp = 90f; } if (!Records.x.banquetIsle && this.character.party) { int num3; int num4; float num2 = c.stats.Stat("Agility", false, out num3) + c.stats.Stat("Strength", false, out num4); float num5 = this.character.stats.Stat("Aura", false, out num3) + this.character.stats.Stat("Strength", false, out num4); if (num2 > num5) { num2 /= 5f; } else { num2 = 0f; } num2 += c.stats.characterRow._PinBreak * 20f; timeToLerp -= num2; if (timeToLerp < 30f) { timeToLerp = 30f; } } while (percentage < 1f && !c.dead && !c.stunned && !c.downed && !this.EndPin()) { this.character.tr.position = characterPosition; Character character = this.NearestFriend(); if (character && savedFriend != character && (percentage > rotatePercentage || rotatePercentage == 0f) && !this.pinLow) { quaternion = Quaternion.LookRotation(character.currentPosition - this.character.currentPosition); savedFriend = character; this.character.alwaysTurn = true; this.character.SetRotation(quaternion, false, false); rotatePercentage = percentage + 0.2f; } Vector3 vector2 = this.character.tr.position + this.character.body.tr.forward * 0.6f; c.tr.position = vector2; c.tr.rotation = this.character.body.tr.rotation; if (c.animID != 50 && c.animID != 10 && (percentage > savedPercentage + 0.05f || savedPercentage == 0f)) { c.PlayAnimation("Pinning", 0f); savedPercentage = percentage; } if (this.character.animID != 50 && (percentage > savedPercentage + 0.05f || savedPercentage == 0f)) { this.character.PlayAnimation("Pinning", 0f); savedPercentage = percentage; } c.SetAnimatorSpeed(3f); percentage = (Links.x.gameplay.seconds - startTime) / timeToLerp; yield return null; } if (Records.x.editor) { Debug.Log(this.EndPin().ToString() + " " + c.animID.ToString()); } if (this.character.mainSelected) { Links.x.rtsCamera.Zoom(false, "Combat"); } if (this.character.npc) { Links.x.combat.lastPinTime = Links.x.gameplay.seconds; } if (this.character.party) { this.character.stats.AddStamina(-15f); } this.character.EndQuip(); this.busy = false; if (!this.character.mainSelected) { this.actions.canEndAttackTime = true; this.actions.EndAttackTime(0f); this.actions.EndTurn(true); } this.character.stats.pinning = false; this.character.PlayIdle(); c.stats.pinned = false; if (c.IsSentient()) { c.PlayIdle(); GraphNode graphNode = c.NearNode(c.tr.position, true, 0, -1, 0); if (graphNode != null) { c.Jump(graphNode, (Vector3)graphNode.position, true, false); } } c.stats.HealEffect("Pinned"); this.character.stats.HealEffect("Pinning"); this.character.charging = false; this.actions.pinTarget = null; if (this.character.mainSelected && (this.character.dead || !Records.x.combat)) { this.actions.EndActions(); } characterPosition = default(Vector3); savedFriend = null; } yield break; } // Token: 0x060001D1 RID: 465 RVA: 0x0002772C File Offset: 0x0002592C private bool EndPin() { if (this.character.dead || this.character.stunned || this.character.downed) { return true; } if (this.character.stats.pinHitCount >= 1) { return true; } if (!this.character.stats.pinning) { return true; } if (this.character.mainSelected && this.character.stats.Stuck() == 1 && !Records.x.inMenus && !Records.x.typing) { if (Links.x.mk && !Records.x.typing && !Records.x.inMenus && (Input.GetKeyDown(Links.x.gameplay.keyControl.GetHotkey("Left")) || Input.GetKeyDown(Links.x.gameplay.keyControl.GetHotkey("Up")) || Input.GetKeyDown(Links.x.gameplay.keyControl.GetHotkey("Right")) || Input.GetKeyDown(Links.x.gameplay.keyControl.GetHotkey("Down")))) { return true; } if (Links.x.joy && Links.x.fellowship.move.magnitude > 0.2f && !Links.x.gameplay.makeCircleMode) { return true; } } return false; } // Token: 0x060001D2 RID: 466 RVA: 0x000278BC File Offset: 0x00025ABC private int FriendCount(float range) { int num = 0; int count = this.combatCharacters.Count; for (int i = 0; i < count; i++) { Character character = this.combatCharacters[i]; if (character && character != this.character && character.hasActions && character.IsSentient() && !this.CanAttack(character)) { float sqrMagnitude = (character.currentPosition - this.character.currentPosition).sqrMagnitude; float num2 = character.AttackRange() + range; if (sqrMagnitude < num2 * num2) { num++; } } } return num; } // Token: 0x060001D3 RID: 467 RVA: 0x00027954 File Offset: 0x00025B54 private bool AnyonePinning(out int friendCount, out Character targ) { friendCount = 0; targ = null; if (this.combatCharacters == null) { this.combatCharacters = Links.x.combat.characters; } int count = this.combatCharacters.Count; for (int i = 0; i < count; i++) { Character character = this.combatCharacters[i]; if (character && character != this.character && character.hasActions && character.IsSentient() && !this.CanAttack(character)) { float sqrMagnitude = (character.currentPosition - this.character.currentPosition).sqrMagnitude; float num = character.AttackRange() + 9f; if (sqrMagnitude < num * num) { friendCount++; } if (character.stats.pinning) { targ = character.actions.ai.pinnedTarget; return true; } } } return false; } // Token: 0x060001D4 RID: 468 RVA: 0x00027A38 File Offset: 0x00025C38 public bool LookForBreakables() { int num = 0; this.breakables.Clear(); if (this.actions.selectedAITargetInteractive != null && this.actions.hasTarget && this.actions.selectedAITargetInteractive.activeSelf) { BreakableActions component = this.actions.selectedAITargetInteractive.GetComponent(); if (!component.destroyed) { if (component.breakable.armor != 0 && this.character.attackTime < 1f) { return false; } num = this.CheckBreakable(component, component.node); if (num == 1 || num == 2) { return true; } } } if (Random.Range(0, 3) == 0 || this.character.party) { if (num == 0) { for (int i = 0; i < this.timedBreakables.Count; i++) { TimedBreakable timedBreakable = this.timedBreakables[i]; if (timedBreakable && !timedBreakable.breakable.destroyed && this.CanAttack(timedBreakable.source)) { this.breakables.Add(timedBreakable.breakable); } } } if (num == 0) { for (int j = 0; j < this.currentTileEffects.Count; j++) { TileEffects tileEffects = this.currentTileEffects[j]; if (tileEffects && tileEffects.isWall && tileEffects.source && this.CanAttack(tileEffects.source)) { this.breakies = tileEffects.breakables; foreach (BreakableActions breakableActions in this.breakies) { if (breakableActions && !breakableActions.destroyed) { this.breakables.Add(breakableActions); } } } } } if (num == 0 && this.character.party) { for (int k = 0; k < this.diaBreakables.Count; k++) { BreakableActions breakableActions2 = this.diaBreakables[k]; if (breakableActions2 && breakableActions2.aiShouldBreakIt && !breakableActions2.destroyed) { this.breakables.Add(breakableActions2); } } } if (this.breakables.Count > 0) { this.breakablesOrdered.Clear(); int num2 = -1; int num3 = -1; int num4 = -1; int num5 = 3; if (num5 < this.breakables.Count) { num5 = this.breakables.Count; } for (int l = 0; l < num5; l++) { float num6 = float.PositiveInfinity; int num7 = -1; for (int m = 0; m < this.breakables.Count; m++) { if (m != num2 && m != num3 && m != num4) { float sqrMagnitude = (this.breakables[m].transform.position - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < num6) { num6 = sqrMagnitude; num7 = m; } } } if (num7 > -1) { bool flag = false; if (num2 == -1) { num2 = num7; flag = true; } if (num3 == -1 && !flag) { num3 = num7; flag = true; } if (num4 == -1 && !flag) { num4 = num7; } this.breakablesOrdered.Add(this.breakables[num7]); } } for (int n = 0; n < this.breakables.Count; n++) { if (n != num2 && n != num3 && n != num4) { this.breakablesOrdered.Add(this.breakables[n]); } } for (int num8 = 0; num8 < this.breakablesOrdered.Count; num8++) { num = this.CheckBreakable(this.breakablesOrdered[num8], this.breakablesOrdered[num8].node); if (num == 1) { break; } } } if (num == 1) { this.SkipMedium(); return true; } if (num == 2) { return true; } } return false; } // Token: 0x060001D5 RID: 469 RVA: 0x00027E38 File Offset: 0x00026038 private int CheckBreakable(BreakableActions b, GraphNode n) { int num = 0; float sqrMagnitude = (b.gameObject.transform.position - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < 625f) { Character character = b.GetComponent(); if (!character) { character = Links.x.gameplay.MakeObjectCharacter(n, b.gameObject, b.transform.position); } if (b.node == null) { b.node = character.node; } float num2 = 36f; if (b.breakable.armor > 0) { num2 = this.character.AttackRange() * this.character.AttackRange(); } if (sqrMagnitude < num2 && (this.character.attackTime >= 1f || b.breakable.armor == 0)) { if (b.breakable.armor > 0) { num = 2; this.actions.AddTarget(character); if (this.findingAction) { this.actions.StartAction("Attack"); } this.FinishFindingAction("Attack", character); this.findingAction = false; } else { num = 1; Links.x.gameplay.BreakableFinished(b, this.character); this.actions.SetSelectedTarget(false, null, null, null); } } else { this.actions.SetSelectedTarget(true, null, null, b.gameObject); num = 3; } } return num; } // Token: 0x060001D6 RID: 470 RVA: 0x00027FA0 File Offset: 0x000261A0 public void LookForPickups() { int count = this.pickups.Count; float num = 20f; float num2 = num * num; this.nearPickups.Clear(); bool flag = false; float num3 = (float)this.character.stats.HealthCurrent() / (float)this.character.stats.HealthMax(); bool flag2 = false; if (num3 < 0.9f) { flag2 = true; } if (this.character.party && this.character.stats.HasSpellbook() && this.character.stats.SpiritCurrent() < 90) { flag = true; } if (this.character.npc && !this.character.stats.semizenMagic && this.character.stats.canCastSpells && this.character.stats.SpiritCurrent() < 150) { flag = true; } for (int i = 0; i < count; i++) { Pickups pickups = this.pickups[i]; if (pickups && ((flag2 && pickups.isHealth) || (pickups.isSpirit && flag)) && this.SubtractVectors(pickups.tr.position, this.character.currentPosition).sqrMagnitude < num2) { this.nearPickups.Add(pickups); } } if (this.debugging) { this.str.Append("\nPickups count: "); this.str.Append(this.nearPickups.Count); } if (this.nearPickups.Count > 0) { this.pickupCoroutine = this.PickupMove(); base.StartCoroutine(this.pickupCoroutine); return; } this.DoSomething4(); } // Token: 0x060001D7 RID: 471 RVA: 0x0002814D File Offset: 0x0002634D private IEnumerator PickupMove() { bool foundItem = false; Pickups itemToPickup = null; GraphNode moveToNode = null; if (!foundItem && !this.character.sailing) { int num3; for (int i = 0; i < this.pickups.Count; i = num3 + 1) { if (!foundItem) { Pickups item = this.pickups[i]; GraphNode node = item.node; if (node != null) { bool flag = true; float num = 144f; if (this.character.inFriendGroup) { num = 49f; } if (!this.spreadStrong) { num = 169f; } if (!this.spread && !this.character.inCircle && ((Vector3)node.position - this.stayNearPosition).sqrMagnitude > num) { flag = false; } if (this.needToKite && !this.character.inCircle && !this.IsPointAwayFromEnemies((Vector3)node.position, true, true)) { flag = false; } if (this.character.inCircle && !this.InCircle(node, true)) { flag = false; } if (flag) { ABPath p = ABPath.ConstructFast(this.character.node, node, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); bool flag2 = false; if (!p.error) { flag2 = true; } if (this.debugging) { this.str.Append("\nLooking for item path: "); this.str.Append(p.error); } if (flag2) { this.tempPath = p.path; bool flag3 = true; GraphNode graphNode = null; int num2 = 0; for (int j = 0; j < this.tempPath.Count; j++) { if (this.tempPath[j] != this.character.node) { graphNode = this.tempPath[j]; num2++; } if (this.character.inCircle && flag3 && !this.InCircle(this.tempPath[j], true)) { flag3 = false; } } if (graphNode != null && flag3) { moveToNode = graphNode; foundItem = true; itemToPickup = item; if (this.debugging) { this.str.Append("\nPicking up ball"); break; } break; } } p.Release(this, false); p = null; } } item = null; } num3 = i; } } if (this.debugging) { this.str.Append("\nFound pickup: "); this.str.Append(foundItem); this.str.Append(" kiting? "); this.str.Append(this.stayOutOfRange); if (itemToPickup) { this.str.Append(itemToPickup); } } this.pickupCoroutine = null; if (foundItem) { this.character.MoveBackEmpty(); this.MakePath(moveToNode, 100, false, false, false, false, false, "Move"); if (this.debugging) { this.str.Append("\nGetting pickup"); } if (this.quipDebugging) { this.character.StartQuip("Moving to pickup"); } } else { this.DoSomething4(); } yield break; } // Token: 0x060001D8 RID: 472 RVA: 0x0002815C File Offset: 0x0002635C public bool Search() { int num = -1; float positiveInfinity = float.PositiveInfinity; Vector3 currentPosition = this.character.currentPosition; GraphNode node = this.character.node; for (int i = 0; i < this.lkPlayerAI.Count; i++) { if (this.CanAttack(this.lkPlayerAI[i]) && (currentPosition - (Vector3)this.lkPositionAI[i].position).sqrMagnitude < positiveInfinity) { num = i; } } if (this.debugging) { this.str.Append("\nLooking for search path, closest lk index: "); this.str.Append(num); } if (num <= -1) { return false; } if (this.quipDebugging) { this.character.StartQuip("Searching"); } bool flag = false; float sqrMagnitude = (currentPosition - (Vector3)this.lkPositionAI[num].position).sqrMagnitude; float num2 = 49f; float num3 = 0f; if (sqrMagnitude < 25f || (this.character.sailing && sqrMagnitude < 49f)) { flag = true; num3 = 2f; } int num4 = Random.Range(6, 8); if (this.GetRow()._MeleeRangeEnd >= 5f) { num4 = Random.Range(2, 3); } if (this.character.boatNavigator) { GraphNode graphNode = this.character.NearNode((Vector3)this.lkPositionAI[num].position, true, 0, -1, 0); if (graphNode == null) { graphNode = this.lkPositionAI[num]; } this.MakePath(graphNode, 30, false, false, true, false, false, "MoveSearch"); return true; } if (this.lkPlayerAI[num].indoorID != this.character.indoorID) { this.findPathCoroutine = this.FindPath(this.lkPlayerAI[num].node, num3, num2, num4, flag, false, true, true, false, "MoveSearch"); } else { this.findPathCoroutine = this.FindPath(this.lkPositionAI[num], num3, num2, num4, flag, false, true, true, false, "MoveSearch"); } base.StartCoroutine(this.findPathCoroutine); return true; } // Token: 0x060001D9 RID: 473 RVA: 0x0002838F File Offset: 0x0002658F public bool HasSpellRequirements(Library.Abilities abilityRow) { bool flag = this.stayOutOfRange; return true; } // Token: 0x060001DA RID: 474 RVA: 0x0002839C File Offset: 0x0002659C public bool TryToCharm() { int summonsCount = Links.x.GetSummonsCount(0); if (Random.Range(0, 3 + summonsCount) != 0) { return false; } this.factionCharacters.Clear(); if (!this.orderedTargets) { this.OrderTargets(); } int count = this.lkPlayerTemp.Count; int num = 0; if (Random.Range(0, 3) == 0) { num = 2; } float num2 = this.character.stats.Charming("Shroom", false) - (float)summonsCount + (float)num; float num3 = this.character.stats.Charming("Forest", false) - (float)summonsCount + (float)num; float num4 = this.character.stats.Charming("Fish", false) - (float)summonsCount + (float)num; for (int i = 0; i < count; i++) { if (this.lkPlayerAI.Count == 0) { string[] array = new string[5]; int num5 = 0; Character character = this.character; array[num5] = ((character != null) ? character.ToString() : null); array[1] = " last known player lists don't match "; array[2] = this.lkPlayerAI.Count.ToString(); array[3] = " "; array[4] = this.lkPlayerTemp.Count.ToString(); Debug.Log(string.Concat(array)); } else { int num6 = this.lkPlayerTemp[i]; if (num6 < this.lkPlayerAI.Count && num6 > -1) { Character character2 = this.lkPlayerAI[num6]; if (this.CanAttack(character2) && this.lkBoolAI[num6] && character2.stats) { string race = character2.stats.race; if (race.Contains("Shroom") || race.Contains("Fish") || race.Contains("Forest")) { float num7 = character2.stats.CharmResistance(false, (float)character2.stats.HealthCurrent()); bool flag = false; if (race.Contains("Shroom") && num2 >= num7) { flag = true; } if (race.Contains("Forest") && num3 >= num7) { flag = true; } if (race.Contains("Fish") && num4 >= num7) { flag = true; } if (flag) { this.factionCharacters.Add(character2); } } } } } } if (this.debugging) { this.str.Append("\nTrying to charm, found "); this.str.Append(this.factionCharacters.Count); this.str.Append(" options"); } if (this.factionCharacters.Count <= 0) { return false; } int num8 = -1; float num9 = float.PositiveInfinity; for (int j = 0; j < this.factionCharacters.Count; j++) { float sqrMagnitude = (this.character.currentPosition - this.factionCharacters[j].currentPosition).sqrMagnitude; if (sqrMagnitude < num9) { num9 = sqrMagnitude; num8 = j; } } if (this.debugging) { this.str.Append("\nFound charm target: "); this.str.Append(this.factionCharacters[num8]); this.str.Append(", health is "); this.str.Append((float)this.factionCharacters[num8].stats.HealthCurrent() / (float)this.factionCharacters[num8].stats.HealthMax()); } float num10 = (float)this.factionCharacters[num8].stats.HealthCurrent() / (float)this.factionCharacters[num8].stats.HealthMax(); if ((num9 > 400f || num10 > 0.5f) && Random.Range(0, 2) == 0) { num8 = -1; if (this.debugging) { this.str.Append("\nFailed random roll"); } } if (num8 > -1) { Character character3 = this.factionCharacters[num8]; string text = "Charm" + character3.stats.race; if (text == "CharmShroom") { text += "er"; } this.actions.AddTarget(character3); if (this.debugging) { this.str.Append("\nFound charm target: "); this.str.Append(text); this.str.Append(" targeting "); this.str.Append(character3); } if (this.quipDebugging) { this.character.StartQuip(text); } this.FinishFindingAction("Charm", character3); this.actions.RemoveAbility(); if (this.debugging) { this.str.Append("\nAdding ability: "); this.str.Append(text); } this.character.actions.StartAction("Charm"); this.findingAction = false; return true; } return false; } // Token: 0x060001DB RID: 475 RVA: 0x000288A0 File Offset: 0x00026AA0 public bool TryToCastSpell(int attemptNumber, int nextDoSomethingNumber) { bool flag = true; if (this.character.party && !this.character.stats.HasSpellbook()) { flag = false; } if (flag) { float num = (float)(this.character.stats.SpiritCurrent() / this.character.stats.SpiritMax()); int num2 = this.ActionsSinceLastSpell(); bool flag2 = false; this.hasGoodWeapon = false; if (num < 0.5f) { int num3 = 3; if (this.HasSpiritPotion()) { num3 = 2; } if (Random.Range(0, num3) == 0) { flag = false; } } if (flag && this.canMeleeRangeAttack) { if (this.character.stats.formationGroup == 2 || this.character.stats.formationGroup == 5 || this.character.stats.formationGroup == 8) { if (this.earlyActions < 3) { flag2 = true; } } else if (this.earlyActions < 5) { flag2 = true; } if (num2 < 2 && !flag2 && attemptNumber == 1) { flag = false; } if (this.hasAlternativeWeapons && flag && !flag2 && attemptNumber == 1 && num2 < 3 && (this.rangeWeaponIndex > -1 || this.meleeWeaponIndex > -1) && (this.rangeWeaponSkill >= 60f || this.meleeWeaponSkill >= 60f) && Random.Range(0, 2) == 0) { this.hasGoodWeapon = true; flag = false; } } if (this.character.npc && Records.x.banquetIsle && this.character.stats.magicPointsBase > 0) { flag = true; } if (!flag && this.debugging) { this.str.Append(string.Concat(new string[] { "\nNot casting because [early combat] ", flag2.ToString(), " ", this.earlyActions.ToString(), " [actions since last cast] ", num2.ToString(), " [good weapon] ", this.hasGoodWeapon.ToString(), " [spirit] ", num.ToString() })); } if (!this.canMeleeRangeAttack) { flag = true; } } if (flag) { bool flag3 = false; int num4 = Random.Range(0, 2); int num5 = 2; int num6 = 3; int num7 = 3; if (num4 == 0) { num5 = 2; num6 = 1; } if (num4 == 1) { num5 = 1; num6 = 2; } return this.LookForSpells(num7, num5, num6, attemptNumber, nextDoSomethingNumber, flag3); } if (!flag) { if (nextDoSomethingNumber == 4) { this.DoSomething4(); } else if (nextDoSomethingNumber == 6) { this.DoSomething6(); } else { this.Skip(); } } return false; } // Token: 0x060001DC RID: 476 RVA: 0x00028B0C File Offset: 0x00026D0C private bool LookForSpells(int firstTactic, int secondTactic, int thirdTactic, int attemptNumber, int nextDoSomethingNumber, bool switched) { bool flag = true; int num = 1; bool flag2 = false; if (this.character.stats.defendingCharacter && this.character.stats.defendingCharacter.IsSentient() && (this.character.stats.defendingCharacter.currentPosition - this.character.currentPosition).sqrMagnitude < 2500f) { flag2 = true; } for (int i = 0; i < 3; i++) { if (flag) { if (i == 0) { num = firstTactic; } if (i == 1) { num = secondTactic; } if (i == 2) { num = thirdTactic; } int count = this.abilityNames.Count; this.bestIndexes.Clear(); this.allIndexes.Clear(); int num2 = -1; for (int j = 0; j < count; j++) { if (this.abilityReady[j]) { Library.Abilities abilities = this.abilityRows[j]; if (abilities._IsSpell) { int targetsFaction = abilities._TargetsFaction; if ((targetsFaction != 6 && targetsFaction != 8 && targetsFaction != 5) || num == 3) { } if (targetsFaction != 3 || num == 1) { } if ((targetsFaction != 4 && targetsFaction != 7 && targetsFaction != 8) || num == 2) { } bool flag3 = true; if (abilities._AINotes == "Summons") { if (this.character.sailing) { flag3 = false; } if (abilities._Name.Contains("Find")) { flag3 = false; } } if (flag2 && !Links.x.library.GetEffectRow(this.abilityNames[j])._IsBuff) { flag3 = false; } if (abilities._AINotes == "NoAI" && this.character.party) { flag3 = false; } if (flag3) { float num3 = 0f; float num4 = 0f; if (!this.character.npc) { num3 = this.character.stats.PaganHitChance(false, abilities._MainSkill); float num5; num4 = this.character.stats.SpellDifficulty(this.uniqueNames[j], out num5); } if (this.debugging) { this.str.Append("\nChecking spell "); this.str.Append(this.uniqueNames[j]); this.str.Append(" hc "); this.str.Append(num3); this.str.Append(" v. "); this.str.Append(num4); } if (num3 >= num4 || this.character.npc) { if (this.debugging) { this.str.Append("\nAdding spell "); this.str.Append(this.uniqueNames[j]); this.str.Append(" to "); } if (this.character.npc) { if (this.earlyActions < 3) { if (j == 0) { this.bestIndexes.Add(j); break; } this.allIndexes.Add(j); } else { this.allIndexes.Add(j); } } else if (this.character.stats.IsFavoriteSpell(this.uniqueNames[j])) { this.bestIndexes.Add(j); if (this.debugging) { this.str.Append(" best"); } } else { this.allIndexes.Add(j); if (this.debugging) { this.str.Append(" all"); } } } } } } } if (this.debugging) { this.str.Append("\nSpell best indexes count: "); this.str.Append(this.bestIndexes.Count); this.str.Append("\nSpell all indexes count: "); this.str.Append(this.allIndexes.Count); } if (this.bestIndexes.Count > 0) { if (this.bestIndexes.Count == 1) { num2 = this.bestIndexes[0]; } else { int num6 = Random.Range(0, this.bestIndexes.Count); num2 = this.bestIndexes[num6]; } } if (num2 == -1) { if (this.debugging && num2 > -1) { this.str.Append("\nFound best index but rolled for random instead"); } if (this.debugging && num2 == -1) { this.str.Append("\nNo best index but rolled for random instead"); } if (this.allIndexes.Count > 0) { if (this.allIndexes.Count == 1) { num2 = this.allIndexes[0]; } else { int num7 = Random.Range(0, this.allIndexes.Count); num2 = this.allIndexes[num7]; } } } if (this.debugging && num2 > -1) { this.str.Append("\nFound spell: " + this.abilityNames[num2]); } if (num2 > -1) { bool flag4 = false; bool flag5 = false; Library.Abilities abilities2 = this.abilityRows[num2]; if (abilities2._AINotes == "Summons") { flag4 = true; } if (abilities2._RadiusCenter != "Mouse") { flag5 = true; } Library.Effects effectRow = Links.x.library.GetEffectRow(this.abilityNames[num2]); bool isBuff = effectRow._IsBuff; int num8 = 1; Vector4 abilityLevel = this.character.stats.GetAbilityLevel(num2); Library.Pagan pagan = this.paganRows[num2]; if (pagan._Slider1 == "Radius") { num8 = (int)abilityLevel.x; } else if (pagan._Slider2 == "Radius") { num8 = (int)abilityLevel.y; } else if (pagan._Slider3 == "Radius") { num8 = (int)abilityLevel.z; } this.factionCharacters.Clear(); this.factionClump.Clear(); this.GetPosition(this.character); this.GetLastTarget(); Character character = null; bool flag6 = false; int count2 = this.characters.Count; float num9 = this.character.stats.SpellRadius(pagan) * this.character.stats.SpellRadius(pagan); bool flag7 = false; if (abilities2._AINotes.Contains("Ailment") || abilities2._Name.Contains("Ailment")) { flag7 = true; } bool flag8 = false; if (abilities2._AINotes.Contains("PartyBuff")) { flag8 = true; } for (int k = 0; k < count2; k++) { Character character2 = this.characters[k]; if (character2 && !flag6 && !character2.inactive && character2.visible == 1 && !character2.dead && (!character2.stunned || (character2.stunned && this.character.stats.ShouldStun(character2))) && !character2.isBoro && !character2.summoned) { if (this.debugging) { this.str.Append("\nCheck spell target: "); this.str.Append(character2); } if (((!this.CanAttack(character2) && isBuff) || (this.CanAttack(character2) && !isBuff && !character2.summoned)) && (character2.currentPosition - this.character.currentPosition).sqrMagnitude < num9) { bool flag9 = true; bool flag10 = false; if (flag9 && character2.stats.HasEffect(effectRow._Name)) { flag10 = true; } if (!flag10) { character = character2; bool flag11 = true; if (!isBuff) { int num10 = this.lkPlayerAI.IndexOf(character2); flag11 = num10 != -1 && this.lkBoolAI[num10]; } else if (this.character.npc) { flag11 = character2.HasSomeoneInSight(); } if (flag11) { if (flag4 || flag5) { flag6 = true; } if (flag7) { if (character2.stats.HasAilment()) { this.factionCharacters.Add(character2); } } else if (flag8) { if (!character2.stats.HasEffect(effectRow._Name)) { this.factionCharacters.Add(character2); } } else { this.factionCharacters.Add(character2); } if (this.debugging) { StringFast stringFast = this.str; string text = "\nTargets added: "; Character character3 = character2; stringFast.Append(text + ((character3 != null) ? character3.ToString() : null)); } } } } } } if (this.factionCharacters.Count > 1 && (flag4 || flag5)) { if (abilities2._AINotes.Contains("PartyBuff")) { int num11 = -1; for (int l = 0; l < this.factionCharacters.Count; l++) { if (this.factionCharacters[l] != this.character) { num11 = l; } } if (num11 > -1) { character = this.factionCharacters[num11]; } else { character = this.factionCharacters[Random.Range(0, this.factionCharacters.Count)]; } } else if (abilities2._AINotes.Contains("Self") && this.factionCharacters.Contains(this.character)) { character = this.character; } else { character = this.factionCharacters[Random.Range(0, this.factionCharacters.Count)]; } } if (this.character.stats.defendingCharacter && isBuff && this.character.stats.defendingCharacter.IsSentient()) { character = this.character.stats.defendingCharacter; } bool flag12 = false; if (this.character.party && (abilities2._TargetsFaction == 7 || abilities2._TargetsFaction == 6)) { flag12 = true; } int num12 = 0; int count3 = this.factionCharacters.Count; int count4 = this.currentTileEffects.Count; int num13 = -1; int num14 = 6; if (count3 > 0 && !flag4 && !flag5) { int count5 = this.characters.Count; float num15 = ((float)num8 * Records.x.nodeSize + 0.1f) * ((float)num8 * Records.x.nodeSize + 0.1f); float num16 = ((float)num8 * Records.x.nodeSize + 2f) * ((float)num8 * Records.x.nodeSize + 2f); if (this.debugging) { this.str.Append("\nEffect radius: " + (Records.x.nodeSize * (float)num8).ToString()); } if (this.debugging) { this.str.Append("\nFaction characters count: " + this.factionCharacters.Count.ToString()); } for (int m = 0; m < count3; m++) { int num17 = 1; int num18 = 0; Character character4 = this.factionCharacters[m]; if (character4 && character4.node != null) { Vector3 vector = character4.currentPosition; GraphNode node = character4.node; if (character4.moving) { vector = (Vector3)character4.GetPathNode(num14).position; } bool flag13 = false; for (int n = 0; n < count4; n++) { if (this.currentTileEffects[n].source != this.character) { float num19 = this.SubtractVectors(vector, this.currentTileEffects[n].mainPosition).sqrMagnitude; if (num19 < num15) { flag13 = true; } } } if (flag13) { if (this.debugging) { this.str.Append("\nToo close to existing effect"); } num17 = 0; } else { for (int num20 = 0; num20 < count3; num20++) { if (num20 != m) { float num19 = this.SubtractVectors(vector, this.factionCharacters[num20].currentPosition).sqrMagnitude; if (num19 <= num15) { num17++; } } } } if (num17 > 0 && flag12) { for (int num21 = 0; num21 < count5; num21++) { if (num21 < this.characters.Count) { Character character2 = this.characters[num21]; if (!character2.inactive && character2.hasActions && !character2.dead && (!character2.stunned || (character2.stunned && this.character.stats.ShouldStun(character2))) && !character2.isBoro && num18 == 0 && ((this.CanAttack(character2) && isBuff) || (!this.CanAttack(character2) && !isBuff))) { float num19 = this.SubtractVectors(vector, character2.currentPosition).sqrMagnitude; if (this.debugging) { this.str.Append("\nCheck friendly fire: "); this.str.Append(character2); this.str.Append(", distance is: "); this.str.Append(num19); this.str.Append(", max is: "); this.str.Append(num16); } if (num19 <= num16) { num18++; if (this.debugging) { this.str.Append("\nFound friend in estimated radius: "); this.str.Append(character2.stats.GetName()); this.str.Append(" for targeting: "); this.str.Append(character4.stats.GetName()); } } } } } } if (num18 > 0) { num17 = 0; } if (this.debugging) { this.str.Append("\nClump count: "); this.str.Append(num17); this.str.Append(" for targeting: "); this.str.Append(character4.stats.GetName()); } this.factionClump.Add(num17); } } for (int num22 = 0; num22 < this.factionCharacters.Count; num22++) { if (num22 < this.factionClump.Count && this.factionClump[num22] > num12 && ((this.factionClump[num22] > 0 && !isBuff) || (this.factionClump[num22] >= 0 && isBuff))) { num12 = this.factionClump[num22]; Character character5 = this.factionCharacters[num22]; num13 = num22; } } if (num13 > -1) { if (this.debugging) { this.str.Append("\nLargest area spell clump is around: "); this.str.Append(this.factionCharacters[num13]); this.str.Append(" at "); this.str.Append(this.factionCharacters[num13].currentPosition); } } else if (this.debugging) { this.str.Append("\nNo area spell clumps found"); } } else if (this.debugging && !flag5 && !flag4) { this.str.Append("\nNo possible targets found for spell"); } if (num13 > -1 || ((flag4 || flag5) && character)) { GraphNode graphNode; if (flag4 || flag5) { graphNode = character.node; } else { character = this.factionCharacters[num13]; graphNode = character.node; if (character.moving) { graphNode = character.GetPathNode(num14); } } if (graphNode != null && this.findingAction) { if (!flag5) { if (this.character.npc && this.character.creatures.creatures.point && (this.character.creatures.creatures.point.transform.position - this.character.currentPosition).sqrMagnitude < 2500f) { GraphNode graphNode2 = this.character.creatures.NearNode(this.character.creatures.creatures.point.transform.position); if (graphNode2 != null) { graphNode = graphNode2; } } if (this.quipDebugging) { this.character.StartQuip(this.abilityNames[num2]); } this.FinishFindingAction("Spell", character); this.actions.RemoveAbility(); this.actions.ClearTargetCharacters(); this.actions.spellNode = graphNode; this.actions.spellIndex = num2; this.character.actions.paganRow = this.paganRows[num2]; this.actions.Ability(this.abilityNames[num2], this.uniqueNames[num2], false, true); this.actions.CastSpell(null, true, graphNode, Vector3.zero, false, false); this.findingAction = false; } else { if (this.debugging) { this.str.Append("\nSingle target spell found "); this.str.Append(this.abilityNames[num2]); this.str.Append(" "); this.str.Append(character); } if (this.quipDebugging) { this.character.StartQuip(this.abilityNames[num2]); } this.FinishFindingAction("Spell", character); this.actions.RemoveAbility(); this.actions.ClearTargetCharacters(); this.actions.AddTarget(character); this.actions.spellNode = graphNode; this.actions.spellIndex = num2; this.character.actions.paganRow = this.paganRows[num2]; this.actions.Ability(this.abilityNames[num2], this.uniqueNames[num2], false, true); this.actions.CastSpell(character, true, graphNode, Vector3.zero, true, false); this.findingAction = false; } flag = false; } else { if (this.debugging) { this.str.Append("\nArea spell check failed because node was not found"); } flag = true; } } else { flag = true; } } } } if (flag) { if (switched) { this.SwitchWeapons(); } if (nextDoSomethingNumber == 4) { return false; } if (nextDoSomethingNumber == 6) { this.DoSomething6(); } else { this.Skip(); } } return flag; } // Token: 0x060001DD RID: 477 RVA: 0x00029E24 File Offset: 0x00028024 public int NearbyCrowd(float radius, Vector3 center, bool lookForEnemies, out Character targetCharacter) { int count = this.lkPlayerAI.Count; Character character = null; this.factionCharacters.Clear(); this.factionClump.Clear(); targetCharacter = null; for (int i = 0; i < count; i++) { Character character2 = this.lkPlayerAI[i]; if ((this.CanAttack(character2) && lookForEnemies) || (!lookForEnemies && !this.CanAttack(character2))) { float num = (radius * Records.x.nodeSize + this.character.attackRadius + character2.attackRadius) * (radius * Records.x.nodeSize + this.character.attackRadius + this.character.attackRadius + character2.attackRadius); if (this.SubtractVectors((Vector3)this.lkPositionAI[i].position, center).sqrMagnitude <= num && !Physics.Linecast(this.character.raycastPosition, character2.AddVectorY(this.GetPosition(character2), 2f), Links.x.sightBlockers)) { this.factionCharacters.Add(character2); } } } int count2 = this.factionCharacters.Count; int num2 = -1; if (count2 <= 0) { return 0; } float num3 = Records.x.nodeSize * radius * (Records.x.nodeSize * radius); for (int j = 0; j < count2; j++) { int num4 = 0; Character character3 = this.factionCharacters[j]; for (int k = 0; k < count2; k++) { if (k != j && this.SubtractVectors(character3.currentPosition, this.factionCharacters[k].currentPosition).sqrMagnitude <= num3) { num4++; } } this.factionClump.Add(num4); } int num5 = 0; for (int l = 0; l < this.factionCharacters.Count; l++) { if (this.factionClump[l] > num5) { num5 = this.factionClump[l]; num2 = l; } } if (num2 > -1) { character = this.factionCharacters[num2]; } if (character && num5 >= 1) { targetCharacter = character; return num5; } return 0; } // Token: 0x060001DE RID: 478 RVA: 0x0002A06C File Offset: 0x0002826C public Character NearbyAttackingEnemy() { int count = this.characters.Count; for (int i = 0; i < this.characters.Count; i++) { Character character = this.characters[i]; if (character && !character.inactive && character.hasActions && this.CanAttack(character) && !character.inRecovery && character != this.character && character.IsAttacking(character.body.stateInfo.shortNameHash) && character.actions.DamageTargets(this.character) && character.invRow1._MeleeRangeEnd < 5f) { float num = 0f; float num2 = 0f; float num3 = 0f; this.GetDistances(character, this.character, out num, out num2, out num3, false, false); if (this.SubtractVectors(character.currentPosition, this.character.currentPosition).sqrMagnitude <= num2 && !Physics.Linecast(this.character.raycastPosition, character.AddVectorY(this.GetPosition(character), 3f), Links.x.sightBlockers)) { return character; } } } return null; } // Token: 0x060001DF RID: 479 RVA: 0x0002A1C0 File Offset: 0x000283C0 public Character EnemyToGuardFrom() { int count = this.characters.Count; Character character = null; float num = 625f; for (int i = 0; i < this.characters.Count; i++) { Character character2 = this.characters[i]; if (character2 && !character2.inactive && character2.hasActions && this.CanAttack(character2) && character2 != this.character) { float sqrMagnitude = this.SubtractVectors(character2.currentPosition, this.character.currentPosition).sqrMagnitude; if (sqrMagnitude <= num && !Physics.Linecast(this.character.raycastPosition, character2.AddVectorY(this.GetPosition(character2), 3f), Links.x.sightBlockers)) { num = sqrMagnitude; character = character2; } } } return character; } // Token: 0x060001E0 RID: 480 RVA: 0x0002A2A0 File Offset: 0x000284A0 public Vector3 SpecialAttackInBound(out bool dodgeSideways) { int count = this.lkPlayer.Count; dodgeSideways = false; for (int i = 0; i < this.lkPlayer.Count; i++) { Character character = this.lkPlayer[i]; if (character && character.InSpecialAttack() && this.CanAttack(character) && character != this.character) { bool flag = false; Vector3 vector; if (character.SpecialAttackTypeNearby(out vector, this.character, out flag)) { dodgeSideways = flag; return vector; } } } return Vector3.zero; } // Token: 0x060001E1 RID: 481 RVA: 0x0002A328 File Offset: 0x00028528 public Character NearbyAttackingProjectileCharacter() { int count = this.projectiles.Count; for (int i = 0; i < count; i++) { Projectile projectile = this.projectiles[i]; if (projectile.target == this.character && !Physics.Linecast(this.character.raycastPosition, projectile.item.position, Links.x.sightBlockers)) { return projectile.action.character; } } return null; } // Token: 0x060001E2 RID: 482 RVA: 0x0002A3A8 File Offset: 0x000285A8 public Projectile NearbyAttackingProjectile() { int count = this.projectiles.Count; for (int i = 0; i < count; i++) { Projectile projectile = this.projectiles[i]; if (projectile.target == this.character && !Physics.Linecast(this.character.raycastPosition, projectile.item.position, Links.x.sightBlockers)) { return projectile; } } return null; } // Token: 0x060001E3 RID: 483 RVA: 0x0002A420 File Offset: 0x00028620 public bool IsPointAwayFromEnemies(Vector3 center, bool mustBeInBackRow, bool mustHaveRangeWeapon) { if ((this.character.stats.formationGroup >= 7 && mustBeInBackRow) || !mustBeInBackRow) { bool flag = false; if (mustHaveRangeWeapon) { flag = this.GetRow()._MeleeRangeEnd >= 5f; if (this.character.vipFollow) { flag = true; } } if (flag || !mustHaveRangeWeapon) { if (!this.character.hasActions) { return true; } for (int i = 0; i < this.lkPlayerAI.Count; i++) { Character character = this.lkPlayerAI[i]; if (!character.interactiveObject && !character.stats.pinned && this.CanAttack(character)) { float num = character.invRow1._MeleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + character.attackRadius + 5f; if (num > 10f) { num = 10f; } if (this.SubtractVectors((Vector3)this.lkPositionAI[i].position, center).sqrMagnitude <= num * num) { return false; } } } } } return true; } // Token: 0x060001E4 RID: 484 RVA: 0x0002A54C File Offset: 0x0002874C public bool IsPointAwayFromEnemiesExcept(Vector3 center, bool mustBeInBackRow, bool mustHaveRangeWeapon, Character c) { if ((this.character.stats.formationGroup >= 7 && mustBeInBackRow) || !mustBeInBackRow) { bool flag = false; if (mustHaveRangeWeapon) { flag = this.GetRow()._MeleeRangeEnd >= 5f; if (this.character.vipFollow) { flag = true; } } if (flag || !mustHaveRangeWeapon) { if (!this.character.hasActions) { return true; } for (int i = 0; i < this.lkPlayerAI.Count; i++) { Character character = this.lkPlayerAI[i]; if (!character.interactiveObject && !character.stats.pinned && character != c && this.CanAttack(character)) { float num = character.invRow1._MeleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + character.attackRadius + 5f; if (num > 10f) { num = 10f; } if (this.SubtractVectors((Vector3)this.lkPositionAI[i].position, center).sqrMagnitude <= num * num) { return false; } } } } } return true; } // Token: 0x060001E5 RID: 485 RVA: 0x0002A684 File Offset: 0x00028884 public void LookForKitingPlace(int num) { if (this.character.stats.Stuck() <= 0 && (num >= 3 || this.kitingCount < 2 || !this.character.npc)) { if (!this.character.npc && Links.x.PartyMembersAlive() == 1) { float num2 = (float)this.character.stats.HealthCurrent() / (float)this.character.stats.HealthMax(); if (num == 1 && num2 < 0.3f && Random.Range(0, 2) == 0) { this.DoSomething2(); return; } } if (this.debugging) { this.str.Append("\nTrying kiting num "); this.str.Append(num); } this.kitingCoroutine = this.Kiting(num); base.StartCoroutine(this.kitingCoroutine); return; } if (this.debugging) { this.str.Append("\nNot kiting because already kited too many times."); } this.kitingCount = 0; if (num == 1) { this.DoSomething2(); return; } if (num == 2) { this.DoSomething5(); return; } this.Skip(); } // Token: 0x060001E6 RID: 486 RVA: 0x0002A795 File Offset: 0x00028995 private IEnumerator Kiting(int num) { bool foundHidingPlace = false; GraphNode hidingNode = null; GraphNode backupNode = null; this.factionCharacters.Clear(); Vector3 center = this.GetPosition(this.character); bool runningFromTarget = false; if (this.hasNearbyAttackingEnemy || this.hasNearbyProjectile) { runningFromTarget = true; } if (this.character.party) { runningFromTarget = false; } float healthPercent = (float)this.character.stats.HealthCurrent() / (float)this.character.stats.HealthMax(); this.noKiting = false; if (!runningFromTarget) { for (int j = 0; j < this.lkPlayerAI.Count; j++) { Character character = this.lkPlayerAI[j]; if (character && character.IsSentient() && !character.interactiveObject && this.CanAttack(character)) { bool flag = true; bool flag2 = true; if (character.invRow1 != null && character.invRow1._MeleeRangeEnd >= 5f) { flag = false; } if (character.altInvRow1 != null && character.altInvRow1._MeleeRangeEnd >= 5f) { flag2 = false; } float num2 = 12f; if (flag && flag2) { float num3 = character.invRow1._MeleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + character.attackRadius + num2 * Records.x.nodeSize; float num4 = this.SubtractVectors((Vector3)this.lkPositionAI[j].position, center).sqrMagnitude; if (num4 <= num3 * num3) { this.factionCharacters.Add(character); } } else { this.factionCharacters.Add(character); } } } } if (this.debugging && !runningFromTarget) { this.str.Append("\nKiting nodes faction count: "); this.str.Append(this.factionCharacters.Count); this.str.Append(", runningFromTarget "); this.str.Append(runningFromTarget); } if ((this.factionCharacters.Count > 0 || runningFromTarget) && Links.x.gaia.pathfindingReady) { bool lowHealth = false; if (healthPercent < 0.2f) { lowHealth = true; } float num5 = 11f; if (num == 2) { num5 = 8f; } if (runningFromTarget) { num5 = 6f; } ConstantPath constPath = ConstantPath.ConstructFast(this.character.node, Records.x.GetConstantPathRadius((int)num5), null); int environment = 1; if (this.character.sailing) { environment = 2; } this.SetNodeConstraint(null, false, false, 0, environment, 0); this.nodeConstraint.constrainWalkability = false; constPath.nnConstraint = this.nodeConstraint; AstarPath.StartPath(constPath, false); yield return base.StartCoroutine(constPath.WaitForPath()); constPath.Claim(this); this.allNodes = constPath.allNodes; this.targetingNodes.Clear(); this.kitingNodes.Clear(); int x = this.allNodes.Count; float num6 = 16f; if (runningFromTarget) { num6 = 9f; } this.SetNodeConstraint(this.character, true, false, 0, environment, this.checkCircleID); for (int k = x - 1; k >= 0; k--) { float sqrMagnitude = this.SubtractVectors((Vector3)this.allNodes[k].position, (Vector3)this.character.node.position).sqrMagnitude; if (sqrMagnitude >= num6 && sqrMagnitude <= 225f && this.nodeConstraint.Suitable(this.allNodes[k])) { if (this.character.inCircle) { if (this.InCircle(this.allNodes[k], true)) { this.targetingNodes.Add(this.allNodes[k]); } } else if (this.PartyInRange((Vector3)this.allNodes[k].position)) { this.targetingNodes.Add(this.allNodes[k]); } } } constPath.Release(this, false); int c = this.factionCharacters.Count; x = this.targetingNodes.Count; Vector3 vector = Vector3.zero; bool flag3 = false; if (runningFromTarget) { if (this.hasNearbyAttackingEnemy) { vector = this.hasNearbyAttackingEnemy.currentPosition; } if (this.hasNearbyProjectile) { vector = this.hasNearbyProjectile.item.position; flag3 = true; } } Vector3 vector2 = Quaternion.LookRotation(vector - center) * Vector3.forward; for (int l = x - 1; l >= 0; l--) { if (lowHealth || runningFromTarget) { GraphNode graphNode = this.targetingNodes[l]; bool flag4 = true; if (runningFromTarget) { Vector3 vector3 = center - (Vector3)graphNode.position; float num7 = Vector3.Dot(vector2, vector3); flag4 = num7 > 0.25f || (flag3 && num7 < -0.5f); } else if (lowHealth) { for (int m = 0; m < c; m++) { if (flag4 && !Physics.Linecast(this.factionCharacters[m].raycastPosition, this.AddVectorY((Vector3)graphNode.position, 3f), Links.x.sightBlockers)) { flag4 = false; } } } if (flag4) { this.kitingNodes.Add(graphNode); } } } int characterRadiusDesired = 30; if (this.kitingNodes.Count > 0 && (lowHealth || runningFromTarget)) { int selected = -1; int num8; for (int i = 0; i < this.kitingNodes.Count; i = num8 + 1) { if (selected == -1) { GraphNode waypoint = this.kitingNodes[i]; ABPath p = ABPath.ConstructFast(this.character.node, waypoint, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); bool flag5 = false; if (!p.error) { flag5 = true; } else if (this.astarDebugging) { Debug.Log("No kiting path to " + ((Vector3)this.kitingNodes[i].position).ToString()); } if (flag5) { this.tempPath = p.path; if (this.tempPath.Count <= characterRadiusDesired) { bool flag6 = true; if (this.character.inCircle) { foreach (GraphNode graphNode2 in this.tempPath) { if (flag6 && !this.InCircle(graphNode2, true)) { flag6 = false; } } } if (flag6) { selected = i; hidingNode = waypoint; foundHidingPlace = true; if (this.debugging) { this.str.Append("\nKiting: found path to node out of sight "); this.str.Append((Vector3)hidingNode.position); } } } } p.Release(this, false); waypoint = null; p = null; } num8 = i; } } if (!foundHidingPlace) { this.kitingNodes.Clear(); Vector3 vector4 = Vector3.zero; for (int n = 0; n < x; n++) { GraphNode graphNode = this.targetingNodes[n]; vector4 = (Vector3)graphNode.position; if (lowHealth || this.CanTargetFromPosition(vector4, lowHealth)) { bool flag7 = true; for (int num9 = 0; num9 < c; num9++) { if (flag7) { Character character = this.factionCharacters[num9]; float num3 = character.invRow1._MeleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + character.attackRadius + 2f; float num10 = num3 * num3; float num4 = this.SubtractVectors(character.currentPosition, vector4).sqrMagnitude; if (num4 <= num10) { flag7 = false; } } } if (flag7) { int count = this.kitingNodes.Count; if (count > 1) { this.kitingNodes.Insert(Random.Range(0, count - 1), graphNode); } else { this.kitingNodes.Add(graphNode); } } } } if (this.kitingNodes.Count == 0) { for (int num11 = 0; num11 < x; num11++) { GraphNode graphNode = this.targetingNodes[num11]; vector4 = (Vector3)graphNode.position; bool flag8 = true; if (lowHealth || this.CanTargetFromPosition(vector4, lowHealth)) { for (int num12 = 0; num12 < c; num12++) { Character character = this.factionCharacters[num12]; if (flag8 && character) { float num3 = character.invRow1._MeleeRangeEnd * Records.x.nodeSize + this.character.attackRadius + character.attackRadius + 2f; float num10 = num3 * num3; float num4 = this.SubtractVectors(character.currentPosition, vector4).sqrMagnitude; if (num4 <= num10) { flag8 = false; } } } if (flag8) { int count2 = this.kitingNodes.Count; if (count2 > 1) { this.kitingNodes.Insert(Random.Range(0, count2 - 1), graphNode); } else { this.kitingNodes.Add(graphNode); } } } } } if (this.debugging) { this.str.Append("\nKiting nodes found out of range: "); this.str.Append(this.kitingNodes.Count); this.str.Append(" targeting nodes found: "); this.str.Append(this.targetingNodes.Count); } if (this.kitingNodes.Count != this.targetingNodes.Count && this.kitingNodes.Count < 5) { for (int num13 = 0; num13 < 5; num13++) { float num14 = float.PositiveInfinity; int num15 = -1; for (int num16 = 0; num16 < x; num16++) { GraphNode graphNode = this.targetingNodes[num16]; vector4 = (Vector3)graphNode.position; bool flag9 = false; if (!lowHealth && !this.CanTargetFromPosition(vector4, lowHealth)) { flag9 = true; } if (!this.kitingNodes.Contains(graphNode)) { float num17 = 0f; for (int num18 = 0; num18 < c; num18++) { Character character = this.factionCharacters[num18]; float sqrMagnitude2 = this.SubtractVectors(this.GetPosition(character), vector4).sqrMagnitude; float num4 = this.SubtractVectors(this.GetPosition(character), this.GetPosition(this.character)).sqrMagnitude; if (sqrMagnitude2 > num4) { num17 += sqrMagnitude2; } } if (num17 > num14 && !flag9) { num14 = num17; num15 = num16; } } } if (num15 > -1) { this.kitingNodes.Add(this.targetingNodes[num15]); } } } if (this.debugging) { this.str.Append("\nKiting nodes found total: "); this.str.Append(this.kitingNodes.Count); } if (this.kitingNodes.Count > 0) { int selected = -1; int num8; for (int i = 0; i < this.kitingNodes.Count; i = num8 + 1) { if (selected == -1) { GraphNode waypoint = this.kitingNodes[i]; ABPath p = ABPath.ConstructFast(this.character.node, waypoint, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); bool flag10 = false; if (!p.error) { flag10 = true; } if (flag10) { bool flag11 = true; if (this.character.inCircle) { this.tempPath = p.path; foreach (GraphNode graphNode3 in this.tempPath) { if (flag11 && !this.InCircle(graphNode3, true)) { flag11 = false; } } } if (flag11) { selected = i; hidingNode = waypoint; foundHidingPlace = true; if (this.debugging) { this.str.Append("\nKiting: found path to node farthest away "); this.str.Append((Vector3)hidingNode.position); } } } p.Release(this, false); waypoint = null; p = null; } num8 = i; } } } constPath = null; } if (!foundHidingPlace && backupNode != null) { foundHidingPlace = true; hidingNode = backupNode; } if (foundHidingPlace) { this.kitingCount++; if (this.quipDebugging) { if (runningFromTarget) { this.character.StartQuip("Dodging"); } else { this.character.StartQuip("Kiting"); } } else if (!this.character.npc && healthPercent < 0.2f) { this.character.StartQuip("Scared"); } if (this.debugging) { this.str.Append("\nFound hiding place "); this.str.Append((Vector3)hidingNode.position); } Character nearestEnemy = this.GetNearestEnemy(this.character.currentPosition); this.character.MoveBackEmpty(); if (nearestEnemy) { this.SetMoveBack(nearestEnemy, (Vector3)hidingNode.position); } this.MakePath(hidingNode, 20, false, false, false, false, true, "MoveKite"); if (this.lkPlayerAI.Count > 0) { this.character.lookTarget = this.lkPlayerAI[Random.Range(0, this.lkPlayerAI.Count)]; } } if (!foundHidingPlace) { this.noKiting = true; if (num == 1) { this.DoSomething2(); } else if (num == 2) { this.DoSomething4(); } else if (this.character.party && (Random.Range(0, 10) == 0 || this.character.stats.formationGroup >= 7)) { this.Skip(); } else { this.Skip(); } } yield break; } // Token: 0x060001E7 RID: 487 RVA: 0x0002A7AC File Offset: 0x000289AC private void SetMoveBack(Character enemy, Vector3 pt) { Vector3 vector = Quaternion.LookRotation(enemy.currentPosition - this.character.currentPosition) * Vector3.forward; Vector3 vector2 = Vector3.Normalize(pt - this.character.currentPosition); if (Vector3.Dot(vector, vector2) < 0f) { this.character.SetMoveBack(enemy); } } // Token: 0x060001E8 RID: 488 RVA: 0x0002A810 File Offset: 0x00028A10 private bool CanTargetFromPosition(Vector3 position, bool lowHealth) { if (lowHealth) { return true; } if (!this.canMeleeRangeAttack) { return true; } if (!this.orderedTargets) { this.OrderTargets(); } int count = this.lkPlayerTemp.Count; float num = 0f; float num2 = 0f; float num3 = 0f; for (int i = 0; i < count; i++) { if (this.lkPlayerAI.Count != 0 && this.lkPlayerTemp[i] < this.lkPlayerAI.Count) { int num4 = this.lkPlayerTemp[i]; Character character = this.lkPlayerAI[num4]; if (this.CanAttack(character) && this.lkBoolAI[num4]) { this.GetPosition(character); if (!this.lkBoolAI[num4]) { (Vector3)this.lkPositionAI[num4].position; } num = 0f; num2 = 0f; num3 = 0f; this.GetDistances(this.character, character, out num, out num3, out num2, false, false); float sqrMagnitude = this.SubtractVectors(this.GetPosition(character), position).sqrMagnitude; if (sqrMagnitude <= num3 && sqrMagnitude >= num2 && !this.CheckSight(position, this.GetPosition(character), false)) { return true; } } } } return false; } // Token: 0x060001E9 RID: 489 RVA: 0x0002A972 File Offset: 0x00028B72 public void LookForFriend(bool revive) { this.friendCoroutine = this.Friend(revive); base.StartCoroutine(this.friendCoroutine); } // Token: 0x060001EA RID: 490 RVA: 0x0002A98E File Offset: 0x00028B8E private IEnumerator Friend(bool revive) { bool foundFriend = false; Character target = null; GraphNode moveToNode = null; this.factionCharacters.Clear(); Vector3 position = this.GetPosition(this.character); float giveItemRange = 1.5f; int hasHealthItem = -1; if (!revive) { this.character.HasHealthItem(); } int count = this.characters.Count; if (!revive) { for (int j = 0; j < count; j++) { target = this.characters[j]; if (target && !target.inactive && target.visible == 1 && target != this.character && target.IsSentient() && target.hasActions) { bool flag = false; if (this.character.npc && target.npc && this.character.stats.IsTargetAnEnemy(target.stats.allegiance)) { flag = true; } if (((!flag && target.npc && this.character.npc) || (!this.character.npc && !target.npc)) && target.node != null) { float num = (float)this.character.stats.HealthCurrent() / (float)this.character.stats.HealthMax(); bool flag2 = false; if (num <= 0.3f || flag2) { float num2 = giveItemRange * Records.x.nodeSize + this.character.attackRadius + target.attackRadius + 20f; if (this.character.inFriendGroup) { num2 = 6f; } float num3 = num2 * num2; float num4 = this.SubtractVectors(this.GetPosition(target), position).sqrMagnitude; if (num4 <= num3 && this.IsPointAwayFromEnemies(target.currentPosition, true, false)) { this.factionCharacters.Add(target); } } } } } } else { float num5 = float.PositiveInfinity; Character character = null; for (int k = 0; k < this.party.Count; k++) { if (this.party[k] && this.party[k].dead && this.party[k].party && this.IsPointAwayFromEnemies(this.party[k].currentPosition, true, true)) { float sqrMagnitude = (this.party[k].currentPosition - this.character.currentPosition).sqrMagnitude; if (sqrMagnitude < num5) { num5 = sqrMagnitude; character = this.party[k]; } } } if (character) { this.factionCharacters.Add(character); } } if (this.debugging) { this.str.Append("\nLooking for friends to help: count is "); this.str.Append(this.factionCharacters.Count); } bool needsPath = false; bool inRange = false; bool givingItem = false; Character itemTarget = null; int num7; for (int i = 0; i < this.factionCharacters.Count; i = num7 + 1) { target = this.factionCharacters[i]; if (!foundFriend) { float num2 = giveItemRange * Records.x.nodeSize + this.character.attackRadius + target.attackRadius; float num3 = num2 * num2; float num4 = this.SubtractVectors(this.GetPosition(target), this.GetPosition(this.character)).sqrMagnitude; if (this.debugging) { this.str.Append("\nFriend distance is "); this.str.Append(num4); this.str.Append(", max is "); this.str.Append(num3); this.str.Append(", "); this.str.Append(target); } if (num4 <= num3) { givingItem = true; needsPath = false; itemTarget = target; inRange = true; foundFriend = true; } else if (!this.character.sailing) { GraphNode graphNode = this.character.NearNode(target.currentPosition, true, 0, -1, 0); if (graphNode != null) { ABPath p = ABPath.ConstructFast(this.character.node, graphNode, null); p.nnConstraint = this.nodeConstraint; AstarPath.StartPath(p, false); yield return base.StartCoroutine(p.WaitForPath()); p.Claim(this); bool flag3 = false; if (!p.error) { flag3 = true; } if (flag3) { this.tempPath = p.path; GraphNode graphNode2 = null; int num6 = 0; bool flag4 = true; for (int l = 0; l < this.tempPath.Count; l++) { if (this.tempPath[l] != this.character.node) { graphNode2 = this.tempPath[l]; num6++; } if (flag4 && this.character.inCircle && !this.InCircle(this.tempPath[l], true)) { flag4 = false; } } if (flag4) { num2 = giveItemRange * Records.x.nodeSize + this.character.attackRadius + target.attackRadius; num3 = num2 * num2; num4 = this.SubtractVectors(this.GetPosition(target), (Vector3)graphNode2.position).sqrMagnitude; inRange = num4 <= num3 || revive; moveToNode = graphNode2; needsPath = true; itemTarget = target; givingItem = true; foundFriend = true; } } p.Release(this, false); p = null; } } } num7 = i; } if (foundFriend && this.findingAction) { if (this.debugging) { this.str.Append("\nFound friend to help, looking for path: "); this.str.Append(needsPath); this.str.Append(", item is "); this.str.Append(hasHealthItem); this.str.Append(", giving item: "); this.str.Append(givingItem); } if (needsPath) { this.actions.giveCharacter = itemTarget; this.actions.givingItem = inRange; this.actions.givingItemID = hasHealthItem; this.actions.AddTarget(itemTarget); this.MakePath(moveToNode, 30, false, false, true, false, false, "MoveFriend"); if (this.quipDebugging) { this.character.StartQuip("Giving item"); } } else if (givingItem && this.findingAction) { this.FinishFindingAction("GiveItem", this.character); this.actions.AddTarget(itemTarget); this.actions.giveCharacter = itemTarget; this.actions.givingItem = true; this.actions.givingItemID = hasHealthItem; this.actions.StartAction("Use"); if (this.quipDebugging) { this.character.StartQuip("Giving item"); } this.findingAction = false; } else { this.Skip(); } } else if (!revive) { this.DoSomething3(); } else { this.DoSomething6(); } yield break; } // Token: 0x060001EB RID: 491 RVA: 0x0002A9A4 File Offset: 0x00028BA4 public bool LookForHealthItem(float healthPercent) { if (!this.findingAction) { return false; } if (this.findingAction) { if (this.debugging) { this.str.Append("\nLooking for health item and skill, item is " + this.character.HasHealthItem().ToString()); } int num = this.character.HasHealthItem(); if (this.debugging) { this.str.Append("\n"); this.str.Append("Using health item " + num.ToString()); } if (num > 0 && this.findingAction) { this.FinishFindingAction("Item", this.character); this.actions.usingItem = true; this.actions.usingItemID = num; this.actions.StartAction("Use"); if (this.quipDebugging) { this.character.StartQuip("Heal with item"); } this.findingAction = false; return true; } } return false; } // Token: 0x060001EC RID: 492 RVA: 0x0002AAA0 File Offset: 0x00028CA0 public bool UsingBuff(int buffIndex) { if (!this.findingAction) { return false; } int num = -1; if (this.character.npc && this.character.stats.canCastSpells) { num = this.character.BuffItemID("Spirit"); if (this.debugging) { this.str.Append("\nLow spirit, found item at "); this.str.Append(num); } } if (num == -1 && buffIndex > -1) { num = this.character.GetInvNum(buffIndex); } if (num > -1) { this.actions.AddEffectFromItem(num); this.character.RemoveItem(num, 1); this.actions.EndTurn(false); if (this.quipDebugging) { this.character.StartQuip("Buff Item"); } this.FinishFindingAction("Buff", this.character); this.TriggerTimeline(this.actions.GetActionSpeed("Use"), false); this.findingAction = false; if (this.character.npc) { this.character.HasBuffItem(); } return true; } return false; } // Token: 0x060001ED RID: 493 RVA: 0x0002ABB4 File Offset: 0x00028DB4 public void PartyResurrection(Character t) { this.resurrectCorout = this.PartyResurrect(t); base.StartCoroutine(this.resurrectCorout); } // Token: 0x060001EE RID: 494 RVA: 0x0002ABD0 File Offset: 0x00028DD0 private IEnumerator PartyResurrect(Character t) { this.busy = true; if (this.character.timelineIcon) { this.character.timelineIcon.Clear(); } this.pinnedTarget = t; float timeToLerp = 50f; float percentage = 0f; float startTime = Links.x.gameplay.seconds; bool gotHit = false; this.character.SetStagger((int)timeToLerp); int startHitCount = this.character.stats.hitCount; while (percentage < 1f && !gotHit) { percentage = (Links.x.gameplay.seconds - startTime) / timeToLerp; if (!this.character.IsSentient()) { gotHit = true; } if (this.character.stats.hitCount > startHitCount) { gotHit = true; } if (this.character.evading) { gotHit = true; } if (this.character.moving) { gotHit = true; } if (!t.dead) { gotHit = true; } if (t.mainSelected) { bool flag = false; if (Links.x.mk) { if (Input.GetKey(Links.x.gameplay.keyControl.GetHotkey("Left")) || Input.GetKey(Links.x.gameplay.keyControl.GetHotkey("Right")) || Input.GetKey(Links.x.gameplay.keyControl.GetHotkey("Up")) || Input.GetKey(Links.x.gameplay.keyControl.GetHotkey("Down"))) { flag = true; } if (Input.GetMouseButtonDown(0)) { flag = true; } } else if (Links.x.joy && Links.x.fellowship.move.magnitude > 0.3f) { flag = true; } gotHit = flag; } yield return null; } if (!gotHit && t.dead) { int num = Mathf.RoundToInt((float)t.stats.characterRow._Life / 2f + Random.Range(1f, (float)t.stats.characterRow._Life / 2f)); t.PartyResurrect(num); } this.EndResurrect(); yield break; } // Token: 0x060001EF RID: 495 RVA: 0x0002ABE8 File Offset: 0x00028DE8 private void EndResurrect() { this.busy = false; this.pinnedTarget = null; this.character.SetStagger(0); if (this.actions) { this.actions.canEndAttackTime = true; if (this.character.hasActions) { this.actions.EndAttackTime(0f); this.actions.EndTurn(true); } } this.resurrectCorout = null; } // Token: 0x060001F0 RID: 496 RVA: 0x0002AC58 File Offset: 0x00028E58 public void SkipFromDodge() { this.findingAction = true; this.findingActionTime = Links.x.gameplay.seconds; this.Skip(); } // Token: 0x060001F1 RID: 497 RVA: 0x0002AC7C File Offset: 0x00028E7C public void Skip() { if (!this.findingAction) { return; } if (this.debugging) { this.str.Append("\nSkip"); } if (this.character.party) { this.character.portrait.QueueIcon(false); } this.FinishFindingAction("Skip", null); this.TriggerTimeline(Random.Range(0.15f, 0.4f), false); if (this.quipDebugging) { this.character.StartQuip("Skip"); } this.findingAction = false; } // Token: 0x060001F2 RID: 498 RVA: 0x0002AD0C File Offset: 0x00028F0C public void SkipMedium() { if (!this.findingAction) { return; } if (this.debugging) { this.str.Append("\nSkip"); } if (this.character.party) { this.character.portrait.QueueIcon(false); } this.FinishFindingAction("Skip", null); this.TriggerTimeline(1f, false); if (this.quipDebugging) { this.character.StartQuip("Skip"); } this.findingAction = false; } // Token: 0x060001F3 RID: 499 RVA: 0x0002AD90 File Offset: 0x00028F90 public void InventorySkip(float t) { } // Token: 0x060001F4 RID: 500 RVA: 0x0002AD94 File Offset: 0x00028F94 public void SkipWatch() { if (!this.findingAction) { return; } if (this.debugging) { this.str.Append("\nSkip Watch"); } this.FinishFindingAction("Skip", null); this.TriggerTimeline(0.75f, false); if (this.character.party) { this.character.portrait.QueueIcon(false); } if (this.quipDebugging) { this.character.StartQuip("Skip"); } this.findingAction = false; } // Token: 0x060001F5 RID: 501 RVA: 0x0002AE18 File Offset: 0x00029018 public void SkipLong() { if (!this.findingAction) { return; } if (this.debugging) { this.str.Append("\nSkip Long"); } this.FinishFindingAction("Skip", null); this.TriggerTimeline(20f, false); if (this.character.party) { this.character.portrait.QueueIcon(false); } if (this.quipDebugging) { this.character.StartQuip("Skip"); } this.findingAction = false; } // Token: 0x060001F6 RID: 502 RVA: 0x0002AE9C File Offset: 0x0002909C public void SwitchItem(int newWeaponID, int swapID) { if (!this.findingAction) { return; } this.switchedWeapon = true; this.character.SwitchItem(swapID * 2, newWeaponID * 2); this.actions.currentHand = 0; } // Token: 0x060001F7 RID: 503 RVA: 0x0002AECC File Offset: 0x000290CC public int ActionsSinceLastShout() { int num = 0; int num2 = this.tactics.Count - 1; bool flag = false; for (int i = num2; i >= 0; i--) { if (!flag) { if (this.tactics[i].Contains("Word")) { break; } num++; } } return num; } // Token: 0x060001F8 RID: 504 RVA: 0x0002AF1C File Offset: 0x0002911C public int ActionsSinceLastWander() { int num = 0; int num2 = this.tactics.Count - 1; bool flag = false; for (int i = num2; i >= 0; i--) { if (!flag) { if (this.tactics[i].Contains("Attack") || this.tactics[i].Contains("Spell") || this.tactics[i].Contains("Target") || this.tactics[i].Contains("Song")) { num++; } else if (this.tactics[i].Contains("Wander")) { flag = true; break; } } } if (!flag) { return -1; } return num; } // Token: 0x060001F9 RID: 505 RVA: 0x0002AFDC File Offset: 0x000291DC public int ActionsSinceLastSpell() { int num = 0; int num2 = this.tactics.Count - 1; bool flag = false; for (int i = num2; i >= 0; i--) { if (!flag) { if (this.tactics[i].Contains("Attack") || this.tactics[i].Contains("Target")) { num++; } else if (this.tactics[i].Contains("Spell")) { break; } } } return num; } // Token: 0x060001FA RID: 506 RVA: 0x0002B05C File Offset: 0x0002925C public int ActionsSinceLastSong() { int num = 0; int num2 = this.tactics.Count - 1; bool flag = false; for (int i = num2; i >= 0; i--) { if (!flag) { if (this.tactics[i].Contains("Attack") || this.tactics[i].Contains("Spell")) { num++; } else if (this.tactics[i].Contains("Song")) { flag = true; break; } } } if (!flag) { return -1; } return num; } // Token: 0x060001FB RID: 507 RVA: 0x0002B0E0 File Offset: 0x000292E0 public int ActionTacticsCount() { if (this.tactics.Count < 20) { int num = 0; int count = this.tactics.Count; for (int i = 0; i < count; i++) { string text = this.tactics[i]; if (!text.Contains("Move") && !text.Contains("Skip")) { num++; } } return num; } return 20; } // Token: 0x060001FC RID: 508 RVA: 0x0002B14C File Offset: 0x0002934C public Vector3 SubtractVectors(Vector3 a, Vector3 b) { Vector3 vector; vector.x = a.x - b.x; vector.y = a.y - b.y; vector.z = a.z - b.z; return vector; } // Token: 0x060001FD RID: 509 RVA: 0x0002B198 File Offset: 0x00029398 public Vector3 SubtractVectorsNoY(Vector3 a, Vector3 b) { Vector3 vector; vector.x = a.x - b.x; vector.y = 0f; vector.z = a.z - b.z; return vector; } // Token: 0x060001FE RID: 510 RVA: 0x0002B1DC File Offset: 0x000293DC public Vector3 AddVectorY(Vector3 a, float b) { Vector3 vector; vector.x = a.x; vector.y = a.y + b; vector.z = a.z; return vector; } // Token: 0x060001FF RID: 511 RVA: 0x0002B214 File Offset: 0x00029414 private void GetLists() { this.lkPlayer = this.character.lkPlayer; this.lkPosition = this.character.lkPosition; this.lkAction = this.character.lkAction; this.lkBool = this.character.lkBool; this.characters = Links.x.diorama.characters; this.abilityNames = this.character.stats.abilityNames; this.abilityLevels = this.character.stats.abilityLevels; this.abilityReady = this.character.stats.abilityReady; this.abilityRows = this.character.stats.abilityRows; this.uniqueNames = this.character.stats.uniqueNames; } // Token: 0x06000200 RID: 512 RVA: 0x0002B2E8 File Offset: 0x000294E8 public int GetSeenCount() { return this.lkPlayerAI.Count; } // Token: 0x06000201 RID: 513 RVA: 0x0002B2F8 File Offset: 0x000294F8 private void GetLastKnownLists() { int num = this.lkPlayer.Count; for (int i = 0; i < this.lkPlayer.Count; i++) { bool flag = false; bool flag2 = false; if (!this.lkPlayer[i]) { flag2 = true; } if (!flag2 && this.lkAction[i].Contains("Done")) { flag2 = true; } if (!flag2) { if (this.lkPlayer[i].interactiveObject && (!this.actions.selectedTargetInteractive || this.actions.selectedTargetInteractive != this.lkPlayer[i].gameObject) && (!this.actions.selectedAITargetInteractive || this.actions.selectedAITargetInteractive != this.lkPlayer[i].gameObject)) { flag2 = true; } if (this.lkPlayer[i].stunned || this.lkPlayer[i].dead) { flag2 = true; } } if (flag2) { this.lkPlayer.RemoveAt(i); this.lkBool.RemoveAt(i); this.lkAction.RemoveAt(i); this.lkPosition.RemoveAt(i); flag = true; } else if (this.lkPlayer[i].dead || (this.lkPlayer[i].stunned && this.character.stats.ShouldStun(this.lkPlayer[i]))) { this.lkPlayer.RemoveAt(i); this.lkBool.RemoveAt(i); this.lkAction.RemoveAt(i); this.lkPosition.RemoveAt(i); flag = true; } if (flag) { i--; } } num = this.lkPlayer.Count; int num2 = -1; if (this.character.node != null) { num2 = (int)this.character.node.Area; } for (int j = 0; j < num; j++) { if (this.lkAction[j].Contains("Search")) { bool flag3 = false; if (this.lkAction[j].Contains("Search4") || this.lkPosition[j] == null) { this.lkAction[j] = "SearchDone"; flag3 = true; } if (!flag3 && this.lkAction[j].Contains("Search3")) { if ((long)num2 != (long)((ulong)this.lkPosition[j].Area)) { this.lkAction[j] = "Search4"; flag3 = true; } else { this.lkAction[j] = "SearchDone"; flag3 = true; } } if (!flag3 && this.lkAction[j].Contains("Search2")) { if ((long)num2 != (long)((ulong)this.lkPosition[j].Area) || this.character.sailing || !this.character.stats.animal) { this.lkAction[j] = "Search3"; flag3 = true; } else { this.lkAction[j] = "SearchDone"; flag3 = true; } } if (!flag3 && this.lkAction[j].Contains("Search1")) { if ((long)num2 != (long)((ulong)this.lkPosition[j].Area) || this.character.sailing || !this.character.stats.animal) { this.lkAction[j] = "Search2"; flag3 = true; } else { this.lkAction[j] = "SearchDone"; flag3 = true; } } if (!flag3 && this.lkAction[j] == "Search") { this.lkAction[j] = "Search1"; } } else if (!this.lkBool[j]) { this.lkAction[j] = "Search"; } } this.lkPlayerAI.Clear(); this.lkPositionAI.Clear(); this.lkBoolAI.Clear(); for (int k = 0; k < this.lkPlayer.Count; k++) { if (this.lkPlayer[k] && !this.lkAction.Contains("Done") && !this.lkPlayer[k].dead && (!this.lkPlayer[k].stunned || (this.lkPlayer[k].stunned && (Records.x.kill || !this.lkPlayer[k].npc))) && !this.lkPlayer[k].missing) { if (this.lkPosition[k] != null) { if (this.CanAttack(this.lkPlayer[k]) && (this.PartyInRange(this.lkPlayer[k].currentPosition) || this.character.npc)) { this.lkPlayerAI.Add(this.lkPlayer[k]); this.lkPositionAI.Add(this.lkPosition[k]); this.lkBoolAI.Add(this.lkBool[k]); } } else if (Records.x.astarDebugging) { Character character = this.character; string text = ((character != null) ? character.ToString() : null); string text2 = " trying to add lkps, no node for "; Character character2 = this.lkPlayer[k]; Debug.Log(text + text2 + ((character2 != null) ? character2.ToString() : null)); } } } } // Token: 0x06000202 RID: 514 RVA: 0x0002B8EC File Offset: 0x00029AEC public bool HasEnemies() { if (this.character.node == null) { return false; } for (int i = 0; i < this.lkPlayer.Count; i++) { Character character = this.lkPlayer[i]; GraphNode graphNode = this.lkPosition[i]; string text = this.lkAction[i]; if (character && !text.Contains("Done") && !character.dead && (!character.stunned || (character.stunned && (Records.x.kill || !character.npc))) && !character.missing && graphNode != null && this.CanAttack(character) && graphNode.GraphIndex == this.character.node.GraphIndex && character.indoorID == this.character.indoorID && (this.character.currentPosition - (Vector3)graphNode.position).sqrMagnitude < 1600f) { return true; } } return false; } // Token: 0x06000203 RID: 515 RVA: 0x0002BA0A File Offset: 0x00029C0A public Vector3 GetPosition(Character target) { return target.currentPosition; } // Token: 0x06000204 RID: 516 RVA: 0x0002BA14 File Offset: 0x00029C14 public void SetNodeConstraint(Character pathfinder, bool constrainTags, bool useBoatSize, int uniqueID, int environment, int checkCircle) { this.nodeConstraint.constrainWalkability = true; this.nodeConstraint.walkable = true; this.nodeConstraint.constrainPenalty = 0; this.nodeConstraint.constrainTags = constrainTags; this.nodeConstraint.checkCircleID = checkCircle; if (!pathfinder) { this.nodeConstraint.passID = 0; this.nodeConstraint.passID2 = 0; this.nodeConstraint.checkConnections = 0; this.nodeConstraint.constrainPenalty = 1; } else { this.nodeConstraint.passID = pathfinder.nodeStationaryID; this.nodeConstraint.passID2 = pathfinder.nodeMovingID; this.nodeConstraint.checkConnections = pathfinder.ConnectionNumber(); if (pathfinder.npc) { this.nodeConstraint.constrainPenalty = 1; } else { this.nodeConstraint.constrainPenalty = 2; } } if (useBoatSize && this.character.boat) { this.nodeConstraint.passID = this.character.boat.nodeStationaryID; this.nodeConstraint.passID2 = this.character.boat.nodeMovingID; this.nodeConstraint.checkConnections = this.character.boat.ConnectionNumber(); } this.nodeConstraint.constrainToEnvironment = environment; if (this.character.ghost) { this.nodeConstraint.constrainToEnvironment = 0; } this.nodeConstraint.constrainDistance = false; this.nodeConstraint.constrainToArea = -1; } // Token: 0x06000205 RID: 517 RVA: 0x0002BB91 File Offset: 0x00029D91 public Library.Inventory GetRow() { return this.character.invRow1; } // Token: 0x06000206 RID: 518 RVA: 0x0002BB9E File Offset: 0x00029D9E public int GetHand() { return 0; } // Token: 0x06000207 RID: 519 RVA: 0x0002BBA4 File Offset: 0x00029DA4 public void GetDistances(Character pathfinder, Character target, out float bestDistance, out float maxDistance, out float minDistance, bool hasPowerDraw, bool accountForBoat) { Library.Inventory inventory = pathfinder.invRow1; if (pathfinder == this.character) { inventory = this.GetRow(); } float num = inventory._MeleeRangeEnd; if (hasPowerDraw) { num += 30f; } float num2 = 0f; if (accountForBoat) { num2 = 3f; } bestDistance = (num * Records.x.nodeSize + pathfinder.attackRadius + target.attackRadius - 1f - num2) * (num * Records.x.nodeSize + pathfinder.attackRadius + target.attackRadius - 1f - num2); maxDistance = (num * Records.x.nodeSize + pathfinder.attackRadius + target.attackRadius - num2) * (num * Records.x.nodeSize + pathfinder.attackRadius + target.attackRadius - num2); minDistance = (inventory._MeleeRangeStart * Records.x.nodeSize + pathfinder.attackRadius + target.attackRadius + num2) * (inventory._MeleeRangeStart * Records.x.nodeSize + pathfinder.attackRadius + target.attackRadius + num2); if (pathfinder.radius > 1f) { bestDistance = minDistance; } if (!accountForBoat && (minDistance == maxDistance || inventory._MeleeRangeStart == 0f)) { minDistance = 0f; } if (this.character.stats.hasCustomAI && this.character.stats.customAI.Contains("MushroomWall")) { bestDistance = minDistance; } if (bestDistance < minDistance) { bestDistance = minDistance; } } // Token: 0x06000208 RID: 520 RVA: 0x0002BD2C File Offset: 0x00029F2C public Character GetLastTarget() { for (int i = 0; i < this.targets.Count; i++) { Character character = this.targets[i]; if (character) { return character; } if (i > 4) { return null; } } return null; } // Token: 0x06000209 RID: 521 RVA: 0x0002BD70 File Offset: 0x00029F70 public bool HasSpiritPotion() { int invNum = this.character.GetInvNum(14); int invNum2 = this.character.GetInvNum(26); int invNum3 = this.character.GetInvNum(28); return (invNum > 1 && Links.x.library.GetInvRow(invNum)._Effect.Contains("Spirit")) || (invNum2 > 1 && Links.x.library.GetInvRow(invNum2)._Effect.Contains("Spirit")) || (invNum3 > 1 && Links.x.library.GetInvRow(invNum3)._Effect.Contains("Spirit")); } // Token: 0x0600020A RID: 522 RVA: 0x0002BE20 File Offset: 0x0002A020 public bool HasAbilityRequirements(Library.Abilities abilityRow) { if (!abilityRow._AddsToAttack) { bool flag = this.stayOutOfRange; } return abilityRow._WeaponReq == "Any" || abilityRow._WeaponReq == "" || abilityRow._WeaponReq == this.GetRow()._WeaponType || abilityRow._WeaponReq == this.GetRow()._MainSkill || (this.character.altInvRow1 != null && (abilityRow._WeaponReq == this.character.altInvRow1._WeaponType || abilityRow._WeaponReq == this.character.altInvRow1._MainSkill)) || (this.character.altInvRow2 != null && (abilityRow._WeaponReq == this.character.altInvRow2._WeaponType || abilityRow._WeaponReq == this.character.altInvRow2._MainSkill)) || (this.character.altInvRow3 != null && (abilityRow._WeaponReq == this.character.altInvRow3._WeaponType || abilityRow._WeaponReq == this.character.altInvRow3._MainSkill)); } // Token: 0x0600020B RID: 523 RVA: 0x0002BF74 File Offset: 0x0002A174 public int HasInstrument() { if (this.character.party && !this.character.stats.HasSongbook()) { return -1; } int invNum = this.character.GetInvNum(14); int invNum2 = this.character.GetInvNum(26); int invNum3 = this.character.GetInvNum(28); Library.Inventory inventory = null; Library.Inventory inventory2 = null; Library.Inventory inventory3 = null; if (invNum > 1) { inventory = Links.x.library.GetInvRow(invNum); if (inventory._MainSkill == "Pipe" || inventory._MainSkill == "Flute" || inventory._MainSkill == "Drum" || inventory._MainSkill == "Horn") { if (!this.character.npc && this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory._MainSkill)) < 50f) { inventory = null; } } else { inventory = null; } } if (invNum2 > 1) { inventory2 = Links.x.library.GetInvRow(invNum2); if (inventory2._MainSkill == "Pipe" || inventory2._MainSkill == "Flute" || inventory2._MainSkill == "Drum" || inventory2._MainSkill == "Horn") { if (!this.character.npc && this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory2._MainSkill)) < 50f) { inventory2 = null; } } else { inventory2 = null; } } if (invNum3 > 1) { inventory3 = Links.x.library.GetInvRow(invNum3); if (inventory3._MainSkill == "Pipe" || inventory3._MainSkill == "Flute" || inventory3._MainSkill == "Drum" || inventory3._MainSkill == "Horn") { if (!this.character.npc && this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory3._MainSkill)) < 50f) { inventory3 = null; } } else { inventory3 = null; } } if (inventory == null && inventory2 == null && inventory3 == null) { this.character.instrumentInUse = -1; return -1; } if (inventory != null && inventory2 == null && inventory3 == null) { this.character.instrumentInUse = 7; return 7; } if (inventory == null && inventory2 != null && inventory3 == null) { this.character.instrumentInUse = 13; return 13; } if (inventory == null && inventory2 == null && inventory3 != null) { this.character.instrumentInUse = 14; return 14; } if (Random.Range(0, 4) > 0) { float num = -1f; int num2 = -1; if (inventory != null) { num = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory._MainSkill)); num2 = 7; } if (inventory2 != null) { float skill = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory2._MainSkill)); if (skill > num) { num = skill; num2 = 13; } } if (inventory3 != null) { float skill2 = this.character.stats.GetSkill(this.character.stats.GetCombatSkillID(inventory3._MainSkill)); if (skill2 > num) { num2 = 13; } } return num2; } if (Random.Range(0, 2) == 0) { int num3 = -1; int num4 = -1; if (inventory != null) { num3 = inventory._DmgMax; num4 = 7; this.character.instrumentInUse = 7; } if (inventory2 != null && inventory2._DmgMax > num3) { num3 = inventory2._DmgMax; num4 = 13; this.character.instrumentInUse = 13; } if (inventory3 != null && inventory3._DmgMax > num3) { num3 = inventory3._DmgMax; num4 = 14; this.character.instrumentInUse = 14; } return num4; } int num5 = Random.Range(0, 3); if (num5 == 0) { if (inventory != null) { this.character.instrumentInUse = 7; return 7; } if (inventory2 != null) { this.character.instrumentInUse = 13; return 13; } if (inventory3 != null) { this.character.instrumentInUse = 14; return 14; } } if (num5 == 1) { if (inventory2 != null) { this.character.instrumentInUse = 13; return 13; } if (inventory != null) { this.character.instrumentInUse = 7; return 7; } if (inventory3 != null) { this.character.instrumentInUse = 14; return 14; } } if (num5 == 2) { if (inventory3 != null) { this.character.instrumentInUse = 14; return 14; } if (inventory2 != null) { this.character.instrumentInUse = 13; return 13; } if (inventory != null) { this.character.instrumentInUse = 7; return 7; } } return -1; } // Token: 0x0600020C RID: 524 RVA: 0x0002C42B File Offset: 0x0002A62B public void UpdateCircleTiles() { this.circleTiles = this.character.group.circleTiles; } // Token: 0x0600020D RID: 525 RVA: 0x0002C444 File Offset: 0x0002A644 private bool InCircle(GraphNode n, bool mustBeInside) { Vector3 vector = this.character.currentPosition; Vector3 vector2 = (Vector3)n.position; float num = 5f; if (mustBeInside) { num = 1.5f; } for (int i = 0; i < this.circleTiles.Count; i++) { vector = (Vector3)this.circleTiles[i].position; float num2 = vector.x - vector2.x; if (num2 < 0f) { num2 *= -1f; } if (num2 < num) { float num3 = vector.z - vector2.z; if (num3 < 0f) { num3 *= -1f; } if (num3 < num) { if (!this.character.npc) { return true; } if (this.character.group.LinkedToCenter(vector2, this.character)) { return true; } } } } return false; } // Token: 0x0400034F RID: 847 [Header("LISTS")] private List lkPlayer; // Token: 0x04000350 RID: 848 private List lkPosition; // Token: 0x04000351 RID: 849 private List lkAction; // Token: 0x04000352 RID: 850 private List lkBool; // Token: 0x04000353 RID: 851 public List lkPlayerAI = new List(); // Token: 0x04000354 RID: 852 private List lkPositionAI = new List(); // Token: 0x04000355 RID: 853 private List lkActionAI = new List(); // Token: 0x04000356 RID: 854 private List lkBoolAI = new List(); // Token: 0x04000357 RID: 855 private List lkPlayerTempDirection = new List(); // Token: 0x04000358 RID: 856 public List lkPlayerTemp = new List(); // Token: 0x04000359 RID: 857 private List abilityNames; // Token: 0x0400035A RID: 858 private List abilityLevels; // Token: 0x0400035B RID: 859 private List abilityReady; // Token: 0x0400035C RID: 860 private List uniqueNames; // Token: 0x0400035D RID: 861 public List abilityRows; // Token: 0x0400035E RID: 862 private List groundItems; // Token: 0x0400035F RID: 863 private List pickupItems = new List(); // Token: 0x04000360 RID: 864 private List pickups; // Token: 0x04000361 RID: 865 private List party; // Token: 0x04000362 RID: 866 private List characters; // Token: 0x04000363 RID: 867 private List combatCharacters; // Token: 0x04000364 RID: 868 private List diaCharacters; // Token: 0x04000365 RID: 869 private List projectiles; // Token: 0x04000366 RID: 870 private List spellDifficulties; // Token: 0x04000367 RID: 871 private List paganRows = new List(); // Token: 0x04000368 RID: 872 private List breakables = new List(); // Token: 0x04000369 RID: 873 private List breakablesOrdered = new List(); // Token: 0x0400036A RID: 874 public List targets = new List(); // Token: 0x0400036B RID: 875 public List tactics = new List(); // Token: 0x0400036C RID: 876 private List currentTileEffects; // Token: 0x0400036D RID: 877 private List bestIndexes = new List(); // Token: 0x0400036E RID: 878 private List allIndexes = new List(); // Token: 0x0400036F RID: 879 [Header("OBJECTS")] public Character character; // Token: 0x04000370 RID: 880 public Actions actions; // Token: 0x04000371 RID: 881 [Header("PATHFINDING")] private NNConstraint nodeConstraint = new NNConstraint(); // Token: 0x04000372 RID: 882 private NNConstraint interactConstraint = new NNConstraint(); // Token: 0x04000373 RID: 883 private List allNodes; // Token: 0x04000374 RID: 884 private List targetingNodes = new List(); // Token: 0x04000375 RID: 885 private List nearNodes = new List(); // Token: 0x04000376 RID: 886 private List orbitNodes = new List(); // Token: 0x04000377 RID: 887 private List specialNodes = new List(); // Token: 0x04000378 RID: 888 private List specialCharacters; // Token: 0x04000379 RID: 889 private List kitingNodes = new List(); // Token: 0x0400037A RID: 890 private List pathNodes = new List(); // Token: 0x0400037B RID: 891 private List friendNodes = new List(); // Token: 0x0400037C RID: 892 private List distanceCheckNodes = new List(); // Token: 0x0400037D RID: 893 private List nearPickups = new List(); // Token: 0x0400037E RID: 894 private List tempPath; // Token: 0x0400037F RID: 895 public List factionCharacters = new List(); // Token: 0x04000380 RID: 896 public List factionClump = new List(); // Token: 0x04000381 RID: 897 private List suitableNodes = new List(); // Token: 0x04000382 RID: 898 private List used = new List(); // Token: 0x04000383 RID: 899 private List bestNodes = new List(); // Token: 0x04000384 RID: 900 private List timedBreakables; // Token: 0x04000385 RID: 901 private List diaBreakables; // Token: 0x04000386 RID: 902 private List diaDoors; // Token: 0x04000387 RID: 903 private List diaChests; // Token: 0x04000388 RID: 904 private List circleTiles; // Token: 0x04000389 RID: 905 private int checkCircleID; // Token: 0x0400038A RID: 906 private float timeSinceTurn; // Token: 0x0400038B RID: 907 private float timeSinceSearchStarted; // Token: 0x0400038C RID: 908 [Header("AI")] public bool findingAction; // Token: 0x0400038D RID: 909 public float findingActionTime; // Token: 0x0400038E RID: 910 public bool doingMeleeAttack; // Token: 0x0400038F RID: 911 public bool needToKite; // Token: 0x04000390 RID: 912 public int rangeWeaponIndex; // Token: 0x04000391 RID: 913 public int rangeWeaponIndex2; // Token: 0x04000392 RID: 914 public int meleeWeaponIndex; // Token: 0x04000393 RID: 915 public int meleeWeaponIndex2; // Token: 0x04000394 RID: 916 private float rangeWeaponSkill; // Token: 0x04000395 RID: 917 private float meleeWeaponSkill; // Token: 0x04000396 RID: 918 private int maxCrowdRadiusFromAbilities; // Token: 0x04000397 RID: 919 private bool hasAlternativeWeapons; // Token: 0x04000398 RID: 920 private bool switchedWeapon; // Token: 0x04000399 RID: 921 private bool orderedTargets; // Token: 0x0400039A RID: 922 private bool noKiting; // Token: 0x0400039B RID: 923 private bool checkingFriendlyFire; // Token: 0x0400039C RID: 924 private bool friendlyFire; // Token: 0x0400039D RID: 925 public GraphNode jumpNode; // Token: 0x0400039E RID: 926 public Character pinnedTarget; // Token: 0x0400039F RID: 927 public string lastAction; // Token: 0x040003A0 RID: 928 public Character hitBy; // Token: 0x040003A1 RID: 929 public Character previouslyAttacked; // Token: 0x040003A2 RID: 930 private bool stayOutOfRange; // Token: 0x040003A3 RID: 931 public int actionCount; // Token: 0x040003A4 RID: 932 private Character hasNearbyAttackingEnemy; // Token: 0x040003A5 RID: 933 private Projectile hasNearbyProjectile; // Token: 0x040003A6 RID: 934 private bool canSwitchWeapons; // Token: 0x040003A7 RID: 935 private int kitingCount; // Token: 0x040003A8 RID: 936 private int spellMeanDifficulty; // Token: 0x040003A9 RID: 937 private int spellAvgDifficulty; // Token: 0x040003AA RID: 938 private Vector3 startingPosition; // Token: 0x040003AB RID: 939 public bool spread; // Token: 0x040003AC RID: 940 public bool busy; // Token: 0x040003AD RID: 941 public bool circleMovement; // Token: 0x040003AE RID: 942 public bool pinLow; // Token: 0x040003AF RID: 943 private bool justAttackWithLeader; // Token: 0x040003B0 RID: 944 private Character stayNearCharacter; // Token: 0x040003B1 RID: 945 private GraphNode stayNearNode; // Token: 0x040003B2 RID: 946 private Vector3 stayNearPosition; // Token: 0x040003B3 RID: 947 public bool jumping; // Token: 0x040003B4 RID: 948 public bool jumpDone; // Token: 0x040003B5 RID: 949 public bool canMeleeRangeAttack; // Token: 0x040003B6 RID: 950 private bool spreadStrong; // Token: 0x040003B7 RID: 951 private bool onlySpecialAttack; // Token: 0x040003B8 RID: 952 private bool allyIsPinning; // Token: 0x040003B9 RID: 953 private GameObject chargeLoop; // Token: 0x040003BA RID: 954 public bool hasGoodWeapon; // Token: 0x040003BB RID: 955 public bool hasGreatWeapon; // Token: 0x040003BC RID: 956 private int moveToFriendTries; // Token: 0x040003BD RID: 957 private int moveToMainTries; // Token: 0x040003BE RID: 958 private int circleMoveTries; // Token: 0x040003BF RID: 959 private Library.Inventory startWeaponRow; // Token: 0x040003C0 RID: 960 public int seenCount; // Token: 0x040003C1 RID: 961 private float lastSpecialAttack; // Token: 0x040003C2 RID: 962 private List breakies; // Token: 0x040003C3 RID: 963 [Header("MISC")] public bool debugging; // Token: 0x040003C4 RID: 964 public bool quipDebugging; // Token: 0x040003C5 RID: 965 private bool astarDebugging; // Token: 0x040003C6 RID: 966 public IEnumerator resurrectCorout; // Token: 0x040003C7 RID: 967 private IEnumerator findTargetCoroutine; // Token: 0x040003C8 RID: 968 private IEnumerator groundItemCoroutine; // Token: 0x040003C9 RID: 969 private IEnumerator pickupCoroutine; // Token: 0x040003CA RID: 970 private IEnumerator spellNodesCoroutine; // Token: 0x040003CB RID: 971 private IEnumerator friendCoroutine; // Token: 0x040003CC RID: 972 private IEnumerator kitingCoroutine; // Token: 0x040003CD RID: 973 private IEnumerator songMoveCoroutine; // Token: 0x040003CE RID: 974 private IEnumerator findPathCoroutine; // Token: 0x040003CF RID: 975 private IEnumerator spellCoroutine; // Token: 0x040003D0 RID: 976 private IEnumerator wanderCoroutine; // Token: 0x040003D1 RID: 977 private IEnumerator orbitRoutine; // Token: 0x040003D2 RID: 978 private StringFast str = new StringFast(64); // Token: 0x040003D3 RID: 979 private bool orbitRight; // Token: 0x040003D4 RID: 980 public bool runBackToFriends; // Token: 0x040003D5 RID: 981 private int earlyActions; // Token: 0x040003D6 RID: 982 public Character chargeTarget; }