public void FireCannon(CannonHandler cannon) { if (cannon is null) { return; } float initialOffset = ((cannon.spacing * (cannon.numberCannons - 1)) / 2f) + cannon.offset; // s(n-1) / 2 float projectileOffset = (this.Pawn.def.size.x / 2f) + 1; // (s/2) + 1 for (int i = 0; i < cannon.numberCannons; i++) { float offset = cannon.spacing * i - initialOffset; //s*i - x SPExtended.SPTuple <float, float> angleOffset = this.AngleRotationProjectileOffset(offset, projectileOffset); ThingDef projectile = cannon.projectile; IntVec3 targetCell = IntVec3.Invalid; Vector3 launchCell = this.Pawn.DrawPos; switch (cannon.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.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.Turret: throw new NotImplementedException(); } 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.spreadRadius * (this.Range / cannon.maxRange)))]; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, this.Pawn.Position, this.Pawn.Map, WipeMode.Vanish); if (cannon.cannonSound is null) { SoundDefOf_Ships.Explosion_PirateCannon.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map, false)); } else { cannon.cannonSound.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map, false)); } projectile2.Launch(this.Pawn, launchCell, c, target, cannon.hitFlags); } }