Envoi sur GitHub du projet updated
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -8,6 +9,14 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace DialogueManagerRuntime
|
||||
{
|
||||
|
||||
public enum MutationBehaviour
|
||||
{
|
||||
Wait,
|
||||
DoNotWait,
|
||||
Skip
|
||||
}
|
||||
|
||||
public enum TranslationSource
|
||||
{
|
||||
None,
|
||||
@@ -16,13 +25,15 @@ namespace DialogueManagerRuntime
|
||||
PO
|
||||
}
|
||||
|
||||
public partial class DialogueManager : Node
|
||||
public partial class DialogueManager : RefCounted
|
||||
{
|
||||
public delegate void DialogueStartedEventHandler(Resource dialogueResource);
|
||||
public delegate void PassedTitleEventHandler(string title);
|
||||
public delegate void GotDialogueEventHandler(DialogueLine dialogueLine);
|
||||
public delegate void MutatedEventHandler(Dictionary mutation);
|
||||
public delegate void DialogueEndedEventHandler(Resource dialogueResource);
|
||||
|
||||
public static DialogueStartedEventHandler? DialogueStarted;
|
||||
public static PassedTitleEventHandler? PassedTitle;
|
||||
public static GotDialogueEventHandler? GotDialogue;
|
||||
public static MutatedEventHandler? Mutated;
|
||||
@@ -38,6 +49,7 @@ namespace DialogueManagerRuntime
|
||||
if (instance == null)
|
||||
{
|
||||
instance = Engine.GetSingleton("DialogueManager");
|
||||
instance.Connect("bridge_dialogue_started", Callable.From((Resource dialogueResource) => DialogueStarted?.Invoke(dialogueResource)));
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@@ -86,11 +98,6 @@ namespace DialogueManagerRuntime
|
||||
instance.Connect("dialogue_ended", Callable.From((Resource dialogueResource) => DialogueEnded?.Invoke(dialogueResource)));
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
Prepare(Instance);
|
||||
}
|
||||
|
||||
|
||||
public static async Task<GodotObject> GetSingleton()
|
||||
{
|
||||
@@ -121,11 +128,11 @@ namespace DialogueManagerRuntime
|
||||
return (Resource)Instance.Call("create_resource_from_text", text);
|
||||
}
|
||||
|
||||
public static async Task<DialogueLine?> GetNextDialogueLine(Resource dialogueResource, string key = "", Array<Variant>? extraGameStates = null)
|
||||
public static async Task<DialogueLine?> GetNextDialogueLine(Resource dialogueResource, string key = "", Array<Variant>? extraGameStates = null, MutationBehaviour mutation_behaviour = MutationBehaviour.Wait)
|
||||
{
|
||||
var instance = (Node)Instance.Call("_bridge_get_new_instance");
|
||||
Prepare(instance);
|
||||
instance.Call("_bridge_get_next_dialogue_line", dialogueResource, key, extraGameStates ?? new Array<Variant>());
|
||||
instance.Call("_bridge_get_next_dialogue_line", dialogueResource, key, extraGameStates ?? new Array<Variant>(), (int)mutation_behaviour);
|
||||
var result = await instance.ToSignal(instance, "bridge_get_next_dialogue_line_completed");
|
||||
instance.QueueFree();
|
||||
|
||||
@@ -134,6 +141,19 @@ namespace DialogueManagerRuntime
|
||||
return new DialogueLine((RefCounted)result[0]);
|
||||
}
|
||||
|
||||
public static async Task<DialogueLine?> GetLine(Resource dialogueResource, string key = "", Array<Variant>? extraGameStates = null)
|
||||
{
|
||||
var instance = (Node)Instance.Call("_bridge_get_new_instance");
|
||||
Prepare(instance);
|
||||
instance.Call("_bridge_get_line", dialogueResource, key, extraGameStates ?? new Array<Variant>());
|
||||
var result = await instance.ToSignal(instance, "bridge_get_line_completed");
|
||||
instance.QueueFree();
|
||||
|
||||
if ((RefCounted)result[0] == null) return null;
|
||||
|
||||
return new DialogueLine((RefCounted)result[0]);
|
||||
}
|
||||
|
||||
|
||||
public static CanvasLayer ShowExampleDialogueBalloon(Resource dialogueResource, string key = "", Array<Variant>? extraGameStates = null)
|
||||
{
|
||||
@@ -163,6 +183,18 @@ namespace DialogueManagerRuntime
|
||||
}
|
||||
|
||||
|
||||
public static Array<string> StaticIdToLineIds(Resource dialogueResource, string staticId)
|
||||
{
|
||||
return (Array<string>)Instance.Call("static_id_to_line_ids", dialogueResource, staticId);
|
||||
}
|
||||
|
||||
|
||||
public static string StaticIdToLineId(Resource dialogueResource, string staticId)
|
||||
{
|
||||
return (string)Instance.Call("static_id_to_line_id", dialogueResource, staticId);
|
||||
}
|
||||
|
||||
|
||||
public static async void Mutate(Dictionary mutation, Array<Variant>? extraGameStates = null, bool isInlineMutation = false)
|
||||
{
|
||||
Instance.Call("_bridge_mutate", mutation, extraGameStates ?? new Array<Variant>(), isInlineMutation);
|
||||
@@ -170,16 +202,167 @@ namespace DialogueManagerRuntime
|
||||
}
|
||||
|
||||
|
||||
public bool ThingHasMethod(GodotObject thing, string method)
|
||||
public static Array<Dictionary> GetMembersForAutoload(Script script)
|
||||
{
|
||||
MethodInfo? info = thing.GetType().GetMethod(method, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
|
||||
return info != null;
|
||||
Array<Dictionary> members = new Array<Dictionary>();
|
||||
|
||||
string typeName = script.ResourcePath.GetFile().GetBaseName();
|
||||
var matchingTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.Name == typeName);
|
||||
foreach (var matchingType in matchingTypes)
|
||||
{
|
||||
var memberInfos = matchingType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||
foreach (var memberInfo in memberInfos)
|
||||
{
|
||||
string type;
|
||||
switch (memberInfo.MemberType)
|
||||
{
|
||||
case MemberTypes.Field:
|
||||
FieldInfo fieldInfo = memberInfo as FieldInfo;
|
||||
|
||||
if (fieldInfo.FieldType.ToString().Contains("EventHandler"))
|
||||
{
|
||||
type = "signal";
|
||||
}
|
||||
else if (fieldInfo.IsLiteral)
|
||||
{
|
||||
type = "constant";
|
||||
}
|
||||
else
|
||||
{
|
||||
type = "property";
|
||||
}
|
||||
break;
|
||||
case MemberTypes.Method:
|
||||
type = "method";
|
||||
break;
|
||||
|
||||
case MemberTypes.NestedType:
|
||||
type = "constant";
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
members.Add(new Dictionary() {
|
||||
{ "name", memberInfo.Name },
|
||||
{ "type", type }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
|
||||
public bool ThingHasConstant(GodotObject thing, string property)
|
||||
{
|
||||
var memberInfos = thing.GetType().GetMember(property, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||
return memberInfos.Length > 0;
|
||||
}
|
||||
|
||||
|
||||
public Variant ResolveThingConstant(GodotObject thing, string property)
|
||||
{
|
||||
var memberInfos = thing.GetType().GetMember(property, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||
foreach (var memberInfo in memberInfos)
|
||||
{
|
||||
if (memberInfo != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (memberInfo.MemberType)
|
||||
{
|
||||
case MemberTypes.Field:
|
||||
return convertValueToVariant((memberInfo as FieldInfo).GetValue(thing));
|
||||
|
||||
case MemberTypes.Property:
|
||||
return convertValueToVariant((memberInfo as PropertyInfo).GetValue(thing));
|
||||
|
||||
case MemberTypes.NestedType:
|
||||
var type = thing.GetType().GetNestedType(property);
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return GetEnumAsDictionary(type);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception($"{property} is not supported by Variant.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception($"{property} is not a public constant on {thing}");
|
||||
}
|
||||
|
||||
|
||||
Dictionary GetEnumAsDictionary(Type enumType)
|
||||
{
|
||||
Dictionary dictionary = new Dictionary();
|
||||
foreach (var value in enumType.GetEnumValuesAsUnderlyingType())
|
||||
{
|
||||
var key = enumType.GetEnumName(value);
|
||||
if (key != null)
|
||||
{
|
||||
dictionary.Add(key, convertValueToVariant(value));
|
||||
}
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
|
||||
Variant convertValueToVariant(object value)
|
||||
{
|
||||
Type rawType = value.GetType();
|
||||
if (rawType.IsEnum)
|
||||
{
|
||||
var values = GetEnumAsDictionary(rawType);
|
||||
value = values[value.ToString()];
|
||||
}
|
||||
|
||||
return value switch
|
||||
{
|
||||
Variant v => v,
|
||||
int v => Variant.From((long)v),
|
||||
float v => Variant.From((double)v),
|
||||
System.String v => Variant.From((string)v),
|
||||
_ => Variant.From(value)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public bool ThingHasMethod(GodotObject thing, string method, Array<Variant> args)
|
||||
{
|
||||
var methodInfos = thing.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||
foreach (var methodInfo in methodInfos)
|
||||
{
|
||||
if (methodInfo.Name == method && args.Count >= methodInfo.GetParameters().Where(p => !p.HasDefaultValue).Count())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public async void ResolveThingMethod(GodotObject thing, string method, Array<Variant> args)
|
||||
{
|
||||
MethodInfo? info = thing.GetType().GetMethod(method, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
|
||||
MethodInfo? info = null;
|
||||
var methodInfos = thing.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
|
||||
foreach (var methodInfo in methodInfos)
|
||||
{
|
||||
if (methodInfo.Name == method && args.Count >= methodInfo.GetParameters().Where(p => !p.HasDefaultValue).Count())
|
||||
{
|
||||
info = methodInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (info == null) return;
|
||||
|
||||
@@ -216,18 +399,15 @@ namespace DialogueManagerRuntime
|
||||
|
||||
if (result is Task taskResult)
|
||||
{
|
||||
// await Tasks and handle result if it is a Task<T>
|
||||
await taskResult;
|
||||
var taskType = taskResult.GetType();
|
||||
if (taskType.IsGenericType && taskType.GetGenericTypeDefinition() == typeof(Task<>))
|
||||
try
|
||||
{
|
||||
var resultProperty = taskType.GetProperty("Result");
|
||||
var taskResultValue = resultProperty.GetValue(taskResult);
|
||||
EmitSignal(SignalName.Resolved, (Variant)taskResultValue);
|
||||
Variant value = (Variant)taskResult.GetType().GetProperty("Result").GetValue(taskResult);
|
||||
EmitSignal(SignalName.Resolved, value);
|
||||
}
|
||||
else
|
||||
catch (Exception)
|
||||
{
|
||||
EmitSignal(SignalName.Resolved, null);
|
||||
EmitSignal(SignalName.Resolved);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -236,6 +416,12 @@ namespace DialogueManagerRuntime
|
||||
}
|
||||
}
|
||||
#nullable enable
|
||||
|
||||
|
||||
public static string GetErrorMessage(int error)
|
||||
{
|
||||
return (string)Instance.Call("_bridge_get_error_message", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -295,12 +481,6 @@ namespace DialogueManagerRuntime
|
||||
get => time;
|
||||
}
|
||||
|
||||
private Dictionary pauses = new Dictionary();
|
||||
public Dictionary Pauses
|
||||
{
|
||||
get => pauses;
|
||||
}
|
||||
|
||||
private Dictionary speeds = new Dictionary();
|
||||
public Dictionary Speeds
|
||||
{
|
||||
@@ -313,6 +493,12 @@ namespace DialogueManagerRuntime
|
||||
get => inline_mutations;
|
||||
}
|
||||
|
||||
private Array<DialogueLine> concurrent_lines = new Array<DialogueLine>();
|
||||
public Array<DialogueLine> ConcurrentLines
|
||||
{
|
||||
get => concurrent_lines;
|
||||
}
|
||||
|
||||
private Array<Variant> extra_game_states = new Array<Variant>();
|
||||
public Array<Variant> ExtraGameStates
|
||||
{
|
||||
@@ -327,17 +513,22 @@ namespace DialogueManagerRuntime
|
||||
|
||||
public DialogueLine(RefCounted data)
|
||||
{
|
||||
id = (string)data.Get("id");
|
||||
type = (string)data.Get("type");
|
||||
next_id = (string)data.Get("next_id");
|
||||
character = (string)data.Get("character");
|
||||
text = (string)data.Get("text");
|
||||
translation_key = (string)data.Get("translation_key");
|
||||
pauses = (Dictionary)data.Get("pauses");
|
||||
speeds = (Dictionary)data.Get("speeds");
|
||||
inline_mutations = (Array<Godot.Collections.Array>)data.Get("inline_mutations");
|
||||
time = (string)data.Get("time");
|
||||
tags = (Array<string>)data.Get("tags");
|
||||
|
||||
foreach (var concurrent_line_data in (Array<RefCounted>)data.Get("concurrent_lines"))
|
||||
{
|
||||
concurrent_lines.Add(new DialogueLine(concurrent_line_data));
|
||||
}
|
||||
|
||||
foreach (var response in (Array<RefCounted>)data.Get("responses"))
|
||||
{
|
||||
responses.Add(new DialogueResponse(response));
|
||||
@@ -345,6 +536,20 @@ namespace DialogueManagerRuntime
|
||||
}
|
||||
|
||||
|
||||
public bool HasTag(string tagName)
|
||||
{
|
||||
string wrapped = $"{tagName}=";
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
if (tag.StartsWith(wrapped))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public string GetTagValue(string tagName)
|
||||
{
|
||||
string wrapped = $"{tagName}=";
|
||||
@@ -389,6 +594,13 @@ namespace DialogueManagerRuntime
|
||||
set => is_allowed = value;
|
||||
}
|
||||
|
||||
private string condition_as_text = "";
|
||||
public string ConditionAsText
|
||||
{
|
||||
get => condition_as_text;
|
||||
set => condition_as_text = value;
|
||||
}
|
||||
|
||||
private string text = "";
|
||||
public string Text
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user