Files
BepInEx/Projects/BanquetForFools/Source/Assembly-CSharp/AttackAI.cs
2025-05-21 20:40:04 +02:00

9696 lines
275 KiB
C#

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<Character>();
}
if (this.character.actions.selectedAITargetInteractive)
{
return target == this.character.actions.selectedAITargetInteractive.GetComponent<Character>();
}
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<Character>();
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<Character>();
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<Character>();
}
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<GameObject>(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<TimedBreakable>().node = this.character.node;
Links.x.cellar.AddCombatBreakable(gameObject.GetComponent<TimedBreakable>());
gameObject.GetComponent<TimedBreakable>().source = this.character;
gameObject.GetComponent<TimedBreakable>().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<Effects>();
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<Effects>();
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<Effects>();
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<Effects>();
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<BreakableActions>();
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<Character>();
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<Character> lkPlayer;
// Token: 0x04000350 RID: 848
private List<GraphNode> lkPosition;
// Token: 0x04000351 RID: 849
private List<string> lkAction;
// Token: 0x04000352 RID: 850
private List<bool> lkBool;
// Token: 0x04000353 RID: 851
public List<Character> lkPlayerAI = new List<Character>();
// Token: 0x04000354 RID: 852
private List<GraphNode> lkPositionAI = new List<GraphNode>();
// Token: 0x04000355 RID: 853
private List<string> lkActionAI = new List<string>();
// Token: 0x04000356 RID: 854
private List<bool> lkBoolAI = new List<bool>();
// Token: 0x04000357 RID: 855
private List<float> lkPlayerTempDirection = new List<float>();
// Token: 0x04000358 RID: 856
public List<int> lkPlayerTemp = new List<int>();
// Token: 0x04000359 RID: 857
private List<string> abilityNames;
// Token: 0x0400035A RID: 858
private List<Vector4> abilityLevels;
// Token: 0x0400035B RID: 859
private List<bool> abilityReady;
// Token: 0x0400035C RID: 860
private List<string> uniqueNames;
// Token: 0x0400035D RID: 861
public List<Library.Abilities> abilityRows;
// Token: 0x0400035E RID: 862
private List<Item> groundItems;
// Token: 0x0400035F RID: 863
private List<Item> pickupItems = new List<Item>();
// Token: 0x04000360 RID: 864
private List<Pickups> pickups;
// Token: 0x04000361 RID: 865
private List<Character> party;
// Token: 0x04000362 RID: 866
private List<Character> characters;
// Token: 0x04000363 RID: 867
private List<Character> combatCharacters;
// Token: 0x04000364 RID: 868
private List<Character> diaCharacters;
// Token: 0x04000365 RID: 869
private List<Projectile> projectiles;
// Token: 0x04000366 RID: 870
private List<int> spellDifficulties;
// Token: 0x04000367 RID: 871
private List<Library.Pagan> paganRows = new List<Library.Pagan>();
// Token: 0x04000368 RID: 872
private List<BreakableActions> breakables = new List<BreakableActions>();
// Token: 0x04000369 RID: 873
private List<BreakableActions> breakablesOrdered = new List<BreakableActions>();
// Token: 0x0400036A RID: 874
public List<Character> targets = new List<Character>();
// Token: 0x0400036B RID: 875
public List<string> tactics = new List<string>();
// Token: 0x0400036C RID: 876
private List<TileEffects> currentTileEffects;
// Token: 0x0400036D RID: 877
private List<int> bestIndexes = new List<int>();
// Token: 0x0400036E RID: 878
private List<int> allIndexes = new List<int>();
// 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<GraphNode> allNodes;
// Token: 0x04000374 RID: 884
private List<GraphNode> targetingNodes = new List<GraphNode>();
// Token: 0x04000375 RID: 885
private List<GraphNode> nearNodes = new List<GraphNode>();
// Token: 0x04000376 RID: 886
private List<GraphNode> orbitNodes = new List<GraphNode>();
// Token: 0x04000377 RID: 887
private List<GraphNode> specialNodes = new List<GraphNode>();
// Token: 0x04000378 RID: 888
private List<Character> specialCharacters;
// Token: 0x04000379 RID: 889
private List<GraphNode> kitingNodes = new List<GraphNode>();
// Token: 0x0400037A RID: 890
private List<GraphNode> pathNodes = new List<GraphNode>();
// Token: 0x0400037B RID: 891
private List<GraphNode> friendNodes = new List<GraphNode>();
// Token: 0x0400037C RID: 892
private List<GraphNode> distanceCheckNodes = new List<GraphNode>();
// Token: 0x0400037D RID: 893
private List<Pickups> nearPickups = new List<Pickups>();
// Token: 0x0400037E RID: 894
private List<GraphNode> tempPath;
// Token: 0x0400037F RID: 895
public List<Character> factionCharacters = new List<Character>();
// Token: 0x04000380 RID: 896
public List<int> factionClump = new List<int>();
// Token: 0x04000381 RID: 897
private List<GraphNode> suitableNodes = new List<GraphNode>();
// Token: 0x04000382 RID: 898
private List<bool> used = new List<bool>();
// Token: 0x04000383 RID: 899
private List<GraphNode> bestNodes = new List<GraphNode>();
// Token: 0x04000384 RID: 900
private List<TimedBreakable> timedBreakables;
// Token: 0x04000385 RID: 901
private List<BreakableActions> diaBreakables;
// Token: 0x04000386 RID: 902
private List<DoorActions> diaDoors;
// Token: 0x04000387 RID: 903
private List<ChestActions> diaChests;
// Token: 0x04000388 RID: 904
private List<GraphNode> 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<BreakableActions> 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;
}