Merge pull request #6786 from pchote/retire-code
Retire legacy Lua API and IRC code.
This commit is contained in:
@@ -53,14 +53,6 @@
|
||||
<HintPath>..\thirdparty\FuzzyLogicLibrary.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="KopiLua">
|
||||
<HintPath>..\thirdparty\KopiLua.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLua">
|
||||
<HintPath>..\thirdparty\NLua.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
@@ -324,10 +316,7 @@
|
||||
<Compile Include="RepairsUnits.cs" />
|
||||
<Compile Include="Reservable.cs" />
|
||||
<Compile Include="ScaredyCat.cs" />
|
||||
<Compile Include="Scripting\LuaScriptEvents.cs" />
|
||||
<Compile Include="Scripting\LuaScriptInterface.cs" />
|
||||
<Compile Include="Scripting\Media.cs" />
|
||||
<Compile Include="Scripting\LuaScriptContext.cs" />
|
||||
<Compile Include="SeedsResource.cs" />
|
||||
<Compile Include="SelfHealing.cs" />
|
||||
<Compile Include="Sellable.cs" />
|
||||
@@ -368,7 +357,6 @@
|
||||
<Compile Include="Widgets\Logic\Ingame\GameInfoObjectivesLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\Ingame\GameInfoStatsLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\Ingame\LeaveMapLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\IrcLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\KickClientLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\ConnectionLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\DiplomacyLogic.cs" />
|
||||
@@ -542,11 +530,6 @@
|
||||
<Name>OpenRA.Game</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\OpenRA.Irc\OpenRA.Irc.csproj">
|
||||
<Project>{85B48234-8B31-4BE6-AF9C-665CC6866841}</Project>
|
||||
<Name>OpenRA.Irc</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\OpenRA.Mods.Common\OpenRA.Mods.Common.csproj">
|
||||
<Project>{fe6c8cc0-2f07-442a-b29f-17617b3b7fc6}</Project>
|
||||
<Name>OpenRA.Mods.Common</Name>
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 System.Reflection;
|
||||
using NLua;
|
||||
using NLua.Event;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[Desc("Part of the legacy Lua API.")]
|
||||
public sealed class LuaScriptContext : IDisposable
|
||||
{
|
||||
public Lua Lua { get; private set; }
|
||||
readonly Cache<string, LuaFunction> functionCache;
|
||||
|
||||
public LuaScriptContext()
|
||||
{
|
||||
Log.AddChannel("lua", "lua.log");
|
||||
Log.Write("lua", "Creating Lua script context");
|
||||
Lua = new Lua();
|
||||
Lua.HookException += OnLuaException;
|
||||
functionCache = new Cache<string, LuaFunction>(Lua.GetFunction);
|
||||
}
|
||||
|
||||
public void RegisterObject(object target, string tableName, bool exposeAllMethods)
|
||||
{
|
||||
Log.Write("lua", "Registering object {0}", target);
|
||||
|
||||
if (tableName != null && Lua.GetTable(tableName) == null)
|
||||
Lua.NewTable(tableName);
|
||||
|
||||
var type = target.GetType();
|
||||
|
||||
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
|
||||
RegisterMethods(tableName, target, methods, exposeAllMethods);
|
||||
}
|
||||
|
||||
public void RegisterType(Type type, string tableName, bool exposeAllMethods)
|
||||
{
|
||||
Log.Write("lua", "Registering type {0}", type);
|
||||
|
||||
if (tableName != null && Lua.GetTable(tableName) == null)
|
||||
Lua.NewTable(tableName);
|
||||
|
||||
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
|
||||
RegisterMethods(tableName, null, methods, exposeAllMethods);
|
||||
}
|
||||
|
||||
void RegisterMethods(string tableName, object target, IEnumerable<MethodInfo> methods, bool allMethods)
|
||||
{
|
||||
foreach (var method in methods)
|
||||
{
|
||||
string methodName;
|
||||
|
||||
var attr = method.GetCustomAttributes<LuaGlobalAttribute>(true).FirstOrDefault();
|
||||
if (attr == null)
|
||||
{
|
||||
if (allMethods)
|
||||
methodName = method.Name;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
methodName = attr.Name ?? method.Name;
|
||||
|
||||
var methodTarget = method.IsStatic ? null : target;
|
||||
|
||||
if (tableName != null)
|
||||
Lua.RegisterFunction(tableName + "." + methodName, methodTarget, method);
|
||||
else
|
||||
Lua.RegisterFunction(methodName, methodTarget, method);
|
||||
}
|
||||
}
|
||||
|
||||
void OnLuaException(object sender, HookExceptionEventArgs e)
|
||||
{
|
||||
ShowException(e.Exception);
|
||||
}
|
||||
|
||||
void ShowException(Exception e)
|
||||
{
|
||||
ShowErrorMessage(e.Message, e.ToString());
|
||||
}
|
||||
|
||||
public void ShowErrorMessage(string shortMessage, string longMessage)
|
||||
{
|
||||
Game.Debug("{0}", shortMessage);
|
||||
Game.Debug("See lua.log for details");
|
||||
Log.Write("lua", "{0}", longMessage ?? shortMessage);
|
||||
}
|
||||
|
||||
public void LoadLuaScripts(Func<string, string> getFileContents, params string[] files)
|
||||
{
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Write("lua", "Loading Lua script {0}", file);
|
||||
var content = getFileContents(file);
|
||||
Lua.DoString(content, file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ShowException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public object[] InvokeLuaFunction(string name, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var function = functionCache[name];
|
||||
if (function == null)
|
||||
return null;
|
||||
return function.Call(args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ShowException(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Lua != null)
|
||||
Lua.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.Scripting
|
||||
{
|
||||
[Desc("Part of the legacy Lua API.")]
|
||||
public class LuaScriptEventsInfo : TraitInfo<LuaScriptEvents> { }
|
||||
|
||||
public class LuaScriptEvents : INotifyKilled, INotifyAddedToWorld, INotifyRemovedFromWorld,
|
||||
INotifyCapture, INotifyDamage, INotifyIdle, INotifyProduction
|
||||
{
|
||||
public event Action<Actor, AttackInfo> OnKilled = (self, e) => { };
|
||||
public event Action<Actor> OnAddedToWorld = self => { };
|
||||
public event Action<Actor> OnRemovedFromWorld = self => { };
|
||||
public event Action<Actor, Actor, Player, Player> OnCaptured = (self, captor, oldOwner, newOwner) => { };
|
||||
public event Action<Actor, AttackInfo> OnDamaged = (self, e) => { };
|
||||
public event Action<Actor> OnIdle = self => { };
|
||||
public event Action<Actor, Actor, CPos> OnProduced = (self, other, exit) => { };
|
||||
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
OnKilled(self, e);
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
{
|
||||
OnAddedToWorld(self);
|
||||
}
|
||||
|
||||
public void RemovedFromWorld(Actor self)
|
||||
{
|
||||
OnRemovedFromWorld(self);
|
||||
}
|
||||
|
||||
public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner)
|
||||
{
|
||||
OnCaptured(self, captor, oldOwner, newOwner);
|
||||
}
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
OnDamaged(self, e);
|
||||
}
|
||||
|
||||
public void TickIdle(Actor self)
|
||||
{
|
||||
OnIdle(self);
|
||||
}
|
||||
|
||||
public void UnitProduced(Actor self, Actor other, CPos exit)
|
||||
{
|
||||
OnProduced(self, other, exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,470 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLua;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Scripting;
|
||||
using OpenRA.Support;
|
||||
using OpenRA.Traits;
|
||||
using WorldRenderer = OpenRA.Graphics.WorldRenderer;
|
||||
|
||||
namespace OpenRA.Mods.RA.Scripting
|
||||
{
|
||||
[Desc("Part of the legacy Lua API.")]
|
||||
public class LuaScriptInterfaceInfo : ITraitInfo, Requires<SpawnMapActorsInfo>
|
||||
{
|
||||
public readonly string[] LuaScripts = { };
|
||||
|
||||
public object Create(ActorInitializer init) { return new LuaScriptInterface(this); }
|
||||
}
|
||||
|
||||
public sealed class LuaScriptInterface : IWorldLoaded, ITick, IDisposable
|
||||
{
|
||||
World world;
|
||||
SpawnMapActors sma;
|
||||
readonly LuaScriptContext context = new LuaScriptContext();
|
||||
readonly LuaScriptInterfaceInfo info;
|
||||
|
||||
public LuaScriptInterface(LuaScriptInterfaceInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void WorldLoaded(World w, WorldRenderer wr)
|
||||
{
|
||||
world = w;
|
||||
sma = world.WorldActor.Trait<SpawnMapActors>();
|
||||
|
||||
context.Lua["World"] = w;
|
||||
context.Lua["WorldRenderer"] = wr;
|
||||
context.RegisterObject(this, "Internal", false);
|
||||
context.RegisterType(typeof(WVec), "WVec", true);
|
||||
context.RegisterType(typeof(CVec), "CVec", true);
|
||||
context.RegisterType(typeof(WPos), "WPos", true);
|
||||
context.RegisterType(typeof(CPos), "CPos", true);
|
||||
context.RegisterType(typeof(WRot), "WRot", true);
|
||||
context.RegisterType(typeof(WAngle), "WAngle", true);
|
||||
context.RegisterType(typeof(WRange), "WRange", true);
|
||||
context.RegisterType(typeof(int2), "int2", true);
|
||||
context.RegisterType(typeof(float2), "float2", true);
|
||||
|
||||
context.LoadLuaScripts(f => GlobalFileSystem.Open(f).ReadAllText(), Game.modData.Manifest.LuaScripts);
|
||||
|
||||
AddMapActorGlobals();
|
||||
|
||||
context.LoadLuaScripts(f => w.Map.Container.GetContent(f).ReadAllText(), info.LuaScripts);
|
||||
|
||||
context.InvokeLuaFunction("WorldLoaded");
|
||||
}
|
||||
|
||||
void AddMapActorGlobals()
|
||||
{
|
||||
foreach (var kv in sma.Actors)
|
||||
{
|
||||
if (context.Lua[kv.Key] != null)
|
||||
context.ShowErrorMessage("{0}: The global name '{1}' is reserved and may not be used by map actor {2}".F(GetType().Name, kv.Key, kv.Value), null);
|
||||
else
|
||||
context.Lua[kv.Key] = kv.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
using (new PerfSample("tick_lua"))
|
||||
context.InvokeLuaFunction("Tick");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
context.Dispose();
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public object New(string typeName, LuaTable args)
|
||||
{
|
||||
var type = Game.modData.ObjectCreator.FindType(typeName);
|
||||
if (type == null)
|
||||
throw new InvalidOperationException("Cannot locate type: {0}".F(typeName));
|
||||
if (args == null)
|
||||
return Activator.CreateInstance(type);
|
||||
var argsArray = ConvertArgs(args);
|
||||
return Activator.CreateInstance(type, argsArray);
|
||||
}
|
||||
|
||||
static object[] ConvertArgs(LuaTable args)
|
||||
{
|
||||
var argsArray = new object[args.Keys.Count];
|
||||
for (var i = 1; i <= args.Keys.Count; i++)
|
||||
{
|
||||
var arg = args[i] as LuaTable;
|
||||
if (arg != null && arg[1] != null && arg[2] != null)
|
||||
argsArray[i - 1] = Convert.ChangeType(arg[1], Enum<TypeCode>.Parse(arg[2].ToString()));
|
||||
else
|
||||
argsArray[i - 1] = args[i];
|
||||
}
|
||||
return argsArray;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void Debug(object obj)
|
||||
{
|
||||
if (obj != null)
|
||||
Game.Debug(obj.ToString());
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public object TraitOrDefault(Actor actor, string className)
|
||||
{
|
||||
var type = Game.modData.ObjectCreator.FindType(className);
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
var method = typeof(Actor).GetMethod("TraitOrDefault");
|
||||
var genericMethod = method.MakeGenericMethod(type);
|
||||
return genericMethod.Invoke(actor, null);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public object Trait(Actor actor, string className)
|
||||
{
|
||||
var ret = TraitOrDefault(actor, className);
|
||||
if (ret == null)
|
||||
throw new InvalidOperationException("Actor {0} does not have trait of type {1}".F(actor, className));
|
||||
return ret;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool HasTrait(Actor actor, string className)
|
||||
{
|
||||
var ret = TraitOrDefault(actor, className);
|
||||
return ret != null;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public object[] ActorsWithTrait(string className)
|
||||
{
|
||||
var type = Game.modData.ObjectCreator.FindType(className);
|
||||
if (type == null)
|
||||
throw new InvalidOperationException("Cannot locate type: {0}".F(className));
|
||||
|
||||
var method = typeof(World).GetMethod("ActorsWithTrait");
|
||||
var genericMethod = method.MakeGenericMethod(type);
|
||||
var result = ((IEnumerable)genericMethod.Invoke(world, null)).Cast<object>().ToArray();
|
||||
return result;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public object TraitInfoOrDefault(string actorType, string className)
|
||||
{
|
||||
var type = Game.modData.ObjectCreator.FindType(className);
|
||||
if (type == null || !world.Map.Rules.Actors.ContainsKey(actorType))
|
||||
return null;
|
||||
|
||||
return world.Map.Rules.Actors[actorType].Traits.GetOrDefault(type);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public object TraitInfo(string actorType, string className)
|
||||
{
|
||||
var ret = TraitInfoOrDefault(actorType, className);
|
||||
if (ret == null)
|
||||
throw new InvalidOperationException("Actor type {0} does not have trait info of type {1}".F(actorType, className));
|
||||
return ret;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool HasTraitInfo(string actorType, string className)
|
||||
{
|
||||
var ret = TraitInfoOrDefault(actorType, className);
|
||||
return ret != null;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void RunAfterDelay(double delay, Action func)
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Add(new DelayedAction((int)delay, func)));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void PlaySpeechNotification(Player player, string notification)
|
||||
{
|
||||
Sound.PlayNotification(world.Map.Rules, player, "Speech", notification, player != null ? player.Country.Race : null);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void PlaySoundNotification(Player player, string notification)
|
||||
{
|
||||
Sound.PlayNotification(world.Map.Rules, player, "Sounds", notification, player != null ? player.Country.Race : null);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void WaitFor(Actor actor, Func<bool> func)
|
||||
{
|
||||
actor.QueueActivity(new WaitFor(func));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void CallFunc(Actor actor, Action func)
|
||||
{
|
||||
actor.QueueActivity(new CallFunc(func));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public int GetFacing(object vec, double currentFacing)
|
||||
{
|
||||
if (vec is CVec)
|
||||
return world.Map.FacingBetween(CPos.Zero, CPos.Zero + (CVec)vec, (int)currentFacing);
|
||||
if (vec is WVec)
|
||||
return Util.GetFacing((WVec)vec, (int)currentFacing);
|
||||
throw new ArgumentException("Unsupported vector type: {0}".F(vec.GetType()));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public WRange GetWRangeFromCells(double cells)
|
||||
{
|
||||
return WRange.FromCells((int)cells);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void SetWinState(Player player, string winState)
|
||||
{
|
||||
player.WinState = Enum<WinState>.Parse(winState);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void PlayRandomMusic()
|
||||
{
|
||||
if (!Game.Settings.Sound.MapMusic || !world.Map.Rules.InstalledMusic.Any())
|
||||
return;
|
||||
Game.ConnectionStateChanged += StopMusic;
|
||||
PlayMusic();
|
||||
}
|
||||
|
||||
void PlayMusic()
|
||||
{
|
||||
var track = world.Map.Rules.InstalledMusic.Random(Game.CosmeticRandom);
|
||||
Sound.PlayMusicThen(track.Value, PlayMusic);
|
||||
}
|
||||
|
||||
void StopMusic(OrderManager orderManager)
|
||||
{
|
||||
if (!orderManager.GameStarted)
|
||||
{
|
||||
Sound.StopMusic();
|
||||
Game.ConnectionStateChanged -= StopMusic;
|
||||
}
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool IsDead(Actor actor)
|
||||
{
|
||||
return actor.IsDead();
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void PlayMovieFullscreen(string movie, Action onComplete)
|
||||
{
|
||||
Media.PlayFMVFullscreen(world, movie, onComplete);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void FlyToPos(Actor actor, WPos pos)
|
||||
{
|
||||
actor.QueueActivity(new Fly(actor, Target.FromPos(pos)));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void FlyAttackActor(Actor actor, Actor targetActor)
|
||||
{
|
||||
actor.QueueActivity(new FlyAttack(Target.FromActor(targetActor)));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void FlyAttackCell(Actor actor, CPos location)
|
||||
{
|
||||
actor.QueueActivity(new FlyAttack(Target.FromCell(actor.World, location)));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void HeliFlyToPos(Actor actor, WPos pos)
|
||||
{
|
||||
actor.QueueActivity(new HeliFly(actor, Target.FromPos(pos)));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void SetUnitStance(Actor actor, string stance)
|
||||
{
|
||||
var at = actor.TraitOrDefault<AutoTarget>();
|
||||
if (at != null)
|
||||
at.Stance = Enum<UnitStance>.Parse(stance);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool RequiredUnitsAreDestroyed(Player player)
|
||||
{
|
||||
return player.HasNoRequiredUnits();
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void AttackMove(Actor actor, CPos location, double nearEnough)
|
||||
{
|
||||
if (actor.HasTrait<AttackMove>())
|
||||
actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, new Move.Move(actor, location, (int)nearEnough)));
|
||||
else
|
||||
actor.QueueActivity(new Move.Move(actor, location, (int)nearEnough));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public int GetRandomInteger(double low, double high)
|
||||
{
|
||||
return world.SharedRandom.Next((int)low, (int)high);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public CPos GetRandomCell()
|
||||
{
|
||||
return world.Map.ChooseRandomCell(world.SharedRandom);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public CPos GetRandomEdgeCell()
|
||||
{
|
||||
return world.Map.ChooseRandomEdgeCell(world.SharedRandom);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public Actor GetNamedActor(string actorName)
|
||||
{
|
||||
return sma.Actors[actorName];
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool IsNamedActor(Actor actor)
|
||||
{
|
||||
return actor.ActorID <= sma.LastMapActorID && actor.ActorID > sma.LastMapActorID - sma.Actors.Count;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public IEnumerable<Actor> GetNamedActors()
|
||||
{
|
||||
return sma.Actors.Values;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public Actor[] FindActorsInBox(WPos topLeft, WPos bottomRight)
|
||||
{
|
||||
return world.ActorMap.ActorsInBox(topLeft, bottomRight).ToArray();
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public Actor[] FindActorsInCircle(WPos location, WRange radius)
|
||||
{
|
||||
return world.FindActorsInCircle(location, radius).ToArray();
|
||||
}
|
||||
|
||||
ClassicProductionQueue GetSharedQueueForCategory(Player player, string category)
|
||||
{
|
||||
return world.ActorsWithTrait<ClassicProductionQueue>()
|
||||
.Where(a => a.Actor.Owner == player && a.Trait.Info.Type == category)
|
||||
.Select(a => a.Trait).FirstOrDefault();
|
||||
}
|
||||
|
||||
ClassicProductionQueue GetSharedQueueForUnit(Player player, string unit)
|
||||
{
|
||||
var ri = world.Map.Rules.Actors[unit];
|
||||
|
||||
var bi = ri.Traits.GetOrDefault<BuildableInfo>();
|
||||
if (bi == null)
|
||||
return null;
|
||||
|
||||
return bi.Queue.Select(q => GetSharedQueueForCategory(player, q)).FirstOrDefault();
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void BuildWithSharedQueue(Player player, string unit, double amount)
|
||||
{
|
||||
var queue = GetSharedQueueForUnit(player, unit);
|
||||
|
||||
if (queue != null)
|
||||
queue.ResolveOrder(queue.Actor, Order.StartProduction(queue.Actor, unit, (int)amount));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void BuildWithPerFactoryQueue(Actor factory, string unit, double amount)
|
||||
{
|
||||
var ri = world.Map.Rules.Actors[unit];
|
||||
|
||||
var bi = ri.Traits.GetOrDefault<BuildableInfo>();
|
||||
if (bi == null)
|
||||
return;
|
||||
|
||||
var queue = factory.TraitsImplementing<ProductionQueue>()
|
||||
.FirstOrDefault(q => q.Enabled);
|
||||
|
||||
if (queue != null)
|
||||
queue.ResolveOrder(factory, Order.StartProduction(factory, unit, (int)amount));
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool SharedQueueIsBusy(Player player, string category)
|
||||
{
|
||||
var queue = GetSharedQueueForCategory(player, category);
|
||||
|
||||
if (queue == null)
|
||||
return true;
|
||||
|
||||
return queue.CurrentItem() != null;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public bool PerFactoryQueueIsBusy(Actor factory)
|
||||
{
|
||||
var queue = factory.TraitsImplementing<ProductionQueue>()
|
||||
.FirstOrDefault(q => q.Enabled);
|
||||
|
||||
if (queue == null)
|
||||
return true;
|
||||
|
||||
return queue.CurrentItem() != null;
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public void Guard(Actor guard, Actor target)
|
||||
{
|
||||
if (target.HasTrait<Guardable>())
|
||||
{
|
||||
var gt = guard.TraitOrDefault<Guard>();
|
||||
|
||||
if (gt != null)
|
||||
gt.GuardTarget(guard, Target.FromActor(target));
|
||||
}
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public IEnumerable<CPos> ExpandFootprint(LuaTable cells, bool allowDiagonal)
|
||||
{
|
||||
return Util.ExpandFootprint(cells.Values.Cast<CPos>(), allowDiagonal);
|
||||
}
|
||||
|
||||
[LuaGlobal]
|
||||
public WPos CenterOfCell(CPos position)
|
||||
{
|
||||
return world.Map.CenterOfCell(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 OpenRA.Irc;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
{
|
||||
class IrcLogic
|
||||
{
|
||||
TextFieldWidget inputBox;
|
||||
TextFieldWidget nicknameBox;
|
||||
Widget connectBG;
|
||||
Widget ircContainer;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public IrcLogic(Widget widget)
|
||||
{
|
||||
var historyPanel = widget.Get<ScrollPanelWidget>("HISTORY_PANEL");
|
||||
var historyTemplate = widget.Get<LabelWidget>("HISTORY_TEMPLATE");
|
||||
var nicknamePanel = widget.Get<ScrollPanelWidget>("NICKNAME_PANEL");
|
||||
var nicknameTemplate = widget.Get<LabelWidget>("NICKNAME_TEMPLATE");
|
||||
|
||||
inputBox = widget.Get<TextFieldWidget>("INPUT_BOX");
|
||||
inputBox.OnEnterKey = EnterPressed;
|
||||
inputBox.OnTabKey = TabPressed;
|
||||
inputBox.IsDisabled = () => IrcClient.Instance.GetChannel(IrcClient.MainChannel) == null;
|
||||
|
||||
nicknameBox = widget.Get<TextFieldWidget>("NICKNAME_BOX");
|
||||
nicknameBox.Text = ChooseNickname(Game.Settings.Irc.Nickname);
|
||||
|
||||
connectBG = widget.Get("IRC_CONNECT_BG");
|
||||
ircContainer = widget.Get("IRC_CONTAINER");
|
||||
|
||||
widget.Get<ButtonWidget>("DISCONNECT_BUTTON").OnClick = IrcClient.Instance.Disconnect;
|
||||
|
||||
MaybeShowConnectPanel();
|
||||
|
||||
historyPanel.Bind(IrcClient.Instance.History, item => MakeLabelWidget(historyTemplate, item), LabelItemEquals, true);
|
||||
|
||||
var mainChannel = IrcClient.Instance.GetChannel(IrcClient.MainChannel);
|
||||
if (mainChannel != null)
|
||||
nicknamePanel.Bind(mainChannel.Users, item => MakeLabelWidget(nicknameTemplate, item), LabelItemEquals, false);
|
||||
|
||||
IrcClient.Instance.OnSync += l =>
|
||||
{
|
||||
var channel = l.GetChannel();
|
||||
if (channel.Name.EqualsIC(IrcClient.MainChannel))
|
||||
nicknamePanel.Bind(channel.Users, item => MakeLabelWidget(nicknameTemplate, item), LabelItemEquals, false);
|
||||
};
|
||||
IrcClient.Instance.OnKick += l =>
|
||||
{
|
||||
if (l.KickeeNickname.EqualsIC(IrcClient.Instance.LocalUser.Nickname) && l.Target.EqualsIC(IrcClient.MainChannel))
|
||||
nicknamePanel.Unbind();
|
||||
};
|
||||
IrcClient.Instance.OnPart += l =>
|
||||
{
|
||||
if (l.PrefixIsSelf() && l.Target.EqualsIC(IrcClient.MainChannel))
|
||||
nicknamePanel.Unbind();
|
||||
};
|
||||
IrcClient.Instance.OnDisconnect += () =>
|
||||
{
|
||||
nicknamePanel.Unbind();
|
||||
MaybeShowConnectPanel();
|
||||
};
|
||||
|
||||
commands.Add("me", args =>
|
||||
{
|
||||
IrcClient.Instance.Act(IrcClient.MainChannel, args);
|
||||
IrcClient.AddAction(IrcClient.Instance.LocalUser.Nickname, args);
|
||||
});
|
||||
commands.Add("slap", args =>
|
||||
{
|
||||
IrcClient.Instance.Act(IrcClient.MainChannel, "slaps {0} around a bit with a large trout".F(args));
|
||||
IrcClient.AddAction(IrcClient.Instance.LocalUser.Nickname, "slaps {0} around a bit with a large trout".F(args));
|
||||
});
|
||||
commands.Add("notice", args =>
|
||||
{
|
||||
var split = args.Split(new[] { ' ' }, 2);
|
||||
if (split.Length < 2)
|
||||
{
|
||||
IrcClient.AddHistory("/notice: Not enough arguments");
|
||||
return;
|
||||
}
|
||||
IrcClient.Instance.Notice(split[0], split[1]);
|
||||
IrcClient.AddSelfNotice(split[0], split[1]);
|
||||
});
|
||||
commands.Add("disconnect", args =>
|
||||
{
|
||||
Game.Settings.Irc.ConnectAutomatically = false;
|
||||
Game.Settings.Save();
|
||||
IrcClient.Instance.Disconnect();
|
||||
});
|
||||
commands.Add("quit", args =>
|
||||
{
|
||||
Game.Settings.Irc.ConnectAutomatically = false;
|
||||
Game.Settings.Save();
|
||||
if (IrcClient.Instance.IsConnected)
|
||||
IrcClient.Instance.Quit(args);
|
||||
else
|
||||
IrcClient.Instance.Disconnect();
|
||||
});
|
||||
commands.Add("nick", args => IrcClient.Instance.SetNickname(args));
|
||||
commands.Add("topic", args => IrcClient.Instance.GetTopic(IrcClient.MainChannel));
|
||||
}
|
||||
|
||||
void MaybeShowConnectPanel()
|
||||
{
|
||||
if (IrcClient.Instance.IsConnected || IrcClient.Instance.IsReconnecting)
|
||||
{
|
||||
ircContainer.Visible = true;
|
||||
connectBG.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game.Settings.Irc.ConnectAutomatically)
|
||||
{
|
||||
ircContainer.Visible = true;
|
||||
connectBG.Visible = false;
|
||||
Connect();
|
||||
return;
|
||||
}
|
||||
|
||||
ircContainer.Visible = false;
|
||||
connectBG.Visible = true;
|
||||
|
||||
var connectAutomaticallyCheckBox = connectBG.Get<CheckboxWidget>("CONNECT_AUTOMATICALLY_CHECKBOX");
|
||||
var connectAutomaticallyChecked = false;
|
||||
connectAutomaticallyCheckBox.IsChecked = () => connectAutomaticallyChecked;
|
||||
connectAutomaticallyCheckBox.OnClick = () => connectAutomaticallyChecked ^= true;
|
||||
|
||||
var connectButton = connectBG.Get<ButtonWidget>("CONNECT_BUTTON");
|
||||
|
||||
connectButton.OnClick = () =>
|
||||
{
|
||||
ircContainer.Visible = true;
|
||||
connectBG.Visible = false;
|
||||
|
||||
Game.Settings.Irc.ConnectAutomatically = connectAutomaticallyCheckBox.IsChecked();
|
||||
Game.Settings.Save();
|
||||
Connect();
|
||||
};
|
||||
}
|
||||
|
||||
static string ChooseNickname(string nickname)
|
||||
{
|
||||
if (!IrcUtils.IsNickname(nickname))
|
||||
{
|
||||
nickname = Game.Settings.Player.Name;
|
||||
if (!IrcUtils.IsNickname(nickname))
|
||||
nickname = Game.Settings.Irc.DefaultNickname;
|
||||
}
|
||||
return nickname;
|
||||
}
|
||||
|
||||
void Connect()
|
||||
{
|
||||
var nickname = ChooseNickname(nicknameBox.Text);
|
||||
var s = Game.Settings.Irc;
|
||||
s.Nickname = nickname;
|
||||
Game.Settings.Save();
|
||||
IrcClient.Instance.Connect(s.Hostname, s.Port, s.ConnectionTimeout, nickname, s.Username ?? nickname, s.Realname ?? nickname);
|
||||
}
|
||||
|
||||
static Widget MakeLabelWidget(LabelWidget template, object item)
|
||||
{
|
||||
var itemString = item.ToString();
|
||||
var widget = (LabelWidget)template.Clone();
|
||||
var font = Game.Renderer.Fonts[widget.Font];
|
||||
itemString = WidgetUtils.WrapText(itemString, widget.Bounds.Width, font);
|
||||
widget.Bounds.Height = font.Measure(itemString).Y;
|
||||
widget.GetText = () => itemString;
|
||||
return widget;
|
||||
}
|
||||
|
||||
bool LabelItemEquals(Widget widget, object item)
|
||||
{
|
||||
return item != null && ((LabelWidget)widget).GetText() == item.ToString();
|
||||
}
|
||||
|
||||
bool EnterPressed()
|
||||
{
|
||||
if (!inputBox.Text.Any())
|
||||
return true;
|
||||
|
||||
var text = inputBox.Text;
|
||||
inputBox.Text = "";
|
||||
|
||||
if (text[0] == '/')
|
||||
{
|
||||
var parts = text.Split(new[] { ' ' }, 2);
|
||||
var name = parts[0].Substring(1);
|
||||
var args = parts.Length > 1 ? parts[1] : null;
|
||||
|
||||
Action<string> command;
|
||||
if (!commands.TryGetValue(name, out command))
|
||||
{
|
||||
IrcClient.AddHistory("{0}: Unknown command".F(name));
|
||||
return true;
|
||||
}
|
||||
command(args);
|
||||
}
|
||||
else
|
||||
{
|
||||
IrcClient.Instance.Message(IrcClient.MainChannel, text);
|
||||
IrcClient.AddMessage(IrcClient.Instance.LocalUser.Nickname, text);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Dictionary<string, Action<string>> commands = new Dictionary<string, Action<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
List<string> tabMatches = new List<string>();
|
||||
int tabMatchesIndex = -1;
|
||||
|
||||
bool TabPressed()
|
||||
{
|
||||
if (!inputBox.Text.Any())
|
||||
return true;
|
||||
|
||||
var channel = IrcClient.Instance.GetChannel(IrcClient.MainChannel);
|
||||
|
||||
if (channel == null)
|
||||
return true;
|
||||
|
||||
var spaceIndex = inputBox.Text.TrimEnd().LastIndexOf(' ');
|
||||
var tabMatchtext = inputBox.Text.Substring(spaceIndex + 1);
|
||||
|
||||
if (tabMatchesIndex < 0 || !tabMatches.Any() || tabMatchtext != tabMatches[tabMatchesIndex])
|
||||
tabMatches = channel.Users.Keys.Where(u => u.StartsWith(tabMatchtext, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
|
||||
if (!tabMatches.Any())
|
||||
return true;
|
||||
|
||||
tabMatchesIndex = (tabMatchesIndex + 1) % tabMatches.Count;
|
||||
inputBox.Text = inputBox.Text.Remove(spaceIndex + 1) + tabMatches[tabMatchesIndex];
|
||||
inputBox.CursorPosition = inputBox.Text.Length;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
showIncompatibleCheckbox.OnClick = () => { showIncompatible ^= true; RefreshServerList(); };
|
||||
}
|
||||
|
||||
// Game.LoadWidget(null, "SERVERBROWSER_IRC", panel.Get("IRC_ROOT"), new WidgetArgs());
|
||||
RefreshServerList();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user