Support map-defined AI in the lobby.
This commit is contained in:
@@ -210,6 +210,9 @@ namespace OpenRA
|
||||
Status = MapStatus.Unavailable;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// If you're thinking about replacing this, then you must be careful to keep this safe.
|
||||
rules = Exts.Lazy(() =>
|
||||
{
|
||||
try
|
||||
|
||||
@@ -249,8 +249,6 @@ namespace OpenRA.Widgets
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
public static Action Once(Action a) { return () => { if (a != null) { a(); a = null; } }; }
|
||||
|
||||
public static string ChooseInitialMap(string initialUid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(initialUid) || Game.ModData.MapCache[initialUid].Status != MapStatus.Available)
|
||||
|
||||
@@ -65,6 +65,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly LabelWidget chatLabel;
|
||||
bool teamChat;
|
||||
|
||||
bool addBotOnMapLoad;
|
||||
|
||||
int lobbyChatUnreadMessages;
|
||||
int globalChatLastReadMessages;
|
||||
int globalChatUnreadMessages;
|
||||
@@ -201,9 +203,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
(orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
|
||||
orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0);
|
||||
|
||||
var botNames = modRules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name);
|
||||
slotsButton.OnMouseDown = _ =>
|
||||
{
|
||||
var botNames = Map.Rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name);
|
||||
var options = new Dictionary<string, IEnumerable<DropDownOption>>();
|
||||
|
||||
var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
|
||||
@@ -711,16 +713,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
// Add a bot on the first lobbyinfo update
|
||||
if (skirmishMode)
|
||||
{
|
||||
Game.LobbyInfoChanged += WidgetUtils.Once(() =>
|
||||
{
|
||||
var slot = orderManager.LobbyInfo.FirstEmptyBotSlot();
|
||||
var bot = modRules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name).FirstOrDefault();
|
||||
var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
|
||||
if (slot != null && bot != null)
|
||||
orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
|
||||
});
|
||||
}
|
||||
addBotOnMapLoad = true;
|
||||
}
|
||||
|
||||
public override void Tick()
|
||||
@@ -796,6 +789,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var currentMap = Map;
|
||||
new Task(() =>
|
||||
{
|
||||
// Force map rules to be loaded on this background thread
|
||||
var unused = currentMap.Rules;
|
||||
Game.RunAfterTick(() =>
|
||||
{
|
||||
@@ -806,6 +800,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
// Tell the server that we have the map
|
||||
if (!currentMap.InvalidCustomRules)
|
||||
orderManager.IssueOrder(Order.Command("state {0}".F(Session.ClientState.NotReady)));
|
||||
|
||||
if (addBotOnMapLoad)
|
||||
{
|
||||
var slot = orderManager.LobbyInfo.FirstEmptyBotSlot();
|
||||
var bot = currentMap.Rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name).FirstOrDefault();
|
||||
var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
|
||||
if (slot != null && bot != null)
|
||||
orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
|
||||
|
||||
addBotOnMapLoad = false;
|
||||
}
|
||||
});
|
||||
}).Start();
|
||||
}
|
||||
@@ -837,7 +842,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
template = emptySlotTemplate.Clone();
|
||||
|
||||
if (Game.IsHost)
|
||||
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager, modRules);
|
||||
LobbyUtils.SetupEditableSlotWidget(this, template, slot, client, orderManager);
|
||||
else
|
||||
LobbyUtils.SetupSlotWidget(template, slot, client);
|
||||
|
||||
@@ -856,7 +861,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
LobbyUtils.SetupClientWidget(template, client, orderManager, client.Bot == null);
|
||||
|
||||
if (client.Bot != null)
|
||||
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager, modRules);
|
||||
LobbyUtils.SetupEditableSlotWidget(this, template, slot, client, orderManager);
|
||||
else
|
||||
LobbyUtils.SetupEditableNameWidget(template, slot, client, orderManager);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowSlotDropDown(Ruleset rules, DropDownButtonWidget dropdown, Session.Slot slot,
|
||||
public static void ShowSlotDropDown(LobbyLogic logic, DropDownButtonWidget dropdown, Session.Slot slot,
|
||||
Session.Client client, OrderManager orderManager)
|
||||
{
|
||||
var options = new Dictionary<string, IEnumerable<SlotDropDownOption>>() { { "Slot", new List<SlotDropDownOption>()
|
||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var bots = new List<SlotDropDownOption>();
|
||||
if (slot.AllowBots)
|
||||
{
|
||||
foreach (var b in rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name))
|
||||
foreach (var b in logic.Map.Rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name))
|
||||
{
|
||||
var bot = b;
|
||||
var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
|
||||
@@ -303,13 +303,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
name.GetText = () => label;
|
||||
}
|
||||
|
||||
public static void SetupEditableSlotWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Ruleset rules)
|
||||
public static void SetupEditableSlotWidget(LobbyLogic logic, Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
|
||||
{
|
||||
var slot = parent.Get<DropDownButtonWidget>("SLOT_OPTIONS");
|
||||
slot.IsVisible = () => true;
|
||||
slot.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
slot.GetText = () => c != null ? c.Name : s.Closed ? "Closed" : "Open";
|
||||
slot.OnMouseDown = _ => ShowSlotDropDown(rules, slot, s, c, orderManager);
|
||||
slot.OnMouseDown = _ => ShowSlotDropDown(logic, slot, s, c, orderManager);
|
||||
|
||||
// Ensure Name selector (if present) is hidden
|
||||
var name = parent.GetOrNull("NAME");
|
||||
|
||||
Reference in New Issue
Block a user