diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 324674b94b..29f8b91081 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -388,6 +388,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/GivesExperience.cs b/OpenRA.Mods.Common/Traits/GivesExperience.cs index c08d066387..14573f1d28 100644 --- a/OpenRA.Mods.Common/Traits/GivesExperience.cs +++ b/OpenRA.Mods.Common/Traits/GivesExperience.cs @@ -22,6 +22,12 @@ namespace OpenRA.Mods.Common.Traits [Desc("Stance the attacking player needs to receive the experience.")] public readonly Stance ValidStances = Stance.Neutral | Stance.Enemy; + [Desc("Percentage of the `Experience` value that is being granted to the killing actor.")] + public readonly int ActorExperienceModifier = 10000; + + [Desc("Percentage of the `Experience` value that is being granted to the player owning the killing actor.")] + public readonly int PlayerExperienceModifier = 0; + public object Create(ActorInitializer init) { return new GivesExperience(init.Self, this); } } @@ -44,14 +50,17 @@ namespace OpenRA.Mods.Common.Traits var valued = self.Info.TraitInfoOrDefault(); - // Default experience is 100 times our value var exp = info.Experience >= 0 ? info.Experience - : valued != null ? valued.Cost * 100 : 0; + : valued != null ? valued.Cost : 0; var killer = e.Attacker.TraitOrDefault(); if (killer != null) - killer.GiveExperience(exp); + killer.GiveExperience(Util.ApplyPercentageModifiers(exp, new[] { info.ActorExperienceModifier })); + + var attackerExp = e.Attacker.Owner.PlayerActor.TraitOrDefault(); + if (attackerExp != null) + attackerExp.GiveExperience(Util.ApplyPercentageModifiers(exp, new[] { info.PlayerExperienceModifier })); } } } diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerExperience.cs b/OpenRA.Mods.Common/Traits/Player/PlayerExperience.cs new file mode 100644 index 0000000000..a632787f26 --- /dev/null +++ b/OpenRA.Mods.Common/Traits/Player/PlayerExperience.cs @@ -0,0 +1,35 @@ +#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; +using System.Linq; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("This trait can be used to track player experience based on units killed with the `GivesExperience` trait.", + "It can also be used as a point score system in scripted maps, for example.", + "Attach this to the player actor.")] + public class PlayerExperienceInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new PlayerExperience(); } + } + + public class PlayerExperience : ISync + { + [Sync] public int Experience { get; private set; } + + public void GiveExperience(int num) + { + Experience += num; + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs index b0b8a35023..ab6aa46eca 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs @@ -23,6 +23,7 @@ namespace OpenRA.Mods.Common.Traits public class PlayerStatistics : ITick, IResolveOrder, INotifyCreated { PlayerResources resources; + PlayerExperience experience; public int OrderCount; @@ -34,6 +35,14 @@ namespace OpenRA.Mods.Common.Traits } } + public int Experience + { + get + { + return experience != null ? experience.Experience : 0; + } + } + public Queue EarnedSamples = new Queue(100); int earnedAtBeginningOfMinute; @@ -51,6 +60,7 @@ namespace OpenRA.Mods.Common.Traits void INotifyCreated.Created(Actor self) { resources = self.TraitOrDefault(); + experience = self.TraitOrDefault(); } void UpdateEarnedThisMinute()