diff --git a/OpenRA.Mods.Common/Activities/CaptureActor.cs b/OpenRA.Mods.Common/Activities/CaptureActor.cs index b0351f5103..0378fbce5e 100644 --- a/OpenRA.Mods.Common/Activities/CaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/CaptureActor.cs @@ -65,6 +65,13 @@ namespace OpenRA.Mods.Common.Activities if (building != null && building.Locked) building.Unlock(); + + if (self.Owner.Stances[oldOwner].HasStance(capturesInfo.PlayerExperienceStances)) + { + var exp = self.Owner.PlayerActor.TraitOrDefault(); + if (exp != null) + exp.GiveExperience(capturesInfo.PlayerExperience); + } } else { diff --git a/OpenRA.Mods.Common/Activities/DonateSupplies.cs b/OpenRA.Mods.Common/Activities/DonateSupplies.cs index f4af59a294..9640f71fab 100644 --- a/OpenRA.Mods.Common/Activities/DonateSupplies.cs +++ b/OpenRA.Mods.Common/Activities/DonateSupplies.cs @@ -10,6 +10,7 @@ #endregion using OpenRA.Mods.Common.Effects; +using OpenRA.Mods.Common.Traits; using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities @@ -18,12 +19,14 @@ namespace OpenRA.Mods.Common.Activities { readonly Actor target; readonly int payload; + readonly int experience; - public DonateSupplies(Actor self, Actor target, int payload) + public DonateSupplies(Actor self, Actor target, int payload, int playerExperience) : base(self, target, EnterBehaviour.Dispose) { this.target = target; this.payload = payload; + this.experience = playerExperience; } protected override void OnInside(Actor self) @@ -33,6 +36,10 @@ namespace OpenRA.Mods.Common.Activities target.Owner.PlayerActor.Trait().GiveCash(payload); + var exp = self.Owner.PlayerActor.TraitOrDefault(); + if (exp != null && target.Owner != self.Owner) + exp.GiveExperience(experience); + if (self.Owner.IsAlliedWith(self.World.RenderPlayer)) self.World.AddFrameEndTask(w => w.Add(new FloatingText(target.CenterPosition, target.Owner.Color.RGB, FloatingText.FormatCashTick(payload), 30))); } diff --git a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs index f14477185d..05e8b4562f 100644 --- a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs @@ -77,6 +77,13 @@ namespace OpenRA.Mods.Common.Activities capturable.EndCapture(); + if (self.Owner.Stances[oldOwner].HasStance(capturesInfo.PlayerExperienceStances)) + { + var exp = self.Owner.PlayerActor.TraitOrDefault(); + if (exp != null) + exp.GiveExperience(capturesInfo.PlayerExperience); + } + if (capturesInfo != null && capturesInfo.ConsumeActor) self.Dispose(); }); diff --git a/OpenRA.Mods.Common/Activities/Repair.cs b/OpenRA.Mods.Common/Activities/Repair.cs index ff3f06fb2f..aeff9e65f5 100644 --- a/OpenRA.Mods.Common/Activities/Repair.cs +++ b/OpenRA.Mods.Common/Activities/Repair.cs @@ -49,6 +49,13 @@ namespace OpenRA.Mods.Common.Activities if (health.DamageState == DamageState.Undamaged) { + if (host.Owner != self.Owner) + { + var exp = host.Owner.PlayerActor.TraitOrDefault(); + if (exp != null) + exp.GiveExperience(repairsUnits.PlayerExperience); + } + Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.FinishRepairingNotification, self.Owner.Faction.InternalName); return NextActivity; } diff --git a/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs b/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs index a3831788bf..64f95b852f 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs @@ -35,6 +35,9 @@ namespace OpenRA.Mods.Common.Traits [Desc("Suffixed by the internal repairing player name.")] public readonly string IndicatorPalettePrefix = "player"; + [Desc("Experience gained by a player for repairing structures of allied players.")] + public readonly int PlayerExperience = 0; + public override object Create(ActorInitializer init) { return new RepairableBuilding(init.Self, this); } } @@ -133,6 +136,16 @@ namespace OpenRA.Mods.Common.Traits if (health.DamageState == DamageState.Undamaged) { + Repairers.Do(r => + { + if (r == self.Owner) + return; + + var exp = r.PlayerActor.TraitOrDefault(); + if (exp != null) + exp.GiveExperience(Info.PlayerExperience); + }); + Repairers.Clear(); RepairActive = false; return; diff --git a/OpenRA.Mods.Common/Traits/Buildings/RepairsUnits.cs b/OpenRA.Mods.Common/Traits/Buildings/RepairsUnits.cs index a1728ff5ca..063724e13e 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RepairsUnits.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RepairsUnits.cs @@ -27,6 +27,9 @@ namespace OpenRA.Mods.Common.Traits [Desc("The sound played when repairing a unit is done.")] public readonly string FinishRepairingNotification = null; + + [Desc("Experience gained by the player owning this actor for repairing an allied unit.")] + public readonly int PlayerExperience = 0; } public class RepairsUnits { } diff --git a/OpenRA.Mods.Common/Traits/Captures.cs b/OpenRA.Mods.Common/Traits/Captures.cs index 8c584d5544..3ec469732c 100644 --- a/OpenRA.Mods.Common/Traits/Captures.cs +++ b/OpenRA.Mods.Common/Traits/Captures.cs @@ -22,11 +22,19 @@ namespace OpenRA.Mods.Common.Traits { [Desc("Types of actors that it can capture, as long as the type also exists in the Capturable Type: trait.")] public readonly HashSet CaptureTypes = new HashSet { "building" }; + [Desc("Unit will do damage to the actor instead of capturing it. Unit is destroyed when sabotaging.")] public readonly bool Sabotage = true; + [Desc("Only used if Sabotage=true. Sabotage damage expressed as a percentage of enemy health removed.")] public readonly int SabotageHPRemoval = 50; + [Desc("Experience granted to the capturing player.")] + public readonly int PlayerExperience = 0; + + [Desc("Stance that the structure's previous owner needs to have for the capturing player to receive Experience.")] + public readonly Stance PlayerExperienceStances = Stance.Enemy; + [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new Captures(init.Self, this); } diff --git a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs index e72302c674..d3d2994399 100644 --- a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs +++ b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs @@ -26,6 +26,12 @@ namespace OpenRA.Mods.Common.Traits [Desc("Destroy the unit after capturing.")] public readonly bool ConsumeActor = false; + [Desc("Experience granted to the capturing player.")] + public readonly int PlayerExperience = 0; + + [Desc("Stance that the structure's previous owner needs to have for the capturing player to receive Experience.")] + public readonly Stance PlayerExperienceStances = Stance.Enemy; + [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new ExternalCaptures(init.Self, this); } diff --git a/OpenRA.Mods.Common/Traits/SupplyTruck.cs b/OpenRA.Mods.Common/Traits/SupplyTruck.cs index 2f731b3636..20f52158fe 100644 --- a/OpenRA.Mods.Common/Traits/SupplyTruck.cs +++ b/OpenRA.Mods.Common/Traits/SupplyTruck.cs @@ -23,6 +23,9 @@ namespace OpenRA.Mods.Common.Traits [Desc("The amount of cash the owner receives.")] public readonly int Payload = 500; + [Desc("The amount of experience the donating player receives.")] + public readonly int PlayerExperience = 0; + [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new SupplyTruck(this); } @@ -71,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits self.CancelActivity(); self.SetTargetLine(target, Color.Yellow); - self.QueueActivity(new DonateSupplies(self, target.Actor, info.Payload)); + self.QueueActivity(new DonateSupplies(self, target.Actor, info.Payload, info.PlayerExperience)); } class SupplyTruckOrderTargeter : UnitOrderTargeter diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs index c089793293..677da89a78 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Mods.Common.Traits; @@ -59,58 +60,70 @@ namespace OpenRA.Mods.Common.Widgets.Logic playerPanel.Bounds.Height += objectiveGroup.Bounds.Height; } + var teamTemplate = playerPanel.Get("TEAM_TEMPLATE"); var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE"); playerPanel.RemoveChildren(); - foreach (var p in world.Players.Where(a => !a.NonCombatant)) + var teams = world.Players.Where(p => !p.NonCombatant && p.Playable) + .Select(p => new Pair(p, p.PlayerActor.TraitOrDefault())) + .OrderByDescending(p => p.Second != null ? p.Second.Experience : 0) + .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.First.ClientIndex) ?? new Session.Client()).Team) + .OrderByDescending(g => g.Sum(gg => gg.Second != null ? gg.Second.Experience : 0)); + + foreach (var t in teams) { - var pp = p; - var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex); - var item = playerTemplate.Clone(); - LobbyUtils.SetupClientWidget(item, client, orderManager, client != null && client.Bot == null); - var nameLabel = item.Get("NAME"); - var nameFont = Game.Renderer.Fonts[nameLabel.Font]; - - var suffixLength = new CachedTransform(s => nameFont.Measure(s).X); - var name = new CachedTransform, string>(c => - WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - c.Second, nameFont)); - - nameLabel.GetText = () => + if (teams.Count() > 1) { - var suffix = pp.WinState == WinState.Undefined ? "" : " (" + pp.WinState + ")"; - if (client != null && client.State == Session.ClientState.Disconnected) - suffix = " (Gone)"; + var teamHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { }); + teamHeader.Get("TEAM").GetText = () => t.Key == 0 ? "No Team" : "Team {0}".F(t.Key); + var teamRating = teamHeader.Get("TEAM_SCORE"); + teamRating.GetText = () => t.Sum(gg => gg.Second != null ? gg.Second.Experience : 0).ToString(); - var sl = suffixLength.Update(suffix); - return name.Update(Pair.New(pp.PlayerName, sl)) + suffix; - }; - nameLabel.GetColor = () => pp.Color.RGB; - - var flag = item.Get("FACTIONFLAG"); - flag.GetImageCollection = () => "flags"; - if (player == null || player.Stances[pp] == Stance.Ally || player.WinState != WinState.Undefined) - { - flag.GetImageName = () => pp.Faction.InternalName; - item.Get("FACTION").GetText = () => pp.Faction.Name; - } - else - { - flag.GetImageName = () => pp.DisplayFaction.InternalName; - item.Get("FACTION").GetText = () => pp.DisplayFaction.Name; + playerPanel.AddChild(teamHeader); } - var team = item.Get("TEAM"); - var teamNumber = pp.PlayerReference.Playable ? ((client == null) ? 0 : client.Team) : pp.PlayerReference.Team; - team.GetText = () => (teamNumber == 0) ? "-" : teamNumber.ToString(); - playerPanel.AddChild(item); + foreach (var p in t.ToList()) + { + var pp = p.First; + var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex); + var item = playerTemplate.Clone(); + LobbyUtils.SetupClientWidget(item, client, orderManager, client != null && client.Bot == null); + var nameLabel = item.Get("NAME"); + var nameFont = Game.Renderer.Fonts[nameLabel.Font]; - var stats = pp.PlayerActor.TraitOrDefault(); - if (stats == null) - break; - var totalKills = stats.UnitsKilled + stats.BuildingsKilled; - var totalDeaths = stats.UnitsDead + stats.BuildingsDead; - item.Get("KILLS").GetText = () => totalKills.ToString(); - item.Get("DEATHS").GetText = () => totalDeaths.ToString(); + var suffixLength = new CachedTransform(s => nameFont.Measure(s).X); + var name = new CachedTransform, string>(c => + WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - c.Second, nameFont)); + + nameLabel.GetText = () => + { + var suffix = pp.WinState == WinState.Undefined ? "" : " (" + pp.WinState + ")"; + if (client != null && client.State == Session.ClientState.Disconnected) + suffix = " (Gone)"; + + var sl = suffixLength.Update(suffix); + return name.Update(Pair.New(pp.PlayerName, sl)) + suffix; + }; + nameLabel.GetColor = () => pp.Color.RGB; + + var flag = item.Get("FACTIONFLAG"); + flag.GetImageCollection = () => "flags"; + if (player == null || player.Stances[pp] == Stance.Ally || player.WinState != WinState.Undefined) + { + flag.GetImageName = () => pp.Faction.InternalName; + item.Get("FACTION").GetText = () => pp.Faction.Name; + } + else + { + flag.GetImageName = () => pp.DisplayFaction.InternalName; + item.Get("FACTION").GetText = () => pp.DisplayFaction.Name; + } + + var experience = p.Second != null ? p.Second.Experience : 0; + item.Get("SCORE").GetText = () => experience.ToString(); + + playerPanel.AddChild(item); + } } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs index 2c5e2a2ef2..b5d4469059 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs @@ -273,6 +273,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic template.Get("DEATHS").GetText = () => (stats.UnitsDead + stats.BuildingsDead).ToString(); template.Get("ASSETS_DESTROYED").GetText = () => "$" + stats.KillsCost; template.Get("ASSETS_LOST").GetText = () => "$" + stats.DeathsCost; + template.Get("EXPERIENCE").GetText = () => stats.Experience.ToString(); template.Get("ACTIONS_MIN").GetText = () => AverageOrdersPerMinute(stats.OrderCount); return template; diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index df68f7ae46..36147a0227 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -21,13 +21,15 @@ namespace OpenRA.Mods.RA.Activities readonly Stance validStances; readonly Cloak cloak; readonly string notification; + readonly int experience; - public Infiltrate(Actor self, Actor target, EnterBehaviour enterBehaviour, Stance validStances, string notification) + public Infiltrate(Actor self, Actor target, EnterBehaviour enterBehaviour, Stance validStances, string notification, int experience) : base(self, target, enterBehaviour) { this.target = target; this.validStances = validStances; this.notification = notification; + this.experience = experience; cloak = self.TraitOrDefault(); } @@ -46,6 +48,10 @@ namespace OpenRA.Mods.RA.Activities foreach (var t in target.TraitsImplementing()) t.Infiltrated(target, self); + var exp = self.Owner.PlayerActor.TraitOrDefault(); + if (exp != null) + exp.GiveExperience(experience); + if (!string.IsNullOrEmpty(notification)) Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", notification, self.Owner.Faction.InternalName); diff --git a/OpenRA.Mods.RA/Scripting/Properties/InfiltrateProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/InfiltrateProperties.cs index d1e510f158..f08a691cbe 100644 --- a/OpenRA.Mods.RA/Scripting/Properties/InfiltrateProperties.cs +++ b/OpenRA.Mods.RA/Scripting/Properties/InfiltrateProperties.cs @@ -30,7 +30,7 @@ namespace OpenRA.Mods.RA.Scripting [Desc("Infiltrate the target actor.")] public void Infiltrate(Actor target) { - Self.QueueActivity(new Infiltrate(Self, target, info.EnterBehaviour, info.ValidStances, info.Notification)); + Self.QueueActivity(new Infiltrate(Self, target, info.EnterBehaviour, info.ValidStances, info.Notification, info.PlayerExperience)); } } } diff --git a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs index 9687f65b50..41fa7ce526 100644 --- a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs +++ b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs @@ -37,6 +37,9 @@ namespace OpenRA.Mods.RA.Traits [Desc("Notification to play when a building is infiltrated.")] public readonly string Notification = "BuildingInfiltrated"; + [Desc("Experience to grant to the infiltrating player.")] + public readonly int PlayerExperience = 0; + public object Create(ActorInitializer init) { return new Infiltrates(this); } } @@ -112,7 +115,7 @@ namespace OpenRA.Mods.RA.Traits self.CancelActivity(); self.SetTargetLine(target, Color.Red); - self.QueueActivity(new Infiltrate(self, target.Actor, info.EnterBehaviour, info.ValidStances, info.Notification)); + self.QueueActivity(new Infiltrate(self, target.Actor, info.EnterBehaviour, info.ValidStances, info.Notification, info.PlayerExperience)); } } diff --git a/mods/cnc/chrome/ingame-infostats.yaml b/mods/cnc/chrome/ingame-infostats.yaml index 8815d31a7e..6e12d1bb1a 100644 --- a/mods/cnc/chrome/ingame-infostats.yaml +++ b/mods/cnc/chrome/ingame-infostats.yaml @@ -35,38 +35,23 @@ Container@SKIRMISH_STATS: Children: Label@NAME: X: 10 - Width: 150 + Width: 210 Height: 25 Text: Player Font: Bold Label@FACTION: - X: 150 - Width: 80 + X: 230 + Width: 120 Height: 25 Text: Faction Font: Bold - Align: Center - Label@STANCE: - X: 240 - Width: 70 + Label@SCORE: + X: 360 + Width: 75 Height: 25 - Text: Team + Text: Score Font: Bold - Align: Center - Label@KILLS: - X: 310 - Width: 70 - Height: 25 - Text: Kills - Font: Bold - Align: Center - Label@DEATHS: - X: 380 - Width: 70 - Height: 25 - Text: Deaths - Font: Bold - Align: Center + Align: Right ScrollPanel@PLAYER_LIST: X: 15 Y: 105 @@ -75,43 +60,51 @@ Container@SKIRMISH_STATS: TopBottomSpacing: 5 ItemSpacing: 5 Children: + ScrollItem@TEAM_TEMPLATE: + Width: PARENT_RIGHT - 27 + Height: 20 + X: 2 + Visible: false + Children: + Label@TEAM: + X: 2 + Y: 0-2 + Width: 160 + Height: 20 + Font: Bold + Label@TEAM_SCORE: + X: 360 + Y: 0-2 + Width: 75 + Height: 20 + Font: Bold + Align: Right Container@PLAYER_TEMPLATE: Width: PARENT_RIGHT-27 Height: 25 X: 2 - Y: 0 Children: Label@NAME: X: 10 - Width: 150 + Width: 210 Height: 25 ClientTooltipRegion@CLIENT_REGION: TooltipContainer: TOOLTIP_CONTAINER Template: INGAME_CLIENT_TOOLTIP X: 10 - Width: 150 + Width: 210 Height: 25 Image@FACTIONFLAG: - X: 159 + X: 230 Y: 6 Width: 32 Height: 16 Label@FACTION: - X: 195 - Width: 40 + X: 264 + Width: 86 Height: 25 - Label@TEAM: - X: 240 - Width: 70 + Label@SCORE: + X: 360 + Width: 75 Height: 25 - Align: Center - Label@KILLS: - X: 310 - Width: 70 - Height: 25 - Align: Center - Label@DEATHS: - X: 380 - Width: 70 - Height: 25 - Align: Center + Align: Right diff --git a/mods/cnc/chrome/ingame-observerstats.yaml b/mods/cnc/chrome/ingame-observerstats.yaml index ae890bb166..4081e2d4e0 100644 --- a/mods/cnc/chrome/ingame-observerstats.yaml +++ b/mods/cnc/chrome/ingame-observerstats.yaml @@ -2,7 +2,7 @@ Background@INGAME_OBSERVERSTATS_BG: Logic: ObserverStatsLogic X: (WINDOW_RIGHT - WIDTH) / 2 Y: (WINDOW_BOTTOM - HEIGHT) / 2 - Width: 940 + Width: 1005 Height: 500 Children: Background@BACKGROUND: @@ -59,41 +59,49 @@ Background@INGAME_OBSERVERSTATS_BG: Font: Bold Text: Power Label@KILLS_HEADER: - X: 495 + X: 475 Y: 40 - Width: 40 + Width: 60 Height: 25 Font: Bold Text: Kills Align: Right Label@DEATHS_HEADER: - X: 555 + X: 535 Y: 40 - Width: 40 + Width: 60 Height: 25 Font: Bold Text: Deaths Align: Right Label@ASSETS_DESTROYED_HEADER: - X: 625 + X: 595 Y: 40 - Width: 60 + Width: 80 Height: 25 Font: Bold Text: Destroyed Align: Right Label@ASSETS_LOST_HEADER: - X: 685 + X: 675 Y: 40 - Width: 60 + Width: 80 Height: 25 Font: Bold Text: Lost Align: Right - Label@ACTIONS_MIN_HEADER: - X: 805 + Label@EXPERIENCE_HEADER: + X: 755 Y: 40 - Width: 40 + Width: 94 + Height: 25 + Font: Bold + Text: Experience + Align: Right + Label@ACTIONS_MIN_HEADER: + X: 850 + Y: 40 + Width: 90 Height: 25 Font: Bold Text: Actions/min @@ -316,33 +324,39 @@ Background@INGAME_OBSERVERSTATS_BG: Width: 80 Height: PARENT_BOTTOM Label@KILLS: - X: 475 + X: 455 Y: 0 - Width: 40 + Width: 60 Height: PARENT_BOTTOM Align: Right Label@DEATHS: - X: 535 + X: 515 Y: 0 - Width: 40 + Width: 60 Height: PARENT_BOTTOM Align: Right Label@ASSETS_DESTROYED: - X: 595 + X: 575 Y: 0 - Width: 60 + Width: 80 Height: PARENT_BOTTOM Align: Right Label@ASSETS_LOST: - X: 660 + X: 655 Y: 0 - Width: 60 + Width: 80 + Height: PARENT_BOTTOM + Align: Right + Label@EXPERIENCE: + X: 735 + Y: 0 + Width: 95 Height: PARENT_BOTTOM Align: Right Label@ACTIONS_MIN: - X: 775 + X: 830 Y: 0 - Width: 40 + Width: 90 Height: PARENT_BOTTOM Align: Right ScrollItem@ECONOMY_PLAYER_TEMPLATE: diff --git a/mods/cnc/rules/campaign-disable-experience.yaml b/mods/cnc/rules/campaign-disable-experience.yaml new file mode 100644 index 0000000000..165095ee8f --- /dev/null +++ b/mods/cnc/rules/campaign-disable-experience.yaml @@ -0,0 +1,23 @@ +^ExistsInWorld: + GivesExperience: + PlayerExperienceModifier: 0 + +^BaseBuilding: + RepairableBuilding: + PlayerExperience: 0 + +^TechBuilding: + RepairableBuilding: + PlayerExperience: 0 + +E6: + Captures: + PlayerExperience: 0 + +HPAD: + RepairsUnits: + PlayerExperience: 0 + +FIX: + RepairsUnits: + PlayerExperience: 0 diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 7169d0ca4d..0601877d6b 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -3,6 +3,7 @@ UpdatesPlayerStatistics: CombatDebugOverlay: GivesExperience: + PlayerExperienceModifier: 1 ScriptTriggers: UpgradeManager: Huntable: @@ -515,6 +516,7 @@ RepairableBuilding: RepairPercent: 40 RepairStep: 14 + PlayerExperience: 15 WithDeathAnimation: DeathSequence: dead UseDeathTypeSuffix: false @@ -560,6 +562,7 @@ RepairableBuilding: RepairPercent: 40 RepairStep: 14 + PlayerExperience: 15 EngineerRepairable: RevealsShroud: Range: 3c0 diff --git a/mods/cnc/rules/infantry.yaml b/mods/cnc/rules/infantry.yaml index 7e035b835e..c893fdc410 100644 --- a/mods/cnc/rules/infantry.yaml +++ b/mods/cnc/rules/infantry.yaml @@ -146,6 +146,7 @@ E6: RepairsBridges: Captures: CaptureTypes: building, husk + PlayerExperience: 50 -AutoTarget: -GainsExperience: diff --git a/mods/cnc/rules/player.yaml b/mods/cnc/rules/player.yaml index db4ae61a3a..7ed7a2fa29 100644 --- a/mods/cnc/rules/player.yaml +++ b/mods/cnc/rules/player.yaml @@ -34,3 +34,4 @@ Player: Id: unrestricted GlobalUpgradeManager: ResourceStorageWarning: + PlayerExperience: diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index a87ea2b146..e16d6ae76a 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -425,6 +425,7 @@ HPAD: Produces: Aircraft.GDI, Aircraft.Nod Reservable: RepairsUnits: + PlayerExperience: 25 WithRepairAnimation: RallyPoint: ProductionQueue@GDI: @@ -532,6 +533,7 @@ FIX: Reservable: RepairsUnits: Interval: 15 + PlayerExperience: 25 RallyPoint: WithRepairAnimation: Power: diff --git a/mods/d2k/chrome/ingame-infostats.yaml b/mods/d2k/chrome/ingame-infostats.yaml index 46b29dd0c9..4832ba512e 100644 --- a/mods/d2k/chrome/ingame-infostats.yaml +++ b/mods/d2k/chrome/ingame-infostats.yaml @@ -35,38 +35,23 @@ Container@SKIRMISH_STATS: Children: Label@NAME: X: 10 - Width: 150 + Width: 210 Height: 25 Text: Player Font: Bold Label@FACTION: - X: 150 - Width: 80 + X: 230 + Width: 120 Height: 25 Text: Faction Font: Bold - Align: Center - Label@STANCE: - X: 280 - Width: 50 + Label@SCORE: + X: 360 + Width: 75 Height: 25 - Text: Team + Text: Score Font: Bold - Align: Center - Label@KILLS: - X: 330 - Width: 60 - Height: 25 - Text: Kills - Font: Bold - Align: Center - Label@DEATHS: - X: 390 - Width: 60 - Height: 25 - Text: Deaths - Font: Bold - Align: Center + Align: Right ScrollPanel@PLAYER_LIST: X: 20 Y: 105 @@ -75,43 +60,52 @@ Container@SKIRMISH_STATS: TopBottomSpacing: 5 ItemSpacing: 5 Children: + ScrollItem@TEAM_TEMPLATE: + BaseName: scrollheader + Width: PARENT_RIGHT - 27 + Height: 20 + X: 2 + Visible: false + Children: + Label@TEAM: + X: 2 + Y: 0-2 + Width: 160 + Height: 20 + Font: Bold + Label@TEAM_SCORE: + X: 360 + Y: 0-2 + Width: 75 + Height: 20 + Font: Bold + Align: Right Container@PLAYER_TEMPLATE: Width: PARENT_RIGHT-27 Height: 25 X: 2 - Y: 0 Children: Label@NAME: X: 10 - Width: 150 + Width: 210 Height: 25 ClientTooltipRegion@CLIENT_REGION: TooltipContainer: TOOLTIP_CONTAINER Template: INGAME_CLIENT_TOOLTIP X: 10 - Width: 150 + Width: 210 Height: 25 Image@FACTIONFLAG: - X: 159 - Y: 3 + X: 230 + Y: 6 Width: 32 Height: 16 Label@FACTION: - X: 195 - Width: 85 + X: 264 + Width: 86 Height: 25 - Label@TEAM: - X: 280 - Width: 50 + Label@SCORE: + X: 360 + Width: 75 Height: 25 - Align: Center - Label@KILLS: - X: 330 - Width: 60 - Height: 25 - Align: Center - Label@DEATHS: - X: 390 - Width: 60 - Height: 25 - Align: Center + Align: Right diff --git a/mods/d2k/rules/campaign-disable-experience.yaml b/mods/d2k/rules/campaign-disable-experience.yaml new file mode 100644 index 0000000000..97855a5e12 --- /dev/null +++ b/mods/d2k/rules/campaign-disable-experience.yaml @@ -0,0 +1,15 @@ +^ExistsInWorld: + GivesExperience: + PlayerExperienceModifier: 0 + +^Building: + RepairableBuilding: + PlayerExperience: 0 + +engineer: + Captures: + PlayerExperience: 0 + +repair_pad: + RepairsUnits: + PlayerExperience: 0 diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index c11436f09e..8abff7fb97 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -3,6 +3,7 @@ UpdatesPlayerStatistics: CombatDebugOverlay: GivesExperience: + PlayerExperienceModifier: 1 ScriptTriggers: UpgradeManager: Huntable: @@ -262,6 +263,7 @@ WithBuildingExplosion: Sequences: building, self_destruct, large_explosion RepairableBuilding: + PlayerExperience: 25 EmitInfantryOnSell: ActorTypes: light_inf MustBeDestroyed: diff --git a/mods/d2k/rules/infantry.yaml b/mods/d2k/rules/infantry.yaml index 428c22c8f2..4224f0178f 100644 --- a/mods/d2k/rules/infantry.yaml +++ b/mods/d2k/rules/infantry.yaml @@ -44,6 +44,7 @@ engineer: EngineerRepair: Captures: CaptureTypes: building, husk + PlayerExperience: 50 -AutoTarget: Voiced: VoiceSet: EngineerVoice diff --git a/mods/d2k/rules/player.yaml b/mods/d2k/rules/player.yaml index 5479a45592..1784c8849c 100644 --- a/mods/d2k/rules/player.yaml +++ b/mods/d2k/rules/player.yaml @@ -91,3 +91,4 @@ Player: GlobalUpgradeManager: ResourceStorageWarning: AdviceInterval: 26 + PlayerExperience: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index 5c3b8f7842..91e82168ff 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -769,6 +769,7 @@ repair_pad: Interval: 10 HpPerStep: 80 FinishRepairingNotification: UnitRepaired + PlayerExperience: 15 RallyPoint: Offset: 1,3 RenderSprites: diff --git a/mods/ra/chrome/ingame-infostats.yaml b/mods/ra/chrome/ingame-infostats.yaml index 9a48a61985..4832ba512e 100644 --- a/mods/ra/chrome/ingame-infostats.yaml +++ b/mods/ra/chrome/ingame-infostats.yaml @@ -35,38 +35,23 @@ Container@SKIRMISH_STATS: Children: Label@NAME: X: 10 - Width: 150 + Width: 210 Height: 25 Text: Player Font: Bold Label@FACTION: - X: 150 - Width: 80 + X: 230 + Width: 120 Height: 25 Text: Faction Font: Bold - Align: Center - Label@STANCE: - X: 260 - Width: 50 + Label@SCORE: + X: 360 + Width: 75 Height: 25 - Text: Team + Text: Score Font: Bold - Align: Center - Label@KILLS: - X: 310 - Width: 70 - Height: 25 - Text: Kills - Font: Bold - Align: Center - Label@DEATHS: - X: 380 - Width: 70 - Height: 25 - Text: Deaths - Font: Bold - Align: Center + Align: Right ScrollPanel@PLAYER_LIST: X: 20 Y: 105 @@ -75,43 +60,52 @@ Container@SKIRMISH_STATS: TopBottomSpacing: 5 ItemSpacing: 5 Children: + ScrollItem@TEAM_TEMPLATE: + BaseName: scrollheader + Width: PARENT_RIGHT - 27 + Height: 20 + X: 2 + Visible: false + Children: + Label@TEAM: + X: 2 + Y: 0-2 + Width: 160 + Height: 20 + Font: Bold + Label@TEAM_SCORE: + X: 360 + Y: 0-2 + Width: 75 + Height: 20 + Font: Bold + Align: Right Container@PLAYER_TEMPLATE: Width: PARENT_RIGHT-27 Height: 25 X: 2 - Y: 0 Children: Label@NAME: X: 10 - Width: 150 + Width: 210 Height: 25 ClientTooltipRegion@CLIENT_REGION: TooltipContainer: TOOLTIP_CONTAINER Template: INGAME_CLIENT_TOOLTIP X: 10 - Width: 150 + Width: 210 Height: 25 Image@FACTIONFLAG: - X: 159 + X: 230 Y: 6 Width: 32 Height: 16 Label@FACTION: - X: 195 - Width: 65 + X: 264 + Width: 86 Height: 25 - Label@TEAM: - X: 260 - Width: 50 + Label@SCORE: + X: 360 + Width: 75 Height: 25 - Align: Center - Label@KILLS: - X: 310 - Width: 70 - Height: 25 - Align: Center - Label@DEATHS: - X: 380 - Width: 70 - Height: 25 - Align: Center + Align: Right diff --git a/mods/ra/chrome/ingame-observerstats.yaml b/mods/ra/chrome/ingame-observerstats.yaml index 97c4d7bf1a..9d1c5ddd20 100644 --- a/mods/ra/chrome/ingame-observerstats.yaml +++ b/mods/ra/chrome/ingame-observerstats.yaml @@ -2,7 +2,7 @@ Background@INGAME_OBSERVERSTATS_BG: Logic: ObserverStatsLogic X: 25 Y: 50 - Width: 950 + Width: 1025 Height: 500 Background: dialog Children: @@ -54,30 +54,30 @@ Background@INGAME_OBSERVERSTATS_BG: Label@POWER_HEADER: X: 425 Y: 40 - Width: 80 + Width: 60 Height: 25 Font: Bold Text: Power Label@KILLS_HEADER: - X: 505 + X: 485 Y: 40 - Width: 40 + Width: 60 Height: 25 Font: Bold Text: Kills Align: Right Label@DEATHS_HEADER: - X: 565 + X: 545 Y: 40 - Width: 40 + Width: 60 Height: 25 Font: Bold Text: Deaths Align: Right Label@ASSETS_DESTROYED_HEADER: - X: 625 + X: 605 Y: 40 - Width: 60 + Width: 80 Height: 25 Font: Bold Text: Destroyed @@ -85,15 +85,23 @@ Background@INGAME_OBSERVERSTATS_BG: Label@ASSETS_LOST_HEADER: X: 685 Y: 40 - Width: 60 + Width: 80 Height: 25 Font: Bold Text: Lost Align: Right - Label@ACTIONS_MIN_HEADER: - X: 805 + Label@EXPERIENCE_HEADER: + X: 765 Y: 40 - Width: 40 + Width: 95 + Height: 25 + Font: Bold + Text: Experience + Align: Right + Label@ACTIONS_MIN_HEADER: + X: 860 + Y: 40 + Width: 90 Height: 25 Font: Bold Text: Actions/min @@ -316,33 +324,39 @@ Background@INGAME_OBSERVERSTATS_BG: Width: 80 Height: PARENT_BOTTOM Label@KILLS: - X: 475 + X: 455 Y: 0 - Width: 40 + Width: 60 Height: PARENT_BOTTOM Align: Right Label@DEATHS: - X: 535 + X: 515 Y: 0 - Width: 40 + Width: 60 Height: PARENT_BOTTOM Align: Right Label@ASSETS_DESTROYED: - X: 595 + X: 575 Y: 0 - Width: 60 + Width: 80 Height: PARENT_BOTTOM Align: Right Label@ASSETS_LOST: - X: 660 + X: 655 Y: 0 - Width: 60 + Width: 80 + Height: PARENT_BOTTOM + Align: Right + Label@EXPERIENCE: + X: 735 + Y: 0 + Width: 95 Height: PARENT_BOTTOM Align: Right Label@ACTIONS_MIN: - X: 775 + X: 830 Y: 0 - Width: 40 + Width: 90 Height: PARENT_BOTTOM Align: Right ScrollItem@ECONOMY_PLAYER_TEMPLATE: diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index c70f48f4e4..0878ef4e7e 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -33,6 +33,8 @@ BADR: Interval: 2 -EjectOnDeath: RejectsOrders: + GivesExperience: + Experience: 1000 BADR.Bomber: Inherits: ^Plane @@ -72,6 +74,8 @@ BADR.Bomber: RejectsOrders: RenderSprites: Image: badr + GivesExperience: + Experience: 1000 MIG: Inherits: ^Plane diff --git a/mods/ra/rules/campaign-disable-experience.yaml b/mods/ra/rules/campaign-disable-experience.yaml new file mode 100644 index 0000000000..9f96c8f607 --- /dev/null +++ b/mods/ra/rules/campaign-disable-experience.yaml @@ -0,0 +1,43 @@ +^ExistsInWorld: + GivesExperience: + PlayerExperienceModifier: 0 + +^Building: + RepairableBuilding: + PlayerExperience: 0 + +E6: + Captures: + PlayerExperience: 0 + +SPY: + Infiltrates: + PlayerExperience: 0 + +MECH: + Captures: + PlayerExperience: 0 + +THF: + Infiltrates: + PlayerExperience: 0 + +HIJACKER: + Captures: + PlayerExperience: 0 + +SPEN: + RepairsUnits: + PlayerExperience: 0 + +SYRD: + RepairsUnits: + PlayerExperience: 0 + +FIX: + RepairsUnits: + PlayerExperience: 0 + +TRUK: + SupplyTruck: + PlayerExperience: 0 diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 332faf3ffe..5b29dc9fca 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -2,6 +2,7 @@ AppearsOnRadar: CombatDebugOverlay: GivesExperience: + PlayerExperienceModifier: 1 ScriptTriggers: UpgradeManager: Huntable: @@ -449,6 +450,7 @@ UpdatesPlayerStatistics: GivesBuildableArea: RepairableBuilding: + PlayerExperience: 25 EngineerRepairable: AcceptsSupplies: WithMakeAnimation: diff --git a/mods/ra/rules/infantry.yaml b/mods/ra/rules/infantry.yaml index c13125b7aa..1c55f4eb92 100644 --- a/mods/ra/rules/infantry.yaml +++ b/mods/ra/rules/infantry.yaml @@ -179,6 +179,7 @@ E6: RepairsBridges: ExternalCaptures: Type: building + PlayerExperience: 25 -AutoTarget: Voiced: VoiceSet: EngineerVoice @@ -209,6 +210,7 @@ SPY: Voice: Move Infiltrates: Types: SpyInfiltrate + PlayerExperience: 50 -AutoTarget: -WithInfantryBody: WithDisguisingInfantryBody: @@ -240,6 +242,8 @@ SPY.England: Prerequisites: ~infantry.england, dome, ~tent, ~techlevel.medium Valued: Cost: 250 + GivesExperience: + Experience: 500 DisguiseToolTip: Name: British Spy RenderSprites: @@ -354,6 +358,7 @@ MECH: Voice: Move Captures: CaptureTypes: husk + PlayerExperience: 25 WithInfantryBody: AttackSequence: repair StandSequences: stand @@ -424,6 +429,7 @@ THF: PipType: Yellow Infiltrates: InfiltrateTypes: Cash + PlayerExperience: 50 -AutoTarget: Voiced: VoiceSet: ThiefVoice @@ -451,6 +457,7 @@ HIJACKER: PipType: Yellow Captures: CaptureTypes: vehicle + PlayerExperience: 50 -AutoTarget: Voiced: VoiceSet: ThiefVoice diff --git a/mods/ra/rules/player.yaml b/mods/ra/rules/player.yaml index b03a64b76d..686dd4c003 100644 --- a/mods/ra/rules/player.yaml +++ b/mods/ra/rules/player.yaml @@ -81,3 +81,4 @@ Player: Image: iconchevrons Sequence: veteran ResourceStorageWarning: + PlayerExperience: diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 8c927f77c4..9c37afa3fb 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -136,6 +136,7 @@ SPEN: -EmitInfantryOnSell: RepairsUnits: FinishRepairingNotification: UnitRepaired + PlayerExperience: 15 RallyPoint: ProductionBar: Power: @@ -225,6 +226,7 @@ SYRD: -EmitInfantryOnSell: RepairsUnits: FinishRepairingNotification: UnitRepaired + PlayerExperience: 15 RallyPoint: ProductionBar: Power: @@ -1569,6 +1571,7 @@ FIX: RepairsUnits: Interval: 10 FinishRepairingNotification: UnitRepaired + PlayerExperience: 15 WithRepairAnimation: Power: Amount: -30 diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index cbea16df42..824a69426c 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -488,6 +488,7 @@ TRUK: Range: 4c0 SupplyTruck: Payload: 500 + PlayerExperience: 50 SpawnActorOnDeath: Actor: moneycrate diff --git a/mods/ts/chrome/ingame-observerstats.yaml b/mods/ts/chrome/ingame-observerstats.yaml index 7372b21194..067a3a20f6 100644 --- a/mods/ts/chrome/ingame-observerstats.yaml +++ b/mods/ts/chrome/ingame-observerstats.yaml @@ -2,7 +2,7 @@ Background@INGAME_OBSERVERSTATS_BG: Logic: ObserverStatsLogic X: 25 Y: 50 - Width: 950 + Width: 1025 Height: 500 Background: dialog Children: @@ -54,30 +54,30 @@ Background@INGAME_OBSERVERSTATS_BG: Label@POWER_HEADER: X: 425 Y: 40 - Width: 80 + Width: 60 Height: 25 Font: Bold Text: Power Label@KILLS_HEADER: - X: 505 + X: 485 Y: 40 - Width: 40 + Width: 60 Height: 25 Font: Bold Text: Kills Align: Right Label@DEATHS_HEADER: - X: 565 + X: 545 Y: 40 - Width: 40 + Width: 60 Height: 25 Font: Bold Text: Deaths Align: Right Label@ASSETS_DESTROYED_HEADER: - X: 625 + X: 605 Y: 40 - Width: 60 + Width: 80 Height: 25 Font: Bold Text: Destroyed @@ -85,15 +85,23 @@ Background@INGAME_OBSERVERSTATS_BG: Label@ASSETS_LOST_HEADER: X: 685 Y: 40 - Width: 60 + Width: 80 Height: 25 Font: Bold Text: Lost Align: Right - Label@ACTIONS_MIN_HEADER: - X: 805 + Label@EXPERIENCE_HEADER: + X: 765 Y: 40 - Width: 40 + Width: 95 + Height: 25 + Font: Bold + Text: Experience + Align: Right + Label@ACTIONS_MIN_HEADER: + X: 860 + Y: 40 + Width: 90 Height: 25 Font: Bold Text: Actions/min @@ -316,33 +324,39 @@ Background@INGAME_OBSERVERSTATS_BG: Width: 80 Height: PARENT_BOTTOM Label@KILLS: - X: 475 + X: 455 Y: 0 - Width: 40 + Width: 60 Height: PARENT_BOTTOM Align: Right Label@DEATHS: - X: 535 + X: 515 Y: 0 - Width: 40 + Width: 60 Height: PARENT_BOTTOM Align: Right Label@ASSETS_DESTROYED: - X: 595 + X: 575 Y: 0 - Width: 60 + Width: 80 Height: PARENT_BOTTOM Align: Right Label@ASSETS_LOST: - X: 660 + X: 655 Y: 0 - Width: 60 + Width: 80 + Height: PARENT_BOTTOM + Align: Right + Label@EXPERIENCE: + X: 735 + Y: 0 + Width: 95 Height: PARENT_BOTTOM Align: Right Label@ACTIONS_MIN: - X: 775 + X: 830 Y: 0 - Width: 40 + Width: 90 Height: PARENT_BOTTOM Align: Right ScrollItem@ECONOMY_PLAYER_TEMPLATE: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index da86dcdc89..be1f92f4e6 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -3,6 +3,7 @@ UpdatesPlayerStatistics: CombatDebugOverlay: GivesExperience: + PlayerExperienceModifier: 1 ScriptTriggers: UpgradeManager: Huntable: @@ -125,6 +126,7 @@ Capturable: RepairableBuilding: IndicatorPalette: mouse + PlayerExperience: 25 WithDeathAnimation: DeathSequence: dead UseDeathTypeSuffix: false diff --git a/mods/ts/rules/gdi-structures.yaml b/mods/ts/rules/gdi-structures.yaml index 4e0c935b07..b09bd65a9f 100644 --- a/mods/ts/rules/gdi-structures.yaml +++ b/mods/ts/rules/gdi-structures.yaml @@ -210,6 +210,7 @@ GAHPAD: PrimaryBuilding: Reservable: RepairsUnits: + PlayerExperience: 15 ProductionBar: WithIdleOverlay@PLATFORM: Sequence: idle-platform @@ -256,6 +257,7 @@ GADEPT: Range: 5c0 Reservable: RepairsUnits: + PlayerExperience: 15 RallyPoint: Palette: mouse IsPlayerPalette: false diff --git a/mods/ts/rules/nod-infantry.yaml b/mods/ts/rules/nod-infantry.yaml index c9409b8422..4499c541a6 100644 --- a/mods/ts/rules/nod-infantry.yaml +++ b/mods/ts/rules/nod-infantry.yaml @@ -117,6 +117,7 @@ MHIJACK: -Crushable: Captures: CaptureTypes: Vehicle + PlayerExperience: 50 RevealsShroud: Range: 6c0 -AutoTarget: diff --git a/mods/ts/rules/nod-structures.yaml b/mods/ts/rules/nod-structures.yaml index 189348ad3c..9a3a2485a6 100644 --- a/mods/ts/rules/nod-structures.yaml +++ b/mods/ts/rules/nod-structures.yaml @@ -215,6 +215,7 @@ NAHPAD: PrimaryBuilding: Reservable: RepairsUnits: + PlayerExperience: 15 ProductionBar: WithIdleOverlay@PLATFORM: Sequence: idle-platform diff --git a/mods/ts/rules/player.yaml b/mods/ts/rules/player.yaml index c52f87d0d4..63bfb7f899 100644 --- a/mods/ts/rules/player.yaml +++ b/mods/ts/rules/player.yaml @@ -52,3 +52,4 @@ Player: PlayerStatistics: PlaceSimpleBeacon: ResourceStorageWarning: + PlayerExperience: diff --git a/mods/ts/rules/shared-infantry.yaml b/mods/ts/rules/shared-infantry.yaml index bc51f8ee15..d456aced45 100644 --- a/mods/ts/rules/shared-infantry.yaml +++ b/mods/ts/rules/shared-infantry.yaml @@ -58,6 +58,7 @@ ENGINEER: RepairNotification: BridgeRepaired Captures: CaptureTypes: building + PlayerExperience: 50 -AutoTarget: -GainsExperience: RenderSprites: