private void ResolveCannons() { if (!this.Pawn.Drafted && broadsideFire.Count > 0) { broadsideFire.Clear(); } if (broadsideFire?.Count > 0) { for (int i = 0; i < broadsideFire.Count; i++) { SPTuple <Stack <int>, CannonHandler> side = broadsideFire[i]; int tick = broadsideFire[i].Third; if (broadsideFire[i].Third % side.Second.TicksPerShot == 0) { FireCannonBroadside(side.Second, side.First.Pop()); } tick++; broadsideFire[i].Third = tick; if (!side.First.AnyNullified()) { broadsideFire.RemoveAt(i); } } } if (multiFireCannon?.Count > 0) { for (int i = 0; i < multiFireCannon.Count; i++) { SPTuple2 <int, int> PairedData = multiFireCannon[i].Third; if (PairedData.First <= 0) { FireTurretCannon(multiFireCannon[i].Second, ref PairedData); PairedData.Second++; multiFireCannon[i].First--; PairedData.First = multiFireCannon[i].Second.TicksPerShot; if (multiFireCannon[i].First == 0) { if (multiFireCannon[i].Second.targetPersists) { multiFireCannon[i].Second.SetTargetConditionalOnThing(LocalTargetInfo.Invalid); } else { multiFireCannon[i].Second.SetTarget(LocalTargetInfo.Invalid); } multiFireCannon.RemoveAt(i); continue; } } else { PairedData.First--; } multiFireCannon[i].Third = PairedData; } } }
private SPTuple2 <float, float> AngleRotationProjectileOffset(float preOffsetX, float preOffsetY) { SPTuple2 <float, float> offset = new SPTuple2 <float, float>(preOffsetX, preOffsetY); switch (this.Pawn.Rotation.AsInt) { case 1: if (this.CompShip.Angle == -45) { SPTuple2 <float, float> newOffset = SPTrig.RotatePointCounterClockwise(preOffsetX, preOffsetY, 45f); offset.First = newOffset.First; offset.Second = newOffset.Second; } else if (this.CompShip.Angle == 45) { SPTuple2 <float, float> newOffset = SPTrig.RotatePointClockwise(preOffsetX, preOffsetY, 45f); offset.First = newOffset.First; offset.Second = newOffset.Second; } break; case 3: if (this.CompShip.Angle == -45) { SPTuple2 <float, float> newOffset = SPTrig.RotatePointClockwise(preOffsetX, preOffsetY, 225f); offset.First = newOffset.First; offset.Second = newOffset.Second; } else if (this.CompShip.Angle == 45) { SPTuple2 <float, float> newOffset = SPTrig.RotatePointCounterClockwise(preOffsetX, preOffsetY, 225f); offset.First = newOffset.First; offset.Second = newOffset.Second; } break; } return(offset); }
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 = this.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.CompShip.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.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Starboard: if (this.CompShip.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.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Bow: if (this.CompShip.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.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } } break; case WeaponLocation.Stern: if (this.CompShip.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.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.East && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z += (int)(Math.Sin(this.CompShip.Angle.DegreesToRadians()) * this.Range); } else if (this.Pawn.Rotation == Rot4.West && this.CompShip.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.CompShip.Angle.DegreesToRadians()) * this.Range); targetCell.z -= (int)(Math.Sin(this.CompShip.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; } bool flag = TryFindShootLineFromTo(cannon.TurretLocation.ToIntVec3(), cannon.cannonTarget, out ShootLine shootLine); //FIX FOR MULTIPLAYER 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.Any() ? 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?.Any() ?? false) { projectile = cannon.loadedAmmo; } else { projectile = cannon.cannonDef.projectile; } try { Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, Pawn.Position, Pawn.Map, WipeMode.Vanish); if (cannon.cannonDef.ammoAllowed?.Any() ?? false) { 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); } catch (Exception ex) { Log.Error($"Exception when firing Cannon: {cannon.cannonDef.LabelCap} on Pawn: {Pawn.LabelCap}. Exception: {ex.Message}"); } }