// 11Mar2013-04:41UTC chinajade private double CalculateMuzzleVelocity() { double launchAngle = WeaponArticulation.AzimuthGet(); double muzzleVelocity = 0.0; var spell = FindVehicleAbilitySpell(); if ((spell != null) && (spell.InternalInfo.SpellMissile != null)) { IEnumerable <WoWMissile> firedMissileQuery = from missile in WoWMissile.InFlightMissiles where (missile.CasterGuid == Me.TransportGuid) && (missile.SpellId == spell.Id) select missile; WoWMissile launchedMissile = firedMissileQuery.FirstOrDefault(); /* N.B This has been commented out to fix momentary game 'freeze up' from framelock but has been left here for - * future reference in the event this logic needs to be further repaired. * * // Launch missile, and wait until launch is observed; * MissileWatchingTimer.Reset(); * * while ((launchedMissile == null) && !MissileWatchingTimer.IsFinished) * { * // WoWMissiles are read directly from the games memory and are not stored in the 'ObjectManager' * // ObjectManager.Update(); * launchedMissile = firedMissileQuery.FirstOrDefault(); * } */ // If we failed to see the missile, report error and move on... if (launchedMissile == null) { QBCLog.Warning( "Muzzle Velocity not calculated--" + "Unable to locate projectile launched by Vehicle Ability button #{0}", AbilityIndex); return(double.NaN); // "we don't know" } // Initial velocity calculation... // * Accounts for uneven terrain // // v0 = sqrt((R^2 * g) / (R * sin(2*theta) + 2 * h * cos^2(theta))) // where, R = range, g = grav const, h = drop height, theta = launch angle double R = launchedMissile.FirePosition.Distance2D(launchedMissile.ImpactPosition); double h = launchedMissile.FirePosition.Z - launchedMissile.ImpactPosition.Z; double sinTwoTheta = Math.Sin(2 * launchAngle); double cosTheta = Math.Cos(launchAngle); muzzleVelocity = Math.Sqrt(((R * R) * GravityInFpsSqr) / (R * sinTwoTheta + 2 * h * (cosTheta * cosTheta))); } return(muzzleVelocity); }
// 9Mar2013-07:55UTC chinajade public static string ToString_FullInfo(this WoWMissile wowMissile, bool useCompactForm = false, int indentLevel = 0) { var tmp = new StringBuilder(); if (wowMissile != null) { var indent = string.Empty.PadLeft(indentLevel); var fieldSeparator = useCompactForm ? " " : string.Format("\n {0}", indent); bool isInFlight = WoWMissile.InFlightMissiles.FirstOrDefault(m => m.BaseAddress == wowMissile.BaseAddress) != null; tmp.AppendFormat("<WoWMissile Key_Spell=\"{0}\" BaseAddress=\"0x{1:x}\"", ((wowMissile.Spell == null) ? "UNKNOWN" : wowMissile.Spell.Name), (wowMissile.BaseAddress)); tmp.AppendFormat("{0}Caster=\"{1}\"", fieldSeparator, (wowMissile.Caster == null) ? "UNKNOWN" : wowMissile.Caster.SafeName); tmp.AppendFormat("{0}CasterGuid=\"0x{1:x}\" <!--Me=\"0x{2:x}\" MyVehicle=\"0x{3:x}\" -->", fieldSeparator, wowMissile.Caster.Guid, StyxWoW.Me.Guid, StyxWoW.Me.TransportGuid); tmp.AppendFormat("{0}FirePosition=\"{1}\"", fieldSeparator, wowMissile.FirePosition); tmp.AppendFormat("{0}Flags=\"0x{1:x}\"", fieldSeparator, wowMissile.Flags); tmp.AppendFormat("{0}ImpactPosition=\"{1}\" <!--dist: {2:F1}-->", fieldSeparator, wowMissile.ImpactPosition, wowMissile.ImpactPosition.Distance(StyxWoW.Me.Location)); tmp.AppendFormat("{0}IsInFlight=\"{1}\"", fieldSeparator, isInFlight); tmp.AppendFormat("{0}Position=\"{1}\" <!--dist: {2:F1}-->", fieldSeparator, wowMissile.Position, wowMissile.Position.Distance(StyxWoW.Me.Location)); tmp.AppendFormat("{0}Spell=\"{1}\"", fieldSeparator, (wowMissile.Spell == null) ? "NONE" : wowMissile.Spell.Name); tmp.AppendFormat("{0}SpellId=\"{1}\"", fieldSeparator, wowMissile.SpellId); tmp.AppendFormat("{0}SpellVisualId=\"{1}\"", fieldSeparator, wowMissile.SpellVisualId); tmp.AppendFormat("{0}Target=\"{1}\"", fieldSeparator, (wowMissile.Target == null) ? "NONE" : wowMissile.Target.SafeName); tmp.AppendFormat("{0}TargetGuid=\"0x{1:x}\"", fieldSeparator, wowMissile.TargetGuid); tmp.AppendFormat("{0}/>", fieldSeparator); } return(tmp.ToString()); }