Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use real (milli)seconds for intervalled notifications #19295

Merged
merged 1 commit into from Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 7 additions & 7 deletions OpenRA.Mods.Common/Traits/Player/BaseAttackNotifier.cs
Expand Up @@ -19,8 +19,8 @@ namespace OpenRA.Mods.Common.Traits
"Attach this to the player actor.")]
public class BaseAttackNotifierInfo : TraitInfo
{
[Desc("Minimum duration (in seconds) between notification events.")]
public readonly int NotifyInterval = 30;
[Desc("Minimum duration (in milliseconds) between notification events.")]
public readonly int NotifyInterval = 30000;

public readonly Color RadarPingColor = Color.Red;

Expand All @@ -44,13 +44,13 @@ public class BaseAttackNotifier : INotifyDamage
readonly RadarPings radarPings;
readonly BaseAttackNotifierInfo info;

int lastAttackTime;
long lastAttackTime;

public BaseAttackNotifier(Actor self, BaseAttackNotifierInfo info)
{
radarPings = self.World.WorldActor.TraitOrDefault<RadarPings>();
this.info = info;
lastAttackTime = -info.NotifyInterval * 25;
reaperrr marked this conversation as resolved.
Show resolved Hide resolved
lastAttackTime = -info.NotifyInterval;
}

void INotifyDamage.Damaged(Actor self, AttackInfo e)
Expand All @@ -71,7 +71,7 @@ void INotifyDamage.Damaged(Actor self, AttackInfo e)
if (e.Attacker.Owner.IsAlliedWith(self.Owner) && e.Damage.Value <= 0)
return;

if (self.World.WorldTick - lastAttackTime > info.NotifyInterval * 25)
if (Game.RunTime > lastAttackTime + info.NotifyInterval)
{
var rules = self.World.Map.Rules;
Game.Sound.PlayNotification(rules, self.Owner, "Speech", info.Notification, self.Owner.Faction.InternalName);
Expand All @@ -82,9 +82,9 @@ void INotifyDamage.Damaged(Actor self, AttackInfo e)
Game.Sound.PlayNotification(rules, p, "Speech", info.AllyNotification, p.Faction.InternalName);

radarPings?.Add(() => self.Owner.IsAlliedWith(self.World.RenderPlayer), self.CenterPosition, info.RadarPingColor, info.RadarPingDuration);
}

lastAttackTime = self.World.WorldTick;
lastAttackTime = Game.RunTime;
}
}
}
}
15 changes: 7 additions & 8 deletions OpenRA.Mods.Common/Traits/Player/HarvesterAttackNotifier.cs
Expand Up @@ -19,8 +19,8 @@ namespace OpenRA.Mods.Common.Traits
[TraitLocation(SystemActors.Player)]
public class HarvesterAttackNotifierInfo : TraitInfo
{
[Desc("Minimum duration (in seconds) between notification events.")]
public readonly int NotifyInterval = 30;
[Desc("Minimum duration (in milliseconds) between notification events.")]
public readonly int NotifyInterval = 30000;

public readonly Color RadarPingColor = Color.Red;

Expand All @@ -39,13 +39,13 @@ public class HarvesterAttackNotifier : INotifyDamage
readonly RadarPings radarPings;
readonly HarvesterAttackNotifierInfo info;

int lastAttackTime;
long lastAttackTime;

public HarvesterAttackNotifier(Actor self, HarvesterAttackNotifierInfo info)
{
radarPings = self.World.WorldActor.TraitOrDefault<RadarPings>();
this.info = info;
lastAttackTime = -info.NotifyInterval * 25;
reaperrr marked this conversation as resolved.
Show resolved Hide resolved
lastAttackTime = -info.NotifyInterval;
}

void INotifyDamage.Damaged(Actor self, AttackInfo e)
Expand All @@ -58,14 +58,13 @@ void INotifyDamage.Damaged(Actor self, AttackInfo e)
if (!self.Info.HasTraitInfo<HarvesterInfo>())
return;

if (self.World.WorldTick - lastAttackTime > info.NotifyInterval * 25)
if (Game.RunTime > lastAttackTime + info.NotifyInterval)
{
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.Notification, self.Owner.Faction.InternalName);

radarPings?.Add(() => self.Owner.IsAlliedWith(self.World.RenderPlayer), self.CenterPosition, info.RadarPingColor, info.RadarPingDuration);
}

lastAttackTime = self.World.WorldTick;
lastAttackTime = Game.RunTime;
}
}
}
}
10 changes: 6 additions & 4 deletions OpenRA.Mods.Common/Traits/Player/PlayerResources.cs
Expand Up @@ -45,7 +45,7 @@ public class PlayerResourcesInfo : TraitInfo, ILobbyOptions
public readonly string InsufficientFundsNotification = null;

[Desc("Delay (in ticks) during which warnings will be muted.")]
public readonly int InsufficientFundsNotificationDelay = 750;
public readonly int InsufficientFundsNotificationInterval = 30000;

[NotificationReference("Sounds")]
public readonly string CashTickUpNotification = null;
Expand Down Expand Up @@ -83,6 +83,8 @@ public PlayerResources(Actor self, PlayerResourcesInfo info)

if (!int.TryParse(startingCash, out Cash))
Cash = info.DefaultCash;

lastNotificationTime = -Info.InsufficientFundsNotificationInterval;
}

[Sync]
Expand All @@ -97,7 +99,7 @@ public PlayerResources(Actor self, PlayerResourcesInfo info)
public int Earned;
public int Spent;

int lastNotificationTick;
long lastNotificationTime;
reaperrr marked this conversation as resolved.
Show resolved Hide resolved

public int ChangeCash(int amount)
{
Expand Down Expand Up @@ -178,9 +180,9 @@ public bool TakeCash(int num, bool notifyLowFunds = false)
if (Cash + Resources < num)
{
if (notifyLowFunds && !string.IsNullOrEmpty(Info.InsufficientFundsNotification) &&
owner.World.WorldTick - lastNotificationTick >= Info.InsufficientFundsNotificationDelay)
Game.RunTime > lastNotificationTime + Info.InsufficientFundsNotificationInterval)
{
lastNotificationTick = owner.World.WorldTick;
lastNotificationTime = Game.RunTime;
Game.Sound.PlayNotification(owner.World.Map.Rules, owner, "Speech", Info.InsufficientFundsNotification, owner.Faction.InternalName);
}

Expand Down
10 changes: 5 additions & 5 deletions OpenRA.Mods.Common/Traits/Player/ResourceStorageWarning.cs
Expand Up @@ -17,8 +17,8 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Provides the player with an audible warning when their storage is nearing full.")]
public class ResourceStorageWarningInfo : TraitInfo, Requires<PlayerResourcesInfo>
{
[Desc("Interval, in seconds, at which to check if more storage is needed.")]
public readonly int AdviceInterval = 20;
[Desc("Interval (in milliseconds) at which to check if more storage is needed.")]
public readonly int AdviceInterval = 20000;

[Desc("The percentage threshold above which a warning is played.")]
public readonly int Threshold = 80;
Expand All @@ -35,7 +35,7 @@ public class ResourceStorageWarning : ITick
readonly ResourceStorageWarningInfo info;
readonly PlayerResources resources;

int nextSiloAdviceTime = 0;
long lastSiloAdviceTime;
reaperrr marked this conversation as resolved.
Show resolved Hide resolved

public ResourceStorageWarning(Actor self, ResourceStorageWarningInfo info)
{
Expand All @@ -45,14 +45,14 @@ public ResourceStorageWarning(Actor self, ResourceStorageWarningInfo info)

void ITick.Tick(Actor self)
{
if (--nextSiloAdviceTime <= 0)
if (Game.RunTime > lastSiloAdviceTime + info.AdviceInterval)
{
var owner = self.Owner;

if (resources.Resources > info.Threshold * resources.ResourceCapacity / 100)
Game.Sound.PlayNotification(self.World.Map.Rules, owner, "Speech", info.Notification, owner.Faction.InternalName);

nextSiloAdviceTime = info.AdviceInterval * 1000 / self.World.Timestep;
lastSiloAdviceTime = Game.RunTime;
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions OpenRA.Mods.Common/Traits/Power/Player/PowerManager.cs
Expand Up @@ -19,7 +19,8 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Attach this to the player actor.")]
public class PowerManagerInfo : TraitInfo, Requires<DeveloperModeInfo>
{
public readonly int AdviceInterval = 250;
[Desc("Interval (in milliseconds) at which to warn the player of low power.")]
public readonly int AdviceInterval = 10000;

[NotificationReference("Speech")]
public readonly string SpeechNotification = null;
Expand Down Expand Up @@ -50,7 +51,7 @@ public class PowerManager : INotifyCreated, ITick, ISync, IResolveOrder
public int PowerOutageRemainingTicks { get; private set; }
public int PowerOutageTotalTicks { get; private set; }

int nextPowerAdviceTime = 0;
long lastPowerAdviceTime;
bool isLowPower = false;
bool wasLowPower = false;
bool wasHackEnabled;
Expand Down Expand Up @@ -128,8 +129,9 @@ void UpdatePowerState()
if (isLowPower != wasLowPower)
UpdatePowerRequiringActors();

// Force the notification to play immediately
if (isLowPower && !wasLowPower)
nextPowerAdviceTime = 0;
lastPowerAdviceTime = -info.AdviceInterval;

wasLowPower = isLowPower;
}
Expand All @@ -156,10 +158,10 @@ void ITick.Tick(Actor self)
UpdatePowerState();
}

if (isLowPower && --nextPowerAdviceTime <= 0)
if (isLowPower && Game.RunTime > lastPowerAdviceTime + info.AdviceInterval)
{
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.SpeechNotification, self.Owner.Faction.InternalName);
nextPowerAdviceTime = info.AdviceInterval;
lastPowerAdviceTime = Game.RunTime;
}

if (PowerOutageRemainingTicks > 0 && --PowerOutageRemainingTicks == 0)
Expand Down
12 changes: 6 additions & 6 deletions OpenRA.Mods.Common/Traits/Sound/AnnounceOnKill.cs
Expand Up @@ -16,8 +16,8 @@ namespace OpenRA.Mods.Common.Traits.Sound
[Desc("Play the Kill voice of this actor when eliminating enemies.")]
public class AnnounceOnKillInfo : TraitInfo
{
[Desc("Minimum duration (in seconds) between sound events.")]
public readonly int Interval = 5;
[Desc("Minimum duration (in milliseconds) between sound events.")]
public readonly int Interval = 5000;

[VoiceReference]
[Desc("Voice to use when killing something.")]
Expand All @@ -30,23 +30,23 @@ public class AnnounceOnKill : INotifyAppliedDamage
{
readonly AnnounceOnKillInfo info;

int lastAnnounce;
long lastAnnounce;

public AnnounceOnKill(Actor self, AnnounceOnKillInfo info)
{
this.info = info;
lastAnnounce = -info.Interval * 25;
reaperrr marked this conversation as resolved.
Show resolved Hide resolved
lastAnnounce = -info.Interval;
}

void INotifyAppliedDamage.AppliedDamage(Actor self, Actor damaged, AttackInfo e)
{
// Don't notify suicides
if (e.DamageState == DamageState.Dead && damaged != e.Attacker)
{
if (self.World.WorldTick - lastAnnounce > info.Interval * 25)
if (Game.RunTime > lastAnnounce + info.Interval)
self.PlayVoice(info.Voice);

lastAnnounce = self.World.WorldTick;
lastAnnounce = Game.RunTime;
}
}
}
Expand Down
@@ -0,0 +1,92 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 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;

namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class UseMillisecondsForSounds : UpdateRule
{
public override string Name => "Convert announcement/notifier intervals to real (milli)seconds.";

public override string Description =>
"AnnounceOnKill.Interval, Harvester- and BaseAttackNotifier.NotifyInterval and\n" +
"ResourceStorageWarning.AdviceInterval were using 'fake' seconds (value * 25 ticks).\n" +
"PowerManager.AdviceInterval and PlayerResources.InsufficientFundsNotificationDelay were using ticks.\n" +
"Converted all of those to use real milliseconds instead.";

public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var announce in actorNode.ChildrenMatching("AnnounceOnKill"))
{
var intervalNode = announce.LastChildMatching("Interval");
if (intervalNode != null)
{
var interval = intervalNode.NodeValue<int>();
intervalNode.Value.Value = FieldSaver.FormatValue(interval * 1000);
}
}

foreach (var notifier in actorNode.ChildrenMatching("BaseAttackNotifier"))
{
var notifyIntervalNode = notifier.LastChildMatching("NotifyInterval");
if (notifyIntervalNode != null)
{
var notifyInterval = notifyIntervalNode.NodeValue<int>();
notifyIntervalNode.Value.Value = FieldSaver.FormatValue(notifyInterval * 1000);
}
}

foreach (var notifier in actorNode.ChildrenMatching("HarvesterAttackNotifier"))
{
var notifyIntervalNode = notifier.LastChildMatching("NotifyInterval");
if (notifyIntervalNode != null)
{
var notifyInterval = notifyIntervalNode.NodeValue<int>();
notifyIntervalNode.Value.Value = FieldSaver.FormatValue(notifyInterval * 1000);
}
}

foreach (var rsw in actorNode.ChildrenMatching("ResourceStorageWarning"))
{
var adviceIntervalNode = rsw.LastChildMatching("AdviceInterval");
if (adviceIntervalNode != null)
{
var adviceInterval = adviceIntervalNode.NodeValue<int>();
adviceIntervalNode.Value.Value = FieldSaver.FormatValue(adviceInterval * 1000);
}
}

foreach (var pm in actorNode.ChildrenMatching("PowerManager"))
{
var adviceIntervalNode = pm.LastChildMatching("AdviceInterval");
if (adviceIntervalNode != null)
{
var adviceInterval = adviceIntervalNode.NodeValue<int>();
adviceIntervalNode.Value.Value = FieldSaver.FormatValue(adviceInterval * 40);
}
}

foreach (var pr in actorNode.ChildrenMatching("PlayerResources"))
{
var noFundsIntervalNode = pr.LastChildMatching("InsufficientFundsNotificationDelay");
if (noFundsIntervalNode != null)
{
var noFundsInterval = noFundsIntervalNode.NodeValue<int>();
noFundsIntervalNode.Value.Value = FieldSaver.FormatValue(noFundsInterval * 40);
noFundsIntervalNode.RenameKey("InsufficientFundsNotificationInterval");
}
}

yield break;
}
}
}
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/UpdateRules/UpdatePath.cs
Expand Up @@ -95,6 +95,7 @@ public class UpdatePath
new ConvertBoundsToWDist(),
new RemoveSmokeTrailWhenDamaged(),
new ReplaceCrateSecondsWithTicks(),
new UseMillisecondsForSounds(),
})
};

Expand Down
4 changes: 2 additions & 2 deletions mods/d2k/rules/player.yaml
Expand Up @@ -92,7 +92,7 @@ Player:
LeaveNotification: Leave
ConquestVictoryConditions:
PowerManager:
AdviceInterval: 650
AdviceInterval: 26000
SpeechNotification: LowPower
AllyRepair:
PlayerResources:
Expand Down Expand Up @@ -157,7 +157,7 @@ Player:
HarvesterInsurance:
GrantConditionOnPrerequisiteManager:
ResourceStorageWarning:
AdviceInterval: 26
AdviceInterval: 26000
PlayerExperience:
GameSaveViewportManager:
PlayerRadarTerrain: