From 38cea38f6bdc0a5f8db1147dd3cc4d2fc59cc0c4 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 24 Mar 2016 16:45:22 +0100 Subject: [PATCH 1/5] Migrate BuildSpeed from float to int --- .../Traits/Player/ClassicProductionQueue.cs | 2 +- .../Traits/Player/ProductionQueue.cs | 8 ++++---- .../UtilityCommands/UpgradeRules.cs | 16 +++++++++++++++ mods/cnc/rules/structures.yaml | 20 +++++++++---------- mods/cnc/rules/tech.yaml | 2 +- mods/d2k/rules/player.yaml | 14 ++++++------- mods/ra/maps/bomber-john/rules.yaml | 2 +- mods/ra/maps/fort-lonestar/rules.yaml | 2 +- mods/ra/maps/training-camp/rules.yaml | 4 ++-- mods/ra/rules/player.yaml | 12 +++++------ mods/ts/rules/player.yaml | 10 +++++----- 11 files changed, 54 insertions(+), 38 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs index 85c3d29a38..7e2a14b062 100644 --- a/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs @@ -128,7 +128,7 @@ namespace OpenRA.Mods.Common.Traits if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait().FastBuild) return 0; - var time = (int)(unit.GetBuildTime() * Info.BuildSpeed); + var time = unit.GetBuildTime() * Info.BuildSpeed / 100; if (info.SpeedUp) { diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs index a7b3d2f86d..b3cb6df09f 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs @@ -34,8 +34,8 @@ namespace OpenRA.Mods.Common.Traits [Desc("Should the prerequisite remain enabled if the owner changes?")] public readonly bool Sticky = true; - [Desc("This value is used to translate the unit cost into build time.")] - public readonly float BuildSpeed = 0.4f; + [Desc("This percentage value is multiplied with actor cost to translate into build time (lower means faster).")] + public readonly int BuildSpeed = 40; [Desc("The build time is multiplied with this value on low power.")] public readonly int LowPowerSlowdown = 3; @@ -319,8 +319,8 @@ namespace OpenRA.Mods.Common.Traits if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait().FastBuild) return 0; - var time = unit.GetBuildTime() * Info.BuildSpeed; - return (int)time; + var time = unit.GetBuildTime() * Info.BuildSpeed / 100; + return time; } protected void CancelProduction(string itemName, uint numberToCancel) diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index d036ba4ed2..443799e906 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -644,6 +644,22 @@ namespace OpenRA.Mods.Common.UtilityCommands node.Key = "ReloadDelay"; } + // Migrated ProductionQueue BuildSpeed to use int percentage instead of float + if (engineVersion < 20160325) + { + if (node.Key.StartsWith("ProductionQueue") || node.Key.StartsWith("ClassicProductionQueue")) + { + var buildSpeedNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "BuildSpeed"); + if (buildSpeedNode != null) + { + // The BuildSpeed value is now an int percentage, so multiply the float with 100. + var oldValue = FieldLoader.GetValue("BuildSpeed", buildSpeedNode.Value.Value); + var newValue = (int)(oldValue * 100); + buildSpeedNode.Value.Value = newValue.ToString(); + } + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index d822c9ad07..bbfa399645 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -25,7 +25,7 @@ FACT: Type: Building.GDI Factions: gdi Group: Building - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 2 QueuedAudio: Building ReadyAudio: ConstructionComplete @@ -33,7 +33,7 @@ FACT: Type: Building.Nod Factions: nod Group: Building - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 2 QueuedAudio: Building ReadyAudio: ConstructionComplete @@ -41,7 +41,7 @@ FACT: Type: Defence.GDI Factions: gdi Group: Defence - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete @@ -49,7 +49,7 @@ FACT: Type: Defence.Nod Factions: nod Group: Defence - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete @@ -260,7 +260,7 @@ PYLE: Type: Infantry.GDI Group: Infantry RequireOwner: false - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ProductionBar: Power: @@ -300,7 +300,7 @@ HAND: Type: Infantry.Nod Group: Infantry RequireOwner: false - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ProductionBar: Power: @@ -344,7 +344,7 @@ AFLD: Type: Vehicle.Nod Group: Vehicle RequireOwner: false - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ReadyAudio: ProductionBar: @@ -391,7 +391,7 @@ WEAP: Type: Vehicle.GDI RequireOwner: false Group: Vehicle - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ProductionBar: Power: @@ -428,13 +428,13 @@ HPAD: Type: Aircraft.GDI Factions: gdi Group: Aircraft - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ProductionQueue@Nod: Type: Aircraft.Nod Factions: nod Group: Aircraft - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ProductionBar@GDI: ProductionType: Aircraft.GDI diff --git a/mods/cnc/rules/tech.yaml b/mods/cnc/rules/tech.yaml index e93ac2f304..193fb57578 100644 --- a/mods/cnc/rules/tech.yaml +++ b/mods/cnc/rules/tech.yaml @@ -65,7 +65,7 @@ BIO: Type: Biolab Group: Infantry RequireOwner: false - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 ProductionBar: RallyPoint: diff --git a/mods/d2k/rules/player.yaml b/mods/d2k/rules/player.yaml index d34531246a..807fd19362 100644 --- a/mods/d2k/rules/player.yaml +++ b/mods/d2k/rules/player.yaml @@ -3,7 +3,7 @@ Player: TechTree: ClassicProductionQueue@Building: Type: Building - BuildSpeed: 1.0 + BuildSpeed: 100 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: BuildingReady @@ -11,7 +11,7 @@ Player: SpeedUp: true ClassicProductionQueue@Upgrade: Type: Upgrade - BuildSpeed: 1.0 + BuildSpeed: 100 LowPowerSlowdown: 0 QueuedAudio: Upgrading ReadyAudio: NewOptions @@ -19,34 +19,34 @@ Player: SpeedUp: true ClassicProductionQueue@Infantry: Type: Infantry - BuildSpeed: 1.0 + BuildSpeed: 100 LowPowerSlowdown: 3 BlockedAudio: NoRoom SpeedUp: true ClassicProductionQueue@Vehicle: Type: Vehicle - BuildSpeed: 1.0 + BuildSpeed: 100 LowPowerSlowdown: 3 QueuedAudio: Building BlockedAudio: NoRoom SpeedUp: true ClassicProductionQueue@Armor: Type: Armor - BuildSpeed: 1.0 + BuildSpeed: 100 LowPowerSlowdown: 3 QueuedAudio: Building BlockedAudio: NoRoom SpeedUp: true ClassicProductionQueue@Starport: Type: Starport - BuildSpeed: 0.85 + BuildSpeed: 85 LowPowerSlowdown: 0 BlockedAudio: NoRoom QueuedAudio: OrderPlaced ReadyAudio: ClassicProductionQueue@Aircraft: Type: Aircraft - BuildSpeed: 1.25 + BuildSpeed: 125 LowPowerSlowdown: 3 QueuedAudio: Building BlockedAudio: NoRoom diff --git a/mods/ra/maps/bomber-john/rules.yaml b/mods/ra/maps/bomber-john/rules.yaml index 9a937155e7..c7834f7bb0 100644 --- a/mods/ra/maps/bomber-john/rules.yaml +++ b/mods/ra/maps/bomber-john/rules.yaml @@ -54,7 +54,7 @@ SILO: Player: ClassicProductionQueue@Building: - BuildSpeed: 0.4 + BuildSpeed: 40 Shroud: FogLocked: True FogEnabled: True diff --git a/mods/ra/maps/fort-lonestar/rules.yaml b/mods/ra/maps/fort-lonestar/rules.yaml index c127edca6f..c4c48f89a7 100644 --- a/mods/ra/maps/fort-lonestar/rules.yaml +++ b/mods/ra/maps/fort-lonestar/rules.yaml @@ -76,7 +76,7 @@ FORTCRATE: Player: ClassicProductionQueue@Infantry: - BuildSpeed: 1 + BuildSpeed: 100 -EnemyWatcher: Shroud: FogLocked: True diff --git a/mods/ra/maps/training-camp/rules.yaml b/mods/ra/maps/training-camp/rules.yaml index c81395d0af..e653458660 100644 --- a/mods/ra/maps/training-camp/rules.yaml +++ b/mods/ra/maps/training-camp/rules.yaml @@ -11,9 +11,9 @@ World: Player: ClassicProductionQueue@Infantry: - BuildSpeed: 1 + BuildSpeed: 100 ClassicProductionQueue@Vehicle: - BuildSpeed: 1 + BuildSpeed: 100 Shroud: FogLocked: True FogEnabled: True diff --git a/mods/ra/rules/player.yaml b/mods/ra/rules/player.yaml index e433ae8e8a..d442ad4cf5 100644 --- a/mods/ra/rules/player.yaml +++ b/mods/ra/rules/player.yaml @@ -3,36 +3,36 @@ Player: TechTree: ClassicProductionQueue@Building: Type: Building - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete SpeedUp: True ClassicProductionQueue@Defense: Type: Defense - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete SpeedUp: True ClassicProductionQueue@Vehicle: Type: Vehicle - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Infantry: Type: Infantry - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Ship: Type: Ship - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Aircraft: Type: Aircraft - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True PlaceBuilding: diff --git a/mods/ts/rules/player.yaml b/mods/ts/rules/player.yaml index da243b3670..64adb4c004 100644 --- a/mods/ts/rules/player.yaml +++ b/mods/ts/rules/player.yaml @@ -4,31 +4,31 @@ Player: GlobalUpgradeManager: ClassicProductionQueue@Building: Type: Building - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete SpeedUp: True ClassicProductionQueue@Defense: Type: Defense - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete SpeedUp: True ClassicProductionQueue@Vehicle: Type: Vehicle - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Infantry: Type: Infantry - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Air: Type: Air - BuildSpeed: .4 + BuildSpeed: 40 LowPowerSlowdown: 3 SpeedUp: True PlaceBuilding: From 01f15d7917efd77c2a03fb8ab1a4e757c5288a11 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 24 Mar 2016 17:15:07 +0100 Subject: [PATCH 2/5] Change TS build speeds to match original --- mods/ts/rules/player.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/ts/rules/player.yaml b/mods/ts/rules/player.yaml index 64adb4c004..7cffe960e3 100644 --- a/mods/ts/rules/player.yaml +++ b/mods/ts/rules/player.yaml @@ -4,31 +4,31 @@ Player: GlobalUpgradeManager: ClassicProductionQueue@Building: Type: Building - BuildSpeed: 40 + BuildSpeed: 48 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete SpeedUp: True ClassicProductionQueue@Defense: Type: Defense - BuildSpeed: 40 + BuildSpeed: 48 LowPowerSlowdown: 3 QueuedAudio: Building ReadyAudio: ConstructionComplete SpeedUp: True ClassicProductionQueue@Vehicle: Type: Vehicle - BuildSpeed: 40 + BuildSpeed: 48 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Infantry: Type: Infantry - BuildSpeed: 40 + BuildSpeed: 48 LowPowerSlowdown: 3 SpeedUp: True ClassicProductionQueue@Air: Type: Air - BuildSpeed: 40 + BuildSpeed: 48 LowPowerSlowdown: 3 SpeedUp: True PlaceBuilding: From 251b1b44d4537eb6805df09b3e890df569c95dbd Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 24 Mar 2016 18:20:32 +0100 Subject: [PATCH 3/5] Migrate StrategicVictoryConditions.RatioRequired to int percentage Remove bogus CriticalRatioRequired from RA Hopes Anchor. --- .../Traits/Player/StrategicVictoryConditions.cs | 4 ++-- .../UtilityCommands/UpgradeRules.cs | 16 ++++++++++++++++ mods/ra/maps/koth-hopes-anchor/rules.yaml | 3 +-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs b/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs index 0af56bdbbb..f03debc8b9 100644 --- a/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs +++ b/OpenRA.Mods.Common/Traits/Player/StrategicVictoryConditions.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits public readonly bool ResetOnHoldLost = true; [Desc("Percentage of all strategic points the player has to hold to win.")] - public readonly float RatioRequired = 0.5f; + public readonly int RatioRequired = 50; [Desc("Delay for the end game notification in milliseconds.")] public readonly int NotificationDelay = 1500; @@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits public int Total { get { return AllPoints.Count(); } } int Owned { get { return AllPoints.Count(a => WorldUtils.AreMutualAllies(player, a.Owner)); } } - public bool Holding { get { return Owned >= info.RatioRequired * Total; } } + public bool Holding { get { return Owned >= info.RatioRequired * Total / 100; } } public void Tick(Actor self) { diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 443799e906..76dd0657a7 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -660,6 +660,22 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Migrated StrategicVictoryConditions RatioRequired to use int percentage instead of float + if (engineVersion < 20160325) + { + if (node.Key.StartsWith("StrategicVictoryConditions")) + { + var ratioNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "RatioRequired"); + if (ratioNode != null) + { + // The RatioRequired value is now an int percentage, so multiply the float with 100. + var oldValue = FieldLoader.GetValue("RatioRequired", ratioNode.Value.Value); + var newValue = (int)(oldValue * 100); + ratioNode.Value.Value = newValue.ToString(); + } + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/ra/maps/koth-hopes-anchor/rules.yaml b/mods/ra/maps/koth-hopes-anchor/rules.yaml index 310ea4ba70..311f3d5b58 100644 --- a/mods/ra/maps/koth-hopes-anchor/rules.yaml +++ b/mods/ra/maps/koth-hopes-anchor/rules.yaml @@ -18,6 +18,5 @@ Player: StrategicVictoryConditions: HoldDuration: 3000 ResetOnHoldLost: true - RatioRequired: 0.65 - CriticalRatioRequired: 0.65 + RatioRequired: 65 -ConquestVictoryConditions: From ade49ba1bed648cf999f3d328ecd238c58a82230 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 24 Mar 2016 18:41:42 +0100 Subject: [PATCH 4/5] Migrated Minelayer.MinefieldDepth to use WDist instead of float --- .../UtilityCommands/UpgradeRules.cs | 16 ++++++++++++++++ OpenRA.Mods.RA/Traits/Minelayer.cs | 6 +++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 76dd0657a7..2345b1f2e2 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -676,6 +676,22 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + // Migrated Minelayer.MinefieldDepth to use WDist instead of float + if (engineVersion < 20160325) + { + if (node.Key.StartsWith("Minelayer")) + { + var depthNode = node.Value.Nodes.FirstOrDefault(x => x.Key == "MinefieldDepth"); + if (depthNode != null) + { + // The MinefieldDepth value is now a WDist, so multiply the float value with 1024. + var oldValue = FieldLoader.GetValue("MinefieldDepth", depthNode.Value.Value); + var newValue = (int)(oldValue * 1024); + depthNode.Value.Value = newValue.ToString(); + } + } + } + UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/OpenRA.Mods.RA/Traits/Minelayer.cs b/OpenRA.Mods.RA/Traits/Minelayer.cs index 799266fe00..ab933a47a8 100644 --- a/OpenRA.Mods.RA/Traits/Minelayer.cs +++ b/OpenRA.Mods.RA/Traits/Minelayer.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA.Traits public readonly string AmmoPoolName = "primary"; - public readonly float MinefieldDepth = 1.5f; + public readonly WDist MinefieldDepth = new WDist(1536); public object Create(ActorInitializer init) { return new Minelayer(init.Self); } } @@ -97,7 +97,7 @@ namespace OpenRA.Mods.RA.Traits } } - static IEnumerable GetMinefieldCells(CPos start, CPos end, float depth) + static IEnumerable GetMinefieldCells(CPos start, CPos end, WDist depth) { var mins = CPos.Min(start, end); var maxs = CPos.Max(start, end); @@ -113,7 +113,7 @@ namespace OpenRA.Mods.RA.Traits for (var i = mins.X; i <= maxs.X; i++) for (var j = mins.Y; j <= maxs.Y; j++) - if (Math.Abs(q.X * i + q.Y * j + c) < depth) + if (Math.Abs(q.X * i + q.Y * j + c) * 1024 < depth.Length) yield return new CPos(i, j); } From 1ee4131f35775d164cbf5ebf2bc0f0313fb7fa51 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 24 Mar 2016 17:46:58 +0100 Subject: [PATCH 5/5] Make ThrowsParticle use WAngle instead of float --- OpenRA.Mods.Common/Traits/ThrowsParticle.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs index b2e63bbc93..5771bfb9d8 100644 --- a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs +++ b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits public readonly int Velocity = 75; [Desc("Speed at which the particle turns.")] - public readonly float TurnSpeed = 15; + public readonly int TurnSpeed = 15; public object Create(ActorInitializer init) { return new ThrowsParticle(init, this); } } @@ -53,8 +53,8 @@ namespace OpenRA.Mods.Common.Traits int tick = 0; int length; - float facing; - float rotation; + WAngle facing; + WAngle rotation; public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info) { @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits // TODO: Carry orientation over from the parent instead of just facing var bodyFacing = init.Contains() ? init.Get() : 0; - facing = Turreted.GetInitialTurretFacing(init, 0); + facing = WAngle.FromFacing(Turreted.GetInitialTurretFacing(init, 0)); // Calculate final position var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); @@ -76,23 +76,23 @@ namespace OpenRA.Mods.Common.Traits length = (finalPos - initialPos).Length / info.Velocity; // Facing rotation - rotation = WDist.FromPDF(Game.CosmeticRandom, 2).Length * info.TurnSpeed / 1024; + rotation = WAngle.FromFacing(WDist.FromPDF(Game.CosmeticRandom, 2).Length * info.TurnSpeed / 1024); - var anim = new Animation(init.World, rs.GetImage(self), () => (int)facing); + var anim = new Animation(init.World, rs.GetImage(self), () => facing.Angle / 4); anim.PlayRepeating(info.Anim); rs.Add(new AnimationWithOffset(anim, () => pos, null)); } public void Tick(Actor self) { - if (tick == length) + if (tick >= length) return; pos = WVec.LerpQuadratic(initialPos, finalPos, angle, tick++, length); // Spin the particle facing += rotation; - rotation *= .9f; + rotation = new WAngle(rotation.Angle * 90 / 100); } } }