From 5157ac917fd2cb203b635650897efc96d319a826 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sat, 18 Jun 2016 12:57:08 +0200 Subject: [PATCH 1/3] Cache PlayerResources in PlayerStatistics and remove a couple of redundant fields. --- .../Traits/Player/PlayerStatistics.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs index c8e34a01d8..b0b8a35023 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs @@ -20,10 +20,9 @@ namespace OpenRA.Mods.Common.Traits public object Create(ActorInitializer init) { return new PlayerStatistics(init.Self); } } - public class PlayerStatistics : ITick, IResolveOrder + public class PlayerStatistics : ITick, IResolveOrder, INotifyCreated { - World world; - Player player; + PlayerResources resources; public int OrderCount; @@ -31,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits { get { - return player.PlayerActor.Trait().Earned - earnedAtBeginningOfMinute; + return resources != null ? resources.Earned - earnedAtBeginningOfMinute : 0; } } @@ -47,23 +46,24 @@ namespace OpenRA.Mods.Common.Traits public int BuildingsKilled; public int BuildingsDead; - public PlayerStatistics(Actor self) + public PlayerStatistics(Actor self) { } + + void INotifyCreated.Created(Actor self) { - world = self.World; - player = self.Owner; + resources = self.TraitOrDefault(); } void UpdateEarnedThisMinute() { EarnedSamples.Enqueue(EarnedThisMinute); - earnedAtBeginningOfMinute = player.PlayerActor.Trait().Earned; + earnedAtBeginningOfMinute = resources != null ? resources.Earned : 0; if (EarnedSamples.Count > 100) EarnedSamples.Dequeue(); } public void Tick(Actor self) { - if (world.WorldTick % 1500 == 1) + if (self.World.WorldTick % 1500 == 1) UpdateEarnedThisMinute(); } From c3e862b2ca047573956067f7563de67e62716fc1 Mon Sep 17 00:00:00 2001 From: Emiel Suilen Date: Sat, 18 Jun 2016 17:26:55 +0200 Subject: [PATCH 2/3] Add a PlayerExperience trait --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + OpenRA.Mods.Common/Traits/GivesExperience.cs | 15 ++++++-- .../Traits/Player/PlayerExperience.cs | 35 +++++++++++++++++++ .../Traits/Player/PlayerStatistics.cs | 10 ++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 OpenRA.Mods.Common/Traits/Player/PlayerExperience.cs 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() From 20d55a1d9366c10694c9e3faac6b5f064356c20b Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sat, 18 Jun 2016 17:27:24 +0200 Subject: [PATCH 3/3] Add Lua integration for PlayerExperience --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Properties/PlayerExperienceProperties.cs | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 OpenRA.Mods.Common/Scripting/Properties/PlayerExperienceProperties.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 29f8b91081..fa44f8d02b 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -245,6 +245,7 @@ + diff --git a/OpenRA.Mods.Common/Scripting/Properties/PlayerExperienceProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/PlayerExperienceProperties.cs new file mode 100644 index 0000000000..87aae502f1 --- /dev/null +++ b/OpenRA.Mods.Common/Scripting/Properties/PlayerExperienceProperties.cs @@ -0,0 +1,43 @@ +#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 Eluant; +using OpenRA.Mods.Common.Traits; +using OpenRA.Scripting; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Scripting +{ + [ScriptPropertyGroup("Player")] + public class PlayerExperienceProperties : ScriptPlayerProperties, Requires + { + readonly PlayerExperience exp; + + public PlayerExperienceProperties(ScriptContext context, Player player) + : base(context, player) + { + exp = player.PlayerActor.Trait(); + } + + public int Experience + { + get + { + return exp.Experience; + } + + set + { + exp.GiveExperience(value - exp.Experience); + } + } + } +} \ No newline at end of file