Initial commit: OpenRA game engine
Fork from OpenRA/OpenRA with one-click launch script (start-ra.cmd) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Movement")]
|
||||
public class AircraftProperties : ScriptActorProperties, Requires<AircraftInfo>
|
||||
{
|
||||
readonly Aircraft aircraft;
|
||||
|
||||
public AircraftProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
aircraft = self.Trait<Aircraft>();
|
||||
}
|
||||
|
||||
[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 destination given, or an auto-selected one otherwise.")]
|
||||
public void ReturnToBase(Actor destination = null)
|
||||
{
|
||||
Self.QueueActivity(new ReturnToBase(Self, destination, true));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Queues a landing activity on the specified actor.")]
|
||||
public void Land(Actor landOn)
|
||||
{
|
||||
Self.QueueActivity(new Land(Self, Target.FromActor(landOn)));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Starts the resupplying activity when being on a host building.")]
|
||||
public void Resupply()
|
||||
{
|
||||
var atLandAltitude = Self.World.Map.DistanceAboveTerrain(Self.CenterPosition) == aircraft.Info.LandAltitude;
|
||||
var host = aircraft.GetActorBelow();
|
||||
if (atLandAltitude && host != null)
|
||||
Self.QueueActivity(new Resupply(Self, host, WDist.Zero));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("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. Returns the aircraft that will attack.")]
|
||||
public Actor[] TargetAirstrike(WPos target, WAngle? facing = null)
|
||||
{
|
||||
foreach (var notify in Self.TraitsImplementing<INotifySupportPower>())
|
||||
notify.Activated(Self);
|
||||
|
||||
return ap.SendAirstrike(Self, target, facing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("AmmoPool")]
|
||||
public class AmmoPoolProperties : ScriptActorProperties, Requires<AmmoPoolInfo>
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly AmmoPool[] ammoPools;
|
||||
|
||||
public AmmoPoolProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
this.self = self;
|
||||
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
|
||||
}
|
||||
|
||||
[Desc("Returns the count of the actor's specified ammopool.")]
|
||||
public int AmmoCount(string poolName = "primary")
|
||||
{
|
||||
var pool = ammoPools.FirstOrDefault(a => a.Info.Name == poolName);
|
||||
if (pool == null)
|
||||
throw new LuaException($"Invalid ammopool name {poolName} queried on actor {self}.");
|
||||
|
||||
return pool.CurrentAmmoCount;
|
||||
}
|
||||
|
||||
[Desc("Returns the maximum count of ammo the actor can load.")]
|
||||
public int MaximumAmmoCount(string poolName = "primary")
|
||||
{
|
||||
var pool = ammoPools.FirstOrDefault(a => a.Info.Name == poolName);
|
||||
if (pool == null)
|
||||
throw new LuaException($"Invalid ammopool name {poolName} queried on actor {self}.");
|
||||
|
||||
return pool.Info.Ammo;
|
||||
}
|
||||
|
||||
[Desc("Adds the specified amount of ammo to the specified ammopool.",
|
||||
"(Use a negative amount to remove ammo.)")]
|
||||
public void Reload(string poolName = "primary", int amount = 1)
|
||||
{
|
||||
var pool = ammoPools.FirstOrDefault(a => a.Info.Name == poolName);
|
||||
if (pool == null)
|
||||
throw new LuaException($"Invalid ammopool name {poolName} queried on actor {self}.");
|
||||
|
||||
if (amount > 0)
|
||||
pool.GiveAmmo(self, amount);
|
||||
else
|
||||
pool.TakeAmmo(self, -amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs
Normal file
47
OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Ability")]
|
||||
public class CaptureProperties : ScriptActorProperties, Requires<CaptureManagerInfo>
|
||||
{
|
||||
readonly CaptureManager captureManager;
|
||||
|
||||
public CaptureProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
captureManager = Self.Trait<CaptureManager>();
|
||||
}
|
||||
|
||||
[Desc("Captures the target actor.")]
|
||||
public void Capture(Actor target)
|
||||
{
|
||||
if (!CanCapture(target))
|
||||
return;
|
||||
|
||||
// NB: Scripted actions get no visible targetlines.
|
||||
Self.QueueActivity(new CaptureActor(Self, Target.FromActor(target), null));
|
||||
}
|
||||
|
||||
[Desc("Checks if the target actor can be captured.")]
|
||||
public bool CanCapture(Actor target)
|
||||
{
|
||||
var targetManager = target.TraitOrDefault<CaptureManager>();
|
||||
return targetManager != null && captureManager.CanTarget(targetManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Ability")]
|
||||
public class CarryallProperties : ScriptActorProperties, Requires<CarryallInfo>
|
||||
{
|
||||
readonly Carryall carryall;
|
||||
|
||||
public CarryallProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
carryall = Self.Trait<Carryall>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Pick up the target actor.")]
|
||||
public void PickupCarryable(Actor target)
|
||||
{
|
||||
var carryable = target.TraitOrDefault<Carryable>();
|
||||
if (carryable == null)
|
||||
throw new LuaException($"Actor '{Self}' cannot carry actor '{target}'!");
|
||||
|
||||
Self.QueueActivity(new PickupUnit(Self, target, carryall.Info.BeforeLoadDelay, null));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Drop the actor being carried at the target location.")]
|
||||
public void DeliverCarryable(CPos target)
|
||||
{
|
||||
Self.QueueActivity(new DeliverUnit(Self, Target.FromCell(Self.World, target), carryall.Info.DropRange, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
39
OpenRA.Mods.Common/Scripting/Properties/CloakProperties.cs
Normal file
39
OpenRA.Mods.Common/Scripting/Properties/CloakProperties.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Cloak")]
|
||||
public class CloakProperties : ScriptActorProperties, Requires<CloakInfo>
|
||||
{
|
||||
readonly Cloak[] cloaks;
|
||||
|
||||
public CloakProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
cloaks = self.TraitsImplementing<Cloak>().ToArray();
|
||||
}
|
||||
|
||||
[Desc("Returns true if the actor is cloaked.")]
|
||||
public bool IsCloaked
|
||||
{
|
||||
get
|
||||
{
|
||||
return cloaks.Any(c => c.Cloaked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
110
OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs
Normal file
110
OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.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("Ignoring visibility, find the closest hostile target and attack move to within 2 cells of it.")]
|
||||
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. " +
|
||||
"The callback function will be called as func(self: actor):boolean.")]
|
||||
public void PatrolUntil(CPos[] waypoints, [ScriptEmmyTypeOverride("fun(self: actor):boolean")] 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)));
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Combat")]
|
||||
public class GeneralCombatProperties : ScriptActorProperties, Requires<AttackBaseInfo>
|
||||
{
|
||||
readonly AttackBase[] attackBases;
|
||||
|
||||
public GeneralCombatProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
attackBases = self.TraitsImplementing<AttackBase>().ToArray();
|
||||
}
|
||||
|
||||
[Desc("Attack the target actor. The target actor needs to be visible.")]
|
||||
public void Attack(Actor targetActor, bool allowMove = true, bool forceAttack = false)
|
||||
{
|
||||
var target = Target.FromActor(targetActor);
|
||||
if (!target.IsValidFor(Self))
|
||||
Log.Write("lua", $"{targetActor} is an invalid target for {Self}!");
|
||||
|
||||
if (!targetActor.Info.HasTraitInfo<FrozenUnderFogInfo>() && !targetActor.CanBeViewedByPlayer(Self.Owner))
|
||||
Log.Write("lua", $"{targetActor} is not revealed for player {Self.Owner}!");
|
||||
|
||||
foreach (var attack in attackBases)
|
||||
attack.AttackTarget(target, AttackSource.Default, true, allowMove, forceAttack);
|
||||
}
|
||||
|
||||
[Desc("Checks if the targeted actor is a valid target for this actor.")]
|
||||
public bool CanTarget(Actor targetActor)
|
||||
{
|
||||
return Target.FromActor(targetActor).IsValidFor(Self);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class ConditionProperties : ScriptActorProperties, Requires<ExternalConditionInfo>
|
||||
{
|
||||
readonly ExternalCondition[] externalConditions;
|
||||
|
||||
public ConditionProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
externalConditions = self.TraitsImplementing<ExternalCondition>().ToArray();
|
||||
}
|
||||
|
||||
[Desc("Grant an external condition on this actor and return the revocation token.",
|
||||
"Conditions must be defined on an ExternalConditions trait on the actor.",
|
||||
"If duration > 0 the condition will be automatically revoked after the defined number of ticks.")]
|
||||
public int GrantCondition(string condition, int duration = 0)
|
||||
{
|
||||
var external = externalConditions.FirstOrDefault(t => t.Info.Condition == condition && t.CanGrantCondition(this));
|
||||
|
||||
if (external == null)
|
||||
throw new LuaException($"Condition `{condition}` has not been listed on an enabled ExternalCondition trait");
|
||||
|
||||
return external.GrantCondition(Self, this, duration);
|
||||
}
|
||||
|
||||
[Desc("Revoke a condition using the token returned by GrantCondition.")]
|
||||
public void RevokeCondition(int token)
|
||||
{
|
||||
foreach (var external in externalConditions)
|
||||
if (external.TryRevokeCondition(Self, this, token))
|
||||
break;
|
||||
}
|
||||
|
||||
[Desc("Check whether this actor accepts a specific external condition.")]
|
||||
public bool AcceptsCondition(string condition)
|
||||
{
|
||||
return externalConditions
|
||||
.Any(t => t.Info.Condition == condition && t.CanGrantCondition(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Ability")]
|
||||
public class DeliversCashProperties : ScriptActorProperties, Requires<IMoveInfo>, Requires<DeliversCashInfo>
|
||||
{
|
||||
readonly DeliversCashInfo info;
|
||||
|
||||
public DeliversCashProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
info = Self.Info.TraitInfo<DeliversCashInfo>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Deliver cash to the target actor.")]
|
||||
public void DeliverCash(Actor target)
|
||||
{
|
||||
var t = Target.FromActor(target);
|
||||
|
||||
// NB: Scripted actions get no visible targetlines.
|
||||
Self.QueueActivity(new DonateCash(Self, t, info.Payload, info.PlayerExperience, null));
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Ability")]
|
||||
public class DeliversExperienceProperties : ScriptActorProperties, Requires<IMoveInfo>, Requires<DeliversExperienceInfo>
|
||||
{
|
||||
readonly DeliversExperienceInfo deliversExperience;
|
||||
readonly GainsExperience gainsExperience;
|
||||
|
||||
public DeliversExperienceProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
deliversExperience = Self.Info.TraitInfo<DeliversExperienceInfo>();
|
||||
gainsExperience = Self.Trait<GainsExperience>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Deliver experience to the target actor.")]
|
||||
public void DeliverExperience(Actor target)
|
||||
{
|
||||
var targetGainsExperience = target.TraitOrDefault<GainsExperience>();
|
||||
if (targetGainsExperience == null)
|
||||
throw new LuaException($"Actor '{target}' cannot gain experience!");
|
||||
|
||||
if (targetGainsExperience.Level == targetGainsExperience.MaxLevel)
|
||||
return;
|
||||
|
||||
var level = gainsExperience.Level;
|
||||
var t = Target.FromActor(target);
|
||||
|
||||
// NB: Scripted actions get no visible targetlines.
|
||||
Self.QueueActivity(new DonateExperience(Self, t, level, deliversExperience.PlayerExperience, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Combat")]
|
||||
public class DemolitionProperties : ScriptActorProperties, Requires<IMoveInfo>, Requires<DemolitionInfo>
|
||||
{
|
||||
readonly Demolition[] demolitions;
|
||||
|
||||
public DemolitionProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
demolitions = Self.TraitsImplementing<Demolition>().ToArray();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Demolish the target actor.")]
|
||||
public void Demolish(Actor target)
|
||||
{
|
||||
// NB: Scripted actions get no visible targetlines.
|
||||
var demolition = demolitions.FirstEnabledConditionalTraitOrDefault();
|
||||
if (demolition != null)
|
||||
Self.QueueActivity(demolition.GetDemolishActivity(Self, Target.FromActor(target), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Scripting;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Diplomacy")]
|
||||
public class DiplomacyProperties : ScriptPlayerProperties
|
||||
{
|
||||
public DiplomacyProperties(ScriptContext context, Player player)
|
||||
: base(context, player) { }
|
||||
|
||||
[Desc("Returns true if the player is allied with the other player.")]
|
||||
public bool IsAlliedWith(Player targetPlayer)
|
||||
{
|
||||
return Player.IsAlliedWith(targetPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Experience")]
|
||||
public class GainsExperienceProperties : ScriptActorProperties, Requires<GainsExperienceInfo>
|
||||
{
|
||||
readonly GainsExperience exp;
|
||||
|
||||
public GainsExperienceProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
exp = self.Trait<GainsExperience>();
|
||||
}
|
||||
|
||||
[Desc("The actor's amount of experience.")]
|
||||
public int Experience => exp.Experience;
|
||||
|
||||
[Desc("The actor's level.")]
|
||||
public int Level => exp.Level;
|
||||
|
||||
[Desc("The actor's maximum possible level.")]
|
||||
public int MaxLevel => exp.MaxLevel;
|
||||
|
||||
[Desc("Returns true if the actor can gain a level.")]
|
||||
public bool CanGainLevel => exp.CanGainLevel;
|
||||
|
||||
[Desc("Gives the actor experience. If 'silent' is true, no animation or sound will be played if the actor levels up.")]
|
||||
public void GiveExperience(int amount, bool silent = false)
|
||||
{
|
||||
exp.GiveExperience(amount, silent);
|
||||
}
|
||||
|
||||
[Desc("Gives the actor level(s). If 'silent' is true, no animation or sound will be played.")]
|
||||
public void GiveLevels(int numLevels, bool silent = false)
|
||||
{
|
||||
exp.GiveLevels(numLevels, silent);
|
||||
}
|
||||
}
|
||||
}
|
||||
226
OpenRA.Mods.Common/Scripting/Properties/GeneralProperties.cs
Normal file
226
OpenRA.Mods.Common/Scripting/Properties/GeneralProperties.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 Eluant;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Effects;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.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 => 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 => Self.IsDead;
|
||||
|
||||
[Desc("Specifies whether the actor is idle (not performing any activities).")]
|
||||
public bool IsIdle => Self.IsIdle;
|
||||
|
||||
[Desc("The player that owns the actor.")]
|
||||
public Player Owner
|
||||
{
|
||||
get => Self.Owner;
|
||||
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new LuaException($"Attempted to change the owner of actor '{Self}' to nil value.");
|
||||
|
||||
if (Self.Owner != value)
|
||||
Self.ChangeOwner(value);
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("The type of the actor (e.g. \"e1\").")]
|
||||
public string Type => Self.Info.Name;
|
||||
|
||||
[Desc("Test whether an actor has a specific property.")]
|
||||
public bool HasProperty(string name)
|
||||
{
|
||||
return Self.HasScriptProperty(name);
|
||||
}
|
||||
|
||||
[Desc("Render a target flash on the actor.")]
|
||||
public void Flash(Color color, int count = 2, int interval = 2, int delay = 0)
|
||||
{
|
||||
// TODO: We can't use floats with Lua, so use the default 0.5f here
|
||||
Self.World.Add(new FlashTarget(Self, color, 0.5f, count, interval, delay));
|
||||
}
|
||||
|
||||
[Desc("The effective (displayed) owner of the actor. " +
|
||||
"This may differ from the true owner in some cases, such as disguised actors.")]
|
||||
public Player EffectiveOwner
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Self.EffectiveOwner == null || Self.EffectiveOwner.Owner == null)
|
||||
return Self.Owner;
|
||||
|
||||
return Self.EffectiveOwner.Owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class GeneralProperties : ScriptActorProperties
|
||||
{
|
||||
readonly AutoTarget autotarget;
|
||||
readonly ScriptTags scriptTags;
|
||||
readonly Tooltip[] tooltips;
|
||||
|
||||
public GeneralProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
autotarget = self.TraitOrDefault<AutoTarget>();
|
||||
scriptTags = self.TraitOrDefault<ScriptTags>();
|
||||
tooltips = self.TraitsImplementing<Tooltip>().ToArray();
|
||||
}
|
||||
|
||||
[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([ScriptEmmyTypeOverride("fun()")] 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 => autotarget?.Stance.ToString();
|
||||
|
||||
set
|
||||
{
|
||||
if (autotarget == null)
|
||||
return;
|
||||
|
||||
if (!Enum.TryParse<UnitStance>(value, true, out var stance))
|
||||
throw new LuaException($"Unknown stance type '{value}'");
|
||||
|
||||
autotarget.SetStance(Self, stance);
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("The actor's tooltip name. Returns nil if the actor has no tooltip.")]
|
||||
public string TooltipName
|
||||
{
|
||||
get
|
||||
{
|
||||
var tooltip = tooltips.FirstEnabledConditionalTraitOrDefault();
|
||||
if (tooltip == null)
|
||||
return null;
|
||||
|
||||
return FluentProvider.GetMessage(tooltip.Info.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("Specifies whether or not the actor supports 'tags'.")]
|
||||
public bool IsTaggable => scriptTags != null;
|
||||
|
||||
[Desc("Add a tag to the actor. Returns true on success, false otherwise (for example the actor may already have the given tag).")]
|
||||
public bool AddTag(string tag)
|
||||
{
|
||||
return IsTaggable && scriptTags.AddTag(tag);
|
||||
}
|
||||
|
||||
[Desc("Remove a tag from the actor. Returns true on success, false otherwise (tag was not present).")]
|
||||
public bool RemoveTag(string tag)
|
||||
{
|
||||
return IsTaggable && scriptTags.RemoveTag(tag);
|
||||
}
|
||||
|
||||
[Desc("Specifies whether or not the actor has a particular tag.")]
|
||||
public bool HasTag(string tag)
|
||||
{
|
||||
return IsTaggable && scriptTags.HasTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class LocationProperties : ScriptActorProperties, Requires<IOccupySpaceInfo>
|
||||
{
|
||||
public LocationProperties(ScriptContext context, Actor self)
|
||||
: base(context, self) { }
|
||||
|
||||
[Desc("The actor position in cell coordinates.")]
|
||||
public CPos Location => Self.Location;
|
||||
|
||||
[Desc("The actor position in world coordinates.")]
|
||||
public WPos CenterPosition => Self.CenterPosition;
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class FacingProperties : ScriptActorProperties, Requires<IFacingInfo>
|
||||
{
|
||||
readonly IFacing facing;
|
||||
|
||||
public FacingProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
facing = self.Trait<IFacing>();
|
||||
}
|
||||
|
||||
[Desc("The direction that the actor is facing.")]
|
||||
public WAngle Facing => facing.Facing;
|
||||
}
|
||||
}
|
||||
36
OpenRA.Mods.Common/Scripting/Properties/GuardProperties.cs
Normal file
36
OpenRA.Mods.Common/Scripting/Properties/GuardProperties.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Combat")]
|
||||
public class GuardProperties : ScriptActorProperties, Requires<GuardInfo>, Requires<IMoveInfo>
|
||||
{
|
||||
readonly 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.Info.HasTraitInfo<GuardableInfo>())
|
||||
guard.GuardTarget(Self, Target.FromActor(targetActor));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Movement")]
|
||||
public class HarvesterProperties : ScriptActorProperties, Requires<HarvesterInfo>
|
||||
{
|
||||
public HarvesterProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{ }
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Search for nearby resources and begin harvesting.")]
|
||||
public void FindResources()
|
||||
{
|
||||
Self.QueueActivity(new FindAndDeliverResources(Self));
|
||||
}
|
||||
}
|
||||
}
|
||||
53
OpenRA.Mods.Common/Scripting/Properties/HealthProperties.cs
Normal file
53
OpenRA.Mods.Common/Scripting/Properties/HealthProperties.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Primitives;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class HealthProperties : ScriptActorProperties, Requires<IHealthInfo>
|
||||
{
|
||||
readonly IHealth health;
|
||||
public HealthProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
health = self.Trait<IHealth>();
|
||||
}
|
||||
|
||||
[Desc("Current health of the actor.")]
|
||||
public int Health
|
||||
{
|
||||
get => health.HP;
|
||||
set => health.InflictDamage(Self, Self, new Damage(health.HP - value), true);
|
||||
}
|
||||
|
||||
[Desc("Maximum health of the actor.")]
|
||||
public int MaxHealth => health.MaxHP;
|
||||
|
||||
[Desc("Kill the actor. damageTypes may be omitted, specified as a string, or as table of strings.")]
|
||||
public void Kill([ScriptEmmyTypeOverride("string|{ [unknown]: string }")] object damageTypes = null)
|
||||
{
|
||||
Damage damage;
|
||||
if (damageTypes is string d)
|
||||
damage = new Damage(health.MaxHP, new BitSet<DamageType>([d]));
|
||||
else if (damageTypes is LuaTable t && t.TryGetClrValue(out string[] ds))
|
||||
damage = new Damage(health.MaxHP, new BitSet<DamageType>(ds));
|
||||
else
|
||||
damage = new Damage(health.MaxHP);
|
||||
|
||||
health.InflictDamage(Self, Self, damage, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Ability")]
|
||||
public class InstantlyRepairsProperties : ScriptActorProperties, Requires<IMoveInfo>, Requires<InstantlyRepairsInfo>
|
||||
{
|
||||
readonly InstantlyRepairs[] instantlyRepairs;
|
||||
|
||||
public InstantlyRepairsProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
instantlyRepairs = Self.TraitsImplementing<InstantlyRepairs>().ToArray();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Enter the target actor to repair it instantly.")]
|
||||
public void InstantlyRepair(Actor target)
|
||||
{
|
||||
// NB: Scripted actions get no visible targetlines.
|
||||
var repair = instantlyRepairs.FirstEnabledConditionalTraitOrDefault();
|
||||
if (repair != null)
|
||||
Self.QueueActivity(new InstantRepair(Self, Target.FromActor(target), repair.Info, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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("MissionObjectives")]
|
||||
public class MissionObjectiveProperties : ScriptPlayerProperties, Requires<MissionObjectivesInfo>
|
||||
{
|
||||
readonly MissionObjectives mo;
|
||||
readonly bool shortGame;
|
||||
|
||||
public MissionObjectiveProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
mo = player.PlayerActor.Trait<MissionObjectives>();
|
||||
shortGame = player.World.WorldActor.Trait<MapOptions>().ShortGame;
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Add a 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 AddObjective(string description, string type = "Primary", bool required = true)
|
||||
{
|
||||
return mo.Add(Player, description, type, required);
|
||||
}
|
||||
|
||||
[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 AddObjective(description);
|
||||
}
|
||||
|
||||
[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 AddObjective(description, "Secondary", false);
|
||||
}
|
||||
|
||||
[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. " +
|
||||
"It is possible to mark a completed objective as a failure.")]
|
||||
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;
|
||||
}
|
||||
|
||||
[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(shortGame);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
OpenRA.Mods.Common/Scripting/Properties/MobileProperties.cs
Normal file
72
OpenRA.Mods.Common/Scripting/Properties/MobileProperties.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.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, WDist.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)
|
||||
{
|
||||
var pos = Self.CenterPosition;
|
||||
mobile.SetPosition(Self, cell);
|
||||
mobile.SetCenterPosition(Self, pos);
|
||||
Self.QueueActivity(mobile.ReturnToCell(Self));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Leave the current position in a random direction.")]
|
||||
public void Scatter()
|
||||
{
|
||||
Self.QueueActivity(false, new Nudge(Self));
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Move to and enter the transport.")]
|
||||
public void EnterTransport(Actor transport)
|
||||
{
|
||||
Self.QueueActivity(new RideTransport(Self, Target.FromActor(transport), null));
|
||||
}
|
||||
|
||||
[Desc("Whether the actor can move (false if immobilized).")]
|
||||
public bool IsMobile => !mobile.IsTraitDisabled && !mobile.IsTraitPaused;
|
||||
}
|
||||
}
|
||||
39
OpenRA.Mods.Common/Scripting/Properties/NukeProperties.cs
Normal file
39
OpenRA.Mods.Common/Scripting/Properties/NukeProperties.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Support Powers")]
|
||||
public class NukeProperties : ScriptActorProperties, Requires<NukePowerInfo>
|
||||
{
|
||||
readonly NukePower np;
|
||||
|
||||
public NukeProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
np = self.TraitsImplementing<NukePower>().First();
|
||||
}
|
||||
|
||||
[Desc("Activate the actor's NukePower.")]
|
||||
public void ActivateNukePower(CPos target)
|
||||
{
|
||||
np.Activate(Self, Self.World.Map.CenterOfCell(target));
|
||||
|
||||
foreach (var notify in Self.TraitsImplementing<INotifySupportPower>())
|
||||
notify.Activated(Self);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Transports")]
|
||||
public class ParadropProperties : ScriptActorProperties, Requires<CargoInfo>, Requires<ParaDropInfo>
|
||||
{
|
||||
readonly ParaDrop paradrop;
|
||||
|
||||
public ParadropProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
paradrop = self.Trait<ParaDrop>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Command transport to paradrop passengers near the target cell.")]
|
||||
public void Paradrop(CPos cell)
|
||||
{
|
||||
foreach (var notify in Self.TraitsImplementing<INotifySupportPower>())
|
||||
notify.Activated(Self);
|
||||
|
||||
paradrop.SetLZ(cell, true);
|
||||
Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell)));
|
||||
Self.QueueActivity(new FlyOffMap(Self));
|
||||
Self.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Support Powers")]
|
||||
public class ParatroopersProperties : ScriptActorProperties, Requires<ParatroopersPowerInfo>
|
||||
{
|
||||
readonly ParatroopersPower pp;
|
||||
|
||||
public ParatroopersProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
pp = self.TraitsImplementing<ParatroopersPower>().First();
|
||||
}
|
||||
|
||||
[Desc("Activate the actor's Paratroopers Power. Returns the aircraft that will drop the reinforcements.")]
|
||||
public Actor[] TargetParatroopers(WPos target, WAngle? facing = null)
|
||||
{
|
||||
foreach (var notify in Self.TraitsImplementing<INotifySupportPower>())
|
||||
notify.Activated(Self);
|
||||
|
||||
var actors = pp.SendParatroopers(Self, target, facing);
|
||||
return actors.Aircraft;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Player")]
|
||||
public class PlayerConditionProperties : ScriptPlayerProperties
|
||||
{
|
||||
readonly ExternalCondition[] externalConditions;
|
||||
|
||||
public PlayerConditionProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
externalConditions = player.PlayerActor.TraitsImplementing<ExternalCondition>().ToArray();
|
||||
}
|
||||
|
||||
[Desc("Grant an external condition on the player actor and return the revocation token.",
|
||||
"Conditions must be defined on an ExternalConditions trait on the player actor.",
|
||||
"If duration > 0 the condition will be automatically revoked after the defined number of ticks.")]
|
||||
public int GrantCondition(string condition, int duration = 0)
|
||||
{
|
||||
var external = externalConditions.FirstOrDefault(t => t.Info.Condition == condition && t.CanGrantCondition(this));
|
||||
|
||||
if (external == null)
|
||||
throw new LuaException($"Condition `{condition}` has not been listed on an enabled ExternalCondition trait");
|
||||
|
||||
return external.GrantCondition(Player.PlayerActor, this, duration);
|
||||
}
|
||||
|
||||
[Desc("Revoke a condition using the token returned by GrantCondition.")]
|
||||
public void RevokeCondition(int token)
|
||||
{
|
||||
foreach (var external in externalConditions)
|
||||
if (external.TryRevokeCondition(Player.PlayerActor, this, token))
|
||||
break;
|
||||
}
|
||||
|
||||
[Desc("Check whether this player actor accepts a specific external condition.")]
|
||||
public bool AcceptsCondition(string condition)
|
||||
{
|
||||
return externalConditions
|
||||
.Any(t => t.Info.Condition == condition && t.CanGrantCondition(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Player")]
|
||||
public class PlayerExperienceProperties : ScriptPlayerProperties, Requires<PlayerExperienceInfo>
|
||||
{
|
||||
readonly PlayerExperience exp;
|
||||
|
||||
public PlayerExperienceProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
exp = player.PlayerActor.Trait<PlayerExperience>();
|
||||
}
|
||||
|
||||
[Desc("Get or set the current experience.")]
|
||||
public int Experience
|
||||
{
|
||||
get => exp.Experience;
|
||||
|
||||
set => exp.GiveExperience(value - exp.Experience);
|
||||
}
|
||||
}
|
||||
}
|
||||
127
OpenRA.Mods.Common/Scripting/Properties/PlayerProperties.cs
Normal file
127
OpenRA.Mods.Common/Scripting/Properties/PlayerProperties.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Scripting;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Player")]
|
||||
public class PlayerProperties : ScriptPlayerProperties
|
||||
{
|
||||
public PlayerProperties(ScriptContext context, Player player)
|
||||
: base(context, player) { }
|
||||
|
||||
[Desc("The player's internal name.")]
|
||||
public string InternalName => Player.InternalName;
|
||||
|
||||
[Desc("The player's name.")]
|
||||
public string Name => Player.ResolvedPlayerName;
|
||||
|
||||
[Desc("The player's color.")]
|
||||
public Color Color => Player.GetColor(Player);
|
||||
|
||||
[Desc("The player's faction.")]
|
||||
public string Faction => Player.Faction.InternalName;
|
||||
|
||||
[Desc("The player's spawnpoint ID.")]
|
||||
public int Spawn => Player.SpawnPoint;
|
||||
|
||||
[Desc("The player's home/starting location.")]
|
||||
public CPos HomeLocation => Player.HomeLocation;
|
||||
|
||||
[Desc("The player's team ID.")]
|
||||
public int Team
|
||||
{
|
||||
get
|
||||
{
|
||||
var c = Player.World.LobbyInfo.Clients.FirstOrDefault(i => i.Index == Player.ClientIndex);
|
||||
return c?.Team ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("The player's handicap level.")]
|
||||
public int Handicap
|
||||
{
|
||||
get
|
||||
{
|
||||
var c = Player.World.LobbyInfo.Clients.FirstOrDefault(i => i.Index == Player.ClientIndex);
|
||||
return c?.Handicap ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Desc("Returns true if the player is a bot.")]
|
||||
public bool IsBot => Player.IsBot;
|
||||
|
||||
[Desc("Returns true if the player is non combatant.")]
|
||||
public bool IsNonCombatant => Player.NonCombatant;
|
||||
|
||||
[Desc("Returns true if the player is the local player.")]
|
||||
public bool IsLocalPlayer => Player == (Player.World.RenderPlayer ?? Player.World.LocalPlayer);
|
||||
|
||||
[Desc("Returns all living actors staying inside the world for this player.")]
|
||||
public Actor[] GetActors()
|
||||
{
|
||||
return Player.World.Actors.Where(actor => actor.Owner == Player && !actor.IsDead && actor.IsInWorld).ToArray();
|
||||
}
|
||||
|
||||
[Desc("Returns an array of actors representing all ground attack units of this player.")]
|
||||
public Actor[] GetGroundAttackers()
|
||||
{
|
||||
return Player.World.ActorsHavingTrait<AttackBase>()
|
||||
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.HasTraitInfo<MobileInfo>())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
[Desc("Returns all living actors of the specified type of this player.")]
|
||||
public Actor[] GetActorsByType(string type)
|
||||
{
|
||||
var result = new List<Actor>();
|
||||
|
||||
if (!Context.World.Map.Rules.Actors.TryGetValue(type, out var ai))
|
||||
throw new LuaException($"Unknown actor type '{type}'");
|
||||
|
||||
result.AddRange(Player.World.Actors
|
||||
.Where(actor => actor.Owner == Player && !actor.IsDead && actor.IsInWorld && actor.Info.Name == ai.Name));
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
[Desc("Returns all living actors of the specified types of this player.")]
|
||||
public Actor[] GetActorsByTypes(string[] types)
|
||||
{
|
||||
var result = new List<Actor>();
|
||||
|
||||
foreach (var type in types)
|
||||
if (!Context.World.Map.Rules.Actors.ContainsKey(type))
|
||||
throw new LuaException($"Unknown actor type '{type}'");
|
||||
|
||||
result.AddRange(Player.World.Actors
|
||||
.Where(actor => actor.Owner == Player && !actor.IsDead && actor.IsInWorld && types.Contains(actor.Info.Name)));
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
[Desc("Check if the player has these prerequisites available.")]
|
||||
public bool HasPrerequisites(string[] type)
|
||||
{
|
||||
var tt = Player.PlayerActor.TraitOrDefault<TechTree>();
|
||||
if (tt == null)
|
||||
throw new LuaException($"Missing TechTree trait on player {Player}!");
|
||||
|
||||
return tt.HasPrerequisites(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Player")]
|
||||
public class PlayerStatsProperties : ScriptPlayerProperties, Requires<PlayerStatisticsInfo>
|
||||
{
|
||||
readonly PlayerStatistics stats;
|
||||
|
||||
public PlayerStatsProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
stats = player.PlayerActor.Trait<PlayerStatistics>();
|
||||
}
|
||||
|
||||
[Desc("The combined value of units killed by this player.")]
|
||||
public int KillsCost => stats.KillsCost;
|
||||
|
||||
[Desc("The combined value of all units lost by this player.")]
|
||||
public int DeathsCost => stats.DeathsCost;
|
||||
|
||||
[Desc("The total number of units killed by this player.")]
|
||||
public int UnitsKilled => stats.UnitsKilled;
|
||||
|
||||
[Desc("The total number of units lost by this player.")]
|
||||
public int UnitsLost => stats.UnitsDead;
|
||||
|
||||
[Desc("The total number of buildings killed by this player.")]
|
||||
public int BuildingsKilled => stats.BuildingsKilled;
|
||||
|
||||
[Desc("The total number of buildings lost by this player.")]
|
||||
public int BuildingsLost => stats.BuildingsDead;
|
||||
}
|
||||
}
|
||||
72
OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs
Normal file
72
OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
using PowerTrait = OpenRA.Mods.Common.Traits.Power;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Power")]
|
||||
public class PlayerPowerProperties : ScriptPlayerProperties, Requires<PowerManagerInfo>
|
||||
{
|
||||
readonly PowerManager pm;
|
||||
|
||||
public PlayerPowerProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
pm = player.PlayerActor.Trait<PowerManager>();
|
||||
}
|
||||
|
||||
[Desc("Returns the total of the power the player has.")]
|
||||
public int PowerProvided => pm.PowerProvided;
|
||||
|
||||
[Desc("Returns the power used by the player.")]
|
||||
public int PowerDrained => pm.PowerDrained;
|
||||
|
||||
[Desc("Returns the player's power state " +
|
||||
"(\"Normal\", \"Low\" or \"Critical\").")]
|
||||
public string PowerState => pm.PowerState.ToString();
|
||||
|
||||
[Desc("Triggers low power for the chosen amount of ticks.")]
|
||||
public void TriggerPowerOutage(int ticks)
|
||||
{
|
||||
pm.TriggerPowerOutage(ticks);
|
||||
}
|
||||
|
||||
[Desc("Whether the player should receive a notification when low on power.")]
|
||||
public bool PlayLowPowerNotification
|
||||
{
|
||||
get => pm.PlayLowPowerNotification;
|
||||
set => pm.PlayLowPowerNotification = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Power")]
|
||||
public class ActorPowerProperties : ScriptActorProperties, Requires<PowerInfo>
|
||||
{
|
||||
readonly PowerTrait[] power;
|
||||
|
||||
public ActorPowerProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
power = self.TraitsImplementing<PowerTrait>().ToArray();
|
||||
}
|
||||
|
||||
[Desc("Returns the power drained/provided by this actor.")]
|
||||
public int Power
|
||||
{
|
||||
get { return power.Sum(p => p.GetEnabledPower()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
311
OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs
Normal file
311
OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs
Normal file
@@ -0,0 +1,311 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class ProductionProperties : ScriptActorProperties, Requires<ProductionInfo>
|
||||
{
|
||||
readonly Production[] productionTraits;
|
||||
|
||||
public ProductionProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
productionTraits = self.TraitsImplementing<Production>().ToArray();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Build a unit, ignoring the production queue. The activity will wait if the exit is blocked.",
|
||||
"If productionType is nil or unavailable, then an exit will be selected based on 'Buildable.BuildAtProductionType'.",
|
||||
"If 'Buildable.BuildAtProductionType' is not set either, a random exit will be selected.")]
|
||||
public void Produce(string actorType, string factionVariant = null, string productionType = null)
|
||||
{
|
||||
if (!Self.World.Map.Rules.Actors.TryGetValue(actorType, out var actorInfo))
|
||||
throw new LuaException($"Unknown actor type '{actorType}'");
|
||||
|
||||
var bi = actorInfo.TraitInfo<BuildableInfo>();
|
||||
Self.QueueActivity(new WaitFor(() =>
|
||||
{
|
||||
// Go through all available traits and see which one successfully produces
|
||||
foreach (var p in productionTraits)
|
||||
{
|
||||
var type = productionType ?? bi.BuildAtProductionType;
|
||||
if (!string.IsNullOrEmpty(type) && !p.Info.Produces.Contains(type))
|
||||
continue;
|
||||
|
||||
var inits = new TypeDictionary
|
||||
{
|
||||
new OwnerInit(Self.Owner),
|
||||
new FactionInit(factionVariant ?? BuildableInfo.GetInitialFaction(actorInfo, p.Faction))
|
||||
};
|
||||
|
||||
if (p.Produce(Self, actorInfo, type, inits, 0))
|
||||
return true;
|
||||
}
|
||||
|
||||
// We didn't produce anything, wait until we do
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
[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
|
||||
{
|
||||
if (rp.Path.Count > 0)
|
||||
return rp.Path[^1];
|
||||
|
||||
var exit = Self.NearestExitOrDefault(Self.CenterPosition);
|
||||
if (exit != null)
|
||||
return Self.Location + exit.Info.ExitCell;
|
||||
|
||||
return Self.Location;
|
||||
}
|
||||
set => rp.Path = [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 => pb.IsPrimary;
|
||||
set => pb.SetPrimaryProducer(Self, value);
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptPropertyGroup("Production")]
|
||||
public class ProductionQueueProperties : ScriptActorProperties, Requires<ProductionQueueInfo>, Requires<ScriptTriggersInfo>
|
||||
{
|
||||
readonly ProductionQueue[] queues;
|
||||
readonly ScriptTriggers triggers;
|
||||
|
||||
public ProductionQueueProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
queues = self.TraitsImplementing<ProductionQueue>().Where(q => q.Enabled).ToArray();
|
||||
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(actors: actor[]) once " +
|
||||
"production of all actors has been completed. The actors array is guaranteed to " +
|
||||
"only contain alive actors.")]
|
||||
public bool Build(string[] actorTypes, [ScriptEmmyTypeOverride("fun(actors: actor[])")] LuaFunction actionFunc = null)
|
||||
{
|
||||
if (triggers.HasAnyCallbacksFor(Trigger.OnProduction))
|
||||
return false;
|
||||
|
||||
var queue = queues.Where(q => actorTypes.All(t => GetBuildableInfo(t).Queue.Contains(q.Info.Type)))
|
||||
.FirstOrDefault(q => !q.AllQueued().Any());
|
||||
|
||||
if (queue == null)
|
||||
return false;
|
||||
|
||||
if (actionFunc != null)
|
||||
{
|
||||
var player = Self.Owner;
|
||||
var squadSize = actorTypes.Length;
|
||||
var squad = new List<Actor>();
|
||||
var func = actionFunc.CopyReference() as LuaFunction;
|
||||
|
||||
Action<Actor, Actor> productionHandler = (a, b) => { };
|
||||
productionHandler = (factory, unit) =>
|
||||
{
|
||||
if (player != factory.Owner)
|
||||
{
|
||||
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.HasAnyCallbacksFor(Trigger.OnProduction))
|
||||
return true;
|
||||
|
||||
return queues.Any(q => GetBuildableInfo(actorType).Queue.Contains(q.Info.Type) && q.AllQueued().Any());
|
||||
}
|
||||
|
||||
BuildableInfo GetBuildableInfo(string actorType)
|
||||
{
|
||||
var ri = Self.World.Map.Rules.Actors[actorType];
|
||||
var bi = ri.TraitInfoOrDefault<BuildableInfo>();
|
||||
|
||||
if (bi == null)
|
||||
throw new LuaException($"Actor of type {actorType} cannot be produced");
|
||||
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 = [];
|
||||
|
||||
queues = [];
|
||||
foreach (var q in player.PlayerActor.TraitsImplementing<ClassicProductionQueue>().Where(q => q.Enabled))
|
||||
queues.Add(q.Info.Type, q);
|
||||
|
||||
void GlobalProductionHandler(Actor factory, Actor unit)
|
||||
{
|
||||
if (factory.Owner != player)
|
||||
return;
|
||||
|
||||
var queue = GetBuildableInfo(unit.Info.Name).Queue.First();
|
||||
|
||||
if (productionHandlers.TryGetValue(queue, out var productionHandler))
|
||||
productionHandler(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(actors: actor[]) 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, [ScriptEmmyTypeOverride("fun(actors: actor[])")] LuaFunction actionFunc = null)
|
||||
{
|
||||
var typeToQueueMap = new Dictionary<string, string>();
|
||||
foreach (var actorType in actorTypes.Distinct())
|
||||
typeToQueueMap.Add(actorType, GetBuildableInfo(actorType).Queue.First());
|
||||
|
||||
// PERF: queues tend to live for a long time so cast to array.
|
||||
var queueTypes = typeToQueueMap.Values.Distinct().ToArray();
|
||||
if (queueTypes.Any(t => !queues.ContainsKey(t) || productionHandlers.ContainsKey(t)))
|
||||
return false;
|
||||
|
||||
if (queueTypes.Any(t => queues[t].AllQueued().Any()))
|
||||
return false;
|
||||
|
||||
if (actionFunc != null)
|
||||
{
|
||||
var squadSize = actorTypes.Length;
|
||||
var squad = new List<Actor>();
|
||||
var func = actionFunc.CopyReference() as LuaFunction;
|
||||
|
||||
void ProductionHandler(Actor factory, Actor 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.TryGetValue(queue, out var cpq))
|
||||
return true;
|
||||
|
||||
return productionHandlers.ContainsKey(queue) || cpq.AllQueued().Any();
|
||||
}
|
||||
|
||||
BuildableInfo GetBuildableInfo(string actorType)
|
||||
{
|
||||
var ri = Player.World.Map.Rules.Actors[actorType];
|
||||
var bi = ri.TraitInfoOrDefault<BuildableInfo>();
|
||||
|
||||
if (bi == null)
|
||||
throw new LuaException($"Actor of type {actorType} cannot be produced");
|
||||
else
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.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 ??= 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 ??= Self.Owner;
|
||||
|
||||
if (rb.RepairActive && rb.Repairers.Contains(repairer))
|
||||
rb.RepairBuilding(Self, repairer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Resources")]
|
||||
public class ResourceProperties : ScriptPlayerProperties, Requires<PlayerResourcesInfo>
|
||||
{
|
||||
readonly PlayerResources pr;
|
||||
|
||||
public ResourceProperties(ScriptContext context, Player player)
|
||||
: base(context, player)
|
||||
{
|
||||
pr = player.PlayerActor.Trait<PlayerResources>();
|
||||
}
|
||||
|
||||
[Desc("The amount of harvestable resources held by the player.")]
|
||||
public int Resources
|
||||
{
|
||||
get => pr.Resources;
|
||||
set => pr.Resources = value.Clamp(0, pr.ResourceCapacity);
|
||||
}
|
||||
|
||||
[Desc("The maximum resource storage of the player.")]
|
||||
public int ResourceCapacity => pr.ResourceCapacity;
|
||||
|
||||
[Desc("The amount of cash held by the player.")]
|
||||
public int Cash
|
||||
{
|
||||
get => pr.Cash;
|
||||
set => pr.Cash = Math.Max(0, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Movement")]
|
||||
public class ScaredCatProperties : ScriptActorProperties, Requires<ScaredyCatInfo>
|
||||
{
|
||||
readonly ScaredyCat scaredyCat;
|
||||
|
||||
public ScaredCatProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
scaredyCat = self.Trait<ScaredyCat>();
|
||||
}
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Makes the unit automatically run around and become faster.")]
|
||||
public void Panic()
|
||||
{
|
||||
scaredyCat.Panic();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("General")]
|
||||
public class SellableProperties : ScriptActorProperties, Requires<SellableInfo>
|
||||
{
|
||||
public SellableProperties(ScriptContext context, Actor self)
|
||||
: base(context, self) { }
|
||||
|
||||
[Desc("Start selling the actor.")]
|
||||
public void Sell()
|
||||
{
|
||||
// PERF: No trait lookup cache in the constructor to avoid doing it for all buildings except just the ones getting sold.
|
||||
Self.Trait<Sellable>().Sell(Self);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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 OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("General")]
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* 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.Linq;
|
||||
using Eluant;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Scripting
|
||||
{
|
||||
[ScriptPropertyGroup("Transports")]
|
||||
public class TransportProperties : ScriptActorProperties, Requires<CargoInfo>
|
||||
{
|
||||
readonly Cargo cargo;
|
||||
|
||||
public TransportProperties(ScriptContext context, Actor self)
|
||||
: base(context, self)
|
||||
{
|
||||
cargo = self.Trait<Cargo>();
|
||||
}
|
||||
|
||||
[Desc("Returns references to passengers inside the transport.")]
|
||||
public Actor[] Passengers => cargo.Passengers.ToArray();
|
||||
|
||||
[Desc("Specifies whether transport has any passengers.")]
|
||||
public bool HasPassengers => cargo.Passengers.Any();
|
||||
|
||||
[Desc("Specifies the amount of passengers.")]
|
||||
public int PassengerCount => cargo.Passengers.Count();
|
||||
|
||||
[Desc("Teleport an existing actor inside this transport.")]
|
||||
public void LoadPassenger(Actor a)
|
||||
{
|
||||
if (!a.IsIdle)
|
||||
throw new LuaException("LoadPassenger requires the passenger to be idle.");
|
||||
|
||||
cargo.Load(Self, a);
|
||||
}
|
||||
|
||||
[Desc("Remove an existing actor (or first actor if none specified) from the transport. This actor is not added to the world.")]
|
||||
public Actor UnloadPassenger(Actor a = null) { return cargo.Unload(Self, a); }
|
||||
|
||||
[ScriptActorPropertyActivity]
|
||||
[Desc("Command transport to unload passengers.")]
|
||||
public void UnloadPassengers(CPos? cell = null, int unloadRange = 5)
|
||||
{
|
||||
if (cell.HasValue)
|
||||
{
|
||||
var destination = Target.FromCell(Self.World, cell.Value);
|
||||
Self.QueueActivity(new UnloadCargo(Self, destination, WDist.FromCells(unloadRange)));
|
||||
}
|
||||
else
|
||||
Self.QueueActivity(new UnloadCargo(Self, WDist.FromCells(unloadRange)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user