Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Radioactivity code migrated to mod DLL.
- Loading branch information
jdj
committed
Jan 24, 2017
1 parent
25c3fd9
commit c1a416b
Showing
7 changed files
with
496 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#region Copyright & License Information | ||
/* | ||
* Copyright 2007-2016 The OpenRA Developers (see AUTHORS) | ||
* This file is part of OpenRA, which is free software. It is made | ||
* available to you under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, either version 3 of | ||
* the License, or (at your option) any later version. For more | ||
* information, see COPYING. | ||
*/ | ||
#endregion | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using OpenRA.GameRules; | ||
using OpenRA.Traits; | ||
using OpenRA.Mods.Common.Traits; | ||
|
||
namespace OpenRA.Mods.yupgi_alert.Traits | ||
{ | ||
[Desc("This actor receives damage from the given weapon when in radioactive area.")] | ||
class DamagedByRadioactivityInfo : UpgradableTraitInfo, Requires<HealthInfo> | ||
{ | ||
[Desc("Related to amount of damage received per DamageInterval ticks. (Damage = DamageCoeff * RadioactivityLevel")] | ||
[FieldLoader.Require] public readonly float DamageCoeff = 0; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
[Desc("Delay between receiving damage.")] | ||
public readonly int DamageInterval = 0; | ||
|
||
[Desc("Apply the damage using these damagetypes.")] | ||
public readonly HashSet<string> DamageTypes = new HashSet<string>(); | ||
|
||
public override object Create(ActorInitializer init) { return new DamagedByRadioactivity(init.Self, this); } | ||
} | ||
|
||
class DamagedByRadioactivity : UpgradableTrait<DamagedByRadioactivityInfo>, ITick, ISync | ||
{ | ||
readonly Health health; | ||
readonly RadioactivityLayer raLayer; | ||
|
||
[Sync] int damageTicks; | ||
|
||
public DamagedByRadioactivity(Actor self, DamagedByRadioactivityInfo info) : base(info) | ||
{ | ||
health = self.Trait<Health>(); | ||
raLayer = self.World.WorldActor.Trait<RadioactivityLayer>(); | ||
} | ||
|
||
public void Tick(Actor self) | ||
{ | ||
if (IsTraitDisabled || --damageTicks > 0) | ||
return; | ||
|
||
// Prevents harming cargo. | ||
if (!self.IsInWorld) | ||
return; | ||
|
||
var level = raLayer.GetLevel(self.Location); | ||
if (level <= 0) | ||
return; | ||
|
||
float dmg = Info.DamageCoeff * level; | ||
if (dmg < 1.0f) | ||
dmg = 1.0f; // cos we will be rounding this as int. | ||
|
||
self.InflictDamage(self.World.WorldActor, new Damage((int) dmg, Info.DamageTypes)); | ||
damageTicks = Info.DamageInterval; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#region Copyright & License Information | ||
/* | ||
* Copyright 2015- OpenRA.Mods.AS Developers (see AUTHORS) | ||
* This file is a part of a third-party plugin for OpenRA, which is | ||
* free software. It is made available to you under the terms of the | ||
* GNU General Public License as published by the Free Software | ||
* Foundation. For more information, see COPYING. | ||
*/ | ||
#endregion | ||
|
||
using System.Linq; | ||
using OpenRA.GameRules; | ||
using OpenRA.Mods.Common; | ||
using OpenRA.Mods.Common.Traits; | ||
using OpenRA.Traits; | ||
|
||
|
||
// Remark: | ||
// While I'm modding latest stable version, | ||
// UpgradableTrait is renamed to ConditionalTrait in bleed version of OpenRA. | ||
|
||
namespace OpenRA.Mods.AS.Traits | ||
{ | ||
[Desc("Explodes a weapon at the actor's position when enabled." | ||
+ "Reload/burstdelays are used as explosion intervals.")] | ||
public class ExplodeWeaponInfo : UpgradableTraitInfo, IRulesetLoaded | ||
{ | ||
[WeaponReference, FieldLoader.Require] | ||
[Desc("Has to be defined in weapons.yaml as well.")] | ||
public readonly string Weapon = null; | ||
|
||
public readonly bool ResetReloadWhenEnabled = true; | ||
|
||
public WeaponInfo WeaponInfo { get; private set; } | ||
|
||
[Desc("Explosion offset relative to actor's position.")] | ||
public readonly WVec LocalOffset = WVec.Zero; | ||
|
||
public override object Create(ActorInitializer init) { return new ExplodeWeapon(init.Self, this); } | ||
|
||
void IRulesetLoaded<ActorInfo>.RulesetLoaded(Ruleset rules, ActorInfo info) | ||
{ | ||
WeaponInfo weaponInfo; | ||
|
||
var weaponToLower = Weapon.ToLowerInvariant(); | ||
if (!rules.Weapons.TryGetValue(weaponToLower, out weaponInfo)) | ||
throw new YamlException("Weapons Ruleset does not contain an entry '{0}'".F(weaponToLower)); | ||
|
||
WeaponInfo = weaponInfo; | ||
} | ||
} | ||
|
||
class ExplodeWeapon : UpgradableTrait<ExplodeWeaponInfo>, ITick | ||
{ | ||
readonly ExplodeWeaponInfo info; | ||
readonly WeaponInfo weapon; | ||
readonly BodyOrientation body; | ||
|
||
int fireDelay; | ||
int burst; | ||
|
||
public ExplodeWeapon(Actor self, ExplodeWeaponInfo info) | ||
: base(info) | ||
{ | ||
this.info = info; | ||
|
||
weapon = info.WeaponInfo; | ||
burst = weapon.Burst; | ||
body = self.TraitOrDefault<BodyOrientation>(); | ||
} | ||
|
||
void ITick.Tick(Actor self) | ||
{ | ||
if (IsTraitDisabled) | ||
return; | ||
|
||
if (--fireDelay < 0) | ||
{ | ||
var localoffset = body != null | ||
? body.LocalToWorld(info.LocalOffset.Rotate(body.QuantizeOrientation(self, self.Orientation))) | ||
: info.LocalOffset; | ||
|
||
weapon.Impact(Target.FromPos(self.CenterPosition + localoffset), self, | ||
self.TraitsImplementing<IFirepowerModifier>().Select(a => a.GetFirepowerModifier()).ToArray()); | ||
|
||
if (--burst > 0) | ||
fireDelay = weapon.BurstDelay; | ||
else | ||
{ | ||
var modifiers = self.TraitsImplementing<IReloadModifier>() | ||
.Select(m => m.GetReloadModifier()); | ||
fireDelay = Util.ApplyPercentageModifiers(weapon.ReloadDelay, modifiers); | ||
burst = weapon.Burst; | ||
} | ||
} | ||
} | ||
|
||
protected override void UpgradeEnabled(Actor self) | ||
{ | ||
if (info.ResetReloadWhenEnabled) | ||
{ | ||
burst = weapon.Burst; | ||
fireDelay = 0; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
OpenRA.Mods.yupgi_alert/Traits/Warheads/CreateRadioactivityWarhead.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#region Copyright & License Information | ||
/* | ||
* Copyright 2007-2016 The OpenRA Developers (see AUTHORS) | ||
* This file is part of OpenRA, which is free software. It is made | ||
* available to you under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, either version 3 of | ||
* the License, or (at your option) any later version. For more | ||
* information, see COPYING. | ||
*/ | ||
#endregion | ||
|
||
using System.Collections.Generic; | ||
using OpenRA.GameRules; | ||
using OpenRA.Mods.Common.Traits; | ||
using OpenRA.Traits; | ||
using OpenRA.Mods.Common.Warheads; | ||
using OpenRA.Mods.yupgi_alert.Traits; | ||
|
||
namespace OpenRA.Mods.yupgi_alert.Warheads | ||
{ | ||
public class CreateRadioactivityWarhead : DamageWarhead, IRulesetLoaded<WeaponInfo> | ||
{ | ||
[Desc("Range between falloff steps, in cells")] | ||
public readonly int Spread = 1; | ||
|
||
[Desc("Radioactivity level percentage at each range step")] | ||
public readonly int[] Falloff = { 100, 37, 14, 5, 0 }; | ||
|
||
// Since radioactivity level is accumulative, we pre-compute this var from Falloff. (Lookup table) | ||
private int[] FalloffDifference; | ||
|
||
[Desc("Ranges at which each Falloff step is defined (in cells). Overrides Spread.")] | ||
public int[] Range = null; | ||
|
||
[Desc("Radio activity level per shot (Sievert?)")] | ||
public int Level = 32; | ||
|
||
[Desc("Radio activity saturates at this level, by this weapon.")] | ||
// this means if the cell is affected by other stronger radioactive weapon, the level can go past this value. | ||
// For details, have a look at RadioactivityLayers.cs:IncreaseLevel() | ||
public int MaxLevel = 128; | ||
|
||
[Desc("Half-life of the RA level, from this weapon, in ticks.")] | ||
public int HalfLife = 15; | ||
|
||
public void RulesetLoaded(Ruleset rules, WeaponInfo info) | ||
{ | ||
if (Range != null) | ||
{ | ||
if (Range.Length != 1 && Range.Length != Falloff.Length) | ||
throw new YamlException("Number of range values must be 1 or equal to the number of Falloff values."); | ||
|
||
for (var i = 0; i < Range.Length - 1; i++) | ||
if (Range[i] > Range[i + 1]) | ||
throw new YamlException("Range values must be specified in an increasing order."); | ||
} | ||
else | ||
Range = Exts.MakeArray(Falloff.Length, i => i * Spread); | ||
|
||
// Compute FalloffDifference LUT. | ||
FalloffDifference = new int[Falloff.Length]; | ||
for(var i = 0; i < FalloffDifference.Length-1; i++) | ||
{ | ||
// with Falloff = { 100, 37, 14, 5, 0 }, you get | ||
// { 63, 23, 9, 5, 0 } | ||
FalloffDifference[i] = Falloff[i] - Falloff[i + 1]; | ||
} | ||
FalloffDifference[FalloffDifference.Length - 1] = 0; | ||
} | ||
|
||
public override void DoImpact(WPos pos, Actor firedBy, IEnumerable<int> damageModifiers) | ||
{ | ||
var world = firedBy.World; | ||
var resLayer = world.WorldActor.Trait<RadioactivityLayer>(); | ||
|
||
if (world.LocalPlayer != null) | ||
{ | ||
var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault<DeveloperMode>(); | ||
if (devMode != null && devMode.ShowCombatGeometry) | ||
{ | ||
WDist[] rng = Exts.MakeArray(Range.Length, i => WDist.FromCells(Range[i])); | ||
world.WorldActor.Trait<WarheadDebugOverlay>().AddImpact(pos, rng, DebugOverlayColor); | ||
} | ||
} | ||
|
||
// Accumulate radiation | ||
var targetTile = world.Map.CellContaining(pos); | ||
for (var i = Range.Length-1; i >=0; i--) | ||
{ | ||
// Find affected cells, from outer Range down to inner range. | ||
var affectedCells = world.Map.FindTilesInAnnulus(targetTile, 0, Range[i]); | ||
|
||
var ra_layer = world.WorldActor.Trait<RadioactivityLayer>(); | ||
|
||
foreach (var cell in affectedCells) | ||
{ | ||
var foff = FalloffDifference[i]; | ||
IncreaseRALevel(cell, foff, ra_layer); | ||
} | ||
} | ||
} | ||
|
||
// Increase radiation level of the cell at given pos, considering falloff | ||
void IncreaseRALevel(CPos pos, int foff, RadioactivityLayer ra_layer) | ||
{ | ||
// increase RA level of the cell by this amount. | ||
int level = this.Level * foff / 100; | ||
ra_layer.IncreaseLevel(pos, level, HalfLife, MaxLevel); | ||
} | ||
} | ||
} |
Oops, something went wrong.
Float values should never be used in game code due to danger of being computed differently between computers. Use percentage values as integers.