static StaticConstructorClass() { ArtilleryStrikeUtility.SetCache(); var thingDefs = DefDatabase <ThingDef> .AllDefsListForReading; for (int i = 0; i < thingDefs.Count; i++) { var tDef = thingDefs[i]; // Add CompPawnTracker and CompThingTracker if (typeof(ThingWithComps).IsAssignableFrom(tDef.thingClass)) { if (tDef.comps == null) { tDef.comps = new List <CompProperties>(); } if (typeof(Pawn).IsAssignableFrom(tDef.thingClass)) { tDef.comps.Add(new CompProperties(typeof(CompPawnTracker))); } tDef.comps.Add(new CompProperties(typeof(CompThingTracker))); } // Make stone chunks catapult ammo else if (tDef.IsWithinCategory(ThingCategoryDefOf.StoneChunks)) { tDef.projectileWhenLoaded = ThingDefOf.VFES_Artillery_Rock; } } }
public override void WorldComponentUpdate() { // Draw shoot lines if (WorldRendererUtility.WorldRenderedNow) { var worldGrid = Find.WorldGrid; foreach (var artilleryComp in cachedArtilleryCompsBombarding) { var material = artilleryComp.parent.Faction == Faction.OfPlayer ? ForcedTargetLineMat : NonPlayerTargetLineMat; foreach (var target in artilleryComp.Targets) { var start = worldGrid.GetTileCenter(artilleryComp.parent.Tile); var end = worldGrid.GetTileCenter(target.Tile); var drawPoints = ArtilleryStrikeUtility.WorldLineDrawPoints(start, end).ToList(); for (int k = 1; k < drawPoints.Count; k++) { var a = drawPoints[k - 1]; var b = drawPoints[k]; GenDraw.DrawWorldLineBetween(a, b, material); } } } } }
public void TryLaunch(int destinationTile) { var arrivalAction = CurrentArrivalAction; if (arrivalAction != null) { arrivalAction.source = parent; } // Play sounds var verb = Turret.CurrentEffectiveVerb; if (verb.verbProps.soundCast != null) { verb.verbProps.soundCast.PlayOneShot(new TargetInfo(parent.Position, parent.Map)); } if (verb.verbProps.soundCastTail != null) { verb.verbProps.soundCastTail.PlayOneShotOnCamera(parent.Map); } // Make active artillery strike thing var activeArtilleryStrike = (ActiveArtilleryStrike)ThingMaker.MakeThing(ThingDefOf.VFES_ActiveArtilleryStrike); activeArtilleryStrike.missRadius = ArtilleryStrikeUtility.FinalisedMissRadius(Turret.CurrentEffectiveVerb.verbProps.ForcedMissRadius, Props.maxForcedMissRadiusFactor, parent.Tile, destinationTile, Props.worldTileRange); // Simulate an attack if (ChangeableProjectile != null) { activeArtilleryStrike.shellDef = ChangeableProjectile.Projectile; activeArtilleryStrike.shellCount = 1; ChangeableProjectile.Notify_ProjectileLaunched(); } else { activeArtilleryStrike.shellDef = verb.GetProjectile(); for (int j = 0; j < verb.verbProps.burstShotCount; j++) { activeArtilleryStrike.shellCount++; if (verb.verbProps.consumeFuelPerShot > 0 && RefuelableComp != null) { RefuelableComp.ConsumeFuel(verb.verbProps.consumeFuelPerShot); } } } NonPublicMethods.Building_TurretGun_BurstComplete(Turret); var artilleryStrikeLeaving = (ArtilleryStrikeLeaving)SkyfallerMaker.MakeSkyfaller(ThingDefOf.VFES_ArtilleryStrikeLeaving, activeArtilleryStrike); artilleryStrikeLeaving.startCell = parent.Position; artilleryStrikeLeaving.edgeCell = FacingEdgeCell; artilleryStrikeLeaving.rotation = CurAngle; artilleryStrikeLeaving.destinationTile = destinationTile; artilleryStrikeLeaving.arrivalAction = arrivalAction; artilleryStrikeLeaving.groupID = Find.TickManager.TicksGame; GenSpawn.Spawn(artilleryStrikeLeaving, parent.Position, parent.Map); }
public override void CompTick() { if (parent.Faction != Faction.OfPlayer) { TryResolveArtilleryCount(); if (Attacking) { // Try and bombard player settlements if (artilleryCooldownTicks > 0) { artilleryCooldownTicks--; } else if (Targets.Select(t => t.WorldObject).Cast <Settlement>().TryRandomElementByWeight(s => StorytellerUtility.DefaultThreatPointsNow(s.Map), out Settlement targetSettlement)) { if (artilleryWarmupTicks < 0) { artilleryWarmupTicks = ArtilleryDef.building.turretBurstWarmupTime.SecondsToTicks(); } else { artilleryWarmupTicks--; if (artilleryWarmupTicks == -1) { var shell = ArtilleryStrikeUtility.GetRandomShellFor(ArtilleryGunDef, parent.Faction.def); if (shell != null) { float missRadius = ArtilleryStrikeUtility.FinalisedMissRadius(ArtilleryGunDef.Verbs[0].forcedMissRadius, ArtilleryProps.maxForcedMissRadiusFactor, parent.Tile, targetSettlement.Tile, ArtilleryProps.worldTileRange); var map = targetSettlement.Map; var strikeCells = ArtilleryStrikeUtility.PotentialStrikeCells(map, missRadius); for (int i = 0; i < artilleryCount; i++) { ArtilleryStrikeUtility.SpawnArtilleryStrikeSkyfaller(shell, map, strikeCells.RandomElement()); } artilleryCooldownTicks = ArtilleryDef.building.turretBurstCooldownTime.SecondsToTicks(); } else { Log.ErrorOnce($"Tried to get shell for bombardment but got null instead (artilleryGunDef={ArtilleryGunDef}, factionDef={parent.Faction.def})", 8173352); } } } } else { artilleryWarmupTicks = -1; } // Reduce the duration of the bombardment bombardmentDurationTicks--; if (bombardmentDurationTicks == 0) { EndBombardment(); } } } }
public override void Arrived(List <ActiveArtilleryStrike> artilleryStrikes, int tile) { // Boom var map = mapParent.Map; if (map != null) { for (int i = 0; i < artilleryStrikes.Count; i++) { var strike = artilleryStrikes[i]; var potentialCells = ArtilleryStrikeUtility.PotentialStrikeCells(map, strike.missRadius); for (int j = 0; j < strike.shellCount; j++) { ArtilleryStrikeUtility.SpawnArtilleryStrikeSkyfaller(strike.shellDef, map, potentialCells.RandomElement()); } } } else { ArtilleryComp.ResetForcedTarget(); } }