Using GeneralPropBuilder for spawn points, vessel and warp exit points, and remotr dialogue triggers

This commit is contained in:
Joshua Thome 2023-03-18 09:17:36 -05:00
parent 88f60f883c
commit e021523151
29 changed files with 230 additions and 191 deletions

View File

@ -149,7 +149,7 @@ namespace NewHorizons.Builder.Body
rename = rename,
};
var singularity = GeneralPropBuilder.MakeNew(polarity ? "BlackHole" : "WhiteHole", planetGO, sector, info);
var singularity = GeneralPropBuilder.MakeNew(polarity ? "BlackHole" : "WhiteHole", sector?.transform ?? planetGO.transform, info);
var singularityRenderer = MakeSingularityGraphics(singularity, polarity, horizon, distort, renderQueue);

View File

@ -1,3 +1,4 @@
using NewHorizons.Builder.Props;
using NewHorizons.External.Modules;
using NewHorizons.Utility;
using System;
@ -12,36 +13,48 @@ namespace NewHorizons.Builder.General
public static SpawnPoint Make(GameObject planetGO, SpawnModule module, OWRigidbody owRigidBody)
{
SpawnPoint playerSpawn = null;
if (!Main.Instance.IsWarpingFromVessel && !Main.Instance.IsWarpingFromShip && module.playerSpawnPoint != null)
{
GameObject spawnGO = new GameObject("PlayerSpawnPoint");
spawnGO.transform.parent = planetGO.transform;
spawnGO.layer = 8;
spawnGO.transform.localPosition = module.playerSpawnPoint;
var playerSpawnInfo = module.playerSpawn;
var shipSpawnInfo = module.shipSpawn;
// Backwards compatibility
#pragma warning disable 612, 618
if (playerSpawnInfo == null && module.playerSpawnPoint != null)
{
playerSpawnInfo = new SpawnModule.PlayerSpawnPoint()
{
position = module.playerSpawnPoint,
rotation = module.playerSpawnRotation,
startWithSuit = module.startWithSuit,
};
}
if (shipSpawnInfo == null && module.shipSpawnPoint != null)
{
shipSpawnInfo = new SpawnModule.ShipSpawnPoint()
{
position = module.shipSpawnPoint,
rotation = module.shipSpawnRotation,
};
}
#pragma warning restore 612, 618
if (!Main.Instance.IsWarpingFromVessel && !Main.Instance.IsWarpingFromShip && playerSpawnInfo != null)
{
bool alignToBody = playerSpawnInfo.rotation == null;
GameObject spawnGO = GeneralPropBuilder.MakeNew("PlayerSpawnPoint", planetGO.transform, playerSpawnInfo, alignToBody);
spawnGO.layer = 8;
playerSpawn = spawnGO.AddComponent<SpawnPoint>();
playerSpawn._triggerVolumes = new OWTriggerVolume[0];
if (module.playerSpawnRotation != null)
{
spawnGO.transform.rotation = Quaternion.Euler(module.playerSpawnRotation);
}
else
{
spawnGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, (playerSpawn.transform.position - planetGO.transform.position).normalized);
}
spawnGO.transform.position = spawnGO.transform.position + spawnGO.transform.TransformDirection(Vector3.up) * 4f;
spawnGO.transform.position += spawnGO.transform.up * 4f;
}
if (module.shipSpawnPoint != null)
if (shipSpawnInfo != null)
{
GameObject spawnGO = new GameObject("ShipSpawnPoint");
spawnGO.transform.parent = planetGO.transform;
bool alignToBody = shipSpawnInfo.rotation == null;
GameObject spawnGO = GeneralPropBuilder.MakeNew("ShipSpawnPoint", planetGO.transform, shipSpawnInfo, alignToBody);
spawnGO.layer = 8;
spawnGO.transform.localPosition = module.shipSpawnPoint;
var spawnPoint = spawnGO.AddComponent<SpawnPoint>();
spawnPoint._isShipSpawn = true;
spawnPoint._triggerVolumes = new OWTriggerVolume[0];
@ -49,20 +62,13 @@ namespace NewHorizons.Builder.General
var ship = SearchUtilities.Find("Ship_Body");
if (ship != null)
{
ship.transform.position = spawnPoint.transform.position;
ship.transform.position = spawnGO.transform.position;
ship.transform.rotation = spawnGO.transform.rotation;
if (module.shipSpawnRotation != null)
// Move it up a bit more when aligning to surface
if (alignToBody)
{
spawnGO.transform.rotation = Quaternion.Euler(module.shipSpawnRotation);
ship.transform.rotation = spawnGO.transform.rotation;
}
else
{
spawnGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, (spawnPoint.transform.position - planetGO.transform.position).normalized);
ship.transform.rotation = spawnGO.transform.rotation;
// Move it up a bit more when aligning to surface
ship.transform.position = ship.transform.position + ship.transform.TransformDirection(Vector3.up) * 4f;
ship.transform.position += ship.transform.up * 4f;
}
ship.GetRequiredComponent<MatchInitialMotion>().SetBodyToMatch(owRigidBody);
@ -83,7 +89,7 @@ namespace NewHorizons.Builder.General
}
}
if ((Main.Instance.IsWarpingFromVessel || (!Main.Instance.IsWarpingFromShip && module.startWithSuit)) && !suitUpQueued)
if ((Main.Instance.IsWarpingFromVessel || (!Main.Instance.IsWarpingFromShip && (playerSpawnInfo?.startWithSuit ?? false))) && !suitUpQueued)
{
suitUpQueued = true;
Delay.RunWhen(() => Main.IsSystemReady, () => SuitUp());

View File

@ -182,7 +182,7 @@ namespace NewHorizons.Builder.Props
var prefab = config.isSeed ? _brambleSeedPrefab : _brambleNodePrefab;
// Spawn the bramble node
var brambleNode = GeneralPropBuilder.MakeFromPrefab(prefab, config.name ?? "Bramble Node to " + config.linksTo, go, sector, config);
var brambleNode = GeneralPropBuilder.MakeFromPrefab(prefab, config.name ?? "Bramble Node to " + config.linksTo, sector?.transform ?? go.transform, config);
foreach (var collider in brambleNode.GetComponentsInChildren<Collider>(true))
{
collider.enabled = true;

View File

@ -90,12 +90,12 @@ namespace NewHorizons.Builder.Props
// We save copies with all their components fixed, good if the user is placing the same detail more than once
if (detail?.path != null && _fixedPrefabCache.TryGetValue((sector, detail.path), out var storedPrefab))
{
prop = GeneralPropBuilder.MakeFromPrefab(storedPrefab.prefab, prefab.name, go, sector, detail, detail.alignToNormal);
prop = GeneralPropBuilder.MakeFromPrefab(storedPrefab.prefab, prefab.name, sector?.transform ?? go.transform, detail, detail.alignToNormal);
isItem = storedPrefab.isItem;
}
else
{
prop = GeneralPropBuilder.MakeFromPrefab(prefab, prefab.name, go, sector, detail, detail.alignToNormal);
prop = GeneralPropBuilder.MakeFromPrefab(prefab, prefab.name, sector?.transform ?? go.transform, detail, detail.alignToNormal);
StreamingHandler.SetUpStreaming(prop, sector);

View File

@ -22,36 +22,23 @@ namespace NewHorizons.Builder.Props
var dialogue = MakeConversationZone(go, sector, info, mod.ModHelper);
RemoteDialogueTrigger remoteTrigger = null;
if (info.remoteTriggerPosition != null || info.remoteTriggerRadius != 0)
if (info.remoteTrigger != null)
{
remoteTrigger = MakeRemoteDialogueTrigger(go, sector, info, dialogue);
remoteTrigger = MakeRemoteDialogueTrigger(go, sector, info, info.remoteTrigger, dialogue);
}
if (!string.IsNullOrEmpty(info.rename))
// Backwards compatibility
#pragma warning disable 612, 618
if (remoteTrigger == null && (info.remoteTriggerPosition != null || info.remoteTriggerRadius != 0))
{
dialogue.name = info.rename;
if (remoteTrigger != null)
var remoteInfo = new PropModule.DialogueInfo.RemoteTriggerInfo
{
remoteTrigger.name = $"{info.rename}_{remoteTrigger.name}";
}
}
if (!string.IsNullOrEmpty(info.parentPath))
{
var parent = go.transform.Find(info.parentPath);
if (parent != null)
{
dialogue.transform.parent = parent;
if (remoteTrigger != null)
{
remoteTrigger.transform.parent = parent;
}
}
else
{
Logger.LogError($"Cannot find parent object at path: {go.name}/{info.parentPath}");
}
position = info.remoteTriggerPosition,
radius = info.remoteTriggerRadius,
prereqCondition = info.remoteTriggerPrereqCondition,
};
remoteTrigger = MakeRemoteDialogueTrigger(go, sector, info, remoteInfo, dialogue);
}
#pragma warning restore 612, 618
// Make the character look at the player
// Useful for dialogue replacement
@ -64,10 +51,9 @@ namespace NewHorizons.Builder.Props
return (dialogue, remoteTrigger);
}
private static RemoteDialogueTrigger MakeRemoteDialogueTrigger(GameObject planetGO, Sector sector, PropModule.DialogueInfo info, CharacterDialogueTree dialogue)
private static RemoteDialogueTrigger MakeRemoteDialogueTrigger(GameObject planetGO, Sector sector, PropModule.DialogueInfo info, PropModule.DialogueInfo.RemoteTriggerInfo remoteTriggerInfo, CharacterDialogueTree dialogue)
{
var conversationTrigger = new GameObject("ConversationTrigger");
conversationTrigger.SetActive(false);
var conversationTrigger = GeneralPropBuilder.MakeNew("ConversationTrigger", sector?.transform ?? planetGO.transform, remoteTriggerInfo, defaultPosition: info.position, defaultParentPath: info.pathToAnimController);
var remoteDialogueTrigger = conversationTrigger.AddComponent<RemoteDialogueTrigger>();
var sphereCollider = conversationTrigger.AddComponent<SphereCollider>();
@ -81,7 +67,7 @@ namespace NewHorizons.Builder.Props
dialogue = dialogue,
prereqConditionType = RemoteDialogueTrigger.MultiConditionType.AND,
// Base game never uses more than one condition anyone so we'll keep it simple
prereqConditions = string.IsNullOrEmpty(info.remoteTriggerPrereqCondition) ? new string[]{ } : new string[] { info.remoteTriggerPrereqCondition },
prereqConditions = string.IsNullOrEmpty(remoteTriggerInfo.prereqCondition) ? new string[]{ } : new string[] { remoteTriggerInfo.prereqCondition },
// Just set your enter conditions in XML instead of complicating it with this
onTriggerEnterConditions = new string[]{ }
}
@ -89,10 +75,8 @@ namespace NewHorizons.Builder.Props
remoteDialogueTrigger._activatedDialogues = new bool[1];
remoteDialogueTrigger._deactivateTriggerPostConversation = true;
sphereCollider.radius = info.remoteTriggerRadius == 0 ? info.radius : info.remoteTriggerRadius;
sphereCollider.radius = remoteTriggerInfo.radius == 0 ? info.radius : remoteTriggerInfo.radius;
conversationTrigger.transform.parent = sector?.transform ?? planetGO.transform;
conversationTrigger.transform.position = planetGO.transform.TransformPoint(info.remoteTriggerPosition ?? info.position);
conversationTrigger.SetActive(true);
return remoteDialogueTrigger;
@ -100,8 +84,7 @@ namespace NewHorizons.Builder.Props
private static CharacterDialogueTree MakeConversationZone(GameObject planetGO, Sector sector, PropModule.DialogueInfo info, IModHelper mod)
{
var conversationZone = new GameObject("ConversationZone");
conversationZone.SetActive(false);
var conversationZone = GeneralPropBuilder.MakeNew("ConversationZone", sector?.transform ?? planetGO.transform, info, defaultParentPath: info.pathToAnimController);
conversationZone.layer = LayerMask.NameToLayer("Interactible");
@ -150,21 +133,6 @@ namespace NewHorizons.Builder.Props
break;
}
conversationZone.transform.parent = sector?.transform ?? planetGO.transform;
if (!string.IsNullOrEmpty(info.parentPath))
{
conversationZone.transform.parent = planetGO.transform.Find(info.parentPath);
}
else if (!string.IsNullOrEmpty(info.pathToAnimController))
{
conversationZone.transform.parent = planetGO.transform.Find(info.pathToAnimController);
}
var pos = (Vector3)(info.position ?? Vector3.zero);
if (info.isRelativeToParent) conversationZone.transform.localPosition = pos;
else conversationZone.transform.position = planetGO.transform.TransformPoint(pos);
conversationZone.SetActive(true);
return dialogueTree;

View File

@ -12,14 +12,28 @@ namespace NewHorizons.Builder.Props
{
public static class GeneralPropBuilder
{
public static GameObject MakeFromExisting(GameObject go, GameObject planetGO, Sector sector, PropModule.GeneralPointPropInfo info, bool alignToBody = false, MVector3 normal = null, MVector3 defaultPosition = null, string defaultParentPath = null)
public static GameObject MakeFromExisting(GameObject go, Transform parent, PropModule.GeneralPointPropInfo info, bool alignToBody = false, MVector3 normal = null, MVector3 defaultPosition = null, string defaultParentPath = null)
{
if (info == null) return go;
if (info is PropModule.GeneralSolarSystemPropInfo solarSystemInfo && !string.IsNullOrEmpty(solarSystemInfo.parentBody))
{
var targetPlanet = AstroObjectLocator.GetAstroObject(solarSystemInfo.parentBody);
if (targetPlanet != null)
{
parent = targetPlanet.transform;
} else
{
Logger.LogError($"Cannot find parent body named {solarSystemInfo.parentBody}");
}
}
if (!string.IsNullOrEmpty(info.rename))
{
go.name = info.rename;
}
go.transform.parent = sector?.transform ?? planetGO.transform;
go.transform.parent = parent;
var parentPath = info.parentPath ?? defaultParentPath;
@ -46,33 +60,37 @@ namespace NewHorizons.Builder.Props
{
go.transform.localPosition = pos;
go.transform.localRotation = rot;
} else if (parent)
{
go.transform.position = parent.TransformPoint(pos);
go.transform.rotation = parent.TransformRotation(rot);
} else
{
go.transform.position = planetGO.transform.TransformPoint(pos);
go.transform.rotation = planetGO.transform.TransformRotation(rot);
go.transform.position = pos;
go.transform.rotation = rot;
}
if (alignToBody)
{
var up = (go.transform.position - planetGO.transform.position).normalized;
if (normal != null) up = planetGO.transform.TransformDirection(normal);
var up = (go.transform.position - parent.position).normalized;
if (normal != null) up = parent.TransformDirection(normal);
go.transform.rotation = Quaternion.FromToRotation(Vector3.up, up);
go.transform.rotation *= rot;
}
return go;
}
public static GameObject MakeNew(string defaultName, GameObject planetGO, Sector sector, PropModule.GeneralPointPropInfo info, bool alignToBody = false, MVector3 normal = null, MVector3 defaultPosition = null, string defaultParentPath = null)
public static GameObject MakeNew(string defaultName, Transform parent, PropModule.GeneralPointPropInfo info, bool alignToBody = false, MVector3 normal = null, MVector3 defaultPosition = null, string defaultParentPath = null)
{
var go = new GameObject(defaultName);
go.SetActive(false);
return MakeFromExisting(go, planetGO, sector, info, alignToBody, normal, defaultPosition, defaultParentPath);
return MakeFromExisting(go, parent, info, alignToBody, normal, defaultPosition, defaultParentPath);
}
public static GameObject MakeFromPrefab(GameObject prefab, string defaultName, GameObject planetGO, Sector sector, PropModule.GeneralPointPropInfo info, bool alignToBody = false, MVector3 normal = null, MVector3 defaultPosition = null, string defaultParentPath = null)
public static GameObject MakeFromPrefab(GameObject prefab, string defaultName, Transform parent, PropModule.GeneralPointPropInfo info, bool alignToBody = false, MVector3 normal = null, MVector3 defaultPosition = null, string defaultParentPath = null)
{
var go = prefab.InstantiateInactive();
go.name = defaultName;
return MakeFromExisting(go, planetGO, sector, info, alignToBody, normal, defaultPosition, defaultParentPath);
return MakeFromExisting(go, parent, info, alignToBody, normal, defaultPosition, defaultParentPath);
}
}
}

View File

@ -18,7 +18,7 @@ namespace NewHorizons.Builder.Props
{
InitPrefab();
var geyserGO = GeneralPropBuilder.MakeFromPrefab(_geyserPrefab, "Geyser", planetGO, sector, info, true);
var geyserGO = GeneralPropBuilder.MakeFromPrefab(_geyserPrefab, "Geyser", sector?.transform ?? planetGO.transform, info, true);
var pos = info.isRelativeToParent ? geyserGO.transform.parent.TransformPoint((Vector3)info.position) : (Vector3)info.position;

View File

@ -93,7 +93,7 @@ namespace NewHorizons.Builder.Props
if (_slideReelPrefab == null) return null;
var slideReelObj = GeneralPropBuilder.MakeFromPrefab(_slideReelPrefab, $"Prefab_IP_Reel_{mod.ModHelper.Manifest.Name}", planetGO, sector, info);
var slideReelObj = GeneralPropBuilder.MakeFromPrefab(_slideReelPrefab, $"Prefab_IP_Reel_{mod.ModHelper.Manifest.Name}", sector?.transform ?? planetGO.transform, info);
var slideReel = slideReelObj.GetComponent<SlideReelItem>();
slideReel.SetSector(sector);
@ -166,7 +166,7 @@ namespace NewHorizons.Builder.Props
if (_autoPrefab == null) return null;
var projectorObj = GeneralPropBuilder.MakeFromPrefab(_autoPrefab, $"Prefab_IP_AutoProjector_{mod.ModHelper.Manifest.Name}", planetGO, sector, info);
var projectorObj = GeneralPropBuilder.MakeFromPrefab(_autoPrefab, $"Prefab_IP_AutoProjector_{mod.ModHelper.Manifest.Name}", sector?.transform ?? planetGO.transform, info);
var autoProjector = projectorObj.GetComponent<AutoSlideProjector>();
autoProjector._sector = sector;

View File

@ -50,7 +50,7 @@ namespace NewHorizons.Builder.Props
{
var socketInfo = quantumGroup.sockets[i];
var socket = GeneralPropBuilder.MakeNew("Socket " + i, go, sector, socketInfo);
var socket = GeneralPropBuilder.MakeNew("Socket " + i, sector?.transform ?? go.transform, socketInfo);
if (socketInfo.isRelativeToGroup)
{

View File

@ -52,7 +52,7 @@ namespace NewHorizons.Builder.Props
if (_prefab == null || sector == null) return null;
GameObject raftObject = GeneralPropBuilder.MakeFromPrefab(_prefab, "Raft_Body", planetGO, sector, info);
GameObject raftObject = GeneralPropBuilder.MakeFromPrefab(_prefab, "Raft_Body", sector?.transform ?? planetGO.transform, info);
StreamingHandler.SetUpStreaming(raftObject, sector);

View File

@ -251,7 +251,7 @@ namespace NewHorizons.Builder.Props
public static void MakeStone(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.StoneInfo info, IModBehaviour mod)
{
var shareStone = GeneralPropBuilder.MakeFromPrefab(_shareStonePrefab, "ShareStone_" + id.ToString(), go, sector, info);
var shareStone = GeneralPropBuilder.MakeFromPrefab(_shareStonePrefab, "ShareStone_" + id.ToString(), sector?.transform ?? go.transform, info);
shareStone.GetComponent<SharedStone>()._connectedPlatform = id;

View File

@ -109,7 +109,7 @@ namespace NewHorizons.Builder.Props
public static GameObject Make(GameObject planetGO, Sector sector, SignalModule.SignalInfo info, IModBehaviour mod)
{
var signalGO = GeneralPropBuilder.MakeNew($"Signal_{info.name}", planetGO, sector, info);
var signalGO = GeneralPropBuilder.MakeNew($"Signal_{info.name}", sector?.transform ?? planetGO.transform, info);
signalGO.layer = LayerMask.NameToLayer("AdvancedEffectVolume");
var source = signalGO.AddComponent<AudioSource>();

View File

@ -99,7 +99,7 @@ namespace NewHorizons.Builder.Props
private static void MakeTornado(GameObject planetGO, Sector sector, PropModule.TornadoInfo info, Vector3 position, bool downwards)
{
var prefab = downwards ? _downPrefab.InstantiateInactive() : _upPrefab.InstantiateInactive();
var tornadoGO = GeneralPropBuilder.MakeFromPrefab(prefab, downwards ? "Tornado_Down" : "Tornado_Up", planetGO, sector, info, true, defaultPosition: position);
var tornadoGO = GeneralPropBuilder.MakeFromPrefab(prefab, downwards ? "Tornado_Down" : "Tornado_Up", sector?.transform ?? planetGO.transform, info, true, defaultPosition: position);
// Add the sound thing before changing the scale
var soundGO = _soundPrefab.InstantiateInactive();

View File

@ -161,7 +161,7 @@ namespace NewHorizons.Builder.Props
}
case PropModule.NomaiTextInfo.NomaiTextType.Scroll:
{
var customScroll = GeneralPropBuilder.MakeFromPrefab(_scrollPrefab, _scrollPrefab.name, planetGO, sector, info);
var customScroll = GeneralPropBuilder.MakeFromPrefab(_scrollPrefab, _scrollPrefab.name, sector?.transform ?? planetGO.transform, info);
var nomaiWallText = MakeWallText(planetGO, sector, info, xmlPath, nhBody);
nomaiWallText.transform.parent = customScroll.transform;
@ -213,7 +213,7 @@ namespace NewHorizons.Builder.Props
}
case PropModule.NomaiTextInfo.NomaiTextType.Computer:
{
var computerObject = GeneralPropBuilder.MakeFromPrefab(_computerPrefab, _computerPrefab.name, planetGO, sector, info, true, info.normal);
var computerObject = GeneralPropBuilder.MakeFromPrefab(_computerPrefab, _computerPrefab.name, sector?.transform ?? planetGO.transform, info, true, info.normal);
var computer = computerObject.GetComponent<NomaiComputer>();
computer.SetSector(sector);
@ -286,7 +286,7 @@ namespace NewHorizons.Builder.Props
case PropModule.NomaiTextInfo.NomaiTextType.CairnVariant:
{
var cairnPrefab = info.type == PropModule.NomaiTextInfo.NomaiTextType.CairnVariant ? _cairnVariantPrefab : _cairnPrefab;
var cairnObject = GeneralPropBuilder.MakeFromPrefab(cairnPrefab, _cairnPrefab.name, planetGO, sector, info, info.rotation == null);
var cairnObject = GeneralPropBuilder.MakeFromPrefab(cairnPrefab, _cairnPrefab.name, sector?.transform ?? planetGO.transform, info, info.rotation == null);
// Idk do we have to set it active before finding things?
cairnObject.SetActive(true);
@ -349,7 +349,7 @@ namespace NewHorizons.Builder.Props
}
case PropModule.NomaiTextInfo.NomaiTextType.Trailmarker:
{
var trailmarkerObject = GeneralPropBuilder.MakeFromPrefab(_trailmarkerPrefab, _trailmarkerPrefab.name, planetGO, sector, info, info.rotation == null);
var trailmarkerObject = GeneralPropBuilder.MakeFromPrefab(_trailmarkerPrefab, _trailmarkerPrefab.name, sector?.transform ?? planetGO.transform, info, info.rotation == null);
// shrink because that is what mobius does on all trailmarkers or else they are the size of the player
trailmarkerObject.transform.localScale = Vector3.one * 0.75f;
@ -380,7 +380,7 @@ namespace NewHorizons.Builder.Props
private static NomaiWallText MakeWallText(GameObject go, Sector sector, PropModule.NomaiTextInfo info, string xmlPath, NewHorizonsBody nhBody)
{
GameObject nomaiWallTextObj = GeneralPropBuilder.MakeNew("NomaiWallText", go, sector, info);
GameObject nomaiWallTextObj = GeneralPropBuilder.MakeNew("NomaiWallText", sector?.transform ?? go.transform, info);
var box = nomaiWallTextObj.AddComponent<BoxCollider>();
box.center = new Vector3(-0.0643f, 1.1254f, 0f);

View File

@ -45,7 +45,7 @@ namespace NewHorizons.Builder.Props
{
InitPrefab();
var launcherGO = GeneralPropBuilder.MakeFromPrefab(_meteorLauncherPrefab, "MeteorLauncher", planetGO, sector, info, true);
var launcherGO = GeneralPropBuilder.MakeFromPrefab(_meteorLauncherPrefab, "MeteorLauncher", sector?.transform ?? planetGO.transform, info, true);
var meteorLauncher = launcherGO.GetComponent<MeteorLauncher>();
meteorLauncher._audioSector = sector;

View File

@ -12,7 +12,7 @@ namespace NewHorizons.Builder.ShipLog
private static readonly List<ShipLogEntryLocation> _locationsToInitialize = new List<ShipLogEntryLocation>();
public static void Make(GameObject go, Sector sector, PropModule.EntryLocationInfo info, IModBehaviour mod)
{
GameObject entryLocationGameObject = GeneralPropBuilder.MakeNew("Entry Location (" + info.id + ")", go, sector, info);
GameObject entryLocationGameObject = GeneralPropBuilder.MakeNew("Entry Location (" + info.id + ")", sector?.transform ?? go.transform, info);
ShipLogEntryLocation newLocation = entryLocationGameObject.AddComponent<ShipLogEntryLocation>();
newLocation._entryID = info.id;

View File

@ -10,7 +10,7 @@ namespace NewHorizons.Builder.ShipLog
{
public static void Make(GameObject go, Sector sector, VolumesModule.RevealVolumeInfo info, IModBehaviour mod)
{
var newRevealGO = GeneralPropBuilder.MakeNew("Reveal Volume (" + info.revealOn + ")", go, sector, info);
var newRevealGO = GeneralPropBuilder.MakeNew("Reveal Volume (" + info.revealOn + ")", sector?.transform ?? go.transform, info);
switch (info.revealOn)
{
case VolumesModule.RevealVolumeInfo.RevealVolumeType.Enter:

View File

@ -17,7 +17,7 @@ namespace NewHorizons.Builder.Volumes
{
public static AudioVolume Make(GameObject planetGO, Sector sector, VolumesModule.AudioVolumeInfo info, IModBehaviour mod)
{
var go = GeneralPropBuilder.MakeNew("AudioVolume", planetGO, sector, info);
var go = GeneralPropBuilder.MakeNew("AudioVolume", sector?.transform ?? planetGO.transform, info);
go.layer = LayerMask.NameToLayer("AdvancedEffectVolume");
var audioSource = go.AddComponent<AudioSource>();

View File

@ -14,7 +14,7 @@ namespace NewHorizons.Builder.Volumes
{
public static HazardVolume Make(GameObject planetGO, Sector sector, OWRigidbody owrb, VolumesModule.HazardVolumeInfo info, IModBehaviour mod)
{
var go = GeneralPropBuilder.MakeNew("HazardVolume", planetGO, sector, info);
var go = GeneralPropBuilder.MakeNew("HazardVolume", sector?.transform ?? planetGO.transform, info);
go.layer = LayerMask.NameToLayer("BasicEffectVolume");
var shape = go.AddComponent<SphereShape>();

View File

@ -17,7 +17,7 @@ namespace NewHorizons.Builder.Volumes
{
public static NHNotificationVolume Make(GameObject planetGO, Sector sector, VolumesModule.NotificationVolumeInfo info, IModBehaviour mod)
{
var go = GeneralPropBuilder.MakeNew("NotificationVolume", planetGO, sector, info);
var go = GeneralPropBuilder.MakeNew("NotificationVolume", sector?.transform ?? planetGO.transform, info);
go.layer = LayerMask.NameToLayer("BasicEffectVolume");
var shape = go.AddComponent<SphereShape>();

View File

@ -10,7 +10,7 @@ namespace NewHorizons.Builder.Volumes
{
public static TVolume Make<TVolume>(GameObject planetGO, Sector sector, VolumesModule.VanishVolumeInfo info) where TVolume : VanishVolume
{
var go = GeneralPropBuilder.MakeNew(typeof(TVolume).Name, planetGO, sector, info);
var go = GeneralPropBuilder.MakeNew(typeof(TVolume).Name, sector?.transform ?? planetGO.transform, info);
go.layer = LayerMask.NameToLayer("BasicEffectVolume");
var collider = go.AddComponent<SphereCollider>();

View File

@ -10,7 +10,7 @@ namespace NewHorizons.Builder.Volumes
{
public static TVolume Make<TVolume>(GameObject planetGO, Sector sector, VolumesModule.VolumeInfo info) where TVolume : MonoBehaviour //Could be BaseVolume but I need to create vanilla volumes too.
{
var go = GeneralPropBuilder.MakeNew(typeof(TVolume).Name, planetGO, sector, info);
var go = GeneralPropBuilder.MakeNew(typeof(TVolume).Name, sector?.transform ?? planetGO.transform, info);
go.layer = LayerMask.NameToLayer("BasicEffectVolume");
var shape = go.AddComponent<SphereShape>();

View File

@ -61,7 +61,7 @@ namespace NewHorizons.Components.ShipLog
var flag = false;
if (starSystem.Equals("SolarSystem")) flag = true;
else if (starSystem.Equals("EyeOfTheUniverse")) flag = false;
else if (config.Spawn?.shipSpawnPoint != null) flag = true;
else if (config.Spawn?.shipSpawn != null) flag = true;
if (!StarChartHandler.HasUnlockedSystem(starSystem)) continue;

View File

@ -2,6 +2,7 @@ using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using NewHorizons.External.Modules;
using NewHorizons.Utility;
using Newtonsoft.Json;
using static NewHorizons.External.Modules.ShipLogModule;
@ -184,30 +185,40 @@ namespace NewHorizons.External.Configs
/// </summary>
public NomaiCoordinates coords;
/// <summary>
/// The position in the solar system the vessel will warp to.
/// </summary>
public MVector3 vesselPosition;
/// <summary>
/// Euler angles by which the vessel will be oriented.
/// </summary>
public MVector3 vesselRotation;
/// <summary>
/// The relative position to the vessel that you will be teleported to when you exit the vessel through the black hole.
/// </summary>
public MVector3 warpExitPosition;
/// <summary>
/// Euler angles by which the warp exit will be oriented.
/// </summary>
public MVector3 warpExitRotation;
/// <summary>
/// A ship log fact which will make a prompt appear showing the coordinates when you're in the Vessel.
/// </summary>
public string promptFact;
/// <summary>
/// The location that the vessel will warp to.
/// </summary>
public VesselInfo vessel;
/// <summary>
/// The location that you will be teleported to when you exit the vessel through the black hole.
/// </summary>
public WarpExitInfo warpExit;
[Obsolete("vesselPosition is deprecated, use vessel.position instead")] public MVector3 vesselPosition;
[Obsolete("vesselRotation is deprecated, use vessel.rotation instead")] public MVector3 vesselRotation;
[Obsolete("warpExitPosition is deprecated, use warpExit.position instead")] public MVector3 warpExitPosition;
[Obsolete("warpExitRotation is deprecated, use warpExit.rotation instead")] public MVector3 warpExitRotation;
[JsonObject]
public class VesselInfo : PropModule.GeneralSolarSystemPropInfo
{
}
[JsonObject]
public class WarpExitInfo : PropModule.GeneralSolarSystemPropInfo
{
/// <summary>
/// If set, keeps the warp exit attached to the vessel. Overrides `parentPath`.
/// </summary>
public bool attachToVessel;
}
}
/// <summary>
@ -270,11 +281,33 @@ namespace NewHorizons.External.Configs
{
Vessel = new VesselModule();
}
Vessel.coords = Vessel.coords ?? coords;
Vessel.vesselPosition = Vessel.vesselPosition ?? vesselPosition;
Vessel.vesselRotation = Vessel.vesselRotation ?? vesselRotation;
Vessel.warpExitPosition = Vessel.warpExitPosition ?? warpExitPosition;
Vessel.warpExitRotation = Vessel.warpExitRotation ?? warpExitRotation;
Vessel.coords ??= coords;
Vessel.vesselPosition ??= vesselPosition;
Vessel.vesselRotation ??= vesselRotation;
Vessel.warpExitPosition ??= warpExitPosition;
Vessel.warpExitRotation ??= warpExitRotation;
}
if (Vessel != null)
{
if (Vessel.vesselPosition != null || Vessel.vesselRotation != null)
{
if (Vessel.vessel == null)
{
Vessel.vessel = new VesselModule.VesselInfo();
}
Vessel.vessel.position ??= Vessel.vesselPosition;
Vessel.vessel.rotation ??= Vessel.vesselRotation;
}
if (Vessel.warpExitPosition != null || Vessel.warpExitRotation != null)
{
if (Vessel.warpExit == null)
{
Vessel.warpExit = new VesselModule.WarpExitInfo();
}
Vessel.warpExit.position ??= Vessel.warpExitPosition;
Vessel.warpExit.rotation ??= Vessel.warpExitRotation;
Vessel.warpExit.attachToVessel = true;
}
}
}
}

View File

@ -131,6 +131,15 @@ namespace NewHorizons.External.Modules
public MVector3 rotation;
}
[JsonObject]
public abstract class GeneralSolarSystemPropInfo : GeneralPropInfo
{
/// <summary>
/// The name of the planet that will be used with `parentPath`. Must be set if `parentPath` is set.
/// </summary>
public string parentBody;
}
[JsonObject]
public class ScatterInfo
{
@ -442,29 +451,23 @@ namespace NewHorizons.External.Modules
/// <summary>
/// Radius of the spherical collision volume where you get the "talk to" prompt when looking at. If you use a
/// remoteTriggerPosition, you can set this to 0 to make the dialogue only trigger remotely.
/// remoteTrigger, you can set this to 0 to make the dialogue only trigger remotely.
/// </summary>
public float radius = 1f;
/// <summary>
/// Allows you to trigger dialogue from a distance when you walk into an area.
/// </summary>
public MVector3 remoteTriggerPosition;
/// <summary>
/// Distance from radius the prompt appears
/// </summary>
[DefaultValue(2f)] public float range = 2f;
/// <summary>
/// The radius of the remote trigger volume.
/// Allows you to trigger dialogue from a distance when you walk into an area.
/// </summary>
public float remoteTriggerRadius;
public RemoteTriggerInfo remoteTrigger;
/// <summary>
/// If setting up a remote trigger volume, this conditions must be met for it to trigger. Note: This is a dialogue condition, not a persistent condition.
/// </summary>
public string remoteTriggerPrereqCondition;
[Obsolete("remoteTriggerPosition is deprecated. Use remoteTrigger.position instead")] public MVector3 remoteTriggerPosition;
[Obsolete("remoteTriggerRadius is deprecated. Use remoteTrigger.radius instead")] public float remoteTriggerRadius;
[Obsolete("remoteTriggerPrereqCondition is deprecated. Use remoteTrigger.prereqCondition instead")] public string remoteTriggerPrereqCondition;
/// <summary>
/// Relative path to the xml file defining the dialogue.
@ -483,6 +486,19 @@ namespace NewHorizons.External.Modules
[EnumMember(Value = @"turnOff")] TurnOff = 0,
[EnumMember(Value = @"turnOffThenOn")] TurnOffThenOn = 1,
}
[JsonObject]
public class RemoteTriggerInfo : GeneralPointPropInfo
{
/// <summary>
/// The radius of the remote trigger volume.
/// </summary>
public float radius;
/// <summary>
/// This condition must be met for the remote trigger volume to trigger.
/// </summary>
public string prereqCondition;
}
}
[JsonObject]

View File

@ -1,5 +1,6 @@
using NewHorizons.Utility;
using NewHorizons.Utility;
using Newtonsoft.Json;
using System;
namespace NewHorizons.External.Modules
{
@ -7,29 +8,32 @@ namespace NewHorizons.External.Modules
public class SpawnModule
{
/// <summary>
/// If you want the player to spawn on the new body, set a value for this. Press `P` in game with Debug mode on to have
/// the game log the position you're looking at to find a good value for this.
/// If you want the player to spawn on the new body, set a value for this.
/// </summary>
public MVector3 playerSpawnPoint;
/// <summary>
/// Euler angles by which the player will be oriented.
/// </summary>
public MVector3 playerSpawnRotation;
public PlayerSpawnPoint playerSpawn;
/// <summary>
/// Required for the system to be accessible by warp drive.
/// </summary>
public MVector3 shipSpawnPoint;
public ShipSpawnPoint shipSpawn;
/// <summary>
/// Euler angles by which the ship will be oriented.
/// </summary>
public MVector3 shipSpawnRotation;
[Obsolete("playerSpawnPoint is deprecated. Use playerSpawn.position instead")] public MVector3 playerSpawnPoint;
[Obsolete("playerSpawnRotation is deprecated. Use playerSpawn.rotation instead")] public MVector3 playerSpawnRotation;
[Obsolete("shipSpawnPoint is deprecated. Use shipSpawn.position instead")] public MVector3 shipSpawnPoint;
[Obsolete("shipSpawnRotation is deprecated. Use shipSpawn.rotation instead")] public MVector3 shipSpawnRotation;
[Obsolete("startWithSuit is deprecated. Use playerSpawn.startWithSuit instead")] public bool startWithSuit;
/// <summary>
/// If you spawn on a planet with no oxygen, you probably want to set this to true ;;)
/// </summary>
public bool startWithSuit;
[JsonObject]
public class PlayerSpawnPoint : PropModule.GeneralPropInfo {
/// <summary>
/// If you spawn on a planet with no oxygen, you probably want to set this to true ;;)
/// </summary>
public bool startWithSuit;
}
[JsonObject]
public class ShipSpawnPoint : PropModule.GeneralPropInfo {
}
}
}

View File

@ -66,7 +66,7 @@ namespace NewHorizons.Handlers
{
foreach (var system in _systems)
{
if (system.Config.canEnterViaWarpDrive && system.Spawn?.shipSpawnPoint != null && HasUnlockedSystem(system.UniqueID))
if (system.Config.canEnterViaWarpDrive && system.Spawn?.shipSpawn != null && HasUnlockedSystem(system.UniqueID))
{
return true;
}

View File

@ -7,6 +7,7 @@ using NewHorizons.Utility;
using Logger = NewHorizons.Utility.Logger;
using static NewHorizons.Main;
using NewHorizons.Components.Orbital;
using NewHorizons.Builder.Props;
namespace NewHorizons.Handlers
{
@ -84,9 +85,9 @@ namespace NewHorizons.Handlers
if (VesselPrefab == null) return null;
Logger.LogVerbose("Creating Vessel");
var vesselObject = VesselPrefab.InstantiateInactive();
var vesselObject = GeneralPropBuilder.MakeFromPrefab(VesselPrefab, VesselPrefab.name, null, system.Config.Vessel?.vessel);
VesselObject = vesselObject;
vesselObject.name = VesselPrefab.name;
vesselObject.transform.parent = null;
var vesselAO = vesselObject.AddComponent<EyeAstroObject>();
@ -98,12 +99,6 @@ namespace NewHorizons.Handlers
vesselAO.Register();
vesselObject.GetComponentInChildren<ReferenceFrameVolume>(true)._referenceFrame._attachedAstroObject = vesselAO;
if (system.Config.Vessel?.vesselPosition != null)
vesselObject.transform.position = system.Config.Vessel.vesselPosition;
if (system.Config.Vessel?.vesselRotation != null)
vesselObject.transform.eulerAngles = system.Config.Vessel.vesselRotation;
VesselSingularityRoot singularityRoot = vesselObject.GetComponentInChildren<VesselSingularityRoot>(true);
VesselWarpController vesselWarpController = vesselObject.GetComponentInChildren<VesselWarpController>(true);
@ -147,11 +142,7 @@ namespace NewHorizons.Handlers
vesselWarpController._targetWarpPlatform.OnReceiveWarpedBody += OnReceiveWarpedBody;
if (system.Config.Vessel?.warpExitPosition != null)
vesselWarpController._targetWarpPlatform.transform.localPosition = system.Config.Vessel.warpExitPosition;
if (system.Config.Vessel?.warpExitRotation != null)
vesselWarpController._targetWarpPlatform.transform.localEulerAngles = system.Config.Vessel.warpExitRotation;
GeneralPropBuilder.MakeFromExisting(vesselWarpController._targetWarpPlatform.gameObject, vesselWarpController._targetWarpPlatform.transform.parent, system.Config.Vessel?.warpExit);
vesselObject.GetComponent<MapMarker>()._labelID = (UITextType)TranslationHandler.AddUI("Vessel");

View File

@ -199,10 +199,13 @@ namespace NewHorizons
pathToAnimController = pathToAnimController,
position = Vector3.zero,
radius = radius,
remoteTriggerPosition = null,
range = range,
remoteTriggerRadius = remoteTriggerRadius,
xmlFile = xmlFile
xmlFile = xmlFile,
remoteTrigger = new PropModule.DialogueInfo.RemoteTriggerInfo()
{
position = null,
radius = remoteTriggerRadius,
},
};
return DialogueBuilder.Make(root, null, info, mod);