diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index e2987960d4..84ed13657c 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -515,7 +515,7 @@
-
+
@@ -586,4 +586,4 @@ copy "FuzzyLogicLibrary.dll" "$(SolutionDir)"
cd "$(SolutionDir)"
-
\ No newline at end of file
+
diff --git a/OpenRA.Mods.RA/Scripting/Global/DateGlobal.cs b/OpenRA.Mods.RA/Scripting/Global/DateTimeGlobal.cs
similarity index 66%
rename from OpenRA.Mods.RA/Scripting/Global/DateGlobal.cs
rename to OpenRA.Mods.RA/Scripting/Global/DateTimeGlobal.cs
index e93919bcf6..c87e7239d2 100644
--- a/OpenRA.Mods.RA/Scripting/Global/DateGlobal.cs
+++ b/OpenRA.Mods.RA/Scripting/Global/DateTimeGlobal.cs
@@ -17,7 +17,8 @@ namespace OpenRA.Mods.RA.Scripting
[ScriptGlobal("Date")]
public class DateGlobal : ScriptGlobal
{
- public DateGlobal(ScriptContext context) : base(context) { }
+ public DateGlobal(ScriptContext context)
+ : base(context) { }
[Desc("True on the 31st of October.")]
public bool IsHalloween
@@ -25,4 +26,17 @@ namespace OpenRA.Mods.RA.Scripting
get { return DateTime.Today.Month == 10 && DateTime.Today.Day == 31; }
}
}
+
+ [ScriptGlobal("Time")]
+ public class TimeGlobal : ScriptGlobal
+ {
+ public TimeGlobal(ScriptContext context)
+ : base(context) { }
+
+ [Desc("Get the current game time (in ticks)")]
+ public int GameTime
+ {
+ get { return context.World.WorldTick; }
+ }
+ }
}
diff --git a/OpenRA.Mods.RA/Scripting/Properties/CombatProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/CombatProperties.cs
index 382599b41d..6f864728e8 100644
--- a/OpenRA.Mods.RA/Scripting/Properties/CombatProperties.cs
+++ b/OpenRA.Mods.RA/Scripting/Properties/CombatProperties.cs
@@ -8,6 +8,9 @@
*/
#endregion
+using Eluant;
+using System;
+using System.Linq;
using OpenRA.Mods.RA.Activities;
using OpenRA.Scripting;
using OpenRA.Traits;
@@ -17,8 +20,13 @@ namespace OpenRA.Mods.RA.Scripting
[ScriptPropertyGroup("Combat")]
public class CombatProperties : ScriptActorProperties, Requires, Requires
{
+ readonly IMove move;
+
public CombatProperties(ScriptContext context, Actor self)
- : base(context, self) { }
+ : base(context, self)
+ {
+ move = self.Trait();
+ }
[ScriptActorPropertyActivity]
[Desc("Seek out and attack nearby targets.")]
@@ -33,11 +41,35 @@ namespace OpenRA.Mods.RA.Scripting
"close enough to complete the activity.")]
public void AttackMove(CPos cell, int closeEnough = 0)
{
- var move = self.TraitOrDefault();
- if (move == null)
- return;
-
self.QueueActivity(new AttackMove.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 AttackMove.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)));
+ }
}
}
diff --git a/OpenRA.Mods.RA/Scripting/Properties/HealthProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/HealthProperties.cs
index c11867ff9e..0143f33983 100644
--- a/OpenRA.Mods.RA/Scripting/Properties/HealthProperties.cs
+++ b/OpenRA.Mods.RA/Scripting/Properties/HealthProperties.cs
@@ -8,6 +8,7 @@
*/
#endregion
+using OpenRA.Mods.RA.Buildings;
using OpenRA.Scripting;
using OpenRA.Traits;
@@ -33,4 +34,34 @@ namespace OpenRA.Mods.RA.Scripting
[Desc("Maximum health of the actor.")]
public int MaxHealth { get { return health.MaxHP; } }
}
+
+ [ScriptPropertyGroup("General")]
+ public class RepairableBuildingProperties : ScriptActorProperties, Requires
+ {
+ readonly RepairableBuilding rb;
+
+ public RepairableBuildingProperties(ScriptContext context, Actor self)
+ : base(context, self)
+ {
+ rb = self.Trait();
+ }
+
+ [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);
+ }
+ }
}
\ No newline at end of file
diff --git a/OpenRA.Mods.RA/Scripting/Properties/PlaneProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/PlaneProperties.cs
index 0624c42e47..d56e8211eb 100644
--- a/OpenRA.Mods.RA/Scripting/Properties/PlaneProperties.cs
+++ b/OpenRA.Mods.RA/Scripting/Properties/PlaneProperties.cs
@@ -27,4 +27,17 @@ namespace OpenRA.Mods.RA.Scripting
self.QueueActivity(new Fly(self, Target.FromCell(self.World, cell)));
}
}
+
+ [ScriptPropertyGroup("Combat")]
+ public class PlaneCombatProperties : ScriptActorProperties, Requires
+ {
+ 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)));
+ }
+ }
}
\ No newline at end of file