Merge pull request #7337 from reaperrr/common29
Moved Lint, UtilityCommands and Scripting properties to Mods.Common
This commit is contained in:
@@ -1,68 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CheckActorReferences : ILintPass
|
||||
{
|
||||
Action<string> emitError;
|
||||
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
this.emitError = emitError;
|
||||
|
||||
foreach (var actorInfo in map.Rules.Actors)
|
||||
foreach (var traitInfo in actorInfo.Value.Traits.WithInterface<ITraitInfo>())
|
||||
CheckTrait(actorInfo.Value, traitInfo, map);
|
||||
}
|
||||
|
||||
void CheckTrait(ActorInfo actorInfo, ITraitInfo traitInfo, Map map)
|
||||
{
|
||||
var actualType = traitInfo.GetType();
|
||||
foreach (var field in actualType.GetFields())
|
||||
{
|
||||
if (field.HasAttribute<ActorReferenceAttribute>())
|
||||
CheckReference(actorInfo, traitInfo, field, map.Rules.Actors, "actor");
|
||||
if (field.HasAttribute<WeaponReferenceAttribute>())
|
||||
CheckReference(actorInfo, traitInfo, field, map.Rules.Weapons, "weapon");
|
||||
if (field.HasAttribute<VoiceReferenceAttribute>())
|
||||
CheckReference(actorInfo, traitInfo, field, map.Rules.Voices, "voice");
|
||||
}
|
||||
}
|
||||
|
||||
string[] GetFieldValues(ITraitInfo traitInfo, FieldInfo fieldInfo)
|
||||
{
|
||||
var type = fieldInfo.FieldType;
|
||||
if (type == typeof(string))
|
||||
return new string[] { (string)fieldInfo.GetValue(traitInfo) };
|
||||
if (type == typeof(string[]))
|
||||
return (string[])fieldInfo.GetValue(traitInfo);
|
||||
|
||||
emitError("Bad type for reference on {0}.{1}. Supported types: string, string[]"
|
||||
.F(traitInfo.GetType().Name, fieldInfo.Name));
|
||||
|
||||
return new string[] { };
|
||||
}
|
||||
|
||||
void CheckReference<T>(ActorInfo actorInfo, ITraitInfo traitInfo, FieldInfo fieldInfo,
|
||||
IReadOnlyDictionary<string, T> dict, string type)
|
||||
{
|
||||
var values = GetFieldValues(traitInfo, fieldInfo);
|
||||
foreach (var v in values)
|
||||
if (v != null && !dict.ContainsKey(v.ToLowerInvariant()))
|
||||
emitError("{0}.{1}.{2}: Missing {3} `{4}`."
|
||||
.F(actorInfo.Name, traitInfo.GetType().Name, fieldInfo.Name, type, v));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CheckActors : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
var actorTypes = map.Actors.Value.Values.Select(a => a.Type);
|
||||
foreach (var actor in actorTypes)
|
||||
if (!map.Rules.Actors.Keys.Contains(actor.ToLowerInvariant()))
|
||||
emitError("Actor {0} is not defined by any rule.".F(actor));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CheckMapCordon : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
if (map.Bounds.Left == 0 || map.Bounds.Top == 0
|
||||
|| map.Bounds.Right == map.MapSize.X || map.Bounds.Bottom == map.MapSize.Y)
|
||||
emitError("This map does not define a valid cordon.\n"
|
||||
+ "A one cell (or greater) border is required on all four sides "
|
||||
+ "between the playable bounds and the map edges");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CheckMapRules : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
try
|
||||
{
|
||||
Game.ModData.RulesetCache.LoadMapRules(map);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
emitError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CheckPlayers : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
var playerNames = map.Players.Values.Select(p => p.Name);
|
||||
foreach (var player in map.Players)
|
||||
foreach (var ally in player.Value.Allies)
|
||||
if (!playerNames.Contains(ally))
|
||||
emitError("Allies contains player {0} that is not in list.".F(ally));
|
||||
|
||||
foreach (var player in map.Players)
|
||||
foreach (var enemy in player.Value.Enemies)
|
||||
if (!playerNames.Contains(enemy))
|
||||
emitError("Enemies contains player {0} that is not in list.".F(enemy));
|
||||
|
||||
var races = map.Rules.Actors["world"].Traits.WithInterface<CountryInfo>().Select(c => c.Race);
|
||||
foreach (var player in map.Players)
|
||||
if (!string.IsNullOrWhiteSpace(player.Value.Race) && player.Value.Race != "Random" && !races.Contains(player.Value.Race))
|
||||
emitError("Invalid race {0} chosen for player {1}.".F(player.Value.Race, player.Value.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class CheckSequences : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
var sequences = MiniYaml.MergeLiberal(map.SequenceDefinitions, Game.ModData.Manifest.Sequences.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
|
||||
|
||||
foreach (var actorInfo in map.Rules.Actors)
|
||||
foreach (var renderInfo in actorInfo.Value.Traits.WithInterface<RenderSimpleInfo>())
|
||||
{
|
||||
var image = renderInfo.Image ?? actorInfo.Value.Name;
|
||||
if (!sequences.Any(s => s.Key == image.ToLowerInvariant()) && !actorInfo.Value.Name.Contains("^"))
|
||||
emitWarning("Sprite image {0} from actor {1} has no sequence definition.".F(image, actorInfo.Value.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class CheckSyncAnnotations : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
/* first, check all the types implementing ISync */
|
||||
foreach (var t in Game.ModData.ObjectCreator.GetTypesImplementing<ISync>())
|
||||
if (!HasAnySyncFields(t))
|
||||
emitWarning("{0} has ISync but nothing marked with [Sync]".F(t.Name));
|
||||
}
|
||||
|
||||
bool HasAnySyncFields(Type t)
|
||||
{
|
||||
var flags = BindingFlags.Public | BindingFlags.NonPublic
|
||||
| BindingFlags.Instance;
|
||||
|
||||
var fs = t.GetFields(flags);
|
||||
var ps = t.GetProperties(flags);
|
||||
|
||||
return fs.Any(f => f.HasAttribute<SyncAttribute>()) ||
|
||||
ps.Any(p => p.HasAttribute<SyncAttribute>()) ||
|
||||
HasAnySyncFields(t.BaseType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CheckTraitPrerequisites : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
foreach (var actorInfo in map.Rules.Actors.Where(a => !a.Key.StartsWith("^")))
|
||||
try
|
||||
{
|
||||
var traits = actorInfo.Value.TraitsInConstructOrder().ToArray();
|
||||
if (traits.Length == 0)
|
||||
emitWarning("Actor {0} has no traits. Is this intended?".F(actorInfo.Key));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
emitError("Actor {0} is not constructible; failure: {1}".F(actorInfo.Key, e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class LintBuildablePrerequisites : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
// Buildings provide their actor names as a prerequisite
|
||||
var buildingPrereqs = map.Rules.Actors.Where(a => a.Value.Traits.Contains<BuildingInfo>())
|
||||
.Select(a => a.Key);
|
||||
|
||||
// ProvidesCustomPrerequisite allows arbitrary prereq definitions
|
||||
var customPrereqs = map.Rules.Actors.SelectMany(a => a.Value.Traits
|
||||
.WithInterface<ProvidesCustomPrerequisiteInfo>())
|
||||
.Select(p => p.Prerequisite);
|
||||
|
||||
// ProvidesTechPrerequisite allows arbitrary prereq definitions
|
||||
// (but only one group at a time during gameplay)
|
||||
var techPrereqs = map.Rules.Actors.SelectMany(a => a.Value.Traits
|
||||
.WithInterface<ProvidesTechPrerequisiteInfo>())
|
||||
.SelectMany(p => p.Prerequisites);
|
||||
|
||||
var providedPrereqs = buildingPrereqs.Concat(customPrereqs).Concat(techPrereqs);
|
||||
|
||||
// TODO: this check is case insensitive while the real check in-game is not
|
||||
foreach (var i in map.Rules.Actors)
|
||||
{
|
||||
var bi = i.Value.Traits.GetOrDefault<BuildableInfo>();
|
||||
if (bi != null)
|
||||
foreach (var prereq in bi.Prerequisites)
|
||||
if (!prereq.StartsWith("~disabled"))
|
||||
if (!providedPrereqs.Contains(prereq.Replace("!", "").Replace("~", "")))
|
||||
emitError("Buildable actor {0} has prereq {1} not provided by anything.".F(i.Key, prereq));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,6 @@
|
||||
<Compile Include="AI\RushFuzzy.cs" />
|
||||
<Compile Include="AI\StateMachine.cs" />
|
||||
<Compile Include="Traits\Attack\AttackLeap.cs" />
|
||||
<Compile Include="Scripting\Properties\RepairableBuildingProperties.cs" />
|
||||
<Compile Include="Traits\PaletteEffects\ChronoshiftPaletteEffect.cs" />
|
||||
<Compile Include="Traits\Chronoshiftable.cs" />
|
||||
<Compile Include="CrateSpawner.cs" />
|
||||
@@ -120,16 +119,11 @@
|
||||
<Compile Include="Traits\DemoTruck.cs" />
|
||||
<Compile Include="Effects\GpsDot.cs" />
|
||||
<Compile Include="Effects\Parachute.cs" />
|
||||
<Compile Include="Lint\CheckActorReferences.cs" />
|
||||
<Compile Include="Lint\CheckSyncAnnotations.cs" />
|
||||
<Compile Include="Lint\CheckTraitPrerequisites.cs" />
|
||||
<Compile Include="Lint\LintBuildablePrerequisites.cs" />
|
||||
<Compile Include="Traits\MadTank.cs" />
|
||||
<Compile Include="Traits\Mine.cs" />
|
||||
<Compile Include="Traits\Minelayer.cs" />
|
||||
<Compile Include="Traits\ParaDrop.cs" />
|
||||
<Compile Include="Traits\PortableChrono.cs" />
|
||||
<Compile Include="Scripting\Properties\GuardProperties.cs" />
|
||||
<Compile Include="Widgets\Logic\TabCompletionLogic.cs" />
|
||||
<Compile Include="Traits\Render\RenderJammerCircle.cs" />
|
||||
<Compile Include="Traits\Render\RenderHarvester.cs" />
|
||||
@@ -175,7 +169,6 @@
|
||||
<Compile Include="Widgets\Logic\ServerCreationLogic.cs" />
|
||||
<Compile Include="Widgets\ObserverProductionIconsWidget.cs" />
|
||||
<Compile Include="Widgets\WorldCommandWidget.cs" />
|
||||
<Compile Include="Player\BaseAttackNotifier.cs" />
|
||||
<Compile Include="Player\HarvesterAttackNotifier.cs" />
|
||||
<Compile Include="Traits\Render\RenderShroudCircle.cs" />
|
||||
<Compile Include="Traits\Infiltration\InfiltrateForCash.cs" />
|
||||
@@ -184,7 +177,6 @@
|
||||
<Compile Include="Traits\Infiltration\InfiltrateForSupportPower.cs" />
|
||||
<Compile Include="Traits\Infiltration\Infiltrates.cs" />
|
||||
<Compile Include="Widgets\Logic\ObserverShroudSelectorLogic.cs" />
|
||||
<Compile Include="Lint\CheckSequences.cs" />
|
||||
<Compile Include="Widgets\Logic\SpawnSelectorTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\ClientTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\CreditsLogic.cs" />
|
||||
@@ -202,19 +194,7 @@
|
||||
<Compile Include="Traits\Attack\AttackGarrisoned.cs" />
|
||||
<Compile Include="Widgets\Logic\LobbyMapPreviewLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\ControlGroupLogic.cs" />
|
||||
<Compile Include="Scripting\Global\ReinforcementsGlobal.cs" />
|
||||
<Compile Include="Scripting\Properties\AirstrikeProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\ProductionProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\MissionObjectiveProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\MobileProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\GeneralProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\CombatProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\PlayerProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\TransportProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\ChronosphereProperties.cs" />
|
||||
<Compile Include="Lint\CheckPlayers.cs" />
|
||||
<Compile Include="Lint\CheckActors.cs" />
|
||||
<Compile Include="Lint\CheckMapCordon.cs" />
|
||||
<Compile Include="Traits\Parachutable.cs" />
|
||||
<Compile Include="Widgets\Logic\InstallFromCDLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\InstallMusicLogic.cs" />
|
||||
@@ -229,14 +209,8 @@
|
||||
<Compile Include="Widgets\Logic\DebugMenuLogic.cs" />
|
||||
<Compile Include="Warheads\PerCellDamageWarhead.cs" />
|
||||
<Compile Include="Scripting\Properties\HarvesterProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\HelicopterProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\PlaneProperties.cs" />
|
||||
<Compile Include="Scripting\Properties\TransportProperties.cs" />
|
||||
<Compile Include="Traits\InvulnerabilityUpgrade.cs" />
|
||||
<Compile Include="Scripting\Properties\TransformProperties.cs" />
|
||||
<Compile Include="UtilityCommands\ActorStatsExport.cs" />
|
||||
<Compile Include="UtilityCommands\ExportCharacterSeparatedRules.cs" />
|
||||
<Compile Include="UtilityCommands\Extensions.cs" />
|
||||
<Compile Include="Lint\CheckMapRules.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
[Desc("Plays an audio notification and shows a radar ping when a building is attacked.",
|
||||
"Attach this to the player actor.")]
|
||||
public class BaseAttackNotifierInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Minimum duration (in seconds) between notification events.")]
|
||||
public readonly int NotifyInterval = 30;
|
||||
|
||||
public readonly Color RadarPingColor = Color.Red;
|
||||
|
||||
[Desc("Length of time (in ticks) to display a location ping in the minimap.")]
|
||||
public readonly int RadarPingDuration = 10 * 25;
|
||||
|
||||
[Desc("The audio notification type to play.")]
|
||||
public string Notification = "BaseAttack";
|
||||
|
||||
public object Create(ActorInitializer init) { return new BaseAttackNotifier(init.Self, this); }
|
||||
}
|
||||
|
||||
public class BaseAttackNotifier : INotifyDamage
|
||||
{
|
||||
readonly RadarPings radarPings;
|
||||
readonly BaseAttackNotifierInfo info;
|
||||
|
||||
int lastAttackTime;
|
||||
|
||||
public BaseAttackNotifier(Actor self, BaseAttackNotifierInfo info)
|
||||
{
|
||||
radarPings = self.World.WorldActor.TraitOrDefault<RadarPings>();
|
||||
this.info = info;
|
||||
lastAttackTime = -info.NotifyInterval * 25;
|
||||
}
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
// only track last hit against our base
|
||||
if (!self.HasTrait<Building>())
|
||||
return;
|
||||
|
||||
if (e.Attacker == null)
|
||||
return;
|
||||
|
||||
if (e.Attacker.Owner == self.Owner)
|
||||
return;
|
||||
|
||||
if (e.Attacker == self.World.WorldActor)
|
||||
return;
|
||||
|
||||
if (e.Attacker.Owner.IsAlliedWith(self.Owner) && e.Damage <= 0)
|
||||
return;
|
||||
|
||||
if (self.World.WorldTick - lastAttackTime > info.NotifyInterval * 25)
|
||||
{
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.Notification, self.Owner.Country.Race);
|
||||
|
||||
if (radarPings != null)
|
||||
radarPings.Add(() => self.Owner == self.World.LocalPlayer, self.CenterPosition, info.RadarPingColor, info.RadarPingDuration);
|
||||
}
|
||||
|
||||
lastAttackTime = self.World.WorldTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptGlobal("Reinforcements")]
|
||||
public class ReinforcementsGlobal : ScriptGlobal
|
||||
{
|
||||
public ReinforcementsGlobal(ScriptContext context) : base(context) { }
|
||||
|
||||
Actor CreateActor(Player owner, string actorType, bool addToWorld, CPos? entryLocation = null, CPos? nextLocation = null)
|
||||
{
|
||||
ActorInfo ai;
|
||||
if (!Context.World.Map.Rules.Actors.TryGetValue(actorType, out ai))
|
||||
throw new LuaException("Unknown actor type '{0}'".F(actorType));
|
||||
|
||||
var initDict = new TypeDictionary();
|
||||
|
||||
initDict.Add(new OwnerInit(owner));
|
||||
|
||||
if (entryLocation.HasValue)
|
||||
{
|
||||
var pi = ai.Traits.GetOrDefault<AircraftInfo>();
|
||||
initDict.Add(new CenterPositionInit(owner.World.Map.CenterOfCell(entryLocation.Value) + new WVec(0, 0, pi != null ? pi.CruiseAltitude.Range : 0)));
|
||||
initDict.Add(new LocationInit(entryLocation.Value));
|
||||
}
|
||||
|
||||
if (entryLocation.HasValue && nextLocation.HasValue)
|
||||
initDict.Add(new FacingInit(Context.World.Map.FacingBetween(CPos.Zero, CPos.Zero + (nextLocation.Value - entryLocation.Value), 0)));
|
||||
|
||||
var actor = Context.World.CreateActor(addToWorld, actorType, initDict);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
void Move(Actor actor, CPos dest)
|
||||
{
|
||||
var move = actor.TraitOrDefault<IMove>();
|
||||
if (move == null)
|
||||
return;
|
||||
|
||||
actor.QueueActivity(move.MoveTo(dest, 2));
|
||||
}
|
||||
|
||||
[Desc("Send reinforcements consisting of multiple units. Supports ground-based, naval and air units. " +
|
||||
"The first member of the entryPath array will be the units' spawnpoint, " +
|
||||
"while the last one will be their destination. If actionFunc is given, " +
|
||||
"it will be executed once a unit has reached its destination. actionFunc " +
|
||||
"will be called as actionFunc(Actor actor)")]
|
||||
public Actor[] Reinforce(Player owner, string[] actorTypes, CPos[] entryPath, int interval = 25, LuaFunction actionFunc = null)
|
||||
{
|
||||
var actors = new List<Actor>();
|
||||
for (var i = 0; i < actorTypes.Length; i++)
|
||||
{
|
||||
var af = actionFunc != null ? actionFunc.CopyReference() as LuaFunction : null;
|
||||
var actor = CreateActor(owner, actorTypes[i], false, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null);
|
||||
actors.Add(actor);
|
||||
|
||||
var actionDelay = i * interval;
|
||||
Action actorAction = () =>
|
||||
{
|
||||
Context.World.Add(actor);
|
||||
for (var j = 1; j < entryPath.Length; j++)
|
||||
Move(actor, entryPath[j]);
|
||||
|
||||
if (af != null)
|
||||
{
|
||||
actor.QueueActivity(new CallFunc(() =>
|
||||
{
|
||||
af.Call(actor.ToLuaValue(Context));
|
||||
af.Dispose();
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
Context.World.AddFrameEndTask(w => w.Add(new DelayedAction(actionDelay, actorAction)));
|
||||
}
|
||||
|
||||
return actors.ToArray();
|
||||
}
|
||||
|
||||
[Desc("Send reinforcements in a transport. A transport can be a ground unit (APC etc.), ships and aircraft. " +
|
||||
"The first member of the entryPath array will be the spawnpoint for the transport, " +
|
||||
"while the last one will be its destination. The last member of the exitPath array " +
|
||||
"is be the place where the transport will be removed from the game. When the transport " +
|
||||
"has reached the destination, it will unload its cargo unless a custom actionFunc has " +
|
||||
"been supplied. Afterwards, the transport will follow the exitPath and leave the map, " +
|
||||
"unless a custom exitFunc has been supplied. actionFunc will be called as " +
|
||||
"actionFunc(Actor transport, Actor[] cargo). exitFunc will be called as exitFunc(Actor transport).")]
|
||||
public LuaTable ReinforceWithTransport(Player owner, string actorType, string[] cargoTypes, CPos[] entryPath, CPos[] exitPath = null,
|
||||
LuaFunction actionFunc = null, LuaFunction exitFunc = null)
|
||||
{
|
||||
var transport = CreateActor(owner, actorType, true, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null);
|
||||
var cargo = transport.TraitOrDefault<Cargo>();
|
||||
|
||||
var passengers = new List<Actor>();
|
||||
if (cargo != null && cargoTypes != null)
|
||||
{
|
||||
foreach (var cargoType in cargoTypes)
|
||||
{
|
||||
var passenger = CreateActor(owner, cargoType, false, entryPath[0]);
|
||||
passengers.Add(passenger);
|
||||
cargo.Load(transport, passenger);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 1; i < entryPath.Length; i++)
|
||||
Move(transport, entryPath[i]);
|
||||
|
||||
if (actionFunc != null)
|
||||
{
|
||||
var af = actionFunc.CopyReference() as LuaFunction;
|
||||
transport.QueueActivity(new CallFunc(() =>
|
||||
{
|
||||
af.Call(transport.ToLuaValue(Context), passengers.ToArray().ToLuaValue(Context));
|
||||
af.Dispose();
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
var heli = transport.TraitOrDefault<Helicopter>();
|
||||
if (heli != null)
|
||||
{
|
||||
transport.QueueActivity(new Turn(transport, heli.Info.InitialFacing));
|
||||
transport.QueueActivity(new HeliLand(true));
|
||||
transport.QueueActivity(new Wait(15));
|
||||
}
|
||||
|
||||
if (cargo != null)
|
||||
{
|
||||
transport.QueueActivity(new UnloadCargo(transport, true));
|
||||
transport.QueueActivity(new WaitFor(() => cargo.IsEmpty(transport)));
|
||||
}
|
||||
|
||||
transport.QueueActivity(new Wait(heli != null ? 50 : 25));
|
||||
}
|
||||
|
||||
if (exitFunc != null)
|
||||
{
|
||||
var ef = exitFunc.CopyReference() as LuaFunction;
|
||||
transport.QueueActivity(new CallFunc(() =>
|
||||
{
|
||||
ef.Call(transport.ToLuaValue(Context));
|
||||
ef.Dispose();
|
||||
}));
|
||||
}
|
||||
else if (exitPath != null)
|
||||
{
|
||||
foreach (var wpt in exitPath)
|
||||
Move(transport, wpt);
|
||||
|
||||
transport.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
|
||||
var ret = Context.CreateTable();
|
||||
ret.Add(1, transport.ToLuaValue(Context));
|
||||
ret.Add(2, passengers.ToArray().ToLuaValue(Context));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptGlobal("Air Support Powers")]
|
||||
public class AirstrikeProperties : ScriptActorProperties, Requires<AirstrikePowerInfo>
|
||||
{
|
||||
readonly AirstrikePower ap;
|
||||
|
||||
public AirstrikeProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
ap = self.TraitsImplementing<AirstrikePower>().First();
|
||||
}
|
||||
|
||||
[Desc("Activate the actor's Airstrike Power.")]
|
||||
public void SendAirstrike(WPos target, bool randomize = true, int facing = 0)
|
||||
{
|
||||
ap.SendAirstrike(Self, target, randomize, facing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Combat")]
|
||||
public class CombatProperties : ScriptActorProperties, Requires<AttackBaseInfo>, Requires<IMoveInfo>
|
||||
{
|
||||
readonly IMove move;
|
||||
|
||||
public CombatProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
move = self.Trait<IMove>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Seek out and attack nearby targets.")]
|
||||
public void Hunt()
|
||||
{
|
||||
Self.QueueActivity(new Hunt(Self));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Move to a cell, but stop and attack anything within range on the way. " +
|
||||
"closeEnough defines an optional range (in cells) that will be considered " +
|
||||
"close enough to complete the activity.")]
|
||||
public void AttackMove(CPos cell, int closeEnough = 0)
|
||||
{
|
||||
Self.QueueActivity(new AttackMoveActivity(Self, move.MoveTo(cell, closeEnough)));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Patrol along a set of given waypoints. The action is repeated by default, " +
|
||||
"and the actor will wait for `wait` ticks at each waypoint.")]
|
||||
public void Patrol(CPos[] waypoints, bool loop = true, int wait = 0)
|
||||
{
|
||||
foreach (var wpt in waypoints)
|
||||
{
|
||||
Self.QueueActivity(new AttackMoveActivity(Self, move.MoveTo(wpt, 2)));
|
||||
Self.QueueActivity(new Wait(wait));
|
||||
}
|
||||
|
||||
if (loop)
|
||||
Self.QueueActivity(new CallFunc(() => Patrol(waypoints, loop, wait)));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Patrol along a set of given waypoints until a condition becomes true. " +
|
||||
"The actor will wait for `wait` ticks at each waypoint.")]
|
||||
public void PatrolUntil(CPos[] waypoints, LuaFunction func, int wait = 0)
|
||||
{
|
||||
Patrol(waypoints, false, wait);
|
||||
|
||||
var repeat = func.Call(Self.ToLuaValue(Context)).First().ToBoolean();
|
||||
if (repeat)
|
||||
using (var f = func.CopyReference() as LuaFunction)
|
||||
Self.QueueActivity(new CallFunc(() => PatrolUntil(waypoints, f, wait)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ExposedForDestroyedActors]
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class BaseActorProperties : ScriptActorProperties
|
||||
{
|
||||
// Note: This class must not make any trait queries so that this
|
||||
// remains safe to call on dead actors.
|
||||
public BaseActorProperties(ScriptContext context, Actor self)
|
||||
: base(context, self) { }
|
||||
|
||||
[Desc("Specifies whether the actor is in the world.")]
|
||||
public bool IsInWorld
|
||||
{
|
||||
get
|
||||
{
|
||||
return Self.IsInWorld;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
Self.World.AddFrameEndTask(w => w.Add(Self));
|
||||
else
|
||||
Self.World.AddFrameEndTask(w => w.Remove(Self));
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("Specifies whether the actor is alive or dead.")]
|
||||
public bool IsDead { get { return Self.IsDead; } }
|
||||
|
||||
[Desc("Specifies whether the actor is idle (not performing any activities).")]
|
||||
public bool IsIdle { get { return Self.IsIdle; } }
|
||||
|
||||
[Desc("The player that owns the actor.")]
|
||||
public Player Owner
|
||||
{
|
||||
get
|
||||
{
|
||||
return Self.Owner;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (Self.Owner != value)
|
||||
Self.ChangeOwner(value);
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("The type of the actor (e.g. \"e1\").")]
|
||||
public string Type { get { return Self.Info.Name; } }
|
||||
|
||||
[Desc("Test whether an actor has a specific property.")]
|
||||
public bool HasProperty(string name)
|
||||
{
|
||||
return Self.HasScriptProperty(name);
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class GeneralProperties : ScriptActorProperties
|
||||
{
|
||||
readonly IFacing facing;
|
||||
readonly AutoTarget autotarget;
|
||||
|
||||
public GeneralProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
facing = self.TraitOrDefault<IFacing>();
|
||||
autotarget = self.TraitOrDefault<AutoTarget>();
|
||||
}
|
||||
|
||||
[Desc("The actor position in cell coordinates.")]
|
||||
public CPos Location { get { return Self.Location; } }
|
||||
|
||||
[Desc("The actor position in world coordinates.")]
|
||||
public WPos CenterPosition { get { return Self.CenterPosition; } }
|
||||
|
||||
[Desc("The direction that the actor is facing.")]
|
||||
public int Facing
|
||||
{
|
||||
get
|
||||
{
|
||||
if (facing == null)
|
||||
throw new LuaException("Actor '{0}' doesn't define a facing".F(Self));
|
||||
|
||||
return facing.Facing;
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Instantly moves the actor to the specified cell.")]
|
||||
public void Teleport(CPos cell)
|
||||
{
|
||||
Self.QueueActivity(new SimpleTeleport(cell));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Run an arbitrary Lua function.")]
|
||||
public void CallFunc(LuaFunction func)
|
||||
{
|
||||
Self.QueueActivity(new CallLuaFunc(func, Context));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Wait for a specified number of game ticks (25 ticks = 1 second).")]
|
||||
public void Wait(int ticks)
|
||||
{
|
||||
Self.QueueActivity(new Wait(ticks));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Remove the actor from the game, without triggering any death notification.")]
|
||||
public void Destroy()
|
||||
{
|
||||
Self.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
|
||||
[Desc("Attempt to cancel any active activities.")]
|
||||
public void Stop()
|
||||
{
|
||||
Self.CancelActivity();
|
||||
}
|
||||
|
||||
[Desc("Current actor stance. Returns nil if this actor doesn't support stances.")]
|
||||
public string Stance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (autotarget == null)
|
||||
return null;
|
||||
|
||||
return autotarget.Stance.ToString();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (autotarget == null)
|
||||
return;
|
||||
|
||||
UnitStance stance;
|
||||
if (!Enum<UnitStance>.TryParse(value, true, out stance))
|
||||
throw new LuaException("Unknown stance type '{0}'".F(value));
|
||||
|
||||
autotarget.Stance = stance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Guard")]
|
||||
public class GuardProperties : ScriptActorProperties, Requires<GuardInfo>, Requires<IMoveInfo>
|
||||
{
|
||||
Guard guard;
|
||||
public GuardProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
guard = self.Trait<Guard>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Guard the target actor.")]
|
||||
public void Guard(Actor targetActor)
|
||||
{
|
||||
if (targetActor.HasTrait<Guardable>())
|
||||
guard.GuardTarget(Self, Target.FromActor(targetActor));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Movement")]
|
||||
public class HelicopterProperties : ScriptActorProperties, Requires<HelicopterInfo>
|
||||
{
|
||||
public HelicopterProperties(ScriptContext context, Actor self)
|
||||
: base(context, self) { }
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Fly within the cell grid.")]
|
||||
public void Move(CPos cell)
|
||||
{
|
||||
Self.QueueActivity(new HeliFly(Self, Target.FromCell(Self.World, cell)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("MissionObjectives")]
|
||||
public class MissionObjectiveProperties : ScriptPlayerProperties
|
||||
{
|
||||
readonly MissionObjectives mo;
|
||||
|
||||
public MissionObjectiveProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
mo = player.PlayerActor.Trait<MissionObjectives>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Add a primary mission objective for this player. The function returns the " +
|
||||
"ID of the newly created objective, so that it can be referred to later.")]
|
||||
public int AddPrimaryObjective(string description)
|
||||
{
|
||||
return mo.Add(Player, description, ObjectiveType.Primary);
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Add a secondary mission objective for this player. The function returns the " +
|
||||
"ID of the newly created objective, so that it can be referred to later.")]
|
||||
public int AddSecondaryObjective(string description)
|
||||
{
|
||||
return mo.Add(Player, description, ObjectiveType.Secondary);
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Mark an objective as completed. This needs the objective ID returned " +
|
||||
"by AddObjective as argument. When this player has completed all primary " +
|
||||
"objectives, (s)he has won the game.")]
|
||||
public void MarkCompletedObjective(int id)
|
||||
{
|
||||
if (id < 0 || id >= mo.Objectives.Count)
|
||||
throw new LuaException("Objective ID is out of range.");
|
||||
|
||||
mo.MarkCompleted(Player, id);
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Mark an objective as failed. This needs the objective ID returned " +
|
||||
"by AddObjective as argument. Secondary objectives do not have any " +
|
||||
"influence whatsoever on the outcome of the game.")]
|
||||
public void MarkFailedObjective(int id)
|
||||
{
|
||||
if (id < 0 || id >= mo.Objectives.Count)
|
||||
throw new LuaException("Objective ID is out of range.");
|
||||
|
||||
mo.MarkFailed(Player, id);
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Returns true if the objective has been successfully completed, false otherwise.")]
|
||||
public bool IsObjectiveCompleted(int id)
|
||||
{
|
||||
if (id < 0 || id >= mo.Objectives.Count)
|
||||
throw new LuaException("Objective ID is out of range.");
|
||||
|
||||
return mo.Objectives[id].State == ObjectiveState.Completed;
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Returns true if the objective has been failed, false otherwise.")]
|
||||
public bool IsObjectiveFailed(int id)
|
||||
{
|
||||
if (id < 0 || id >= mo.Objectives.Count)
|
||||
throw new LuaException("Objective ID is out of range.");
|
||||
|
||||
return mo.Objectives[id].State == ObjectiveState.Failed;
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Returns the description of an objective.")]
|
||||
public string GetObjectiveDescription(int id)
|
||||
{
|
||||
if (id < 0 || id >= mo.Objectives.Count)
|
||||
throw new LuaException("Objective ID is out of range.");
|
||||
|
||||
return mo.Objectives[id].Description;
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Returns the type of an objective.")]
|
||||
public string GetObjectiveType(int id)
|
||||
{
|
||||
if (id < 0 || id >= mo.Objectives.Count)
|
||||
throw new LuaException("Objective ID is out of range.");
|
||||
|
||||
return mo.Objectives[id].Type == ObjectiveType.Primary ? "Primary" : "Secondary";
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Returns true if this player has lost all units/actors that have" +
|
||||
"the MustBeDestroyed trait (according to the short game option).")]
|
||||
public bool HasNoRequiredUnits()
|
||||
{
|
||||
return Player.HasNoRequiredUnits();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Movement")]
|
||||
public class MobileProperties : ScriptActorProperties, Requires<MobileInfo>
|
||||
{
|
||||
readonly Mobile mobile;
|
||||
|
||||
public MobileProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
mobile = self.Trait<Mobile>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Moves within the cell grid. closeEnough defines an optional range " +
|
||||
"(in cells) that will be considered close enough to complete the activity.")]
|
||||
public void Move(CPos cell, int closeEnough = 0)
|
||||
{
|
||||
Self.QueueActivity(new Move(Self, cell, WRange.FromCells(closeEnough)));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Moves within the cell grid, ignoring lane biases.")]
|
||||
public void ScriptedMove(CPos cell)
|
||||
{
|
||||
Self.QueueActivity(new Move(Self, cell));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Moves from outside the world into the cell grid")]
|
||||
public void MoveIntoWorld(CPos cell)
|
||||
{
|
||||
Self.QueueActivity(mobile.MoveIntoWorld(Self, cell, mobile.ToSubCell));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Leave the current position in a random direction.")]
|
||||
public void Scatter()
|
||||
{
|
||||
Self.Trait<Mobile>().Nudge(Self, Self, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Movement")]
|
||||
public class PlaneProperties : ScriptActorProperties, Requires<PlaneInfo>
|
||||
{
|
||||
public PlaneProperties(ScriptContext context, Actor self)
|
||||
: base(context, self) { }
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Fly within the cell grid.")]
|
||||
public void Move(CPos cell)
|
||||
{
|
||||
Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell)));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Return to the base, which is either the airfield given, or an auto-selected one otherwise.")]
|
||||
public void ReturnToBase(Actor airfield = null)
|
||||
{
|
||||
Self.QueueActivity(new ReturnToBase(Self, airfield));
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Combat")]
|
||||
public class PlaneCombatProperties : ScriptActorProperties, Requires<AttackPlaneInfo>
|
||||
{
|
||||
public PlaneCombatProperties(ScriptContext context, Actor self)
|
||||
: base(context, self) { }
|
||||
|
||||
[Desc("Fly an attack against the target actor.")]
|
||||
public void Attack(Actor target)
|
||||
{
|
||||
Self.QueueActivity(new FlyAttack(Target.FromActor(target)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Player")]
|
||||
public class PlayerProperties : ScriptPlayerProperties
|
||||
{
|
||||
public PlayerProperties(ScriptContext context, Player player)
|
||||
: base(context, player) { }
|
||||
|
||||
[Desc("The player's name.")]
|
||||
public string Name { get { return Player.PlayerName; } }
|
||||
|
||||
[Desc("Returns an array of actors representing all ground attack units of this player.")]
|
||||
public Actor[] GetGroundAttackers()
|
||||
{
|
||||
return Player.World.ActorsWithTrait<AttackBase>().Select(a => a.Actor)
|
||||
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.HasTrait<Mobile>())
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Scripting;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class ProductionProperties : ScriptActorProperties, Requires<ProductionInfo>
|
||||
{
|
||||
readonly Production p;
|
||||
|
||||
public ProductionProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
p = self.Trait<Production>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Build a unit, ignoring the production queue. The activity will wait if the exit is blocked.")]
|
||||
public void Produce(string actorType, string raceVariant = null)
|
||||
{
|
||||
ActorInfo actorInfo;
|
||||
if (!Self.World.Map.Rules.Actors.TryGetValue(actorType, out actorInfo))
|
||||
throw new LuaException("Unknown actor type '{0}'".F(actorType));
|
||||
|
||||
Self.QueueActivity(new WaitFor(() => p.Produce(Self, actorInfo, raceVariant)));
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class RallyPointProperties : ScriptActorProperties, Requires<RallyPointInfo>
|
||||
{
|
||||
readonly RallyPoint rp;
|
||||
|
||||
public RallyPointProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
rp = self.Trait<RallyPoint>();
|
||||
}
|
||||
|
||||
[Desc("Query or set a factory's rally point")]
|
||||
public CPos RallyPoint
|
||||
{
|
||||
get { return rp.Location; }
|
||||
set { rp.Location = value; }
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class PrimaryBuildingProperties : ScriptActorProperties, Requires<PrimaryBuildingInfo>
|
||||
{
|
||||
readonly PrimaryBuilding pb;
|
||||
|
||||
public PrimaryBuildingProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
pb = self.Trait<PrimaryBuilding>();
|
||||
}
|
||||
|
||||
[Desc("Query or set the factory's primary building status")]
|
||||
public bool IsPrimaryBuilding
|
||||
{
|
||||
get { return pb.IsPrimary; }
|
||||
set { pb.SetPrimaryProducer(Self, value); }
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class ProductionQueueProperties : ScriptActorProperties, Requires<ProductionQueueInfo>, Requires<ScriptTriggersInfo>
|
||||
{
|
||||
readonly List<ProductionQueue> queues;
|
||||
readonly ScriptTriggers triggers;
|
||||
|
||||
public ProductionQueueProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
queues = self.TraitsImplementing<ProductionQueue>().Where(q => q.Enabled).ToList();
|
||||
triggers = TriggerGlobal.GetScriptTriggers(self);
|
||||
}
|
||||
|
||||
[Desc("Build the specified set of actors using a TD-style (per building) production queue. " +
|
||||
"The function will return true if production could be started, false otherwise. " +
|
||||
"If an actionFunc is given, it will be called as actionFunc(Actor[] actors) once " +
|
||||
"production of all actors has been completed. The actors array is guaranteed to " +
|
||||
"only contain alive actors.")]
|
||||
public bool Build(string[] actorTypes, LuaFunction actionFunc = null)
|
||||
{
|
||||
if (triggers.Triggers[Trigger.OnProduction].Any())
|
||||
return false;
|
||||
|
||||
var queue = queues.Where(q => actorTypes.All(t => GetBuildableInfo(t).Queue.Contains(q.Info.Type)))
|
||||
.FirstOrDefault(q => q.CurrentItem() == null);
|
||||
|
||||
if (queue == null)
|
||||
return false;
|
||||
|
||||
if (actionFunc != null)
|
||||
{
|
||||
var playerIndex = Self.Owner.ClientIndex;
|
||||
var squadSize = actorTypes.Length;
|
||||
var squad = new List<Actor>();
|
||||
var func = actionFunc.CopyReference() as LuaFunction;
|
||||
|
||||
Action<Actor, Actor> productionHandler = (_, __) => { };
|
||||
productionHandler = (factory, unit) =>
|
||||
{
|
||||
if (playerIndex != factory.Owner.ClientIndex)
|
||||
{
|
||||
triggers.OnProducedInternal -= productionHandler;
|
||||
return;
|
||||
}
|
||||
|
||||
squad.Add(unit);
|
||||
if (squad.Count >= squadSize)
|
||||
{
|
||||
using (func)
|
||||
using (var luaSquad = squad.Where(u => !u.IsDead).ToArray().ToLuaValue(Context))
|
||||
func.Call(luaSquad).Dispose();
|
||||
|
||||
triggers.OnProducedInternal -= productionHandler;
|
||||
}
|
||||
};
|
||||
|
||||
triggers.OnProducedInternal += productionHandler;
|
||||
}
|
||||
|
||||
foreach (var actorType in actorTypes)
|
||||
queue.ResolveOrder(Self, Order.StartProduction(Self, actorType, 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Check whether the factory's production queue that builds this type of actor is currently busy." +
|
||||
"Note: it does not check whether this particular type of actor is being produced.")]
|
||||
public bool IsProducing(string actorType)
|
||||
{
|
||||
if (triggers.Triggers[Trigger.OnProduction].Any())
|
||||
return true;
|
||||
|
||||
return queues.Where(q => GetBuildableInfo(actorType).Queue.Contains(q.Info.Type))
|
||||
.Any(q => q.CurrentItem() != null);
|
||||
}
|
||||
|
||||
BuildableInfo GetBuildableInfo(string actorType)
|
||||
{
|
||||
var ri = Self.World.Map.Rules.Actors[actorType];
|
||||
var bi = ri.Traits.GetOrDefault<BuildableInfo>();
|
||||
|
||||
if (bi == null)
|
||||
throw new LuaException("Actor of type {0} cannot be produced".F(actorType));
|
||||
else
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class ClassicProductionQueueProperties : ScriptPlayerProperties, Requires<ClassicProductionQueueInfo>, Requires<ScriptTriggersInfo>
|
||||
{
|
||||
readonly Dictionary<string, Action<Actor, Actor>> productionHandlers;
|
||||
readonly Dictionary<string, ClassicProductionQueue> queues;
|
||||
|
||||
public ClassicProductionQueueProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
productionHandlers = new Dictionary<string, Action<Actor, Actor>>();
|
||||
|
||||
queues = new Dictionary<string, ClassicProductionQueue>();
|
||||
foreach (var q in player.PlayerActor.TraitsImplementing<ClassicProductionQueue>().Where(q => q.Enabled))
|
||||
queues.Add(q.Info.Type, q);
|
||||
|
||||
Action<Actor, Actor> globalProductionHandler = (factory, unit) =>
|
||||
{
|
||||
if (factory.Owner != player)
|
||||
return;
|
||||
|
||||
var queue = GetBuildableInfo(unit.Info.Name).Queue.First();
|
||||
|
||||
if (productionHandlers.ContainsKey(queue))
|
||||
productionHandlers[queue](factory, unit);
|
||||
};
|
||||
|
||||
var triggers = TriggerGlobal.GetScriptTriggers(player.PlayerActor);
|
||||
triggers.OnOtherProducedInternal += globalProductionHandler;
|
||||
}
|
||||
|
||||
[Desc("Build the specified set of actors using classic (RA-style) production queues. " +
|
||||
"The function will return true if production could be started, false otherwise. " +
|
||||
"If an actionFunc is given, it will be called as actionFunc(Actor[] actors) once " +
|
||||
"production of all actors has been completed. The actors array is guaranteed to " +
|
||||
"only contain alive actors. Note: This function will fail to work when called " +
|
||||
"during the first tick")]
|
||||
public bool Build(string[] actorTypes, LuaFunction actionFunc = null)
|
||||
{
|
||||
var typeToQueueMap = new Dictionary<string, string>();
|
||||
foreach (var actorType in actorTypes.Distinct())
|
||||
typeToQueueMap.Add(actorType, GetBuildableInfo(actorType).Queue.First());
|
||||
|
||||
var queueTypes = typeToQueueMap.Values.Distinct();
|
||||
|
||||
if (queueTypes.Any(t => !queues.ContainsKey(t) || productionHandlers.ContainsKey(t)))
|
||||
return false;
|
||||
|
||||
if (queueTypes.Any(t => queues[t].CurrentItem() != null))
|
||||
return false;
|
||||
|
||||
if (actionFunc != null)
|
||||
{
|
||||
var squadSize = actorTypes.Length;
|
||||
var squad = new List<Actor>();
|
||||
var func = actionFunc.CopyReference() as LuaFunction;
|
||||
|
||||
Action<Actor, Actor> productionHandler = (factory, unit) =>
|
||||
{
|
||||
squad.Add(unit);
|
||||
if (squad.Count >= squadSize)
|
||||
{
|
||||
using (func)
|
||||
using (var luaSquad = squad.Where(u => !u.IsDead).ToArray().ToLuaValue(Context))
|
||||
func.Call(luaSquad).Dispose();
|
||||
|
||||
foreach (var q in queueTypes)
|
||||
productionHandlers.Remove(q);
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var q in queueTypes)
|
||||
productionHandlers.Add(q, productionHandler);
|
||||
}
|
||||
|
||||
foreach (var actorType in actorTypes)
|
||||
{
|
||||
var queue = queues[typeToQueueMap[actorType]];
|
||||
queue.ResolveOrder(queue.Actor, Order.StartProduction(queue.Actor, actorType, 1));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Check whether the production queue that builds this type of actor is currently busy." +
|
||||
"Note: it does not check whether this particular type of actor is being produced.")]
|
||||
public bool IsProducing(string actorType)
|
||||
{
|
||||
var queue = GetBuildableInfo(actorType).Queue.First();
|
||||
|
||||
if (!queues.ContainsKey(queue))
|
||||
return true;
|
||||
|
||||
return productionHandlers.ContainsKey(queue) || queues[queue].CurrentItem() != null;
|
||||
}
|
||||
|
||||
BuildableInfo GetBuildableInfo(string actorType)
|
||||
{
|
||||
var ri = Player.World.Map.Rules.Actors[actorType];
|
||||
var bi = ri.Traits.GetOrDefault<BuildableInfo>();
|
||||
|
||||
if (bi == null)
|
||||
throw new LuaException("Actor of type {0} cannot be produced".F(actorType));
|
||||
else
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class RepairableBuildingProperties : ScriptActorProperties, Requires<RepairableBuildingInfo>
|
||||
{
|
||||
readonly RepairableBuilding rb;
|
||||
|
||||
public RepairableBuildingProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
rb = self.Trait<RepairableBuilding>();
|
||||
}
|
||||
|
||||
[Desc("Start repairs on this building. `repairer` can be an allied player.")]
|
||||
public void StartBuildingRepairs(Player repairer = null)
|
||||
{
|
||||
repairer = repairer ?? Self.Owner;
|
||||
|
||||
if (!rb.Repairers.Contains(repairer))
|
||||
rb.RepairBuilding(Self, repairer);
|
||||
}
|
||||
|
||||
[Desc("Stop repairs on this building. `repairer` can be an allied player.")]
|
||||
public void StopBuildingRepairs(Player repairer = null)
|
||||
{
|
||||
repairer = repairer ?? Self.Owner;
|
||||
|
||||
if (rb.RepairActive && rb.Repairers.Contains(repairer))
|
||||
rb.RepairBuilding(Self, repairer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Transform")]
|
||||
public class TransformProperties : ScriptActorProperties, Requires<TransformsInfo>
|
||||
{
|
||||
readonly Transforms transforms;
|
||||
|
||||
public TransformProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
transforms = self.Trait<Transforms>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Queue a new transformation.")]
|
||||
public void Deploy()
|
||||
{
|
||||
transforms.DeployTransform(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Mods.RA.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.UtilityCommands
|
||||
{
|
||||
public static class ActorStatsExport
|
||||
{
|
||||
public static DataTable GenerateTable()
|
||||
{
|
||||
var rules = Game.ModData.RulesetCache.LoadDefaultRules();
|
||||
|
||||
var table = new DataTable();
|
||||
table.Columns.Add("Name", typeof(string));
|
||||
table.Columns.Add("Cost", typeof(int));
|
||||
table.Columns.Add("HitPoints", typeof(int));
|
||||
table.Columns.Add("Armor", typeof(string));
|
||||
table.Columns.Add("Damage /s", typeof(float));
|
||||
|
||||
var armorList = new List<string>();
|
||||
foreach (var actorInfo in rules.Actors.Values)
|
||||
{
|
||||
var armor = actorInfo.Traits.GetOrDefault<ArmorInfo>();
|
||||
if (armor != null)
|
||||
if (!armorList.Contains(armor.Type))
|
||||
armorList.Add(armor.Type);
|
||||
}
|
||||
|
||||
armorList.Sort();
|
||||
foreach (var armorType in armorList)
|
||||
table.Columns.Add("vs. " + armorType, typeof(float));
|
||||
|
||||
foreach (var actorInfo in rules.Actors.Values)
|
||||
{
|
||||
if (actorInfo.Name.StartsWith("^"))
|
||||
continue;
|
||||
|
||||
var buildable = actorInfo.Traits.GetOrDefault<BuildableInfo>();
|
||||
if (buildable == null)
|
||||
continue;
|
||||
|
||||
var row = table.NewRow();
|
||||
var tooltip = actorInfo.Traits.GetOrDefault<TooltipInfo>();
|
||||
row["Name"] = tooltip != null ? tooltip.Name : actorInfo.Name;
|
||||
|
||||
var value = actorInfo.Traits.GetOrDefault<ValuedInfo>();
|
||||
row["Cost"] = value != null ? value.Cost : 0;
|
||||
|
||||
var health = actorInfo.Traits.GetOrDefault<HealthInfo>();
|
||||
row["HitPoints"] = health != null ? health.HP : 0;
|
||||
|
||||
var armor = actorInfo.Traits.GetOrDefault<ArmorInfo>();
|
||||
row["Armor"] = armor != null ? armor.Type : "";
|
||||
|
||||
var armaments = actorInfo.Traits.WithInterface<ArmamentInfo>();
|
||||
if (armaments.Any())
|
||||
{
|
||||
var weapons = armaments.Select(a => rules.Weapons[a.Weapon.ToLowerInvariant()]);
|
||||
foreach (var weapon in weapons)
|
||||
{
|
||||
var warhead = weapon.Warheads.FirstOrDefault(w => (w is DamageWarhead)) as DamageWarhead;
|
||||
if (warhead != null)
|
||||
{
|
||||
var rateOfFire = weapon.ReloadDelay > 1 ? weapon.ReloadDelay : 1;
|
||||
var burst = weapon.Burst;
|
||||
var delay = weapon.BurstDelay;
|
||||
var damage = warhead.Damage;
|
||||
var damagePerSecond = (1000f / Game.Timestep) * (damage * burst) / (delay + burst * rateOfFire);
|
||||
row["Damage /s"] = Math.Round(damagePerSecond, 1, MidpointRounding.AwayFromZero);
|
||||
|
||||
foreach (var armorType in armorList)
|
||||
{
|
||||
var vs = warhead.Versus.ContainsKey(armorType) ? warhead.Versus[armorType] : 100;
|
||||
row["vs. " + armorType] = Math.Round(damagePerSecond * vs / 100, 1, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.Rows.Add(row);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace OpenRA.Mods.RA.UtilityCommands
|
||||
{
|
||||
class ExportCharacterSeparatedRules : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--generate-dps-table"; } }
|
||||
|
||||
[Desc("Export the damage per second evaluation into a CSV file for inspection.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
{
|
||||
Game.ModData = modData;
|
||||
var table = ActorStatsExport.GenerateTable();
|
||||
var filename = "{0}-mod-dps.csv".F(Game.ModData.Manifest.Mod.Id);
|
||||
using (var outfile = new StreamWriter(filename))
|
||||
outfile.Write(table.ToCharacterSeparatedValues(";", true));
|
||||
Console.WriteLine("{0} has been saved.".F(filename));
|
||||
Console.WriteLine("Open as values separated by semicolon.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2015 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. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRA.Mods.RA.UtilityCommands
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static string ToCharacterSeparatedValues(this DataTable table, string delimiter, bool includeHeader)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
|
||||
if (includeHeader)
|
||||
{
|
||||
foreach (DataColumn column in table.Columns)
|
||||
{
|
||||
result.Append(column.ColumnName);
|
||||
result.Append(delimiter);
|
||||
}
|
||||
|
||||
result.Remove(result.Length, 0);
|
||||
result.AppendLine();
|
||||
}
|
||||
|
||||
foreach (DataRow row in table.Rows)
|
||||
{
|
||||
for (var x = 0; x < table.Columns.Count; x++)
|
||||
{
|
||||
if (x != 0)
|
||||
result.Append(delimiter);
|
||||
|
||||
result.Append(row[table.Columns[x]]);
|
||||
}
|
||||
|
||||
result.AppendLine();
|
||||
}
|
||||
|
||||
result.Remove(result.Length, 0);
|
||||
result.AppendLine();
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user