Compare commits
64 Commits
playtest-2
...
release-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
029be6120f | ||
|
|
1f9fd2cb3f | ||
|
|
7bfb0feed7 | ||
|
|
61aa1bb366 | ||
|
|
5c9445a115 | ||
|
|
9b5c71a033 | ||
|
|
006aecfde9 | ||
|
|
56da6282eb | ||
|
|
f47d19fa4f | ||
|
|
9b224da1bc | ||
|
|
30803f704e | ||
|
|
9c120ff9c3 | ||
|
|
581e302e7d | ||
|
|
747bc1d24d | ||
|
|
4aaded0ca3 | ||
|
|
4c3014e7a4 | ||
|
|
487c4e83cf | ||
|
|
8039ed7310 | ||
|
|
854cbe7ca9 | ||
|
|
86373246c9 | ||
|
|
4d5a6faaa7 | ||
|
|
39fdf86130 | ||
|
|
20831d332c | ||
|
|
5aab8d5485 | ||
|
|
fd59408928 | ||
|
|
1f1300639d | ||
|
|
ee5d6d8c65 | ||
|
|
00d6b5764c | ||
|
|
d177b68067 | ||
|
|
a23fae327b | ||
|
|
35b08bc6b7 | ||
|
|
ad997263a5 | ||
|
|
4196543678 | ||
|
|
78613eab38 | ||
|
|
ccf369c9c1 | ||
|
|
76a44f6463 | ||
|
|
25e27e7f1e | ||
|
|
d6b3d2cc2d | ||
|
|
40f2dc9140 | ||
|
|
f7c9e5ecaa | ||
|
|
2b3c9421ff | ||
|
|
2ff6e937c9 | ||
|
|
4c7eae56ff | ||
|
|
d39dd9980d | ||
|
|
29a826172d | ||
|
|
e2a60b1f46 | ||
|
|
192bab75ff | ||
|
|
3f39a056c6 | ||
|
|
bac5e80eac | ||
|
|
57db412ad9 | ||
|
|
012a71a7a2 | ||
|
|
3773b1e893 | ||
|
|
fd26f08a1b | ||
|
|
f6edbb7cfe | ||
|
|
e3f667be4b | ||
|
|
0dcf0bab32 | ||
|
|
34ef718543 | ||
|
|
2b778e2226 | ||
|
|
20e977e4c2 | ||
|
|
53a88c6870 | ||
|
|
bbf95f1f13 | ||
|
|
d2a494b7bb | ||
|
|
89630cf91e | ||
|
|
c271ce4e1d |
1
AUTHORS
1
AUTHORS
@@ -108,6 +108,7 @@ Also thanks to:
|
||||
* Pizzaoverhead
|
||||
* Piët Delport (pjdelport)
|
||||
* Psydev
|
||||
* Raphael Vogt (TheRaffy, Yellow)
|
||||
* Raymond Bedrossian (Squiggles211)
|
||||
* Raymond Martineau (mart0258)
|
||||
* Riderr3
|
||||
|
||||
@@ -200,5 +200,55 @@ namespace OpenRA
|
||||
|
||||
return ruleset;
|
||||
}
|
||||
|
||||
static bool AnyCustomYaml(MiniYaml yaml)
|
||||
{
|
||||
return yaml != null && (yaml.Value != null || yaml.Nodes.Any());
|
||||
}
|
||||
|
||||
static bool AnyFlaggedTraits(ModData modData, List<MiniYamlNode> actors)
|
||||
{
|
||||
foreach (var actorNode in actors)
|
||||
{
|
||||
foreach (var traitNode in actorNode.Value.Nodes)
|
||||
{
|
||||
try
|
||||
{
|
||||
var traitName = traitNode.Key.Split('@')[0];
|
||||
var traitType = modData.ObjectCreator.FindType(traitName + "Info");
|
||||
if (traitType.GetInterface("ILobbyCustomRulesIgnore") == null)
|
||||
return true;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool DefinesUnsafeCustomRules(ModData modData, IReadOnlyFileSystem fileSystem,
|
||||
MiniYaml mapRules, MiniYaml mapWeapons, MiniYaml mapVoices, MiniYaml mapNotifications, MiniYaml mapSequences)
|
||||
{
|
||||
// Maps that define any weapon, voice, notification, or sequence overrides are always flagged
|
||||
if (AnyCustomYaml(mapWeapons) || AnyCustomYaml(mapVoices) || AnyCustomYaml(mapNotifications) || AnyCustomYaml(mapSequences))
|
||||
return true;
|
||||
|
||||
// Any trait overrides that aren't explicitly whitelisted are flagged
|
||||
if (mapRules != null)
|
||||
{
|
||||
if (AnyFlaggedTraits(modData, mapRules.Nodes))
|
||||
return true;
|
||||
|
||||
if (mapRules.Value != null)
|
||||
{
|
||||
var mapFiles = FieldLoader.GetValue<string[]>("value", mapRules.Value);
|
||||
foreach (var f in mapFiles)
|
||||
if (AnyFlaggedTraits(modData, MiniYaml.FromStream(fileSystem.Open(f))))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace OpenRA.Chat
|
||||
|
||||
void OnJoin(object sender, JoinEventArgs e)
|
||||
{
|
||||
if (e.Who == client.Nickname || e.Channel != channel.Name)
|
||||
if (e.Who == client.Nickname || channel == null || e.Channel != channel.Name)
|
||||
return;
|
||||
|
||||
AddNotification("{0} joined the chat.".F(e.Who));
|
||||
@@ -284,7 +284,7 @@ namespace OpenRA.Chat
|
||||
|
||||
void OnPart(object sender, PartEventArgs e)
|
||||
{
|
||||
if (e.Data.Channel != channel.Name)
|
||||
if (channel == null || e.Data.Channel != channel.Name)
|
||||
return;
|
||||
|
||||
AddNotification("{0} left the chat.".F(e.Who));
|
||||
|
||||
@@ -21,6 +21,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -80,12 +81,14 @@ namespace OpenRA
|
||||
Lazy<Ruleset> rules;
|
||||
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
|
||||
public bool InvalidCustomRules { get; private set; }
|
||||
public bool DefinesUnsafeCustomRules { get; private set; }
|
||||
public bool RulesLoaded { get; private set; }
|
||||
|
||||
public void SetRulesetGenerator(ModData modData, Func<Ruleset> generator)
|
||||
public void SetRulesetGenerator(ModData modData, Func<Pair<Ruleset, bool>> generator)
|
||||
{
|
||||
InvalidCustomRules = false;
|
||||
RulesLoaded = false;
|
||||
DefinesUnsafeCustomRules = false;
|
||||
|
||||
// Note: multiple threads may try to access the value at the same time
|
||||
// We rely on the thread-safety guarantees given by Lazy<T> to prevent race conitions.
|
||||
@@ -97,7 +100,9 @@ namespace OpenRA
|
||||
|
||||
try
|
||||
{
|
||||
return generator();
|
||||
var ret = generator();
|
||||
DefinesUnsafeCustomRules = ret.Second;
|
||||
return ret.First;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -146,6 +151,15 @@ namespace OpenRA
|
||||
public Ruleset Rules { get { return innerData.Rules; } }
|
||||
public bool InvalidCustomRules { get { return innerData.InvalidCustomRules; } }
|
||||
public bool RulesLoaded { get { return innerData.RulesLoaded; } }
|
||||
public bool DefinesUnsafeCustomRules
|
||||
{
|
||||
get
|
||||
{
|
||||
// Force lazy rules to be evaluated
|
||||
var force = innerData.Rules;
|
||||
return innerData.DefinesUnsafeCustomRules;
|
||||
}
|
||||
}
|
||||
|
||||
Download download;
|
||||
public long DownloadBytes { get; private set; }
|
||||
@@ -297,8 +311,11 @@ namespace OpenRA
|
||||
var musicDefinitions = LoadRuleSection(yaml, "Music");
|
||||
var notificationDefinitions = LoadRuleSection(yaml, "Notifications");
|
||||
var sequenceDefinitions = LoadRuleSection(yaml, "Sequences");
|
||||
return Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
|
||||
var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
|
||||
voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
|
||||
var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
|
||||
weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
|
||||
return Pair.New(rules, flagged);
|
||||
});
|
||||
|
||||
if (p.Contains("map.png"))
|
||||
@@ -338,6 +355,11 @@ namespace OpenRA
|
||||
return true;
|
||||
}
|
||||
|
||||
public void PreloadRules()
|
||||
{
|
||||
var unused = Rules;
|
||||
}
|
||||
|
||||
public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action<MapPreview> parseMetadata = null)
|
||||
{
|
||||
var newData = innerData.Clone();
|
||||
@@ -384,8 +406,11 @@ namespace OpenRA
|
||||
var musicDefinitions = LoadRuleSection(rulesYaml, "Music");
|
||||
var notificationDefinitions = LoadRuleSection(rulesYaml, "Notifications");
|
||||
var sequenceDefinitions = LoadRuleSection(rulesYaml, "Sequences");
|
||||
return Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
|
||||
var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
|
||||
voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
|
||||
var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
|
||||
weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
|
||||
return Pair.New(rules, flagged);
|
||||
});
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
@@ -77,18 +77,17 @@ namespace OpenRA.Network
|
||||
if (world == null)
|
||||
{
|
||||
if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
|
||||
Game.AddChatLine(client.Color.RGB, client.Name + " (Team)", order.TargetString);
|
||||
Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = world.FindPlayerByClient(client);
|
||||
if (player != null && ((world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally) || player.WinState == WinState.Lost))
|
||||
{
|
||||
var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
|
||||
Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
|
||||
}
|
||||
if (player != null && player.WinState == WinState.Lost)
|
||||
Game.AddChatLine(client.Color.RGB, client.Name + " (Dead)", order.TargetString);
|
||||
else if (player != null && world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally)
|
||||
Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
|
||||
else if (orderManager.LocalClient != null && orderManager.LocalClient.IsObserver && client.IsObserver)
|
||||
Game.AddChatLine(client.Color.RGB, client.Name + " (Spectators)", order.TargetString);
|
||||
Game.AddChatLine(client.Color.RGB, "[Spectators] " + client.Name, order.TargetString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,5 +58,11 @@ namespace OpenRA.Orders
|
||||
{
|
||||
return world.Map.Contains(cell) ? Cursor : "generic-blocked";
|
||||
}
|
||||
|
||||
public override bool InputOverridesSelection(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
// Custom order generators always override selection
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace OpenRA.Orders
|
||||
}
|
||||
|
||||
// Used for classic mouse orders, determines whether or not action at xy is move or select
|
||||
public static bool InputOverridesSelection(World world, int2 xy, MouseInput mi)
|
||||
public virtual bool InputOverridesSelection(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
var actor = world.ScreenMap.ActorsAt(xy).WithHighestSelectionPriority(xy);
|
||||
if (actor == null)
|
||||
@@ -95,10 +95,21 @@ namespace OpenRA.Orders
|
||||
var underCursor = world.Selection.Actors.WithHighestSelectionPriority(xy);
|
||||
|
||||
var o = OrderForUnit(underCursor, target, actorsAt, cell, mi);
|
||||
if (o != null && o.Order.OverrideSelection)
|
||||
return false;
|
||||
if (o != null)
|
||||
{
|
||||
var modifiers = TargetModifiers.None;
|
||||
if (mi.Modifiers.HasModifier(Modifiers.Ctrl))
|
||||
modifiers |= TargetModifiers.ForceAttack;
|
||||
if (mi.Modifiers.HasModifier(Modifiers.Shift))
|
||||
modifiers |= TargetModifiers.ForceQueue;
|
||||
if (mi.Modifiers.HasModifier(Modifiers.Alt))
|
||||
modifiers |= TargetModifiers.ForceMove;
|
||||
|
||||
return true;
|
||||
if (o.Order.TargetOverridesSelection(modifiers))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace OpenRA.Scripting
|
||||
.ToArray();
|
||||
|
||||
runtime.Globals["GameDir"] = Platform.GameDir;
|
||||
runtime.DoBuffer(File.Open(Platform.ResolvePath(".", "lua", "scriptwrapper.lua"), FileMode.Open).ReadAllText(), "scriptwrapper.lua").Dispose();
|
||||
runtime.DoBuffer(File.Open(Platform.ResolvePath(".", "lua", "scriptwrapper.lua"), FileMode.Open, FileAccess.Read).ReadAllText(), "scriptwrapper.lua").Dispose();
|
||||
tick = (LuaFunction)runtime.Globals["Tick"];
|
||||
|
||||
// Register globals
|
||||
|
||||
@@ -392,7 +392,7 @@ namespace OpenRA.Server
|
||||
SendOrderTo(newConn, "Message", motd);
|
||||
}
|
||||
|
||||
if (Map.Rules != ModData.DefaultRules && !LobbyInfo.IsSinglePlayer)
|
||||
if (!LobbyInfo.IsSinglePlayer && Map.DefinesUnsafeCustomRules)
|
||||
SendOrderTo(newConn, "Message", "This map contains custom rules. Game experience may change.");
|
||||
|
||||
if (Settings.DisableSinglePlayer)
|
||||
|
||||
@@ -101,6 +101,7 @@ namespace OpenRA
|
||||
public int Samples = 25;
|
||||
public bool IgnoreVersionMismatch = false;
|
||||
public bool SendSystemInformation = true;
|
||||
public int SystemInformationVersionPrompt = 0;
|
||||
public string UUID = System.Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,12 @@ namespace OpenRA.Traits
|
||||
[Desc("Force the DefaultCash option by disabling changes in the lobby.")]
|
||||
public readonly bool DefaultCashLocked = false;
|
||||
|
||||
[Desc("Speech notification to play when the player does not have any funds.")]
|
||||
public readonly string InsufficientFundsNotification = null;
|
||||
|
||||
[Desc("Delay (in ticks) during which warnings will be muted.")]
|
||||
public readonly int InsufficientFundsNotificationDelay = 750;
|
||||
|
||||
public object Create(ActorInitializer init) { return new PlayerResources(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -32,10 +38,12 @@ namespace OpenRA.Traits
|
||||
{
|
||||
const float DisplayCashFracPerFrame = .07f;
|
||||
const int DisplayCashDeltaPerFrame = 37;
|
||||
readonly PlayerResourcesInfo info;
|
||||
readonly Player owner;
|
||||
|
||||
public PlayerResources(Actor self, PlayerResourcesInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
owner = self.Owner;
|
||||
|
||||
Cash = self.World.LobbyInfo.GlobalSettings.StartingCash;
|
||||
@@ -52,6 +60,8 @@ namespace OpenRA.Traits
|
||||
public int Earned;
|
||||
public int Spent;
|
||||
|
||||
int lastNotificationTick;
|
||||
|
||||
public bool CanGiveResources(int amount)
|
||||
{
|
||||
return Resources + amount <= ResourceCapacity;
|
||||
@@ -111,9 +121,19 @@ namespace OpenRA.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public bool TakeCash(int num)
|
||||
public bool TakeCash(int num, bool notifyLowFunds = false)
|
||||
{
|
||||
if (Cash + Resources < num) return false;
|
||||
if (Cash + Resources < num)
|
||||
{
|
||||
if (notifyLowFunds && !string.IsNullOrEmpty(info.InsufficientFundsNotification) &&
|
||||
owner.World.WorldTick - lastNotificationTick >= info.InsufficientFundsNotificationDelay)
|
||||
{
|
||||
lastNotificationTick = owner.World.WorldTick;
|
||||
Game.Sound.PlayNotification(owner.World.Map.Rules, owner, "Speech", info.InsufficientFundsNotification, owner.Faction.InternalName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Spend ore before cash
|
||||
Resources -= num;
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace OpenRA.Traits
|
||||
int OrderPriority { get; }
|
||||
bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor);
|
||||
bool IsQueued { get; }
|
||||
bool OverrideSelection { get; }
|
||||
bool TargetOverridesSelection(TargetModifiers modifiers);
|
||||
}
|
||||
|
||||
public interface IResolveOrder { void ResolveOrder(Actor self, Order order); }
|
||||
@@ -319,6 +319,7 @@ namespace OpenRA.Traits
|
||||
public interface ITraitInfo : ITraitInfoInterface { object Create(ActorInitializer init); }
|
||||
|
||||
public class TraitInfo<T> : ITraitInfo where T : new() { public virtual object Create(ActorInitializer init) { return new T(); } }
|
||||
public interface ILobbyCustomRulesIgnore { }
|
||||
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:InterfaceNamesMustBeginWithI", Justification = "Not a real interface, but more like a tag.")]
|
||||
public interface Requires<T> where T : class, ITraitInfoInterface { }
|
||||
|
||||
@@ -103,10 +103,8 @@ namespace OpenRA.Widgets
|
||||
var selectableActor = World.ScreenMap.ActorsAt(mousePos).Any(x =>
|
||||
x.Info.HasTraitInfo<SelectableInfo>() && (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x)));
|
||||
|
||||
var ignoreSelection = mi.Modifiers.HasModifier(Modifiers.Ctrl) || mi.Modifiers.HasModifier(Modifiers.Alt) ||
|
||||
UnitOrderGenerator.InputOverridesSelection(World, mousePos, mi);
|
||||
|
||||
if (ignoreSelection || !selectableActor)
|
||||
var uog = (UnitOrderGenerator)World.OrderGenerator;
|
||||
if (!selectableActor || uog.InputOverridesSelection(World, mousePos, mi))
|
||||
{
|
||||
// Order units instead of selecting
|
||||
ApplyOrders(World, mi);
|
||||
@@ -347,8 +345,16 @@ namespace OpenRA.Widgets
|
||||
|
||||
bool TogglePixelDouble()
|
||||
{
|
||||
Game.Settings.Graphics.PixelDouble ^= true;
|
||||
worldRenderer.Viewport.Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1;
|
||||
if (worldRenderer.Viewport.Zoom == 1f)
|
||||
worldRenderer.Viewport.Zoom = 2f;
|
||||
else
|
||||
{
|
||||
// Reset zoom to regular view if it was anything else before
|
||||
// (like a zoom level only reachable by using the scroll wheel).
|
||||
worldRenderer.Viewport.Zoom = 1f;
|
||||
}
|
||||
|
||||
Game.Settings.Graphics.PixelDouble = worldRenderer.Viewport.Zoom == 2f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,11 +32,20 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
if (IsCanceled) return NextActivity;
|
||||
if (host == null || !host.IsInWorld) return NextActivity;
|
||||
if (IsCanceled)
|
||||
{
|
||||
if (remainingTicks-- == 0)
|
||||
return NextActivity;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
if (host == null || !host.IsInWorld)
|
||||
return NextActivity;
|
||||
|
||||
health = self.TraitOrDefault<Health>();
|
||||
if (health == null) return NextActivity;
|
||||
if (health == null)
|
||||
return NextActivity;
|
||||
|
||||
if (health.DamageState == DamageState.Undamaged)
|
||||
{
|
||||
@@ -56,7 +65,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.StartRepairingNotification, self.Owner.Faction.InternalName);
|
||||
}
|
||||
|
||||
if (!self.Owner.PlayerActor.Trait<PlayerResources>().TakeCash(cost))
|
||||
if (!self.Owner.PlayerActor.Trait<PlayerResources>().TakeCash(cost, true))
|
||||
{
|
||||
remainingTicks = 1;
|
||||
return this;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
@@ -664,6 +665,11 @@ namespace OpenRA.Mods.Common.Effects
|
||||
// of vertical facing bound by the maximum vertical rate of turn
|
||||
var vDist = new WVec(-diffClfMslHgt - info.CruiseAltitude.Length, -speed, 0);
|
||||
desiredVFacing = (sbyte)vDist.HorizontalLengthSquared != 0 ? vDist.Yaw.Facing : vFacing;
|
||||
|
||||
// If the missile is launched above CruiseAltitude, it has to descend instead of climbing
|
||||
if (-diffClfMslHgt > info.CruiseAltitude.Length)
|
||||
desiredVFacing = -desiredVFacing;
|
||||
|
||||
desiredVFacing = desiredVFacing.Clamp(-info.VerticalRateOfTurn, info.VerticalRateOfTurn);
|
||||
|
||||
ChangeSpeed();
|
||||
@@ -675,6 +681,11 @@ namespace OpenRA.Mods.Common.Effects
|
||||
// of vertical facing bound by the maximum vertical rate of turn
|
||||
var vDist = new WVec(-diffClfMslHgt - info.CruiseAltitude.Length, -speed, 0);
|
||||
desiredVFacing = (sbyte)vDist.HorizontalLengthSquared != 0 ? vDist.Yaw.Facing : vFacing;
|
||||
|
||||
// If the missile is launched above CruiseAltitude, it has to descend instead of climbing
|
||||
if (-diffClfMslHgt > info.CruiseAltitude.Length)
|
||||
desiredVFacing = -desiredVFacing;
|
||||
|
||||
desiredVFacing = desiredVFacing.Clamp(-info.VerticalRateOfTurn, info.VerticalRateOfTurn);
|
||||
|
||||
ChangeSpeed();
|
||||
@@ -701,9 +712,10 @@ namespace OpenRA.Mods.Common.Effects
|
||||
var velVec = tarDistVec + predVel;
|
||||
var desiredHFacing = velVec.HorizontalLengthSquared != 0 ? velVec.Yaw.Facing : hFacing;
|
||||
|
||||
if (allowPassBy && System.Math.Abs(desiredHFacing - hFacing) >= System.Math.Abs(desiredHFacing + 128 - hFacing))
|
||||
var delta = Util.NormalizeFacing(hFacing - desiredHFacing);
|
||||
if (allowPassBy && delta > 64 && delta < 192)
|
||||
{
|
||||
desiredHFacing += 128;
|
||||
desiredHFacing = (desiredHFacing + 128) & 0xFF;
|
||||
targetPassedBy = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -299,7 +299,6 @@
|
||||
<Compile Include="Traits\Burns.cs" />
|
||||
<Compile Include="Traits\C4Demolition.cs" />
|
||||
<Compile Include="Traits\Health.cs" />
|
||||
<Compile Include="Traits\Player\InsufficientFundsWarning.cs" />
|
||||
<Compile Include="Traits\PowerTooltip.cs" />
|
||||
<Compile Include="Traits\VeteranProductionIconOverlay.cs" />
|
||||
<Compile Include="Traits\Capturable.cs" />
|
||||
|
||||
@@ -19,7 +19,10 @@ namespace OpenRA.Mods.Common.Orders
|
||||
{
|
||||
public string OrderID { get { return "Move"; } }
|
||||
public int OrderPriority { get { return 4; } }
|
||||
public bool OverrideSelection { get { return false; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers)
|
||||
{
|
||||
return modifiers.HasModifier(TargetModifiers.ForceMove);
|
||||
}
|
||||
|
||||
readonly AircraftInfo info;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
public string OrderID { get; private set; }
|
||||
public int OrderPriority { get; private set; }
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
public string OrderID { get; private set; }
|
||||
public int OrderPriority { get; private set; }
|
||||
public bool? ForceAttack = null;
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
public abstract bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor);
|
||||
public abstract bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor);
|
||||
|
||||
@@ -398,7 +398,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
server.SendMessage("{0} changed the map to {1}.".F(client.Name, server.Map.Title));
|
||||
|
||||
if (server.Map.Rules.Actors != server.ModData.DefaultRules.Actors)
|
||||
if (server.Map.DefinesUnsafeCustomRules)
|
||||
server.SendMessage("This map contains custom rules. Game experience may change.");
|
||||
|
||||
if (server.Settings.DisableSinglePlayer)
|
||||
|
||||
@@ -309,7 +309,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public string OrderID { get; private set; }
|
||||
public int OrderPriority { get; private set; }
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
bool CanTargetActor(Actor self, Target target, ref TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public string OrderID { get { return "SetRallyPoint"; } }
|
||||
public int OrderPriority { get { return 0; } }
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var cost = Math.Max(1, (hpToRepair * Info.RepairPercent * buildingValue) / (health.MaxHP * 100));
|
||||
|
||||
// TakeCash will return false if the player can't pay, and will stop him from contributing this Tick
|
||||
var activePlayers = Repairers.Count(player => player.PlayerActor.Trait<PlayerResources>().TakeCash(cost));
|
||||
var activePlayers = Repairers.Count(player => player.PlayerActor.Trait<PlayerResources>().TakeCash(cost, true));
|
||||
|
||||
RepairActive = activePlayers > 0;
|
||||
|
||||
|
||||
@@ -266,9 +266,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (passengerFacing != null)
|
||||
passengerFacing.Facing = facing.Value.Facing + Info.PassengerFacing;
|
||||
|
||||
var passengerTurreted = passenger.TraitOrDefault<Turreted>();
|
||||
if (passengerTurreted != null)
|
||||
passengerTurreted.TurretFacing = facing.Value.Facing + Info.PassengerFacing;
|
||||
foreach (var t in passenger.TraitsImplementing<Turreted>())
|
||||
t.TurretFacing = facing.Value.Facing + Info.PassengerFacing;
|
||||
}
|
||||
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
|
||||
@@ -84,7 +84,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// The upgrade manager exists, but may not have finished being created yet.
|
||||
// We'll defer the upgrades until the end of the tick, at which point it will be ready.
|
||||
if (Cloaked)
|
||||
{
|
||||
wasCloaked = true;
|
||||
self.World.AddFrameEndTask(_ => GrantUpgrades(self));
|
||||
}
|
||||
}
|
||||
|
||||
public bool Cloaked { get { return !IsTraitDisabled && remainingTime <= 0; } }
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var cost = csv != null ? csv.Value : (valued != null ? valued.Cost : 0);
|
||||
|
||||
var health = self.TraitOrDefault<Health>();
|
||||
var dudesValue = info.ValuePercent * cost;
|
||||
var dudesValue = info.ValuePercent * cost / 100;
|
||||
if (health != null)
|
||||
{
|
||||
if (100 * health.HP >= info.MinHpPercent * health.MaxHP)
|
||||
|
||||
@@ -452,7 +452,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public string OrderID { get { return "Harvest"; } }
|
||||
public int OrderPriority { get { return 10; } }
|
||||
public bool IsQueued { get; protected set; }
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
|
||||
@@ -720,7 +720,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
readonly Mobile mobile;
|
||||
readonly bool rejectMove;
|
||||
public bool OverrideSelection { get { return false; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers)
|
||||
{
|
||||
return modifiers.HasModifier(TargetModifiers.ForceMove);
|
||||
}
|
||||
|
||||
public MoveOrderTargeter(Actor self, Mobile unit)
|
||||
{
|
||||
|
||||
@@ -20,8 +20,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("This actor will remain visible (but not updated visually) under fog, once discovered.")]
|
||||
public class FrozenUnderFogInfo : ITraitInfo, Requires<BuildingInfo>, IDefaultVisibilityInfo
|
||||
{
|
||||
public readonly bool StartsRevealed = false;
|
||||
|
||||
[Desc("Players with these stances can always see the actor.")]
|
||||
public readonly Stance AlwaysVisibleStances = Stance.Ally;
|
||||
|
||||
@@ -55,8 +53,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
var map = init.World.Map;
|
||||
|
||||
// Spawned actors (e.g. building husks) shouldn't be revealed
|
||||
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
|
||||
// Explore map-placed actors if the "Explore Map" option is enabled
|
||||
var exploredMap = !init.World.LobbyInfo.GlobalSettings.Shroud;
|
||||
startsRevealed = exploredMap && init.Contains<SpawnedByMapInit>() && !init.Contains<HiddenUnderFogInit>();
|
||||
var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
|
||||
footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray();
|
||||
}
|
||||
@@ -142,4 +141,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return IsVisible(self, self.World.RenderPlayer) || isRendering ? r : SpriteRenderable.None;
|
||||
}
|
||||
}
|
||||
|
||||
public class HiddenUnderFogInit : IActorInit { }
|
||||
}
|
||||
@@ -17,7 +17,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Used for day/night effects.")]
|
||||
class GlobalLightingPaletteEffectInfo : ITraitInfo
|
||||
class GlobalLightingPaletteEffectInfo : ITraitInfo, ILobbyCustomRulesIgnore
|
||||
{
|
||||
[Desc("Do not modify graphics that use any palette in this list.")]
|
||||
public readonly HashSet<string> ExcludePalettes = new HashSet<string> { "cursor", "chrome", "colorpicker", "fog", "shroud", "alpha" };
|
||||
|
||||
@@ -16,7 +16,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Can be paradropped by a ParaDrop actor.")]
|
||||
class ParachutableInfo : ITraitInfo
|
||||
class ParachutableInfo : ITraitInfo, Requires<IPositionableInfo>
|
||||
{
|
||||
[Desc("If we land on invalid terrain for my actor type should we be killed?")]
|
||||
public readonly bool KilledOnImpassableTerrain = true;
|
||||
@@ -51,8 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
self = init.Self;
|
||||
this.info = info;
|
||||
|
||||
positionable = self.TraitOrDefault<IPositionable>();
|
||||
positionable = self.Trait<IPositionable>();
|
||||
}
|
||||
|
||||
void INotifyParachuteLanded.OnLanded(Actor ignore)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2016 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Provides the player with an audible warning when they run out of money while producing.")]
|
||||
public class InsufficientFundsWarningInfo : ITraitInfo, Requires<PlayerResourcesInfo>
|
||||
{
|
||||
[Desc("The speech to play for the warning.")]
|
||||
public readonly string Notification = "InsufficientFunds";
|
||||
|
||||
public object Create(ActorInitializer init) { return new InsufficientFundsWarning(this); }
|
||||
}
|
||||
|
||||
public class InsufficientFundsWarning : INotifyInsufficientFunds
|
||||
{
|
||||
readonly InsufficientFundsWarningInfo info;
|
||||
|
||||
bool played;
|
||||
|
||||
public InsufficientFundsWarning(InsufficientFundsWarningInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
void INotifyInsufficientFunds.InsufficientFunds(Actor self)
|
||||
{
|
||||
Game.RunAfterTick(() =>
|
||||
{
|
||||
if (played)
|
||||
return;
|
||||
|
||||
played = true;
|
||||
var owner = self.Owner;
|
||||
Game.Sound.PlayNotification(self.World.Map.Rules, owner, "Speech", info.Notification, owner.Faction.InternalName);
|
||||
});
|
||||
}
|
||||
|
||||
void INotifyInsufficientFunds.SufficientFunds(Actor self)
|
||||
{
|
||||
played = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -415,12 +415,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public bool Started { get; private set; }
|
||||
public int Slowdown { get; private set; }
|
||||
|
||||
readonly INotifyInsufficientFunds[] insufficientFunds;
|
||||
readonly Player owner;
|
||||
readonly PowerManager pm;
|
||||
|
||||
bool insufficientFundsPlayed;
|
||||
|
||||
public ProductionItem(ProductionQueue queue, string item, int cost, PowerManager pm, Action onComplete)
|
||||
{
|
||||
Item = item;
|
||||
@@ -429,8 +425,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
OnComplete = onComplete;
|
||||
Queue = queue;
|
||||
this.pm = pm;
|
||||
owner = queue.Actor.Owner;
|
||||
insufficientFunds = owner.PlayerActor.TraitsImplementing<INotifyInsufficientFunds>().ToArray();
|
||||
}
|
||||
|
||||
public void Tick(PlayerResources pr)
|
||||
@@ -441,13 +435,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (time > 0)
|
||||
RemainingTime = TotalTime = time;
|
||||
|
||||
// Don't play a QueuedAudio notification when we can't start building (because we don't have the money to)
|
||||
// Also don't play it when the time to build is actually 0 (i.e. normally dev cheats)
|
||||
// to prevent overlapping with the ReadyAudio notification
|
||||
var initialCost = RemainingCost / RemainingTime;
|
||||
if (time != 0 && initialCost != 0 && pr.Cash + pr.Resources > initialCost)
|
||||
Game.Sound.PlayNotification(owner.World.Map.Rules, owner, "Speech", Queue.Info.QueuedAudio, owner.Faction.InternalName);
|
||||
|
||||
Started = true;
|
||||
}
|
||||
|
||||
@@ -471,23 +458,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
|
||||
var costThisFrame = RemainingCost / RemainingTime;
|
||||
if (costThisFrame != 0 && !pr.TakeCash(costThisFrame))
|
||||
{
|
||||
if (!insufficientFundsPlayed)
|
||||
{
|
||||
insufficientFundsPlayed = true;
|
||||
foreach (var funds in insufficientFunds)
|
||||
funds.InsufficientFunds(owner.PlayerActor);
|
||||
}
|
||||
|
||||
if (costThisFrame != 0 && !pr.TakeCash(costThisFrame, true))
|
||||
return;
|
||||
}
|
||||
|
||||
if (insufficientFundsPlayed)
|
||||
insufficientFundsPlayed = false;
|
||||
|
||||
foreach (var funds in insufficientFunds)
|
||||
funds.SufficientFunds(owner.PlayerActor);
|
||||
|
||||
RemainingCost -= costThisFrame;
|
||||
RemainingTime -= 1;
|
||||
|
||||
@@ -140,6 +140,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
DefaultAnimation.PlayFetchIndex(NormalizeSequence(self, Info.Sequence), () => adjacent);
|
||||
UpdateNeighbours(self);
|
||||
|
||||
// Set the initial animation frame before the render tick (for frozen actor previews)
|
||||
self.World.AddFrameEndTask(_ => DefaultAnimation.Tick());
|
||||
}
|
||||
|
||||
static void UpdateNeighbours(Actor self)
|
||||
|
||||
@@ -77,6 +77,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
// Actor has been disposed by something else before its death (for example `Enter`).
|
||||
if (self.Disposed)
|
||||
return;
|
||||
|
||||
var td = new TypeDictionary
|
||||
{
|
||||
new ParentActorInit(self),
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -26,25 +27,28 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new Targetable(init.Self, this); }
|
||||
}
|
||||
|
||||
public class Targetable : UpgradableTrait<TargetableInfo>, ITargetable
|
||||
public class Targetable : UpgradableTrait<TargetableInfo>, ITargetable, INotifyCreated
|
||||
{
|
||||
protected static readonly string[] None = new string[] { };
|
||||
protected Cloak cloak;
|
||||
protected Cloak[] cloaks;
|
||||
|
||||
public Targetable(Actor self, TargetableInfo info)
|
||||
: base(info)
|
||||
: base(info) { }
|
||||
|
||||
void INotifyCreated.Created(Actor self)
|
||||
{
|
||||
cloak = self.TraitOrDefault<Cloak>();
|
||||
cloaks = self.TraitsImplementing<Cloak>().ToArray();
|
||||
}
|
||||
|
||||
public virtual bool TargetableBy(Actor self, Actor viewer)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return false;
|
||||
if (cloak == null || (!viewer.IsDead && viewer.Info.HasTraitInfo<IgnoresCloakInfo>()))
|
||||
|
||||
if (!cloaks.Any() || (!viewer.IsDead && viewer.Info.HasTraitInfo<IgnoresCloakInfo>()))
|
||||
return true;
|
||||
|
||||
return cloak.IsVisible(self, viewer.Owner);
|
||||
return cloaks.All(c => c.IsTraitDisabled || c.IsVisible(self, viewer.Owner));
|
||||
}
|
||||
|
||||
public virtual HashSet<string> TargetTypes { get { return Info.TargetTypes; } }
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class EditorActorLayer : IWorldLoaded, ITickRender, IRender, IRadarSignature, ICreatePlayers
|
||||
{
|
||||
readonly EditorActorLayerInfo info;
|
||||
readonly Dictionary<string, EditorActorPreview> previews = new Dictionary<string, EditorActorPreview>();
|
||||
readonly List<EditorActorPreview> previews = new List<EditorActorPreview>();
|
||||
readonly Dictionary<CPos, List<EditorActorPreview>> cellMap = new Dictionary<CPos, List<EditorActorPreview>>();
|
||||
|
||||
SpatiallyPartitioned<EditorActorPreview> screenMap;
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary()), true);
|
||||
|
||||
// Update neighbours in one pass
|
||||
foreach (var p in previews.Values)
|
||||
foreach (var p in previews)
|
||||
UpdateNeighbours(p.Footprint);
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (wr.World.Type != WorldType.Editor)
|
||||
return;
|
||||
|
||||
foreach (var kv in previews.Values)
|
||||
kv.Tick();
|
||||
foreach (var p in previews)
|
||||
p.Tick();
|
||||
}
|
||||
|
||||
static readonly IEnumerable<IRenderable> NoRenderables = Enumerable.Empty<IRenderable>();
|
||||
@@ -104,7 +104,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var owner = Players.Players[reference.InitDict.Get<OwnerInit>().PlayerName];
|
||||
|
||||
var preview = new EditorActorPreview(worldRenderer, id, reference, owner);
|
||||
previews.Add(id, preview);
|
||||
previews.Add(preview);
|
||||
screenMap.Add(preview, preview.Bounds);
|
||||
|
||||
foreach (var kv in preview.Footprint)
|
||||
@@ -132,7 +132,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void Remove(EditorActorPreview preview)
|
||||
{
|
||||
previews.Remove(preview.ID);
|
||||
previews.Remove(preview);
|
||||
screenMap.Remove(preview);
|
||||
|
||||
foreach (var kv in preview.Footprint)
|
||||
@@ -155,7 +155,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
void SyncMultiplayerCount()
|
||||
{
|
||||
var newCount = previews.Count(p => p.Value.Info.Name == "mpspawn");
|
||||
var newCount = previews.Count(p => p.Info.Name == "mpspawn");
|
||||
var mp = Players.Players.Where(p => p.Key.StartsWith("Multi")).ToList();
|
||||
foreach (var kv in mp)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var id = previews.Count();
|
||||
var possibleName = "Actor" + id.ToString();
|
||||
|
||||
while (previews.ContainsKey(possibleName))
|
||||
while (previews.Any(p => p.ID == possibleName))
|
||||
{
|
||||
id++;
|
||||
possibleName = "Actor" + id.ToString();
|
||||
@@ -258,7 +258,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
var nodes = new List<MiniYamlNode>();
|
||||
foreach (var a in previews)
|
||||
nodes.Add(new MiniYamlNode(a.Key, a.Value.Save()));
|
||||
nodes.Add(new MiniYamlNode(a.ID, a.Save()));
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
var initDict = actorReference.InitDict;
|
||||
initDict.Add(new SkipMakeAnimsInit());
|
||||
initDict.Add(new SpawnedByMapInit(kv.Key));
|
||||
var actor = world.CreateActor(actorReference.Type, initDict);
|
||||
Actors[kv.Key] = actor;
|
||||
LastMapActorID = actor.ActorID;
|
||||
@@ -45,4 +46,14 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
|
||||
public class SkipMakeAnimsInit : IActorInit, ISuppressInitExport { }
|
||||
public class SpawnedByMapInit : IActorInit<string>, ISuppressInitExport
|
||||
{
|
||||
public readonly string Name;
|
||||
public SpawnedByMapInit(string name) { Name = name; }
|
||||
|
||||
public string Value(World world)
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Adds a particle-based overlay.")]
|
||||
public class WeatherOverlayInfo : ITraitInfo
|
||||
public class WeatherOverlayInfo : ITraitInfo, ILobbyCustomRulesIgnore
|
||||
{
|
||||
[Desc("Factor for particle density. As higher as more particles will get spawned.")]
|
||||
public readonly float ParticleDensityFactor = 0.0007625f;
|
||||
|
||||
@@ -124,11 +124,4 @@ namespace OpenRA.Mods.Common.Traits
|
||||
bool AdjacentWallCanConnect(Actor self, CPos wallLocation, string wallType, out CVec facing);
|
||||
void SetDirty();
|
||||
}
|
||||
|
||||
[RequireExplicitImplementation]
|
||||
interface INotifyInsufficientFunds
|
||||
{
|
||||
void InsufficientFunds(Actor self);
|
||||
void SufficientFunds(Actor self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,14 @@ namespace OpenRA.Mods.Common
|
||||
}
|
||||
}
|
||||
|
||||
public static int NormalizeFacing(int f)
|
||||
{
|
||||
if (f >= 0)
|
||||
return f & 0xFF;
|
||||
|
||||
return 0xFF - (-f & 0xFF);
|
||||
}
|
||||
|
||||
public static WPos BetweenCells(World w, CPos from, CPos to)
|
||||
{
|
||||
return WPos.Lerp(w.Map.CenterOfCell(from), w.Map.CenterOfCell(to), 1, 2);
|
||||
|
||||
@@ -390,7 +390,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
if (health != 100)
|
||||
initDict.Add(new HealthInit(health));
|
||||
if (facing != 0)
|
||||
initDict.Add(new FacingInit(facing));
|
||||
initDict.Add(new FacingInit(255 - facing));
|
||||
|
||||
if (section == "INFANTRY")
|
||||
actor.Add(new SubCellInit(Exts.ParseIntegerInvariant(parts[4])));
|
||||
|
||||
@@ -757,6 +757,26 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
node.Key = "EffectImage";
|
||||
}
|
||||
|
||||
if (engineVersion < 20160408)
|
||||
{
|
||||
var traitNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "InsufficientFundsWarning");
|
||||
if (traitNode != null)
|
||||
{
|
||||
var prNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "PlayerResources");
|
||||
if (prNode != null)
|
||||
prNode.Value.Nodes.Add(new MiniYamlNode("InsufficientFundsNotification", new MiniYaml("InsufficientFunds")));
|
||||
|
||||
node.Value.Nodes.Remove(traitNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (engineVersion < 20160418)
|
||||
{
|
||||
// Removed FrozenUnderFog.StartsRevealed
|
||||
if (node.Key == "FrozenUnderFog")
|
||||
node.Value.Nodes.RemoveAll(x => x.Key == "StartsRevealed");
|
||||
}
|
||||
|
||||
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,9 @@ namespace OpenRA.Mods.Common.Warheads
|
||||
|
||||
public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
|
||||
{
|
||||
if (!target.IsValidFor(firedBy))
|
||||
return;
|
||||
|
||||
var pos = target.CenterPosition;
|
||||
var world = firedBy.World;
|
||||
var targetTile = world.Map.CellContaining(pos);
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var pp = p;
|
||||
var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex);
|
||||
var item = playerTemplate.Clone();
|
||||
LobbyUtils.SetupClientWidget(item, client, orderManager, client.Bot == null);
|
||||
LobbyUtils.SetupClientWidget(item, client, orderManager, client != null && client.Bot == null);
|
||||
var nameLabel = item.Get<LabelWidget>("NAME");
|
||||
var nameFont = Game.Renderer.Fonts[nameLabel.Font];
|
||||
|
||||
|
||||
@@ -40,12 +40,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
if (timer != null)
|
||||
{
|
||||
// Timers in replays should be synced to the effective game time, not the playback time.
|
||||
var timestep = world.Timestep;
|
||||
if (world.IsReplay)
|
||||
{
|
||||
GameSpeed speed;
|
||||
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>();
|
||||
if (gameSpeeds.Speeds.TryGetValue(world.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
|
||||
timestep = speed.Timestep;
|
||||
}
|
||||
|
||||
timer.GetText = () =>
|
||||
{
|
||||
if (status == null && shouldShowStatus())
|
||||
return statusText();
|
||||
|
||||
return WidgetUtils.FormatTime(world.WorldTick, world.Timestep);
|
||||
return WidgetUtils.FormatTime(world.WorldTick, timestep);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -781,7 +781,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
new Task(() =>
|
||||
{
|
||||
// Force map rules to be loaded on this background thread
|
||||
var unused = map.Rules;
|
||||
map.PreloadRules();
|
||||
}).Start();
|
||||
}
|
||||
|
||||
@@ -799,7 +799,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
new Task(() =>
|
||||
{
|
||||
// Force map rules to be loaded on this background thread
|
||||
var unused = currentMap.Rules;
|
||||
currentMap.PreloadRules();
|
||||
Game.RunAfterTick(() =>
|
||||
{
|
||||
// Map may have changed in the meantime
|
||||
|
||||
@@ -109,8 +109,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
|
||||
if (install != null)
|
||||
{
|
||||
install.OnClick = () => lobby.Map.Install(
|
||||
() => orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))));
|
||||
install.OnClick = () => lobby.Map.Install(() =>
|
||||
{
|
||||
lobby.Map.PreloadRules();
|
||||
Game.RunAfterTick(() => orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady))));
|
||||
});
|
||||
install.IsHighlighted = () => installHighlighted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var adminIndicator = parent.GetOrNull("ADMIN_INDICATOR");
|
||||
if (adminIndicator != null)
|
||||
adminIndicator.IsVisible = () => c.IsAdmin;
|
||||
adminIndicator.IsVisible = () => c != null && c.IsAdmin;
|
||||
|
||||
var block = parent.GetOrNull("LATENCY");
|
||||
if (block != null)
|
||||
@@ -253,8 +253,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
}
|
||||
|
||||
var tooltip = parent.Get<ClientTooltipRegionWidget>("CLIENT_REGION");
|
||||
tooltip.IsVisible = () => visible;
|
||||
tooltip.Bind(orderManager, c.Index);
|
||||
tooltip.IsVisible = () => c != null && visible;
|
||||
if (c != null)
|
||||
tooltip.Bind(orderManager, c.Index);
|
||||
}
|
||||
|
||||
public static void SetupEditableNameWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
|
||||
|
||||
@@ -12,16 +12,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
[SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:ConstantsMustAppearBeforeFields",
|
||||
Justification = "SystemInformation version should be defined next to the dictionary it refers to.")]
|
||||
public class MainMenuLogic : ChromeLogic
|
||||
{
|
||||
protected enum MenuType { Main, Singleplayer, Extras, MapEditor, None }
|
||||
protected enum MenuType { Main, Singleplayer, Extras, MapEditor, SystemInfoPrompt, None }
|
||||
|
||||
protected MenuType menuType = MenuType.Main;
|
||||
readonly Widget rootMenu;
|
||||
@@ -32,6 +36,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
// Update news once per game launch
|
||||
static bool fetchedNews;
|
||||
|
||||
// Increment the version number when adding new stats
|
||||
const int SystemInformationVersion = 1;
|
||||
Dictionary<string, Pair<string, string>> GetSystemInformation()
|
||||
{
|
||||
var lang = System.Globalization.CultureInfo.InstalledUICulture.TwoLetterISOLanguageName;
|
||||
return new Dictionary<string, Pair<string, string>>()
|
||||
{
|
||||
{ "id", Pair.New("Anonymous ID", Game.Settings.Debug.UUID) },
|
||||
{ "platform", Pair.New("OS Type", Platform.CurrentPlatform.ToString()) },
|
||||
{ "os", Pair.New("OS Version", Environment.OSVersion.ToString()) },
|
||||
{ "runtime", Pair.New(".NET Runtime", Platform.RuntimeVersion) },
|
||||
{ "gl", Pair.New("OpenGL Version", Game.Renderer.GLVersion) },
|
||||
{ "lang", Pair.New("System Language", lang) }
|
||||
};
|
||||
}
|
||||
|
||||
void SwitchMenu(MenuType type)
|
||||
{
|
||||
menuType = type;
|
||||
@@ -201,7 +221,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var newsBG = widget.GetOrNull("NEWS_BG");
|
||||
if (newsBG != null)
|
||||
{
|
||||
newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None;
|
||||
newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.SystemInfoPrompt;
|
||||
|
||||
newsPanel = Ui.LoadWidget<ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
|
||||
newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
|
||||
@@ -209,26 +229,79 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
newsStatus = newsPanel.Get<LabelWidget>("NEWS_STATUS");
|
||||
SetNewsStatus("Loading news");
|
||||
}
|
||||
|
||||
Game.OnRemoteDirectConnect += OnRemoteDirectConnect;
|
||||
|
||||
// System information opt-out prompt
|
||||
var sysInfoPrompt = widget.Get("SYSTEM_INFO_PROMPT");
|
||||
sysInfoPrompt.IsVisible = () => menuType == MenuType.SystemInfoPrompt;
|
||||
if (Game.Settings.Debug.SystemInformationVersionPrompt < SystemInformationVersion)
|
||||
{
|
||||
menuType = MenuType.SystemInfoPrompt;
|
||||
|
||||
var sysInfoCheckbox = sysInfoPrompt.Get<CheckboxWidget>("SYSINFO_CHECKBOX");
|
||||
sysInfoCheckbox.IsChecked = () => Game.Settings.Debug.SendSystemInformation;
|
||||
sysInfoCheckbox.OnClick = () => Game.Settings.Debug.SendSystemInformation ^= true;
|
||||
|
||||
var sysInfoData = sysInfoPrompt.Get<ScrollPanelWidget>("SYSINFO_DATA");
|
||||
var template = sysInfoData.Get<LabelWidget>("DATA_TEMPLATE");
|
||||
sysInfoData.RemoveChildren();
|
||||
|
||||
foreach (var info in GetSystemInformation().Values)
|
||||
{
|
||||
var label = template.Clone() as LabelWidget;
|
||||
var text = info.First + ": " + info.Second;
|
||||
label.GetText = () => text;
|
||||
sysInfoData.AddChild(label);
|
||||
}
|
||||
|
||||
sysInfoPrompt.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
|
||||
{
|
||||
Game.Settings.Debug.SystemInformationVersionPrompt = SystemInformationVersion;
|
||||
Game.Settings.Save();
|
||||
SwitchMenu(MenuType.Main);
|
||||
LoadAndDisplayNews(newsBG);
|
||||
};
|
||||
}
|
||||
else
|
||||
LoadAndDisplayNews(newsBG);
|
||||
}
|
||||
|
||||
void LoadAndDisplayNews(Widget newsBG)
|
||||
{
|
||||
if (newsBG != null)
|
||||
{
|
||||
var cacheFile = Platform.ResolvePath("^", "news.yaml");
|
||||
var currentNews = ParseNews(cacheFile);
|
||||
if (currentNews != null)
|
||||
DisplayNews(currentNews);
|
||||
|
||||
var newsButton = newsBG.GetOrNull<DropDownButtonWidget>("NEWS_BUTTON");
|
||||
|
||||
if (newsButton != null)
|
||||
{
|
||||
if (!fetchedNews)
|
||||
new Download(Game.Settings.Game.NewsUrl + SysInfoQuery(), cacheFile, e => { },
|
||||
{
|
||||
// Send the mod and engine version to support version-filtered news (update prompts)
|
||||
var newsURL = Game.Settings.Game.NewsUrl + "?version={0}&mod={1}&modversion={2}".F(
|
||||
Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version));
|
||||
|
||||
// Append system profile data if the player has opted in
|
||||
if (Game.Settings.Debug.SendSystemInformation)
|
||||
newsURL += "&" + GetSystemInformation()
|
||||
.Select(kv => kv.Key + "=" + Uri.EscapeUriString(kv.Value.Second))
|
||||
.JoinWith("&");
|
||||
|
||||
new Download(newsURL, cacheFile, e => { },
|
||||
(e, c) => NewsDownloadComplete(e, cacheFile, currentNews,
|
||||
() => newsButton.AttachPanel(newsPanel)));
|
||||
}
|
||||
|
||||
newsButton.OnClick = () => newsButton.AttachPanel(newsPanel);
|
||||
}
|
||||
}
|
||||
|
||||
Game.OnRemoteDirectConnect += OnRemoteDirectConnect;
|
||||
}
|
||||
|
||||
void OnRemoteDirectConnect(string host, int port)
|
||||
@@ -252,23 +325,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
() => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });
|
||||
}
|
||||
|
||||
string SysInfoQuery()
|
||||
{
|
||||
if (!Game.Settings.Debug.SendSystemInformation)
|
||||
return null;
|
||||
|
||||
return "?id={0}&platform={1}&os={2}&runtime={3}&gl={4}&lang={5}&version={6}&mod={7}&modversion={8}".F(
|
||||
Uri.EscapeUriString(Game.Settings.Debug.UUID),
|
||||
Uri.EscapeUriString(Platform.CurrentPlatform.ToString()),
|
||||
Uri.EscapeUriString(Environment.OSVersion.ToString()),
|
||||
Uri.EscapeUriString(Platform.RuntimeVersion),
|
||||
Uri.EscapeUriString(Game.Renderer.GLVersion),
|
||||
Uri.EscapeUriString(System.Globalization.CultureInfo.InstalledUICulture.TwoLetterISOLanguageName),
|
||||
Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version));
|
||||
}
|
||||
|
||||
void SetNewsStatus(string message)
|
||||
{
|
||||
message = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
foreach (var p in allPreviews)
|
||||
{
|
||||
p.GetMinimap();
|
||||
var unused = p.Rules;
|
||||
p.PreloadRules();
|
||||
}
|
||||
}).Start();
|
||||
|
||||
|
||||
@@ -315,7 +315,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
Game.RunAfterTick(() => RefreshServerListInner(games));
|
||||
};
|
||||
|
||||
currentQuery = new Download(Game.Settings.Server.MasterServer + "games", _ => { }, onComplete);
|
||||
var queryURL = Game.Settings.Server.MasterServer + "games?version={0}&mod={1}&modversion={2}".F(
|
||||
Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version));
|
||||
|
||||
currentQuery = new Download(queryURL, _ => { }, onComplete);
|
||||
}
|
||||
|
||||
int GroupSortOrder(GameServer testEntry)
|
||||
|
||||
@@ -233,6 +233,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
// Queue a new item
|
||||
Game.Sound.Play(TabClick);
|
||||
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Faction.InternalName);
|
||||
World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, icon.Name, handleCount));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class GpsSatellite : IEffect
|
||||
{
|
||||
readonly GpsPowerInfo info;
|
||||
readonly Animation anim;
|
||||
readonly string palette;
|
||||
WPos pos;
|
||||
|
||||
public GpsSatellite(World world, WPos pos, GpsPowerInfo info)
|
||||
public GpsSatellite(World world, WPos pos, string image, string sequence, string palette)
|
||||
{
|
||||
this.info = info;
|
||||
this.palette = palette;
|
||||
this.pos = pos;
|
||||
|
||||
anim = new Animation(world, info.SatelliteImage);
|
||||
anim.PlayRepeating(info.SatelliteSequence);
|
||||
anim = new Animation(world, image);
|
||||
anim.PlayRepeating(sequence);
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
@@ -42,7 +42,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
return anim.Render(pos, wr.Palette(info.SatellitePalette));
|
||||
return anim.Render(pos, wr.Palette(palette));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,19 +19,21 @@ namespace OpenRA.Mods.RA.Effects
|
||||
class SatelliteLaunch : IEffect
|
||||
{
|
||||
readonly GpsPowerInfo info;
|
||||
readonly Actor launcher;
|
||||
readonly Animation doors;
|
||||
readonly WPos pos;
|
||||
int frame = 0;
|
||||
|
||||
public SatelliteLaunch(Actor a, GpsPowerInfo info)
|
||||
public SatelliteLaunch(Actor launcher, GpsPowerInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.launcher = launcher;
|
||||
|
||||
doors = new Animation(a.World, info.DoorImage);
|
||||
doors = new Animation(launcher.World, info.DoorImage);
|
||||
doors.PlayThen(info.DoorSequence,
|
||||
() => a.World.AddFrameEndTask(w => w.Remove(this)));
|
||||
() => launcher.World.AddFrameEndTask(w => w.Remove(this)));
|
||||
|
||||
pos = a.CenterPosition;
|
||||
pos = launcher.CenterPosition;
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
@@ -39,12 +41,16 @@ namespace OpenRA.Mods.RA.Effects
|
||||
doors.Tick();
|
||||
|
||||
if (++frame == 19)
|
||||
world.AddFrameEndTask(w => w.Add(new GpsSatellite(world, pos, info)));
|
||||
{
|
||||
var palette = info.SatellitePaletteIsPlayerPalette ? info.SatellitePalette + launcher.Owner.InternalName : info.SatellitePalette;
|
||||
world.AddFrameEndTask(w => w.Add(new GpsSatellite(world, pos, info.SatelliteImage, info.SatelliteSequence, palette)));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
return doors.Render(pos, wr.Palette(info.DoorPalette));
|
||||
var palette = info.DoorPaletteIsPlayerPalette ? info.DoorPalette + launcher.Owner.InternalName : info.DoorPalette;
|
||||
return doors.Render(pos, wr.Palette(palette));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,12 @@ namespace OpenRA.Mods.RA.Traits
|
||||
static readonly FrozenActorAction Refresh = (fufubg, fal, gps, fa) =>
|
||||
{
|
||||
// Refreshes the visual state of the frozen actor, so ownership changes can be seen.
|
||||
fa.RefreshState();
|
||||
// This only makes sense if the frozen actor has already been revealed (i.e. has renderables)
|
||||
if (fa.HasRenderables)
|
||||
{
|
||||
fa.RefreshState();
|
||||
fa.NeedRenderables = true;
|
||||
}
|
||||
};
|
||||
static readonly FrozenActorAction Remove = (fufubg, fal, gps, fa) =>
|
||||
{
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
public string OrderID { get { return "BeginMinefield"; } }
|
||||
public int OrderPriority { get { return 5; } }
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
public string OrderID { get { return "PortableChronoTeleport"; } }
|
||||
public int OrderPriority { get { return 5; } }
|
||||
public bool IsQueued { get; protected set; }
|
||||
public bool OverrideSelection { get { return true; } }
|
||||
public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; }
|
||||
|
||||
public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
|
||||
@@ -25,11 +25,21 @@ namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
public readonly string DoorImage = "atek";
|
||||
[SequenceReference("DoorImage")] public readonly string DoorSequence = "active";
|
||||
[PaletteReference] public readonly string DoorPalette = "effect";
|
||||
|
||||
[Desc("Palette to use for rendering the launch animation")]
|
||||
[PaletteReference("DoorPaletteIsPlayerPalette")] public readonly string DoorPalette = "player";
|
||||
|
||||
[Desc("Custom palette is a player palette BaseName")]
|
||||
public readonly bool DoorPaletteIsPlayerPalette = true;
|
||||
|
||||
public readonly string SatelliteImage = "sputnik";
|
||||
[SequenceReference("SatelliteImage")] public readonly string SatelliteSequence = "idle";
|
||||
[PaletteReference] public readonly string SatellitePalette = "effect";
|
||||
|
||||
[Desc("Palette to use for rendering the satellite projectile")]
|
||||
[PaletteReference("SatellitePaletteIsPlayerPalette")] public readonly string SatellitePalette = "player";
|
||||
|
||||
[Desc("Custom palette is a player palette BaseName")]
|
||||
public readonly bool SatellitePaletteIsPlayerPalette = true;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new GpsPower(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -226,6 +226,66 @@ Container@MENU_BACKGROUND:
|
||||
Text: Back
|
||||
Font: Bold
|
||||
Key: escape
|
||||
Container@SYSTEM_INFO_PROMPT:
|
||||
X: (WINDOW_RIGHT - WIDTH)/2
|
||||
Y: (WINDOW_BOTTOM - HEIGHT)/2
|
||||
Width: 490
|
||||
Height: 222
|
||||
Children:
|
||||
Label@TITLE:
|
||||
Width: PARENT_RIGHT
|
||||
Y: 0-25
|
||||
Font: BigBold
|
||||
Contrast: true
|
||||
Align: Center
|
||||
Text: System Information
|
||||
Background@bg:
|
||||
Width: PARENT_RIGHT
|
||||
Height: PARENT_BOTTOM
|
||||
Background: panel-black
|
||||
Children:
|
||||
Label@PROMPT_TEXT_A:
|
||||
X: 15
|
||||
Y: 15
|
||||
Width: PARENT_RIGHT - 30
|
||||
Height: 16
|
||||
Align: Center
|
||||
Text: We would like to collect some details that will help us optimize OpenRA.
|
||||
Label@PROMPT_TEXT_B:
|
||||
X: 15
|
||||
Y: 33
|
||||
Width: PARENT_RIGHT - 30
|
||||
Height: 16
|
||||
Align: Center
|
||||
Text: With your permission, the following anonymous system data will be sent:
|
||||
ScrollPanel@SYSINFO_DATA:
|
||||
X: 15
|
||||
Y: 63
|
||||
Width: PARENT_RIGHT - 30
|
||||
TopBottomSpacing: 4
|
||||
ItemSpacing: 4
|
||||
Height: 110
|
||||
Children:
|
||||
Label@DATA_TEMPLATE:
|
||||
X: 8
|
||||
Height: 13
|
||||
VAlign: Top
|
||||
Font: Small
|
||||
Checkbox@SYSINFO_CHECKBOX:
|
||||
X: PARENT_RIGHT - 15 - WIDTH
|
||||
Y: PARENT_BOTTOM - 35
|
||||
Width: 190
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Send System Information
|
||||
Button@BACK_BUTTON:
|
||||
X: PARENT_RIGHT - WIDTH
|
||||
Y: PARENT_BOTTOM - 1
|
||||
Width: 140
|
||||
Height: 35
|
||||
Text: Continue
|
||||
Font: Bold
|
||||
Key: return
|
||||
Container@NEWS_BG:
|
||||
Children:
|
||||
DropDownButton@NEWS_BUTTON:
|
||||
|
||||
@@ -23,7 +23,7 @@ World:
|
||||
Red: 0.75
|
||||
Green: 0.85
|
||||
Blue: 1.5
|
||||
Ambient: 0.35
|
||||
Ambient: 0.45
|
||||
MissionData:
|
||||
Briefing: Use a GDI Commando to infiltrate the Nod base. **** ** destroy the ******** so that the base is incapacitated. Get in, hit it, and get the **** out.
|
||||
BriefingVideo: gdi6.vqa
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -25,7 +25,7 @@ Player:
|
||||
hpad: 0
|
||||
eye: 1
|
||||
tmpl: 1
|
||||
fix: 0
|
||||
fix: 1
|
||||
silo: 1
|
||||
BuildingFractions:
|
||||
proc: 20%
|
||||
@@ -146,7 +146,7 @@ Player:
|
||||
hpad: 2
|
||||
eye: 1
|
||||
tmpl: 1
|
||||
fix: 0
|
||||
fix: 1
|
||||
silo: 1
|
||||
BuildingFractions:
|
||||
proc: 17%
|
||||
@@ -267,7 +267,7 @@ Player:
|
||||
hpad: 2
|
||||
eye: 1
|
||||
tmpl: 1
|
||||
fix: 0
|
||||
fix: 1
|
||||
silo: 1
|
||||
BuildingFractions:
|
||||
proc: 17%
|
||||
|
||||
@@ -48,6 +48,11 @@
|
||||
GenericVisibility: Enemy, Neutral
|
||||
ShowOwnerRow: false
|
||||
|
||||
^TechBuilding:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
ShowOwnerRow: false
|
||||
|
||||
^CommonHuskDefaults:
|
||||
Tooltip:
|
||||
GenericVisibility: Enemy, Ally, Neutral
|
||||
@@ -57,3 +62,29 @@
|
||||
^DINO:
|
||||
Tooltip:
|
||||
ShowOwnerRow: false
|
||||
|
||||
MISS:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
ShowOwnerRow: False
|
||||
|
||||
ARCO:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
ShowOwnerRow: False
|
||||
|
||||
ARCO.Husk:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
|
||||
V19.Husk:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
|
||||
HOSP.Husk:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
|
||||
BIO.Husk:
|
||||
Tooltip:
|
||||
GenericVisibility: None
|
||||
|
||||
@@ -337,6 +337,7 @@ ARCO:
|
||||
Actor: ARCO.Husk
|
||||
Tooltip:
|
||||
Name: Oil Pump
|
||||
ShowOwnerRow: True
|
||||
|
||||
ARCO.Husk:
|
||||
Inherits: ^CivBuildingHusk
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
SelfHealing@ELITE:
|
||||
Step: 2
|
||||
Delay: 100
|
||||
HealIfBelow: 1
|
||||
HealIfBelow: 100
|
||||
DamageCooldown: 125
|
||||
UpgradeTypes: selfheal
|
||||
UpgradeMinEnabledLevel: 1
|
||||
@@ -234,7 +234,7 @@
|
||||
SelfHealing@HOSPITAL:
|
||||
Step: 5
|
||||
Delay: 100
|
||||
HealIfBelow: 1
|
||||
HealIfBelow: 100
|
||||
DamageCooldown: 125
|
||||
UpgradeTypes: hospitalheal
|
||||
UpgradeMinEnabledLevel: 1
|
||||
@@ -518,7 +518,6 @@
|
||||
GenericStancePrefix: false
|
||||
ShowOwnerRow: false
|
||||
FrozenUnderFog:
|
||||
StartsRevealed: true
|
||||
|
||||
^CivBuildingHusk:
|
||||
Inherits@1: ^SpriteActor
|
||||
@@ -532,7 +531,6 @@
|
||||
GenericStancePrefix: false
|
||||
ShowOwnerRow: false
|
||||
FrozenUnderFog:
|
||||
StartsRevealed: true
|
||||
ScriptTriggers:
|
||||
|
||||
^TechBuilding:
|
||||
@@ -546,6 +544,8 @@
|
||||
EngineerRepairable:
|
||||
RevealsShroud:
|
||||
Range: 3c0
|
||||
Tooltip:
|
||||
ShowOwnerRow: True
|
||||
|
||||
^CivField:
|
||||
Inherits: ^CivBuilding
|
||||
@@ -567,11 +567,11 @@
|
||||
Tooltip:
|
||||
Name: Field (Destroyed)
|
||||
GenericVisibility: None
|
||||
ShowOwnerRow: false
|
||||
RenderSprites:
|
||||
Palette: terrain
|
||||
WithSpriteBody:
|
||||
FrozenUnderFog:
|
||||
StartsRevealed: true
|
||||
ScriptTriggers:
|
||||
|
||||
^Wall:
|
||||
@@ -614,6 +614,7 @@
|
||||
Inherits@1: ^SpriteActor
|
||||
Tooltip:
|
||||
Name: Tree
|
||||
ShowOwnerRow: false
|
||||
RenderSprites:
|
||||
Palette: staticterrain
|
||||
WithSpriteBody:
|
||||
@@ -635,6 +636,7 @@
|
||||
Inherits@1: ^SpriteActor
|
||||
Tooltip:
|
||||
Name: Blossom Tree
|
||||
ShowOwnerRow: false
|
||||
RenderSprites:
|
||||
Palette: staticterrain
|
||||
WithSpriteBody:
|
||||
@@ -651,6 +653,7 @@
|
||||
Inherits@1: ^SpriteActor
|
||||
Tooltip:
|
||||
Name: Rock
|
||||
ShowOwnerRow: false
|
||||
RenderSprites:
|
||||
Palette: staticterrain
|
||||
WithSpriteBody:
|
||||
@@ -720,6 +723,7 @@
|
||||
AlwaysVisible:
|
||||
Tooltip:
|
||||
Name: Bridge
|
||||
ShowOwnerRow: false
|
||||
Targetable:
|
||||
RequiresForceFire: yes
|
||||
TargetTypes: Ground, Water
|
||||
@@ -736,6 +740,7 @@
|
||||
Tooltip:
|
||||
Name: Crate
|
||||
GenericName: Crate
|
||||
ShowOwnerRow: false
|
||||
Crate:
|
||||
TerrainTypes: Clear, Rough, Road, Tiberium, BlueTiberium, Beach
|
||||
RenderSprites:
|
||||
|
||||
@@ -148,8 +148,6 @@ E6:
|
||||
CaptureTypes: building, husk
|
||||
-AutoTarget:
|
||||
-GainsExperience:
|
||||
Selectable:
|
||||
Priority: 5
|
||||
|
||||
RMBO:
|
||||
Inherits: ^Soldier
|
||||
|
||||
@@ -190,6 +190,61 @@ Container@MAINMENU:
|
||||
Height: 30
|
||||
Text: Back
|
||||
Font: Bold
|
||||
Background@SYSTEM_INFO_PROMPT:
|
||||
X: (WINDOW_RIGHT - WIDTH)/2
|
||||
Y: (WINDOW_BOTTOM - HEIGHT)/2
|
||||
Width: 520
|
||||
Height: 260
|
||||
Children:
|
||||
Label@PROMPT_TITLE:
|
||||
Width: PARENT_RIGHT
|
||||
Y: 20
|
||||
Height: 25
|
||||
Font: Bold
|
||||
Align: Center
|
||||
Text: System Information
|
||||
Label@PROMPT_TEXT_A:
|
||||
X: 15
|
||||
Y: 50
|
||||
Width: PARENT_RIGHT - 30
|
||||
Height: 16
|
||||
Align: Center
|
||||
Text: We would like to collect some details that will help us optimize OpenRA.
|
||||
Label@PROMPT_TEXT_B:
|
||||
X: 15
|
||||
Y: 68
|
||||
Width: PARENT_RIGHT - 30
|
||||
Height: 16
|
||||
Align: Center
|
||||
Text: With your permission, the following anonymous system data will be sent:
|
||||
ScrollPanel@SYSINFO_DATA:
|
||||
X: 20
|
||||
Y: 98
|
||||
Width: PARENT_RIGHT - 40
|
||||
TopBottomSpacing: 4
|
||||
ItemSpacing: 4
|
||||
Height: 110
|
||||
Children:
|
||||
Label@DATA_TEMPLATE:
|
||||
X: 8
|
||||
Height: 13
|
||||
VAlign: Top
|
||||
Font: Small
|
||||
Checkbox@SYSINFO_CHECKBOX:
|
||||
X: 40
|
||||
Y: PARENT_BOTTOM - 42
|
||||
Width: 200
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Send System Information
|
||||
Button@BACK_BUTTON:
|
||||
X: PARENT_RIGHT - WIDTH - 20
|
||||
Y: PARENT_BOTTOM - 45
|
||||
Width: 120
|
||||
Height: 25
|
||||
Text: Continue
|
||||
Font: Bold
|
||||
Key: return
|
||||
Background@NEWS_BG:
|
||||
X: (WINDOW_RIGHT - WIDTH)/2
|
||||
Y: 35
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
SelfHealing@ELITE:
|
||||
Step: 2
|
||||
Delay: 125
|
||||
HealIfBelow: 1
|
||||
HealIfBelow: 100
|
||||
DamageCooldown: 125
|
||||
UpgradeTypes: selfheal
|
||||
UpgradeMinEnabledLevel: 1
|
||||
|
||||
@@ -47,8 +47,6 @@ engineer:
|
||||
-AutoTarget:
|
||||
Voiced:
|
||||
VoiceSet: EngineerVoice
|
||||
Selectable:
|
||||
Priority: 5
|
||||
|
||||
trooper:
|
||||
Inherits: ^Infantry
|
||||
|
||||
@@ -61,6 +61,7 @@ Player:
|
||||
AllyRepair:
|
||||
PlayerResources:
|
||||
SelectableCash: 2500, 5000, 7000, 10000, 20000
|
||||
InsufficientFundsNotification: InsufficientFunds
|
||||
ActorGroupProxy:
|
||||
DeveloperMode:
|
||||
BaseAttackNotifier:
|
||||
@@ -86,4 +87,3 @@ Player:
|
||||
GlobalUpgradeManager:
|
||||
ResourceStorageWarning:
|
||||
AdviceInterval: 26
|
||||
InsufficientFundsWarning:
|
||||
|
||||
@@ -652,9 +652,9 @@ wall:
|
||||
SellSounds: CHUNG.WAV
|
||||
Guardable:
|
||||
ThrowsShrapnel:
|
||||
Weapons: Debris, Debris2, Debris3, Debris4
|
||||
Pieces: 3, 7
|
||||
Range: 2c0, 5c0
|
||||
Weapons: Debris, Debris3
|
||||
Pieces: 2, 2
|
||||
Range: 2c0, 4c0
|
||||
|
||||
medium_gun_turret:
|
||||
Inherits: ^Defense
|
||||
|
||||
@@ -203,6 +203,61 @@ Container@MAINMENU:
|
||||
Height: 30
|
||||
Text: Back
|
||||
Font: Bold
|
||||
Background@SYSTEM_INFO_PROMPT:
|
||||
X: (WINDOW_RIGHT - WIDTH)/2
|
||||
Y: (WINDOW_BOTTOM - HEIGHT)/2
|
||||
Width: 520
|
||||
Height: 260
|
||||
Children:
|
||||
Label@PROMPT_TITLE:
|
||||
Width: PARENT_RIGHT
|
||||
Y: 20
|
||||
Height: 25
|
||||
Font: Bold
|
||||
Align: Center
|
||||
Text: System Information
|
||||
Label@PROMPT_TEXT_A:
|
||||
X: 15
|
||||
Y: 50
|
||||
Width: PARENT_RIGHT - 30
|
||||
Height: 16
|
||||
Align: Center
|
||||
Text: We would like to collect some details that will help us optimize OpenRA.
|
||||
Label@PROMPT_TEXT_B:
|
||||
X: 15
|
||||
Y: 68
|
||||
Width: PARENT_RIGHT - 30
|
||||
Height: 16
|
||||
Align: Center
|
||||
Text: With your permission, the following anonymous system data will be sent:
|
||||
ScrollPanel@SYSINFO_DATA:
|
||||
X: 20
|
||||
Y: 98
|
||||
Width: PARENT_RIGHT - 40
|
||||
TopBottomSpacing: 4
|
||||
ItemSpacing: 4
|
||||
Height: 110
|
||||
Children:
|
||||
Label@DATA_TEMPLATE:
|
||||
X: 8
|
||||
Height: 13
|
||||
VAlign: Top
|
||||
Font: Small
|
||||
Checkbox@SYSINFO_CHECKBOX:
|
||||
X: 40
|
||||
Y: PARENT_BOTTOM - 42
|
||||
Width: 200
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Send System Information
|
||||
Button@BACK_BUTTON:
|
||||
X: PARENT_RIGHT - WIDTH - 20
|
||||
Y: PARENT_BOTTOM - 45
|
||||
Width: 120
|
||||
Height: 25
|
||||
Text: Continue
|
||||
Font: Bold
|
||||
Key: return
|
||||
Container@PERFORMANCE_INFO:
|
||||
Logic: PerfDebugLogic
|
||||
Children:
|
||||
|
||||
Binary file not shown.
@@ -190,6 +190,8 @@ DOG:
|
||||
|
||||
TRUK:
|
||||
-Demolishable:
|
||||
Targetable:
|
||||
TargetTypes: Ground, Truk
|
||||
Armor:
|
||||
Type: Truk
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
Colt45:
|
||||
ValidTargets: Ground, Infantry, Truk
|
||||
Warhead@1Dam: SpreadDamage
|
||||
ValidTargets: Barrel, Infantry, Truk
|
||||
Versus:
|
||||
Truk: 50
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,7 @@ Players:
|
||||
Name: Creeps
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
Enemies: Creeps
|
||||
Enemies: Multi0, Multi1, Multi2, Multi3, Multi4, Multi5, Multi6, Multi7
|
||||
PlayerReference@Multi0:
|
||||
Name: Multi0
|
||||
Playable: True
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 921 B |
@@ -1,211 +0,0 @@
|
||||
MapFormat: 11
|
||||
|
||||
RequiresMod: ra
|
||||
|
||||
Title: Burlesca
|
||||
|
||||
Author: s1w
|
||||
|
||||
Tileset: TEMPERAT
|
||||
|
||||
MapSize: 64,64
|
||||
|
||||
Bounds: 4,4,56,56
|
||||
|
||||
Visibility: Lobby
|
||||
|
||||
Categories: Conquest
|
||||
|
||||
Players:
|
||||
PlayerReference@Neutral:
|
||||
Name: Neutral
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
PlayerReference@Multi0:
|
||||
Name: Multi0
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
Faction: Random
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi1:
|
||||
Name: Multi1
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
Faction: Random
|
||||
Enemies: Creeps
|
||||
PlayerReference@Creeps:
|
||||
Name: Creeps
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
Enemies: Multi0, Multi1
|
||||
|
||||
Actors:
|
||||
Actor2: mpspawn
|
||||
Location: 13,25
|
||||
Owner: Neutral
|
||||
Actor17: tc05
|
||||
Location: 32,52
|
||||
Owner: Neutral
|
||||
Actor23: tc03
|
||||
Location: 33,51
|
||||
Owner: Neutral
|
||||
Actor24: t08
|
||||
Location: 32,55
|
||||
Owner: Neutral
|
||||
Actor3: brl3
|
||||
Location: 28,33
|
||||
Owner: Neutral
|
||||
Actor4: brl3
|
||||
Location: 23,39
|
||||
Owner: Neutral
|
||||
Actor6: brl3
|
||||
Location: 38,27
|
||||
Owner: Neutral
|
||||
Actor0: brl3
|
||||
Location: 33,33
|
||||
Owner: Neutral
|
||||
Actor5: mpspawn
|
||||
Location: 50,38
|
||||
Owner: Neutral
|
||||
Actor1: t02
|
||||
Location: 23,41
|
||||
Owner: Neutral
|
||||
Actor7: v15
|
||||
Location: 6,30
|
||||
Owner: Neutral
|
||||
Actor8: v16
|
||||
Location: 6,31
|
||||
Owner: Neutral
|
||||
Actor14: tc04
|
||||
Location: 30,8
|
||||
Owner: Neutral
|
||||
Actor13: t12
|
||||
Location: 33,7
|
||||
Owner: Neutral
|
||||
Actor12: tc03
|
||||
Location: 44,4
|
||||
Owner: Neutral
|
||||
Actor11: tc02
|
||||
Location: 40,4
|
||||
Owner: Neutral
|
||||
Actor9: v16
|
||||
Location: 57,38
|
||||
Owner: Neutral
|
||||
Actor10: rice
|
||||
Location: 58,38
|
||||
Owner: Neutral
|
||||
Actor15: tc05
|
||||
Location: 57,4
|
||||
Owner: Neutral
|
||||
Actor16: t01
|
||||
Location: 59,7
|
||||
Owner: Neutral
|
||||
Actor18: t16
|
||||
Location: 55,3
|
||||
Owner: Neutral
|
||||
Actor19: t03
|
||||
Location: 56,20
|
||||
Owner: Neutral
|
||||
Actor20: tc04
|
||||
Location: 46,25
|
||||
Owner: Neutral
|
||||
Actor21: t07
|
||||
Location: 52,24
|
||||
Owner: Neutral
|
||||
Actor22: tc04
|
||||
Location: 9,38
|
||||
Owner: Neutral
|
||||
Actor25: tc01
|
||||
Location: 13,37
|
||||
Owner: Neutral
|
||||
Actor26: tc03
|
||||
Location: 16,15
|
||||
Owner: Neutral
|
||||
Actor27: tc03
|
||||
Location: 58,39
|
||||
Owner: Neutral
|
||||
Actor28: t06
|
||||
Location: 4,22
|
||||
Owner: Neutral
|
||||
Actor29: t10
|
||||
Location: 39,15
|
||||
Owner: Neutral
|
||||
Actor30: t15
|
||||
Location: 15,48
|
||||
Owner: Neutral
|
||||
Actor31: tc04
|
||||
Location: 4,57
|
||||
Owner: Neutral
|
||||
Actor32: t01
|
||||
Location: 7,58
|
||||
Owner: Neutral
|
||||
Actor33: t06
|
||||
Location: 4,55
|
||||
Owner: Neutral
|
||||
Actor34: t08
|
||||
Location: 7,53
|
||||
Owner: Neutral
|
||||
Actor35: t08
|
||||
Location: 19,41
|
||||
Owner: Neutral
|
||||
Actor36: t08
|
||||
Location: 56,4
|
||||
Owner: Neutral
|
||||
Actor37: t08
|
||||
Location: 59,51
|
||||
Owner: Neutral
|
||||
Actor39: tc01
|
||||
Location: 21,58
|
||||
Owner: Neutral
|
||||
Actor50: mine
|
||||
Location: 30,53
|
||||
Owner: Neutral
|
||||
Actor40: t12
|
||||
Location: 46,49
|
||||
Owner: Neutral
|
||||
Actor41: t17
|
||||
Location: 4,12
|
||||
Owner: Neutral
|
||||
Actor42: t12
|
||||
Location: 19,10
|
||||
Owner: Neutral
|
||||
Actor43: t08
|
||||
Location: 57,35
|
||||
Owner: Neutral
|
||||
Actor44: tc01
|
||||
Location: 56,28
|
||||
Owner: Neutral
|
||||
Actor45: t08
|
||||
Location: 51,8
|
||||
Owner: Neutral
|
||||
Actor46: tc04
|
||||
Location: 4,26
|
||||
Owner: Neutral
|
||||
Actor47: tc01
|
||||
Location: 42,43
|
||||
Owner: Neutral
|
||||
Actor48: t08
|
||||
Location: 27,44
|
||||
Owner: Neutral
|
||||
Actor49: tc03
|
||||
Location: 43,42
|
||||
Owner: Neutral
|
||||
Actor38: mine
|
||||
Location: 28,57
|
||||
Owner: Neutral
|
||||
Actor51: mine
|
||||
Location: 37,6
|
||||
Owner: Neutral
|
||||
Actor52: mine
|
||||
Location: 34,10
|
||||
Owner: Neutral
|
||||
Actor53: t07
|
||||
Location: 25,57
|
||||
Owner: Neutral
|
||||
Actor55: mine
|
||||
Location: 57,43
|
||||
Owner: Neutral
|
||||
Actor54: mine
|
||||
Location: 6,19
|
||||
Owner: Neutral
|
||||
BIN
mods/ra/maps/caffeinated.oramap
Normal file
BIN
mods/ra/maps/caffeinated.oramap
Normal file
Binary file not shown.
Binary file not shown.
BIN
mods/ra/maps/cold-front-1v1.oramap
Normal file
BIN
mods/ra/maps/cold-front-1v1.oramap
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -22,66 +22,54 @@ Players:
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
PlayerReference@Creeps:
|
||||
Name: Creeps
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
PlayerReference@Multi0:
|
||||
Name: Multi0
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi1:
|
||||
Name: Multi1
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi2:
|
||||
Name: Multi2
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi3:
|
||||
Name: Multi3
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi4:
|
||||
Name: Multi4
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi5:
|
||||
Name: Multi5
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi6:
|
||||
Name: Multi6
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi7:
|
||||
Name: Multi7
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
|
||||
Actors:
|
||||
Actor0: apc
|
||||
|
||||
@@ -22,66 +22,54 @@ Players:
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
PlayerReference@Creeps:
|
||||
Name: Creeps
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
PlayerReference@Multi0:
|
||||
Name: Multi0
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi1:
|
||||
Name: Multi1
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi2:
|
||||
Name: Multi2
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi3:
|
||||
Name: Multi3
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi4:
|
||||
Name: Multi4
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi5:
|
||||
Name: Multi5
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi6:
|
||||
Name: Multi6
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi7:
|
||||
Name: Multi7
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: soviet
|
||||
Enemies: Creeps
|
||||
|
||||
Actors:
|
||||
Actor0: apc
|
||||
|
||||
Binary file not shown.
@@ -21,7 +21,7 @@ World:
|
||||
Red: 0.75
|
||||
Green: 0.85
|
||||
Blue: 1.5
|
||||
Ambient: 0.35
|
||||
Ambient: 0.45
|
||||
MusicPlaylist:
|
||||
BackgroundMusic: rain
|
||||
FlashPaletteEffect@LIGHTNINGSTRIKE:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
mods/ra/maps/northwestpassage.oramap
Normal file
BIN
mods/ra/maps/northwestpassage.oramap
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user