diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 69a7168c51..b554a2271e 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -24,6 +24,8 @@ namespace OpenRA.GameRules public readonly Dictionary Versus; [Desc("Can this damage resource patches?")] public readonly bool DestroyResources = false; + [Desc("Will this splatter resources and which?")] + public readonly string AddsResourceType = null; [Desc("Explosion effect to use.")] public readonly string Explosion = null; [Desc("Palette to use for explosion effect.")] diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index e41391e672..203bb22924 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -153,6 +153,13 @@ namespace OpenRA.Traits return true; } + public bool CanSpawnResourceAt(ResourceType newResourceType, CPos cell) + { + var currentResourceType = GetResource(cell); + return currentResourceType == newResourceType + || (currentResourceType == null && AllowResourceAt(newResourceType, cell)); + } + CellContents CreateResourceCell(ResourceType t, CPos p) { world.Map.CustomTerrain[p.X, p.Y] = world.TileSet.GetTerrainIndex(t.Info.TerrainType); diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index 5b74721ac1..85434ef1d6 100644 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -18,7 +18,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - public static class Combat /* some utility bits that are shared between various things */ + // some utility bits that are shared between various things + public static class Combat { static string GetImpactSound(WarheadInfo warhead, bool isWater) { @@ -49,10 +50,10 @@ namespace OpenRA.Mods.RA Sound.Play(GetImpactSound(warhead, isWater), pos); var smudgeLayers = world.WorldActor.TraitsImplementing().ToDictionary(x => x.Info.Type); + var resLayer = warhead.DestroyResources || !string.IsNullOrEmpty(warhead.AddsResourceType) ? world.WorldActor.Trait() : null; if (warhead.Size[0] > 0) { - var resLayer = world.WorldActor.Trait(); var allCells = world.Map.FindTilesInCircle(targetTile, warhead.Size[0]).ToList(); // `smudgeCells` might want to just be an outer shell of the cells: @@ -76,10 +77,29 @@ namespace OpenRA.Mods.RA } // Destroy all resources in range, not just the outer shell: - foreach (var cell in allCells) - { - if (warhead.DestroyResources) + if (warhead.DestroyResources) + foreach (var cell in allCells) resLayer.Destroy(cell); + + // Splatter resources: + if (!string.IsNullOrEmpty(warhead.AddsResourceType)) + { + var resourceType = world.WorldActor.TraitsImplementing() + .FirstOrDefault(t => t.Info.Name == warhead.AddsResourceType); + + if (resourceType == null) + Log.Write("debug", "Warhead defines an invalid resource type '{0}'".F(warhead.AddsResourceType)); + else + { + foreach (var cell in allCells) + { + if (!resLayer.CanSpawnResourceAt(resourceType, cell)) + continue; + + var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resLayer.GetResourceDensity(cell)); + resLayer.AddResource(resourceType, cell, splash); + } + } } } else @@ -202,6 +222,7 @@ namespace OpenRA.Mods.RA var falloff = (float)GetDamageFalloff(distance * 1f / warhead.Spread.Range); rawDamage = (float)(falloff * rawDamage); } + return (float)(rawDamage * modifier * (float)warhead.EffectivenessAgainst(target.Info)); } } diff --git a/OpenRA.Mods.RA/SeedsResource.cs b/OpenRA.Mods.RA/SeedsResource.cs index 9fc911bf58..aaf1491484 100644 --- a/OpenRA.Mods.RA/SeedsResource.cs +++ b/OpenRA.Mods.RA/SeedsResource.cs @@ -63,16 +63,13 @@ namespace OpenRA.Mods.RA .SkipWhile(p => resLayer.GetResource(p) == resourceType && resLayer.IsFull(p.X, p.Y)) .Cast().FirstOrDefault(); - if (cell != null && self.World.Map.IsInMap(cell.Value) && - (resLayer.GetResource(cell.Value) == resourceType - || (resLayer.GetResource(cell.Value) == null && resLayer.AllowResourceAt(resourceType, cell.Value)))) + if (cell != null && resLayer.CanSpawnResourceAt(resourceType, cell.Value)) resLayer.AddResource(resourceType, cell.Value, 1); - } static IEnumerable RandomWalk(CPos p, MersenneTwister r) { - for (; ; ) + for (;;) { var dx = r.Next(-1, 2); var dy = r.Next(-1, 2); diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index 551b1fa100..659e3442b2 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -71,6 +71,8 @@ HARV: HuskActor: HARV.Husk -GainsExperience: RenderHarvester: + Explodes: + Weapon: TiberiumExplosion APC: Inherits: ^Tank diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index 88d16172e9..b39c74ee23 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -877,6 +877,21 @@ Tiberium: Damage: 2 PreventProne: yes +TiberiumExplosion: + Warhead: + Damage: 10 + Spread: 9 + Size: 1,1 + Versus: + None: 90% + Wood: 75% + Light: 60% + Heavy: 25% + Explosion: chemball + InfDeath: 3 + ImpactSound: xplosml2.aud + AddsResourceType: Tiberium + Heal: ROF: 4 Warhead: diff --git a/mods/d2k/rules/vehicles.yaml b/mods/d2k/rules/vehicles.yaml index 578719fff0..dbf7d659d3 100644 --- a/mods/d2k/rules/vehicles.yaml +++ b/mods/d2k/rules/vehicles.yaml @@ -77,7 +77,7 @@ HARVESTER: RevealsShroud: Range: 4c0 Explodes: - Weapon: UnitExplodeScale + Weapon: SpiceExplosion EmptyWeapon: UnitExplodeScale LeavesHusk: HuskActor: Harvester.Husk diff --git a/mods/d2k/weapons.yaml b/mods/d2k/weapons.yaml index 03d4716eac..9ac483f540 100644 --- a/mods/d2k/weapons.yaml +++ b/mods/d2k/weapons.yaml @@ -649,3 +649,18 @@ Shrapnel: Damage: 60 ImpactSound: EXPLLG5.WAV +SpiceExplosion: + Warhead: + Damage: 10 + Spread: 9 + Size: 2,2 + Versus: + None: 90% + Wood: 75% + Light: 60% + Heavy: 25% + Explosion: med_explosion + InfDeath: 3 + ImpactSound: EXPLLG5.WAV + AddsResourceType: Spice + diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index f780c9b749..e21411aac0 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -285,7 +285,7 @@ HARV: FullHuskActor: HARV.FullHusk FullnessThreshold: 50 Explodes: - Weapon: UnitExplodeSmall + Weapon: OreExplosion EmptyWeapon: UnitExplodeSmall MCV: diff --git a/mods/ra/weapons.yaml b/mods/ra/weapons.yaml index b20867ea02..0b0d816376 100644 --- a/mods/ra/weapons.yaml +++ b/mods/ra/weapons.yaml @@ -1360,3 +1360,18 @@ MADTankDetonate: ImpactSound: mineblo1.aud SmudgeType: Crater +OreExplosion: + Warhead: + Damage: 10 + Spread: 9 + Size: 1,1 + Versus: + None: 90% + Wood: 75% + Light: 60% + Heavy: 25% + Explosion: med_explosion + InfDeath: 3 + ImpactSound: kaboom25.aud + AddsResourceType: Ore +