public static bool TargetMeetsRequirements(CannonHandler cannon, LocalTargetInfo obj) { float distance = (cannon.TurretLocation.ToIntVec3() - obj.Cell).LengthHorizontal; bool result = (distance >= cannon.MinRange && (distance < cannon.MaxRange || cannon.MaxRange <= -1)) && cannon.AngleBetween(obj.CenterVector3); //Log.Message($"Result {result} Details--> distance: {distance} min: {cannon.MinRange} max: {cannon.MaxRange} angle: {cannon.AngleBetween(obj.CenterVector3)}"); return(result); }
private void InitializeCannons() { if (Cannons.Count <= 0 && Props.cannons.AnyNullified()) { foreach (CannonHandler cannon in Props.cannons) { var cannonPermanent = new CannonHandler(this.Pawn, cannon); cannonPermanent.SetTarget(LocalTargetInfo.Invalid); cannonPermanent.ResetCannonAngle(); Cannons.Add(cannonPermanent); } if (Cannons.Select(x => x.key).GroupBy(y => y).AnyNullified(key => key.Count() > 1)) { Log.Warning("Duplicate CannonHandler key has been found. These are intended to be unique."); } } }
public void AddCannons(List <CannonHandler> cannonList) { if (cannonList is null) { return; } foreach (CannonHandler cannon in cannonList) { var cannonPermanent = new CannonHandler(this.Pawn, cannon); cannonPermanent.SetTarget(LocalTargetInfo.Invalid); cannonPermanent.ResetCannonAngle(); if (Cannons.AnyNullified(x => x.baseCannonRenderLocation == cannonPermanent.baseCannonRenderLocation)) { Cannons.FindAll(x => x.baseCannonRenderLocation == cannonPermanent.baseCannonRenderLocation).ForEach(y => y.TryRemoveShell()); Cannons.RemoveAll(x => x.baseCannonRenderLocation == cannonPermanent.baseCannonRenderLocation); } Cannons.Add(cannonPermanent); } }
public void FireCannonBroadside(CannonHandler cannon, int i) { if (cannon is null) { return; } float initialOffset; float offset; bool mirrored = false; if (this.Pawn.Rotation == Rot4.South || Pawn.Rotation == Rot4.West) { mirrored = true; } if (cannon.cannonDef.splitCannonGroups) { int group = cannon.CannonGroup(i); float groupOffset = cannon.cannonDef.centerPoints[group]; initialOffset = ((cannon.cannonDef.spacing * (cannon.cannonDef.cannonsPerPoint[group] - 1)) / 2f) + groupOffset; // s(n-1) / 2 offset = (cannon.cannonDef.spacing * i - initialOffset) * (mirrored ? -1 : 1); //s*i - x } else { initialOffset = ((cannon.cannonDef.spacing * (cannon.cannonDef.numberCannons - 1)) / 2f) + cannon.cannonDef.offset; // s(n-1) / 2 offset = (cannon.cannonDef.spacing * i - initialOffset) * (mirrored ? -1 : 1); //s*i - x } float projectileOffset = (this.Pawn.def.size.x / 2f) + cannon.cannonDef.projectileOffset; // (s/2) SPTuple2 <float, float> angleOffset = AngleRotationProjectileOffset(offset, projectileOffset); ThingDef projectile = cannon.cannonDef.projectile; IntVec3 targetCell = IntVec3.Invalid; Vector3 launchCell = this.Pawn.DrawPos; switch (cannon.cannonDef.weaponLocation) { case WeaponLocation.Port: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.x += offset; launchCell.z += projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.x += offset; launchCell.z -= projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Starboard: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.z -= projectileOffset; launchCell.x += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.z += projectileOffset; launchCell.x += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.Second; launchCell.z += angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.Second; launchCell.z -= angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.Second; launchCell.z -= angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.Second; launchCell.z += angleOffset.First; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Bow: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.x += offset; launchCell.z += projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.x += offset; launchCell.z -= projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Stern: if (this.CompVehicle.Angle == 0) { if (this.Pawn.Rotation == Rot4.North) { launchCell.x -= projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)this.Range; } else if (this.Pawn.Rotation == Rot4.East) { launchCell.x += offset; launchCell.z += projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.South) { launchCell.x += projectileOffset; launchCell.z += offset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)this.Range; } else if (this.Pawn.Rotation == Rot4.West) { launchCell.x += offset; launchCell.z -= projectileOffset; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.z -= (int)this.Range; } } else { if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == -45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompVehicle.Angle == 45) { launchCell.x += angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == -45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x += (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompVehicle.Angle == 45) { launchCell.x -= angleOffset.First; launchCell.z += angleOffset.Second; targetCell = new IntVec3((int)launchCell.x, this.Pawn.Position.y, (int)launchCell.z); targetCell.x -= (int)(Math.Cos(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompVehicle.Angle.DegreesToRadians()) * this.Range); } } break; } LocalTargetInfo target = new LocalTargetInfo(targetCell); ShootLine shootLine; bool flag = TryFindShootLineFromTo(this.Pawn.Position, target, out shootLine); //FIX FOR MULTIPLAYER IntVec3 c = target.Cell + GenRadial.RadialPattern[Rand.Range(0, GenRadial.NumCellsInRadius(cannon.cannonDef.spreadRadius * (this.Range / cannon.cannonDef.maxRange)))]; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, this.Pawn.Position, this.Pawn.Map, WipeMode.Vanish); if (cannon.cannonDef.cannonSound is null) { SoundDefOf_Ships.Explosion_PirateCannon.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map, false)); } else { cannon.cannonDef.cannonSound.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map, false)); } if (cannon.cannonDef.moteCannon != null) { MoteMaker.MakeStaticMote(launchCell, this.Pawn.Map, cannon.cannonDef.moteCannon, 1f); } projectile2.Launch(this.Pawn, launchCell, c, target, cannon.cannonDef.hitFlags); }
public void FireTurretCannon(CannonHandler cannon, ref SPTuple2 <int, int> data) { if (cannon is null) { return; } TryFindShootLineFromTo(cannon.TurretLocation.ToIntVec3(), cannon.cannonTarget, out ShootLine shootLine); IntVec3 c = cannon.cannonTarget.Cell + GenRadial.RadialPattern[Rand.Range(0, GenRadial.NumCellsInRadius(cannon.cannonDef.spreadRadius * (Range / cannon.cannonDef.maxRange)))]; if (data.Second >= cannon.cannonDef.projectileShifting.Count) { data.Second = 0; } float horizontalOffset = cannon.cannonDef.projectileShifting.AnyNullified() ? cannon.cannonDef.projectileShifting[data.Second] : 0; Vector3 launchCell = cannon.TurretLocation + new Vector3(horizontalOffset, 1f, cannon.cannonDef.projectileOffset).RotatedBy(cannon.TurretRotation); ThingDef projectile; if (!cannon.cannonDef.ammoAllowed.NullOrEmpty()) { projectile = cannon.loadedAmmo?.projectileWhenLoaded; } else { projectile = cannon.cannonDef.projectile; } try { Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, Pawn.Position, Pawn.Map, WipeMode.Vanish); if (!cannon.cannonDef.ammoAllowed.NullOrEmpty()) { cannon.ConsumeShellChambered(); } if (cannon.cannonDef.cannonSound is null) { SoundDefOf_Ships.Explosion_PirateCannon.PlayOneShot(new TargetInfo(Pawn.Position, Pawn.Map, false)); } else { cannon.cannonDef.cannonSound.PlayOneShot(new TargetInfo(Pawn.Position, Pawn.Map, false)); } if (cannon.cannonDef.moteFlash != null) { MoteMaker.MakeStaticMote(launchCell, Pawn.Map, cannon.cannonDef.moteFlash, 2); } if (cannon.cannonDef.moteCannon != null) { MoteThrown mote = (MoteThrown)ThingMaker.MakeThing(cannon.cannonDef.moteCannon, null); mote.exactPosition = launchCell; mote.Scale = 1f; mote.rotationRate = 15f; mote.SetVelocity(cannon.TurretRotation, cannon.cannonDef.moteSpeedThrown); HelperMethods.ThrowMoteEnhanced(launchCell, Pawn.Map, mote); } projectile2.Launch(Pawn, launchCell, c, cannon.cannonTarget, cannon.cannonDef.hitFlags, parent); if (cannon.cannonDef.graphicData.graphicClass == typeof(Graphic_Animate)) { cannon.StartAnimation(2, 1, AnimationWrapperType.Reset); } } catch (Exception ex) { Log.Error($"Exception when firing Cannon: {cannon.cannonDef.LabelCap} on Pawn: {Pawn.LabelCap}. Exception: {ex.Message}"); } }
public CannonHandler(Pawn pawn, CannonHandler reference) { this.pawn = pawn; uniqueID = Find.UniqueIDsManager.GetNextThingID(); cannonDef = reference.cannonDef; cannonRenderOffset = reference.cannonRenderOffset; cannonRenderLocation = reference.cannonRenderLocation; defaultAngleRotated = reference.defaultAngleRotated; aimPieOffset = reference.aimPieOffset; angleRestricted = reference.angleRestricted; baseCannonRenderLocation = reference.baseCannonRenderLocation; cannonTurretDrawSize = reference.cannonTurretDrawSize; cannonTurretDrawSize = reference.cannonTurretDrawSize; baseCannonDrawSize = reference.baseCannonDrawSize; drawLayer = reference.drawLayer; key = reference.key; parentKey = reference.parentKey; if (string.IsNullOrEmpty(key)) { Log.Error($"Failed to properly create {cannonDef.label} on {pawn.LabelShort}, a key must be included for each CannonHandler"); } else if (CompCannon.Cannons.AnyNullified(c => c.key == key)) { Log.Error($"Duplicate key {key} found on {pawn.LabelShort}. Duplicate registered on {cannonDef.label}{uniqueID}"); } targetPersists = reference.targetPersists; autoTargeting = reference.autoTargeting; manualTargeting = reference.manualTargeting; DisableAnimation(); LockedStatusRotation = true; ResetCannonAngle(); if (cannonDef.splitCannonGroups) { if (cannonDef.cannonsPerPoint.Count != cannonDef.centerPoints.Count || (cannonDef.cannonsPerPoint.Count == 0 && cannonDef.centerPoints.Count == 0)) { Log.Warning("Could Not initialize cannon groups for " + this.pawn.LabelShort); return; } int group = 0; for (int i = 0; i < cannonDef.numberCannons; i++) { if ((i + 1) > (cannonDef.cannonsPerPoint[group] * (group + 1))) { group++; } cannonGroupDict.Add(i, group); //if (ShipHarmony.debug) //{ // Log.Message(string.Concat(new object[] // { // "Initializing ", pawn.LabelShortCap, // " with cannon ", cannonDef.label, // " with ", cannonDef.cannonsPerPoint[group], // " cannons in group: ", group // })); //} } } }
public void BeginTargeting(TargetingParameters targetParams, Action <LocalTargetInfo> action, CannonHandler cannon, Action actionWhenFinished = null, Texture2D mouseAttachment = null) { this.action = action; this.targetParams = targetParams; caster = cannon.pawn; this.cannon = cannon; this.cannon.SetTarget(LocalTargetInfo.Invalid); this.actionWhenFinished = actionWhenFinished; this.mouseAttachment = mouseAttachment; map = cannon.pawn.Map; this.cannon.LockedStatusRotation = false; }