public static void ResolveCollision(ref Manifold m) { var rv = m.B.Velocity - m.A.Velocity; if (float.IsNaN(m.Normal.X) || float.IsNaN(m.Normal.Y)) { return; } var velAlongNormal = Vec2.DotProduct(rv, m.Normal); if (velAlongNormal > 0) { return; } var e = Math.Min(m.A.Restitution, m.B.Restitution); var j = -(1 + e) * velAlongNormal; j = j / (m.A.IMass + m.B.IMass); var impulse = m.Normal * j; m.A.Velocity = !m.A.Locked ? m.A.Velocity - impulse * m.A.IMass : m.A.Velocity; m.B.Velocity = !m.B.Locked ? m.B.Velocity + impulse * m.B.IMass : m.B.Velocity; }
private bool IsTacticalPositionEligible(TacticalPosition tacticalPosition) { if (!this.CheckAndDetermineFormation(ref this._mainInfantry, (Func <Formation, bool>)(f => f.QuerySystem.IsInfantryFormation))) { return(false); } float num1 = this.team.QuerySystem.AveragePosition.Distance(tacticalPosition.Position.AsVec2); Vec2 vec2 = this.team.QuerySystem.AverageEnemyPosition; float num2 = vec2.Distance(this._mainInfantry.QuerySystem.AveragePosition); if ((double)num1 > 20.0 && (double)num1 > (double)num2 * 0.5) { return(false); } int countOfUnits = this._mainInfantry.CountOfUnits; if ((double)this._mainInfantry.MaximumInterval * (double)(countOfUnits - 1) + (double)this._mainInfantry.UnitDiameter * (double)countOfUnits < (double)tacticalPosition.Width) { return(false); } vec2 = this.team.QuerySystem.AverageEnemyPosition - tacticalPosition.Position.AsVec2; vec2 = vec2.Normalized(); float num3 = vec2.DotProduct(tacticalPosition.Direction); return(tacticalPosition.IsInsurmountable ? (double)Math.Abs(num3) >= 0.5 : (double)num3 >= 0.5); }
protected override void CalculateCurrentOrder() { WorldPosition medianPosition; Vec2 direction; if (this.formation.QuerySystem.ClosestEnemyFormation != null) { medianPosition = this.formation.QuerySystem.MedianPosition; medianPosition.SetVec2((double)this.formation.QuerySystem.AveragePosition.DistanceSquared(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) > 400.0 ? this.formation.QuerySystem.HighGroundCloseToForeseenBattleGround : this.formation.QuerySystem.AveragePosition); Vec2 vec2_1; if ((double)this.formation.QuerySystem.AveragePosition.DistanceSquared(this.formation.QuerySystem.HighGroundCloseToForeseenBattleGround) <= 25.0) { Vec2 vec2_2 = this.formation.Direction; vec2_2 = (double)vec2_2.DotProduct((this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized()) < 0.5 ? this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition : this.formation.Direction; vec2_1 = vec2_2.Normalized(); } else { vec2_1 = (this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - medianPosition.AsVec2).Normalized(); } direction = vec2_1; } else { direction = this.formation.Direction; medianPosition = this.formation.QuerySystem.MedianPosition; medianPosition.SetVec2(this.formation.QuerySystem.AveragePosition); } this.CurrentOrder = MovementOrder.MovementOrderMove(medianPosition); this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtDirection(direction); }
public Vec3 GetClosestPointToEscape(Vec2 position) { if (this._nodes.Count == 1) { return(this._nodes[0]); } float num1 = float.MaxValue; Vec3 vec3_1 = this._nodes[0]; for (int index = 0; index < this._nodes.Count - 1; ++index) { Vec3 node1 = this._nodes[index]; Vec3 node2 = this._nodes[index + 1]; float num2 = node1.DistanceSquared(node2); if ((double)num2 > 0.0) { float num3 = Math.Max(0.0f, Math.Min(1f, Vec2.DotProduct(position - node1.AsVec2, node2.AsVec2 - node1.AsVec2) / num2)); Vec3 vec3_2 = node1 + num3 * (node2 - node1); float num4 = vec3_2.AsVec2.DistanceSquared(position); if ((double)num1 > (double)num4) { num1 = num4; vec3_1 = vec3_2; } } else { num1 = 0.0f; vec3_1 = node1; } } return(vec3_1); }
protected override void CalculateCurrentOrder() { if (this._switchedToShieldWallRecently && !this._switchedToShieldWallTimer.Check(Mission.Current.Time) && (double)this.formation.QuerySystem.FormationDispersedness > 2.0) { WorldPosition medianPosition = this.formation.QuerySystem.MedianPosition; if (this._reformPosition.IsValid) { medianPosition.SetVec2(this._reformPosition); } else { this._reformPosition = this.formation.QuerySystem.AveragePosition + (this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized() * 5f; medianPosition.SetVec2(this._reformPosition); } this.CurrentOrder = MovementOrder.MovementOrderMove(medianPosition); } else { this._switchedToShieldWallRecently = false; bool flag = false; Vec2 vec2_1; if (this.formation.QuerySystem.ClosestEnemyFormation != null && this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation) { Vec2 vec2_2 = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition; double num1 = (double)vec2_2.Normalize(); Vec2 currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity; float num2 = currentVelocity.Normalize(); if (num1 < 30.0 && (double)num2 > 2.0 && (double)vec2_2.DotProduct(currentVelocity) > 0.5) { flag = true; WorldPosition medianPosition = this.formation.QuerySystem.MedianPosition; if (this._reformPosition.IsValid) { medianPosition.SetVec2(this._reformPosition); } else { vec2_1 = this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition; this._reformPosition = this.formation.QuerySystem.AveragePosition + vec2_1.Normalized() * 5f; medianPosition.SetVec2(this._reformPosition); } this.CurrentOrder = MovementOrder.MovementOrderMove(medianPosition); } } if (flag) { return; } this._reformPosition = Vec2.Invalid; WorldPosition position = this.formation.Team.QuerySystem.EnemyTeams.SelectMany <TeamQuerySystem, Formation>((Func <TeamQuerySystem, IEnumerable <Formation> >)(t => t.Team.FormationsIncludingSpecial)).Count <Formation>() == 1 ? this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition : this.formation.QuerySystem.Team.MedianTargetFormationPosition; vec2_1 = this.formation.QuerySystem.Team.MedianTargetFormationPosition.AsVec2 - this.formation.QuerySystem.AveragePosition; Vec2 direction = vec2_1.Normalized(); this.CurrentOrder = MovementOrder.MovementOrderMove(position); this.CurrentFacingOrder = FacingOrder.FacingOrderLookAtDirection(direction); } }
protected override void CalculateCurrentOrder() { Vec2 vec2_1; WorldPosition medianPosition; Vec2 vec2_2; WorldPosition worldPosition; if (this.formation.QuerySystem.ClosestEnemyFormation == null || this._mainFormation == null) { vec2_1 = this.formation.Direction; medianPosition = this.formation.QuerySystem.MedianPosition; medianPosition.SetVec2(this.formation.QuerySystem.AveragePosition); } else { vec2_2 = this.formation.Direction; ref Vec2 local = ref vec2_2; worldPosition = this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition; Vec2 asVec2_1 = worldPosition.AsVec2; worldPosition = this._mainFormation.QuerySystem.MedianPosition; Vec2 asVec2_2 = worldPosition.AsVec2; Vec2 v = (asVec2_1 - asVec2_2).Normalized(); Vec2 vec2_3; if ((double)local.DotProduct(v) >= 0.5) { vec2_3 = this.formation.Direction; } else { worldPosition = this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition; Vec2 asVec2_3 = worldPosition.AsVec2; worldPosition = this._mainFormation.QuerySystem.MedianPosition; Vec2 asVec2_4 = worldPosition.AsVec2; vec2_3 = asVec2_3 - asVec2_4; } vec2_1 = vec2_3.Normalized(); worldPosition = this._mainFormation.OrderPosition; Vec2 asVec2_5 = worldPosition.AsVec2; worldPosition = this._mainFormation.QuerySystem.MedianPosition; Vec2 asVec2_6 = worldPosition.AsVec2; Vec2 vec2_4 = asVec2_5 - asVec2_6; float num1 = this._mainFormation.QuerySystem.MovementSpeed * 7f; float length = vec2_4.Length; if ((double)length > 0.0) { float num2 = num1 / length; if ((double)num2 < 1.0) { vec2_4 *= num2; } } medianPosition = this._mainFormation.QuerySystem.MedianPosition; medianPosition.SetVec2(medianPosition.AsVec2 + vec2_1 * 8f + vec2_4); }
public Vec2 GetDirection(Formation f) { Vec2 vec2 = this.Direction(f); if (f.IsAIControlled && (double)vec2.DotProduct(this._previousDirection) > 0.870000004768372) { vec2 = this._previousDirection; } else { this._previousDirection = vec2; } return(vec2); }
protected override float GetAiWeight() { FormationQuerySystem querySystem = attackingFormation.QuerySystem; if (querySystem.ClosestEnemyFormation == null || querySystem.ClosestEnemyFormation.ClosestEnemyFormation == querySystem) { return(0f); } Vec2 vec = (querySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - querySystem.AveragePosition).Normalized(); Vec2 v = (querySystem.ClosestEnemyFormation.ClosestEnemyFormation.MedianPosition.AsVec2 - querySystem.ClosestEnemyFormation.MedianPosition.AsVec2).Normalized(); if (vec.DotProduct(v) > -0.5f) { return(0f); } return(1.2f); }
protected override float GetAiWeight() { FormationQuerySystem querySystem = this.formation.QuerySystem; if (querySystem.ClosestEnemyFormation == null || querySystem.ClosestEnemyFormation.ClosestEnemyFormation == querySystem) { return(0.0f); } Vec2 vec2 = (querySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - querySystem.AveragePosition).Normalized(); WorldPosition medianPosition = querySystem.ClosestEnemyFormation.ClosestEnemyFormation.MedianPosition; Vec2 asVec2_1 = medianPosition.AsVec2; medianPosition = querySystem.ClosestEnemyFormation.MedianPosition; Vec2 asVec2_2 = medianPosition.AsVec2; Vec2 v = (asVec2_1 - asVec2_2).Normalized(); return((double)vec2.DotProduct(v) > -0.5 ? 0.0f : 1.2f); }
protected override void CalculateCurrentOrder() { Vec2 vec2_1; if (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation != null && this._mainFormation != null) { Vec2 vec2_2 = (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized(); Vec2 v = (this._mainFormation.QuerySystem.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition).Normalized(); vec2_1 = (double)vec2_2.DotProduct(v) <= 0.5 ? vec2_2 : this._mainFormation.FacingOrder.GetDirection(this._mainFormation); } else { vec2_1 = this.formation.Direction; } WorldPosition medianPosition; if (this._mainFormation == null) { medianPosition = this.formation.QuerySystem.MedianPosition; medianPosition.SetVec2(this.formation.QuerySystem.AveragePosition); } else { medianPosition = this._mainFormation.QuerySystem.MedianPosition; medianPosition.SetVec2(medianPosition.AsVec2 - vec2_1 * (float)(((double)this._mainFormation.Depth + (double)this.formation.Depth) * 0.5)); } WorldPosition worldPosition = this.CurrentOrder.GetPosition(this.formation); if (worldPosition.IsValid && this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.IsRangedCavalryFormation) { Vec2 averagePosition = this.formation.QuerySystem.AveragePosition; ref Vec2 local = ref averagePosition; worldPosition = this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MedianPosition; Vec2 asVec2 = worldPosition.GetNavMeshVec3().AsVec2; if ((double)local.DistanceSquared(asVec2) < (double)this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MissileRange * (double)this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.MissileRange) { worldPosition = this.CurrentOrder.GetPosition(this.formation); if ((double)worldPosition.GetNavMeshVec3().DistanceSquared(medianPosition.GetNavMeshVec3()) < (double)this.formation.Depth * (double)this.formation.Depth) { goto label_10; } } }
public override float Distance(Vec3 pp) { var p = pp + _offset; //From http://mercury.sexy/hg_sdf/ var q = new Vec2(new Vec2(p.X, p.Z).Magnitude(), p.Y); var tip = q - new Vec2(0, _height); var mantleDir = new Vec2(_height, _radius).Normalize(); var mantle = Vec2.DotProduct(tip, mantleDir); var d = Math.Max(mantle, -q.Y); var projected = Vec2.DotProduct(tip, new Vec2(mantleDir.Y, mantleDir.X)); if (q.Y > _height && projected < 0) { d = (float)Math.Max(d, tip.Magnitude()); } if (q.X > _radius && projected > new Vec2(_height, _radius).Magnitude()) { d = (float)Math.Max(d, (q - new Vec2(_radius, 0)).Magnitude()); } return(d); }
public Vec2 GetTargetPos(Vec2 position, float distance) { Vec2 v1 = this._direction.LeftVec(); Vec2 vec2_1 = this._center + v1 * this._halfLength; Vec2 vec2_2 = this._center - v1 * this._halfLength; Vec2 vec2_3 = position - this._center; bool flag1 = (double)vec2_3.Normalized().DotProduct(this._direction) > 0.0; Vec2 vec2_4 = vec2_3.DotProduct(v1) * v1; bool flag2 = (double)vec2_4.Length < (double)this._halfLength; bool flag3 = true; Vec2 vec2_5; if (flag2) { position = this._center + vec2_4 + this._direction * (this._radius * (flag1 ? 1f : -1f)); } else { flag3 = (double)vec2_4.DotProduct(v1) > 0.0; vec2_5 = position - (flag3 ? vec2_1 : vec2_2); Vec2 vec2_6 = vec2_5.Normalized(); position = (flag3 ? vec2_1 : vec2_2) + vec2_6 * this._radius; } Vec2 vec2_7 = this._center + vec2_4; double num1 = 2.0 * Math.PI * (double)this._radius; while ((double)distance > 0.0) { if (flag2 & flag1) { vec2_5 = vec2_1 - vec2_7; double num2; if ((double)vec2_5.Length >= (double)distance) { num2 = (double)distance; } else { vec2_5 = vec2_1 - vec2_7; num2 = (double)vec2_5.Length; } float num3 = (float)num2; Vec2 vec2_6 = vec2_7; vec2_5 = vec2_1 - vec2_7; Vec2 vec2_8 = vec2_5.Normalized() * num3; position = vec2_6 + vec2_8; position += this._direction * this._radius; distance -= num3; flag2 = false; flag3 = true; } else if (!flag2 & flag3) { vec2_5 = position - vec2_1; Vec2 v2 = vec2_5.Normalized(); vec2_5 = this._direction; double num2 = Math.Acos((double)MBMath.ClampFloat(vec2_5.DotProduct(v2), -1f, 1f)); double num3 = 2.0 * Math.PI * ((double)distance / num1); double num4 = num2 + num3 < Math.PI ? num2 + num3 : Math.PI; double num5 = (num4 - num2) / Math.PI * (num1 / 2.0); Vec2 direction = this._direction; direction.RotateCCW((float)num4); position = vec2_1 + direction * this._radius; distance -= (float)num5; flag2 = true; flag1 = false; } else if (flag2) { vec2_5 = vec2_2 - vec2_7; double num2; if ((double)vec2_5.Length >= (double)distance) { num2 = (double)distance; } else { vec2_5 = vec2_2 - vec2_7; num2 = (double)vec2_5.Length; } float num3 = (float)num2; Vec2 vec2_6 = vec2_7; vec2_5 = vec2_2 - vec2_7; Vec2 vec2_8 = vec2_5.Normalized() * num3; position = vec2_6 + vec2_8; position -= this._direction * this._radius; distance -= num3; flag2 = false; flag3 = false; } else { vec2_5 = position - vec2_2; Vec2 v2 = vec2_5.Normalized(); vec2_5 = this._direction; double num2 = Math.Acos((double)MBMath.ClampFloat(vec2_5.DotProduct(v2), -1f, 1f)); double num3 = 2.0 * Math.PI * ((double)distance / num1); double num4 = num2 - num3 > 0.0 ? num2 - num3 : 0.0; double num5 = num2 - num4; double num6 = num5 / Math.PI * (num1 / 2.0); Vec2 vec2_6 = v2; vec2_6.RotateCCW((float)num5); position = vec2_2 + vec2_6 * this._radius; distance -= (float)num6; flag2 = true; flag1 = true; } } return(position); }
private int LocateAttackers(SiegeQuerySystem.RegionEnum region) { int num1 = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; foreach (Agent activeAgent in this._attackerTeam.ActiveAgents) { Vec3 position = activeAgent.Position; Vec2 vec2 = position.AsVec2 - this._leftDefenderOrigin; if ((double)vec2.Normalize() < 10.0) { ++num2; ++num1; } else { if ((double)vec2.DotProduct(this._leftToMidDir) >= 0.0 && (double)vec2.DotProduct(this._leftToMidDir.RightVec()) >= 0.0) { ++num1; } else { position = activeAgent.Position; vec2 = position.AsVec2 - this._middleDefenderOrigin; if ((double)vec2.DotProduct(this._midToLeftDir) >= 0.0 && (double)vec2.DotProduct(this._midToLeftDir.RightVec()) >= 0.0) { ++num1; } } position = activeAgent.Position; vec2 = position.AsVec2 - this._middleDefenderOrigin; if ((double)vec2.Normalize() < 10.0) { ++num4; ++num3; } else { if ((double)vec2.DotProduct(this._leftToMidDir) >= 0.0 && (double)vec2.DotProduct(this._leftToMidDir.LeftVec()) >= 0.0) { ++num3; } else { position = activeAgent.Position; vec2 = position.AsVec2 - this._rightDefenderOrigin; if ((double)vec2.DotProduct(this._rightToMidDir) >= 0.0 && (double)vec2.DotProduct(this._rightToMidDir.RightVec()) >= 0.0) { ++num3; } } position = activeAgent.Position; vec2 = position.AsVec2 - this._rightDefenderOrigin; if ((double)vec2.Normalize() < 10.0) { ++num6; ++num5; } else { if ((double)vec2.DotProduct(this._midToRightDir) >= 0.0 && (double)vec2.DotProduct(this._midToRightDir.LeftVec()) >= 0.0) { ++num5; } else { position = activeAgent.Position; vec2 = position.AsVec2 - this._rightDefenderOrigin; if ((double)vec2.DotProduct(this._rightToMidDir) >= 0.0 && (double)vec2.DotProduct(this._rightToMidDir.LeftVec()) >= 0.0) { ++num5; } } if (activeAgent.GetCurrentNavigationFaceId() % 10 == 1) { ++num7; } } } } } float time = MBCommon.GetTime(MBCommon.TimeType.Mission); this._leftRegionMemberCount.SetValue(num1, time); this._leftCloseAttackerCount.SetValue(num2, time); this._middleRegionMemberCount.SetValue(num3, time); this._middleCloseAttackerCount.SetValue(num4, time); this._rightRegionMemberCount.SetValue(num5, time); this._rightCloseAttackerCount.SetValue(num6, time); this._insideAttackerCount.SetValue(num7, time); switch (region) { case SiegeQuerySystem.RegionEnum.Left: return(num1); case SiegeQuerySystem.RegionEnum.LeftClose: return(num2); case SiegeQuerySystem.RegionEnum.Middle: return(num3); case SiegeQuerySystem.RegionEnum.MiddleClose: return(num4); case SiegeQuerySystem.RegionEnum.Right: return(num5); case SiegeQuerySystem.RegionEnum.RightClose: return(num6); case SiegeQuerySystem.RegionEnum.Inside: return(num7); default: return(0); } }
public RTSCameraAgentComponent(Agent agent) : base(agent) { for (int i = 0; i < _colors.Length; ++i) { _colors[i] = new Contour(null, false); } CurrentTargetPosition = new QueryData <WorldPosition>(() => { try { var unit = Agent; var formation = unit.Formation; if (formation == null) { return(WorldPosition.Invalid); } var targetFormation = QueryDataStore.Get(formation.TargetFormation); if (QueryLibrary.IsRangedCavalry(unit)) { var targetAgent = unit.GetTargetAgent(); if (targetAgent == null || targetAgent.Formation != formation.TargetFormation) { Vec2 unitPosition = unit.Position.AsVec2; targetAgent = targetFormation.NearestAgent(unitPosition); } return(targetAgent?.GetWorldPosition() ?? new WorldPosition()); } if (QueryLibrary.IsCavalry(unit)) { var targetAgent = unit.GetTargetAgent(); if (targetAgent == null || targetAgent.Formation != formation.TargetFormation) { Vec2 unitPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) * 0.2f + unit.Position.AsVec2 * 0.8f; targetAgent = targetFormation.NearestOfAverageOfNearestPosition(unitPosition, 7); } if (targetAgent != null) { if (targetAgent.HasMount) { return(targetAgent.GetWorldPosition()); } var targetPosition = targetAgent.GetWorldPosition(); var targetDirection = targetPosition.AsVec2 - unit.Position.AsVec2; var distance = targetDirection.Normalize(); var result = targetPosition; // new if (distance > 20) { CurrentDirection = targetDirection; result.SetVec2(targetDirection * 10 + targetPosition.AsVec2); } else if (distance > 5 && targetDirection.DotProduct(CurrentDirection) < 0) { result.SetVec2( (CurrentDirection.DotProduct(targetDirection * distance) + 50) * CurrentDirection + unit.Position.AsVec2); } else { result.SetVec2(CurrentDirection * 10 + targetPosition.AsVec2); } // old //if (distance < 3) //{ // result = unit.GetWorldPosition(); // result.SetVec2(CurrentDirection * 20 + result.AsVec2); //} //else //{ // if (distance < 20 && targetDirection.DotProduct(CurrentDirection) < 0) // { // result.SetVec2(-targetDirection * 50 + result.AsVec2); // } // else // { // CurrentDirection = targetDirection; // result.SetVec2(targetDirection * 10 + result.AsVec2); // } //} return(result.GetNavMesh() == UIntPtr.Zero || !Mission.Current.IsPositionInsideBoundaries(result.AsVec2) ? targetPosition : result); } return(WorldPosition.Invalid); } else { var targetAgent = unit.GetTargetAgent(); if (targetAgent == null || targetAgent.Formation != formation.TargetFormation) { Vec2 unitPosition = formation.GetCurrentGlobalPositionOfUnit(unit, true) * 0.2f + unit.Position.AsVec2 * 0.8f; targetAgent = targetFormation.NearestAgent(unitPosition); } return(targetAgent?.GetWorldPosition() ?? new WorldPosition()); } } catch (Exception e) { Utility.DisplayMessage(e.ToString()); } return(WorldPosition.Invalid); }, 0.2f); }
private BehaviorTacticalCharge.ChargeState CheckAndChangeState() { BehaviorTacticalCharge.ChargeState chargeState = this._chargeState; if (this.formation.QuerySystem.ClosestEnemyFormation == null) { chargeState = BehaviorTacticalCharge.ChargeState.Undetermined; } else { switch (this._chargeState) { case BehaviorTacticalCharge.ChargeState.Undetermined: if (this.formation.QuerySystem.ClosestEnemyFormation != null && (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) / (double)this.formation.QuerySystem.MovementSpeedMaximum <= 5.0)) { chargeState = BehaviorTacticalCharge.ChargeState.Charging; break; } break; case BehaviorTacticalCharge.ChargeState.Charging: if (!this.formation.QuerySystem.IsCavalryFormation && !this.formation.QuerySystem.IsRangedCavalryFormation) { if (!this.formation.QuerySystem.IsInfantryFormation || !this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation) { chargeState = BehaviorTacticalCharge.ChargeState.Charging; break; } Vec2 vec2 = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition; double num1 = (double)vec2.Normalize(); Vec2 currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity; double num2 = (double)currentVelocity.Normalize(); if (num1 / num2 <= 6.0 && (double)vec2.DotProduct(currentVelocity) > 0.5) { this._chargeState = BehaviorTacticalCharge.ChargeState.Bracing; break; } break; } if ((double)this._initialChargeDirection.DotProduct(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2 - this.formation.QuerySystem.AveragePosition) <= 0.0) { chargeState = BehaviorTacticalCharge.ChargeState.ChargingPast; break; } break; case BehaviorTacticalCharge.ChargeState.ChargingPast: if (this._chargingPastTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission)) || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) >= (double)this._desiredChargeStopDistance) { chargeState = BehaviorTacticalCharge.ChargeState.Reforming; break; } break; case BehaviorTacticalCharge.ChargeState.Reforming: if (this._reformTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission)) || (double)this.formation.QuerySystem.AveragePosition.Distance(this.formation.QuerySystem.ClosestEnemyFormation.MedianPosition.AsVec2) <= 30.0) { chargeState = BehaviorTacticalCharge.ChargeState.Charging; break; } break; case BehaviorTacticalCharge.ChargeState.Bracing: bool flag = false; if (this.formation.QuerySystem.IsInfantryFormation && this.formation.QuerySystem.ClosestEnemyFormation.IsCavalryFormation) { Vec2 vec2 = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestEnemyFormation.AveragePosition; double num1 = (double)vec2.Normalize(); Vec2 currentVelocity = this.formation.QuerySystem.ClosestEnemyFormation.CurrentVelocity; double num2 = (double)currentVelocity.Normalize(); if (num1 / num2 <= 8.0 && (double)vec2.DotProduct(currentVelocity) > 0.330000013113022) { flag = true; } } if (!flag) { this._bracePosition = Vec2.Invalid; this._chargeState = BehaviorTacticalCharge.ChargeState.Charging; break; } break; } } return(chargeState); }
static void PostfixCalculateCurrentOrder(ref Formation ___formation, BehaviorMountedSkirmish __instance, ref bool ____engaging, ref MovementOrder ____currentOrder) { WorldPosition position = ___formation.QuerySystem.MedianPosition; if (___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation == null) { position.SetVec2(___formation.QuerySystem.AveragePosition); } else { bool num = (___formation.QuerySystem.AverageAllyPosition - ___formation.Team.QuerySystem.AverageEnemyPosition).LengthSquared <= 3600f; bool engaging = ____engaging; engaging = (____engaging = (num || ((!____engaging) ? ((___formation.QuerySystem.AveragePosition - ___formation.QuerySystem.AverageAllyPosition).LengthSquared <= 3600f) : (!(___formation.QuerySystem.UnderRangedAttackRatio > ___formation.QuerySystem.MakingRangedAttackRatio) && ((!___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsCavalryFormation && !___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsRangedCavalryFormation) || (___formation.QuerySystem.AveragePosition - ___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MedianPosition.AsVec2).LengthSquared / (___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed * ___formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed) >= 16f))))); if (!____engaging) { position = new WorldPosition(Mission.Current.Scene, new Vec3(___formation.QuerySystem.AverageAllyPosition, ___formation.Team.QuerySystem.MedianPosition.GetNavMeshZ() + 100f)); } else { Vec2 vec = (___formation.QuerySystem.AveragePosition - ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.AveragePosition).Normalized().LeftVec(); FormationQuerySystem closestSignificantlyLargeEnemyFormation = ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation; float num2 = 50f + (___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation.Width + ___formation.Depth) * 0.5f; float num3 = 0f; Formation formation = ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation; for (int i = 0; i < Mission.Current.Teams.Count; i++) { Team team = Mission.Current.Teams[i]; if (!team.IsEnemyOf(___formation.Team)) { continue; } for (int j = 0; j < team.FormationsIncludingSpecialAndEmpty.Count; j++) { Formation formation2 = team.FormationsIncludingSpecialAndEmpty[j]; if (formation2.CountOfUnits > 0 && formation2.QuerySystem != closestSignificantlyLargeEnemyFormation) { Vec2 v = formation2.QuerySystem.AveragePosition - closestSignificantlyLargeEnemyFormation.AveragePosition; float num4 = v.Normalize(); if (vec.DotProduct(v) > 0.8f && num4 < num2 && num4 > num3) { num3 = num4; formation = formation2; } } } } if (___formation.QuerySystem.RangedCavalryUnitRatio > 0.95f && ___formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation == formation) { ____currentOrder = MovementOrder.MovementOrderCharge; return; } bool flag = formation.QuerySystem.IsCavalryFormation || formation.QuerySystem.IsRangedCavalryFormation; float num5 = flag ? 35f : 20f; num5 += (formation.Depth + ___formation.Width) * 0.25f; //num5 = Math.Min(num5, ___formation.QuerySystem.MissileRange - ___formation.Width * 0.5f); Ellipse ellipse = new Ellipse(formation.QuerySystem.MedianPosition.AsVec2, num5, formation.Width * 0.25f * (flag ? 1.5f : 1f), formation.Direction); position.SetVec2(ellipse.GetTargetPos(___formation.QuerySystem.AveragePosition, 20f)); } } ____currentOrder = MovementOrder.MovementOrderMove(position); }
public Vec2 GetTargetPos(Vec2 position, float distance) { Vec2 v = _direction.LeftVec(); Vec2 vec = _center + v * _halfLength; Vec2 vec2 = _center - v * _halfLength; Vec2 vec3 = position - _center; bool flag = vec3.Normalized().DotProduct(_direction) > 0f; Vec2 v2 = vec3.DotProduct(v) * v; bool flag2 = v2.Length < _halfLength; bool flag3 = true; if (flag2) { position = _center + v2 + _direction * (_radius * (float)(flag ? 1 : (-1))); } else { flag3 = (v2.DotProduct(v) > 0f); Vec2 v3 = (position - (flag3 ? vec : vec2)).Normalized(); position = (flag3 ? vec : vec2) + v3 * _radius; } Vec2 vec4 = _center + v2; double num = Math.PI * 2.0 * (double)_radius; while (distance > 0f) { if (flag2 && flag) { float num2 = ((vec - vec4).Length < distance) ? (vec - vec4).Length : distance; position = vec4 + (vec - vec4).Normalized() * num2; position += _direction * _radius; distance -= num2; flag2 = false; flag3 = true; } else if (!flag2 && flag3) { Vec2 v4 = (position - vec).Normalized(); double num3 = Math.Acos(MBMath.ClampFloat(_direction.DotProduct(v4), -1f, 1f)); double num4 = Math.PI * 2.0 * ((double)distance / num); double num5 = (num3 + num4 < Math.PI) ? (num3 + num4) : Math.PI; double num6 = (num5 - num3) / Math.PI * (num / 2.0); Vec2 direction = _direction; direction.RotateCCW((float)num5); position = vec + direction * _radius; distance -= (float)num6; flag2 = true; flag = false; } else if (flag2) { float num7 = ((vec2 - vec4).Length < distance) ? (vec2 - vec4).Length : distance; position = vec4 + (vec2 - vec4).Normalized() * num7; position -= _direction * _radius; distance -= num7; flag2 = false; flag3 = false; } else { Vec2 vec5 = (position - vec2).Normalized(); double num8 = Math.Acos(MBMath.ClampFloat(_direction.DotProduct(vec5), -1f, 1f)); double num9 = Math.PI * 2.0 * ((double)distance / num); double num10 = (num8 - num9 > 0.0) ? (num8 - num9) : 0.0; double num11 = num8 - num10; double num12 = num11 / Math.PI * (num / 2.0); Vec2 v5 = vec5; v5.RotateCCW((float)num11); position = vec2 + v5 * _radius; distance -= (float)num12; flag2 = true; flag = true; } } return(position); }
protected override void CalculateCurrentOrder() { WorldPosition position = this.formation.QuerySystem.MedianPosition; if (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation == null) { position.SetVec2(this.formation.QuerySystem.AveragePosition); } else { int num1 = (double)(this.formation.QuerySystem.AverageAllyPosition - this.formation.Team.QuerySystem.AverageEnemyPosition).LengthSquared <= 3600.0 ? 1 : 0; bool engaging = this._engaging; this._engaging = num1 != 0 || (this._engaging ? (double)this.formation.QuerySystem.UnderRangedAttackRatio <= (double)this.formation.QuerySystem.MakingRangedAttackRatio && (!this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsCavalryFormation && !this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.IsRangedCavalryFormation || (double)(this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MedianPosition.AsVec2).LengthSquared / ((double)this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed * (double)this.formation.QuerySystem.FastestSignificantlyLargeEnemyFormation.MovementSpeed) >= 16.0) : (double)(this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.AverageAllyPosition).LengthSquared <= 3600.0); if (this._engaging) { Vec2 vec2_1 = this.formation.QuerySystem.AveragePosition - this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.AveragePosition; vec2_1 = vec2_1.Normalized(); Vec2 vec2_2 = vec2_1.LeftVec(); FormationQuerySystem largeEnemyFormation = this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation; float num2 = (float)(50.0 + ((double)this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation.Width + (double)this.formation.Depth) * 0.5); float num3 = 0.0f; Formation formation1 = this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation; for (int index1 = 0; index1 < Mission.Current.Teams.Count; ++index1) { Team team = Mission.Current.Teams[index1]; if (team.IsEnemyOf(this.formation.Team)) { for (int index2 = 0; index2 < team.FormationsIncludingSpecialAndEmpty.Count; ++index2) { Formation formation2 = team.FormationsIncludingSpecialAndEmpty[index2]; if (formation2.CountOfUnits > 0 && formation2.QuerySystem != largeEnemyFormation) { Vec2 v = formation2.QuerySystem.AveragePosition - largeEnemyFormation.AveragePosition; float num4 = v.Normalize(); if ((double)vec2_2.DotProduct(v) > 0.800000011920929 && (double)num4 < (double)num2 && (double)num4 > (double)num3) { num3 = num4; formation1 = formation2; } } } } } if (((double)this.formation.QuerySystem.RangedCavalryUnitRatio <= 0.949999988079071 ? 0 : (this.formation.QuerySystem.ClosestSignificantlyLargeEnemyFormation.Formation == formation1 ? 1 : 0)) == 0) { bool flag = formation1.QuerySystem.IsCavalryFormation || formation1.QuerySystem.IsRangedCavalryFormation; float radius = Math.Min((flag ? 35f : 20f) + (float)(((double)formation1.Depth + (double)this.formation.Width) * 0.5), this.formation.QuerySystem.MissileRange - this.formation.Width * 0.5f); BehaviorMountedSkirmish.Ellipse ellipse = new BehaviorMountedSkirmish.Ellipse(formation1.QuerySystem.MedianPosition.AsVec2, radius, (float)((double)formation1.Width * 0.5 * (flag ? 1.5 : 1.0)), formation1.Direction); position.SetVec2(ellipse.GetTargetPos(this.formation.QuerySystem.AveragePosition, 20f)); } else { this.CurrentOrder = MovementOrder.MovementOrderCharge; return; } } else { position = new WorldPosition(Mission.Current.Scene, new Vec3(this.formation.QuerySystem.AverageAllyPosition, this.formation.Team.QuerySystem.MedianPosition.GetNavMeshZ() + 100f)); } } this.CurrentOrder = MovementOrder.MovementOrderMove(position); }