Add support for dialogue attention points (#929)

## Minor features

- Added `attentionPoint` and `swappedAttentionPoints` to dialogue props
to allow for controlling what the camera looks at when advancing
dialogue. Closes #904 (Requested by @MegaPiggy)
This commit is contained in:
Joshua Thome 2024-09-06 17:37:55 -05:00 committed by GitHub
commit fe86014b97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 153 additions and 2 deletions

View File

@ -9,6 +9,7 @@ using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using UnityEngine;
@ -35,7 +36,7 @@ namespace NewHorizons.Builder.Props
}
else
{
return (AddToExistingDialogue(go, info, xml, dialogueName), null);
return (AddToExistingDialogue(go, sector, info, xml, dialogueName), null);
}
}
@ -53,6 +54,8 @@ namespace NewHorizons.Builder.Props
var dialogue = MakeConversationZone(go, sector, info, xml, dialogueName);
MakeAttentionPoints(go, sector, dialogue, info);
RemoteDialogueTrigger remoteTrigger = null;
if (info.remoteTrigger != null)
{
@ -70,7 +73,7 @@ namespace NewHorizons.Builder.Props
return (dialogue, remoteTrigger);
}
private static CharacterDialogueTree AddToExistingDialogue(GameObject go, DialogueInfo info, string xml, string dialogueName)
private static CharacterDialogueTree AddToExistingDialogue(GameObject go, Sector sector, DialogueInfo info, string xml, string dialogueName)
{
var dialogueObject = go.FindChild(info.pathToExistingDialogue);
if (dialogueObject == null) dialogueObject = SearchUtilities.Find(info.pathToExistingDialogue);
@ -163,6 +166,8 @@ namespace NewHorizons.Builder.Props
FixDialogueNextFrame(existingDialogue);
MakeAttentionPoints(go, sector, existingDialogue, info);
return existingDialogue;
}
@ -332,6 +337,32 @@ namespace NewHorizons.Builder.Props
return dialogueTree;
}
private static void MakeAttentionPoints(GameObject go, Sector sector, CharacterDialogueTree dialogue, DialogueInfo info)
{
if (info.attentionPoint != null)
{
var ptGo = GeneralPropBuilder.MakeNew("AttentionPoint", go, sector, info.attentionPoint, defaultParent: dialogue.transform);
dialogue._attentionPoint = ptGo.transform;
dialogue._attentionPointOffset = info.attentionPoint.offset;
ptGo.SetActive(true);
}
if (info.swappedAttentionPoints != null && info.swappedAttentionPoints.Length > 0)
{
foreach (var pointInfo in info.swappedAttentionPoints)
{
var ptGo = GeneralPropBuilder.MakeNew($"AttentionPoint_{pointInfo.dialogueNode}_{pointInfo.dialoguePage}", go, sector, pointInfo, defaultParent: dialogue.transform);
var swapper = ptGo.AddComponent<DialogueAttentionPointSwapper>();
swapper._dialogueTree = dialogue;
swapper._attentionPoint = ptGo.transform;
swapper._attentionPointOffset = pointInfo.offset;
swapper._nodeName = pointInfo.dialogueNode;
swapper._dialoguePage = pointInfo.dialoguePage;
swapper._lookEasing = pointInfo.lookEasing;
ptGo.SetActive(true);
}
}
}
private static void MakePlayerTrackingZone(GameObject go, CharacterDialogueTree dialogue, DialogueInfo info)
{
var character = go.transform.Find(info.pathToAnimController);

View File

@ -0,0 +1,32 @@
using NewHorizons.External.SerializableData;
using Newtonsoft.Json;
using System.ComponentModel;
namespace NewHorizons.External.Modules.Props.Dialogue
{
[JsonObject]
public class AttentionPointInfo : GeneralPointPropInfo
{
/// <summary>
/// An additional offset to apply to apply when the camera looks at this attention point.
/// </summary>
public MVector3 offset;
}
[JsonObject]
public class SwappedAttentionPointInfo : AttentionPointInfo
{
/// <summary>
/// The name of the dialogue node to activate this attention point for. If null or blank, activates for every node.
/// </summary>
public string dialogueNode;
/// <summary>
/// The index of the page in the current dialogue node to activate this attention point for, if the node has multiple pages.
/// </summary>
public int dialoguePage;
/// <summary>
/// The easing factor which determines how 'snappy' the camera is when looking at the attention point.
/// </summary>
[DefaultValue(1)] public float lookEasing = 1f;
}
}

View File

@ -47,6 +47,16 @@ namespace NewHorizons.External.Modules.Props.Dialogue
/// </summary>
[DefaultValue(2f)] public float range = 2f;
/// <summary>
/// The point that the camera looks at when dialogue advances.
/// </summary>
public AttentionPointInfo attentionPoint;
/// <summary>
/// Additional points that the camera looks at when dialogue advances through specific dialogue nodes and pages.
/// </summary>
public SwappedAttentionPointInfo[] swappedAttentionPoints;
/// <summary>
/// Allows you to trigger dialogue from a distance when you walk into an area.
/// </summary>

View File

@ -1625,6 +1625,17 @@
"format": "float",
"default": 2.0
},
"attentionPoint": {
"description": "The point that the camera looks at when dialogue advances.",
"$ref": "#/definitions/AttentionPointInfo"
},
"swappedAttentionPoints": {
"type": "array",
"description": "Additional points that the camera looks at when dialogue advances through specific dialogue nodes and pages.",
"items": {
"$ref": "#/definitions/SwappedAttentionPointInfo"
}
},
"remoteTrigger": {
"description": "Allows you to trigger dialogue from a distance when you walk into an area.",
"$ref": "#/definitions/RemoteTriggerInfo"
@ -1640,6 +1651,73 @@
}
}
},
"AttentionPointInfo": {
"type": "object",
"additionalProperties": false,
"properties": {
"position": {
"description": "Position of the object",
"$ref": "#/definitions/MVector3"
},
"isRelativeToParent": {
"type": "boolean",
"description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object."
},
"parentPath": {
"type": "string",
"description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)."
},
"rename": {
"type": "string",
"description": "An optional rename of this object"
},
"offset": {
"description": "An additional offset to apply to apply when the camera looks at this attention point.",
"$ref": "#/definitions/MVector3"
}
}
},
"SwappedAttentionPointInfo": {
"type": "object",
"additionalProperties": false,
"properties": {
"offset": {
"description": "An additional offset to apply to apply when the camera looks at this attention point.",
"$ref": "#/definitions/MVector3"
},
"position": {
"description": "Position of the object",
"$ref": "#/definitions/MVector3"
},
"isRelativeToParent": {
"type": "boolean",
"description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object."
},
"parentPath": {
"type": "string",
"description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)."
},
"rename": {
"type": "string",
"description": "An optional rename of this object"
},
"dialogueNode": {
"type": "string",
"description": "The name of the dialogue node to activate this attention point for. If null or blank, activates for every node."
},
"dialoguePage": {
"type": "integer",
"description": "The index of the page in the current dialogue node to activate this attention point for, if the node has multiple pages.",
"format": "int32"
},
"lookEasing": {
"type": "number",
"description": "The easing factor which determines how 'snappy' the camera is when looking at the attention point.",
"format": "float",
"default": 1
}
}
},
"RemoteTriggerInfo": {
"type": "object",
"additionalProperties": false,