Track LocalMods as part of monolith
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
|
||||
using Barotrauma;
|
||||
using MoreLevelContent.Shared.Data;
|
||||
using MoreLevelContent.Shared.Generation;
|
||||
using MoreLevelContent.Shared.XML;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Changes what map feature the current level has.
|
||||
/// </summary>
|
||||
[InjectScriptedEvent]
|
||||
internal class AlterMapFeatureAction : EventAction
|
||||
{
|
||||
[Serialize("", IsPropertySaveable.Yes, description: "The Identifier this levels map feature should change to.")]
|
||||
public Identifier MapFeatureIdentifier { get; set; }
|
||||
|
||||
public AlterMapFeatureAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
|
||||
{
|
||||
if (MapFeatureIdentifier.IsEmpty)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in event \"{parentEvent.Prefab.Identifier}\": MapFeatureIdentifier has not been configured.",
|
||||
contentPackage: element.ContentPackage);
|
||||
}
|
||||
}
|
||||
|
||||
private bool isFinished = false;
|
||||
public override bool IsFinished(ref string goToLabel)
|
||||
{
|
||||
return isFinished;
|
||||
}
|
||||
public override void Reset()
|
||||
{
|
||||
isFinished = false;
|
||||
}
|
||||
|
||||
// This is going to break people mid-joining
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (isFinished) { return; }
|
||||
if (MapFeatureModule.TryGetFeature(MapFeatureIdentifier, out var feature))
|
||||
{
|
||||
var data = Level.Loaded?.LevelData?.MLC();
|
||||
if (data != null)
|
||||
{
|
||||
data.MapFeatureData.Name = feature.Name;
|
||||
}
|
||||
}
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
public override string ToDebugString()
|
||||
{
|
||||
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(AlterMapFeatureAction)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
|
||||
using Barotrauma;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MoreLevelContent.Networking;
|
||||
using MoreLevelContent.Shared;
|
||||
using MoreLevelContent.Shared.Data;
|
||||
using MoreLevelContent.Shared.Generation;
|
||||
using MoreLevelContent.Shared.Utils;
|
||||
using MoreLevelContent.Shared.XML;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Remove the fog of war from a nearby area
|
||||
/// </summary>
|
||||
[InjectScriptedEvent]
|
||||
internal class RevealMapAreaAction : EventAction
|
||||
{
|
||||
private bool isFinished = false;
|
||||
private readonly Random random;
|
||||
|
||||
public RevealMapAreaAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
|
||||
{
|
||||
//the action chooses the same mission if
|
||||
// 1. event seed is the same (based on level seed, changes when events are completed)
|
||||
// 2. event is the same (two different events shouldn't choose the same mission)
|
||||
// 3. the MissionAction is the same (two different actions in the same event shouldn't choose the same mission)
|
||||
// Taken from MissionAction
|
||||
random = new MTRandom(
|
||||
parentEvent.RandomSeed +
|
||||
ToolBox.StringToInt(ParentEvent.Prefab.Identifier.Value) +
|
||||
ParentEvent.Actions.Count);
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
isFinished = true;
|
||||
if (GameMain.GameSession.GameMode is CampaignMode campaign)
|
||||
{
|
||||
Location loc = MLCUtils.FindUnlockLocation(new MLCUtils.FindLocationInfo()
|
||||
{
|
||||
MinDistance = 3,
|
||||
MustBeFurtherOnMap = true,
|
||||
MustBeHidden = true
|
||||
});
|
||||
|
||||
if (loc == null)
|
||||
{
|
||||
Log.Error("Failed to find a location to unlock");
|
||||
return;
|
||||
}
|
||||
|
||||
campaign.Map.Discover(loc, false);
|
||||
|
||||
// Probably have to do some syncing here, maybe not
|
||||
if (campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.IncrementLastUpdateIdForFlag(MultiPlayerCampaign.NetFlags.MapAndMissions);
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
ShowNotification(loc);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
public static void ShowNotification(Location loc)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is not CampaignMode campaign) return;
|
||||
_ = new GUIMessageBox(TextManager.Get("mapupdate.generic.header"), TextManager.GetWithVariable("mapupdate.revealed.location", "[location1]", loc.DisplayName),
|
||||
Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, iconStyle: "", relativeSize: new Vector2(0.2f, 0.06f), minSize: new Point(64, 74));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
public override bool IsFinished(ref string goToLabel) => isFinished;
|
||||
public override void Reset() => isFinished = false;
|
||||
public override string ToDebugString()
|
||||
{
|
||||
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(RevealMapFeatureAction)}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
using Barotrauma;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MoreLevelContent.Networking;
|
||||
using MoreLevelContent.Shared;
|
||||
using MoreLevelContent.Shared.Data;
|
||||
using MoreLevelContent.Shared.Generation;
|
||||
using MoreLevelContent.Shared.XML;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds and reveals a hidden map feature.
|
||||
/// </summary>
|
||||
[InjectScriptedEvent]
|
||||
internal class RevealMapFeatureAction : EventAction
|
||||
{
|
||||
[Serialize("", IsPropertySaveable.Yes, description: "The Identifier of the map feature to search for.")]
|
||||
public Identifier MapFeatureIdentifier { get; set; }
|
||||
|
||||
private bool isFinished = false;
|
||||
|
||||
|
||||
public RevealMapFeatureAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
|
||||
{
|
||||
if (MapFeatureIdentifier.IsEmpty)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in event \"{parentEvent.Prefab.Identifier}\": MapFeatureIdentifier has not been configured.",
|
||||
contentPackage: element.ContentPackage);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is CampaignMode campaign)
|
||||
{
|
||||
LocationConnection featureConnection;
|
||||
try
|
||||
{
|
||||
featureConnection = FindConnectionWithMapFeature(MapFeatureIdentifier);
|
||||
} catch(Exception e)
|
||||
{
|
||||
isFinished = true;
|
||||
Log.Error($"RevealMapFeatureAction crashed! {e.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (featureConnection != null)
|
||||
{
|
||||
MapFeatureModule.TryGetFeature(featureConnection.LevelData.MLC().MapFeatureData.Name, out MapFeature feature);
|
||||
|
||||
// Probably have to do some syncing here, maybe not
|
||||
if (campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.IncrementLastUpdateIdForFlag(MultiPlayerCampaign.NetFlags.MapAndMissions);
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
ShowNotification(feature, featureConnection);
|
||||
#else
|
||||
MapDirector.Instance.NotifyMapFeatureRevealed(featureConnection, featureConnection.LevelData.MLC().MapFeatureData);
|
||||
featureConnection.LevelData.MLC().MapFeatureData.Revealed = true;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
public static void ShowNotification(MapFeature feature, LocationConnection featureConnection)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is not CampaignMode campaign) return;
|
||||
_ = new GUIMessageBox(TextManager.GetWithVariable("mapfeature.revealed.header", "[feature]", feature.Display.DisplayName), TextManager.Get("mapfeature.revealed.description"),
|
||||
Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, iconStyle: feature.Display.Icon, relativeSize: new Vector2(0.2f, 0.06f), minSize: new Point(64, 74));
|
||||
featureConnection.LevelData.MLC().MapFeatureData.Revealed = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
private LocationConnection FindConnectionWithMapFeature(Identifier name)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is not CampaignMode campaign) return null;
|
||||
|
||||
LocationConnection currentConnection;
|
||||
if (Level.Loaded.Type == LevelData.LevelType.LocationConnection)
|
||||
{
|
||||
var start = Level.Loaded.StartLocation;
|
||||
var end = Level.Loaded.EndLocation;
|
||||
currentConnection = start.Connections.Where(c => c.OtherLocation(start) == end).FirstOrDefault();
|
||||
} else
|
||||
{
|
||||
currentConnection = campaign.CurrentLocation.Connections.FirstOrDefault();
|
||||
}
|
||||
|
||||
HashSet<LocationConnection> checkedConnections = new HashSet<LocationConnection>();
|
||||
HashSet<LocationConnection> pendingConnections = new HashSet<LocationConnection>() { currentConnection };
|
||||
|
||||
do
|
||||
{
|
||||
List<LocationConnection> currentConnections = pendingConnections.ToList();
|
||||
pendingConnections.Clear();
|
||||
foreach (var connection in currentConnections)
|
||||
{
|
||||
checkedConnections.Add(connection);
|
||||
var data = connection.LevelData.MLC();
|
||||
if (data == null)
|
||||
{
|
||||
Log.Error("Missing data");
|
||||
continue;
|
||||
}
|
||||
MapFeatureData feature = data.MapFeatureData;
|
||||
if (feature.Name == name && !feature.Revealed)
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Location location in connection.Locations)
|
||||
{
|
||||
foreach (var item in location.Connections)
|
||||
{
|
||||
if (checkedConnections.Contains(item)) { continue; }
|
||||
pendingConnections.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} while (pendingConnections.Any());
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool IsFinished(ref string goToLabel) => isFinished;
|
||||
public override void Reset() => isFinished = false;
|
||||
public override string ToDebugString()
|
||||
{
|
||||
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(RevealMapFeatureAction)} -> ({(MapFeatureIdentifier)})";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
133
LocalMods/More Level Content/CSharp/Shared/ScriptedEvents/RevealPirateBase.cs
Executable file
133
LocalMods/More Level Content/CSharp/Shared/ScriptedEvents/RevealPirateBase.cs
Executable file
@@ -0,0 +1,133 @@
|
||||
|
||||
using Barotrauma;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MoreLevelContent.Shared;
|
||||
using MoreLevelContent.Shared.Data;
|
||||
using MoreLevelContent.Shared.Generation;
|
||||
using MoreLevelContent.Shared.Generation.Pirate;
|
||||
using MoreLevelContent.Shared.XML;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Changes what map feature the current level has.
|
||||
/// </summary>
|
||||
[InjectScriptedEvent]
|
||||
internal class RevealPirateBaseAction //: BinaryOptionAction
|
||||
{
|
||||
/*
|
||||
public RevealPirateBaseAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element) { }
|
||||
|
||||
private LocationConnection FindPirateBase()
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is not CampaignMode campaign) return null;
|
||||
|
||||
LocationConnection startSearchConnection;
|
||||
if (Level.Loaded.Type == LevelData.LevelType.LocationConnection)
|
||||
{
|
||||
var start = Level.Loaded.StartLocation;
|
||||
var end = Level.Loaded.EndLocation;
|
||||
startSearchConnection = start.Connections.Where(c => c.OtherLocation(start) == end).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
startSearchConnection = campaign.CurrentLocation.Connections.FirstOrDefault();
|
||||
}
|
||||
|
||||
HashSet<LocationConnection> checkedConnections = new HashSet<LocationConnection>();
|
||||
HashSet<LocationConnection> pendingConnections = new HashSet<LocationConnection>() { startSearchConnection };
|
||||
|
||||
do
|
||||
{
|
||||
List<LocationConnection> currentConnections = pendingConnections.ToList();
|
||||
pendingConnections.Clear();
|
||||
foreach (var connection in currentConnections)
|
||||
{
|
||||
checkedConnections.Add(connection);
|
||||
var data = connection.LevelData.MLC();
|
||||
if (data == null)
|
||||
{
|
||||
Log.Error("Missing data");
|
||||
continue;
|
||||
}
|
||||
var pirateData = data.PirateData;
|
||||
// Don't use the current connection, only look for active and not revealed bases
|
||||
if (startSearchConnection != connection && pirateData.Status == PirateOutpostStatus.Active && !pirateData.Revealed)
|
||||
{
|
||||
Log.Debug("Found connection with pirate base");
|
||||
return connection;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Location location in connection.Locations)
|
||||
{
|
||||
foreach (var item in location.Connections)
|
||||
{
|
||||
if (checkedConnections.Contains(item)) { continue; }
|
||||
pendingConnections.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} while (pendingConnections.Any());
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override bool? DetermineSuccess()
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is not CampaignMode campaign) return false;
|
||||
|
||||
try
|
||||
{
|
||||
LocationConnection connection = FindPirateBase();
|
||||
if (connection != null)
|
||||
{
|
||||
#if CLIENT
|
||||
ShowNotification(connection);
|
||||
#endif
|
||||
if (!Main.IsClient)
|
||||
{
|
||||
var data = connection.LevelData.MLC().PirateData;
|
||||
data.Revealed = true;
|
||||
|
||||
PirateOutpostDirector.UpdateStatus(data, connection);
|
||||
if (campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.IncrementLastUpdateIdForFlag(MultiPlayerCampaign.NetFlags.MapAndMissions);
|
||||
}
|
||||
Log.Debug("Updated status of pirate base to revealed");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Log.Error($"RevealMapFeatureAction crashed! {e.Message}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
public static void ShowNotification(LocationConnection connection)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is not CampaignMode) return;
|
||||
_ = new GUIMessageBox
|
||||
(TextManager.Get("mapupdate.generic.header"),
|
||||
RichString.Rich(TextManager.GetWithVariables("mapupdate.piratebase.revealed",
|
||||
("[location1]", $"‖color:gui.orange‖{connection.Locations[0].DisplayName}‖end‖"),
|
||||
("[location2]", $"‖color:gui.orange‖{connection.Locations[1].DisplayName}‖end‖"))),
|
||||
Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, iconStyle: "PirateBase", relativeSize: new Vector2(0.2f, 0.06f), minSize: new Point(64, 74));
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Barotrauma;
|
||||
using MoreLevelContent.Shared.XML;
|
||||
|
||||
namespace MoreLevelContent
|
||||
{
|
||||
[InjectScriptedEvent]
|
||||
internal class SpawnCreatureNearbyAction : EventAction
|
||||
{
|
||||
public SpawnCreatureNearbyAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsFinished(ref string goToLabel) => throw new System.NotImplementedException();
|
||||
public override void Reset() => throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using Barotrauma;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MoreLevelContent.Shared;
|
||||
using MoreLevelContent.Shared.XML;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static Barotrauma.Level;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
[InjectScriptedEvent]
|
||||
internal class TeleportCharacterAction : EventAction
|
||||
{
|
||||
[Serialize("", IsPropertySaveable.Yes, description: "Tag of the target(s) to teleport.")]
|
||||
public Identifier TargetTag { get; set; }
|
||||
|
||||
public TeleportCharacterAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
|
||||
{
|
||||
}
|
||||
|
||||
private bool isFinished;
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (isFinished) { return; }
|
||||
// Try to find a ruin to tp to
|
||||
Submarine wreck = null;
|
||||
Submarine ruin = null;
|
||||
foreach (var sub in Submarine.Loaded)
|
||||
{
|
||||
if (sub.Info.Type == SubmarineType.Ruin)
|
||||
{
|
||||
ruin = sub;
|
||||
break;
|
||||
}
|
||||
if (sub.Info.Type == SubmarineType.Wreck)
|
||||
{
|
||||
wreck = sub;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Tp();
|
||||
} catch { Teleport(Vector2.Zero); }
|
||||
isFinished = true;
|
||||
|
||||
void Tp()
|
||||
{
|
||||
if (ruin != null)
|
||||
{
|
||||
Teleport(ruin);
|
||||
return;
|
||||
}
|
||||
// If we can't find a ruin, try to find a wreck
|
||||
if (wreck != null)
|
||||
{
|
||||
Teleport(wreck);
|
||||
return;
|
||||
}
|
||||
// If both those fail, try to find an abyss cave
|
||||
if (Loaded != null && Loaded.TryGetInterestingPosition(false, PositionType.AbyssCave, Sonar.DefaultSonarRange, out InterestingPosition pos, suppressWarning: true))
|
||||
{
|
||||
Teleport(pos.Position.ToVector2());
|
||||
return;
|
||||
}
|
||||
// Try to find a cave, main path or side path position
|
||||
if (Loaded != null && Loaded.TryGetInterestingPosition(false, PositionType.Cave | PositionType.MainPath | PositionType.SidePath, Sonar.DefaultSonarRange, out InterestingPosition pos2, suppressWarning: true))
|
||||
{
|
||||
Teleport(pos2.Position.ToVector2());
|
||||
return;
|
||||
}
|
||||
// If all else fails, teleport to a random waypoint or 0,0
|
||||
Teleport(WayPoint.GetRandom(SpawnType.Path)?.WorldPosition ?? Vector2.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
void Teleport(Submarine target)
|
||||
{
|
||||
var wp = WayPoint.GetRandom(sub: target);
|
||||
Teleport(wp.WorldPosition);
|
||||
}
|
||||
|
||||
void Teleport(Vector2 worldPos)
|
||||
{
|
||||
foreach (var target in ParentEvent.GetTargets(TargetTag))
|
||||
{
|
||||
if (target is Character c)
|
||||
{
|
||||
c.TeleportTo(worldPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsFinished(ref string goToLabel)
|
||||
{
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
public override void Reset() { isFinished = false; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user