mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-26 09:35:26 +00:00
commit
9b26509cea
34
.github/workflows/build.yaml
vendored
Normal file
34
.github/workflows/build.yaml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [dev]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.merged != 'true') || github.event_name == 'push'
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
|
||||
# Replace / with _ in ref name so that it can be used in a filename
|
||||
- uses: mad9000/actions-find-and-replace-string@2
|
||||
id: sanitizeRef
|
||||
with:
|
||||
source: ${{ github.ref_name }}
|
||||
find: '/'
|
||||
replace: '_'
|
||||
# Get short-sha so that it can be used in a filename
|
||||
- uses: benjlevesque/short-sha@v1.2
|
||||
id: short-sha
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: "5.0.x"
|
||||
- run: dotnet build -c Release
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: QSB-${{ steps.sanitizeRef.outputs.value }}-${{ steps.short-sha.outputs.sha }}
|
||||
path: .\QSB\Bin\Release
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -8,6 +8,8 @@
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
.idea
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
@ -365,3 +367,7 @@ IgnoreInGithub/
|
||||
OWML.Config.json
|
||||
WeavedFiles/QSB.dll
|
||||
WeavedFiles/QSB.dll.mdb
|
||||
qsb-unityproject
|
||||
|
||||
# User specific locations
|
||||
DevEnv.targets
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,49 +0,0 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3095198160
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 44badca86c2222e5cc39a8497439be0c
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: b2ece8ae09df261ff59d764d08696641
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
Script: {instanceID: 0}
|
||||
- Class: 4
|
||||
Script: {instanceID: 0}
|
||||
- Class: 21
|
||||
Script: {instanceID: 0}
|
||||
- Class: 23
|
||||
Script: {instanceID: 0}
|
||||
- Class: 28
|
||||
Script: {instanceID: 0}
|
||||
- Class: 33
|
||||
Script: {instanceID: 0}
|
||||
- Class: 43
|
||||
Script: {instanceID: 0}
|
||||
- Class: 48
|
||||
Script: {instanceID: 0}
|
||||
- Class: 114
|
||||
Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
- Class: 128
|
||||
Script: {instanceID: 0}
|
||||
- Class: 222
|
||||
Script: {instanceID: 0}
|
||||
- Class: 223
|
||||
Script: {instanceID: 0}
|
||||
- Class: 224
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/Cube.prefab
|
||||
- Assets/Capsule.prefab
|
||||
- Assets/DebugVis.mat
|
||||
- Assets/LogCanvas.prefab
|
||||
- Assets/Sphere.prefab
|
||||
Dependencies: []
|
Binary file not shown.
@ -1,34 +0,0 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 2593345828
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: d97fbc9cde41b6514223a2f68ba96af8
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: ff0e1233df027a80b5add90668c49830
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 43
|
||||
Script: {instanceID: 0}
|
||||
- Class: 74
|
||||
Script: {instanceID: 0}
|
||||
- Class: 91
|
||||
Script: {instanceID: 0}
|
||||
Assets:
|
||||
- Assets/Riebeck/Idle_to_playing.anim
|
||||
- Assets/Chert/Chert_Drum_Panicked.anim
|
||||
- Assets/Riebeck/Traveller_Riebeck.controller
|
||||
- Assets/Chert/Traveller_Chert.controller
|
||||
- Assets/Chert/Chert_Drum_Chipper.anim
|
||||
- Assets/Riebeck/Riebeck_DreamIdle.anim
|
||||
- Assets/Chert/Chert_Chatter_Chipper.anim
|
||||
- Assets/Riebeck/Riebeck_Playing.anim
|
||||
- Assets/Chert/Chert_Chatter_Panicked.anim
|
||||
- Assets/Chert/Chert_Chatter_Nervous.anim
|
||||
- Assets/Chert/hourglasstwinsmeshescharacters2.asset
|
||||
- Assets/Riebeck/Playing_banjo.anim
|
||||
- Assets/Riebeck/Playing_to_idle.anim
|
||||
- Assets/Chert/Chert_Dream.anim
|
||||
- Assets/Riebeck/Riebeck_Talking.anim
|
||||
Dependencies: []
|
Binary file not shown.
@ -1,30 +0,0 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 1991351671
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: e0f93ad04981fd266a4300b0be721792
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 6968c5d2bbef57a79632abd61ea01bb3
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
Script: {instanceID: 0}
|
||||
- Class: 4
|
||||
Script: {instanceID: 0}
|
||||
- Class: 114
|
||||
Script: {fileID: 372142912, guid: 93b08009869340045a8e7321508b6355, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1768714887, guid: 93b08009869340045a8e7321508b6355, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1267208747, guid: 93b08009869340045a8e7321508b6355, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/NetworkProbe.prefab
|
||||
- Assets/NETWORK_Player_Body.prefab
|
||||
- Assets/NetworkOrb.prefab
|
||||
- Assets/NetworkShip.prefab
|
||||
Dependencies: []
|
8
DevEnv.targets.example
Normal file
8
DevEnv.targets.example
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<GameDir>C:\Program Files\Epic Games\OuterWilds</GameDir>
|
||||
<OwmlDir>$(AppData)\OuterWildsModManager\OWML</OwmlDir>
|
||||
<UnityAssetsDir>$(SolutionDir)\qsb-unityproject\Assets</UnityAssetsDir>
|
||||
</PropertyGroup>
|
||||
</Project>
|
33
Directory.Build.props
Normal file
33
Directory.Build.props
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup>
|
||||
<DevEnvLoc>$(MSBuildThisFileDirectory)DevEnv.targets</DevEnvLoc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(DevEnvLoc)" Condition="Exists('$(DevEnvLoc)')" />
|
||||
|
||||
<PropertyGroup Label="Common Properties">
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>9</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<OutputPath>bin\$(Configuration)\QSB</OutputPath>
|
||||
<OutputPath Condition="Exists($(OwmlDir))">$(OwmlDir)\Mods\QSB</OutputPath>
|
||||
<NeutralLanguage>en-GB</NeutralLanguage>
|
||||
<Company>Henry Pointer, Aleksander Waage, Ricardo Lopes</Company>
|
||||
<Copyright>Copyright © Henry Pointer, Aleksander Waage, Ricardo Lopes 2020-2021</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Default Locations" Condition="!Exists('$(DevEnvLoc)')">
|
||||
<GameDir>C:\Program Files\Epic Games\OuterWilds</GameDir>
|
||||
<OwmlDir>$(AppData)\OuterWildsModManager\OWML</OwmlDir>
|
||||
<UnityAssetsDir>$(SolutionDir)\qsb-unityproject\Assets</UnityAssetsDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,236 +0,0 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Mdb;
|
||||
using Mono.Cecil.Pdb;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
internal class Helpers
|
||||
{
|
||||
public static string UnityEngineDLLDirectoryName()
|
||||
{
|
||||
var directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
|
||||
return (directoryName == null) ? null : directoryName.Replace("file:\\", "");
|
||||
}
|
||||
|
||||
public static ISymbolReaderProvider GetSymbolReaderProvider(string inputFile)
|
||||
{
|
||||
var text = inputFile.Substring(0, inputFile.Length - 4);
|
||||
ISymbolReaderProvider result;
|
||||
if (File.Exists(text + ".pdb"))
|
||||
{
|
||||
Console.WriteLine("Symbols will be read from " + text + ".pdb");
|
||||
result = new PdbReaderProvider();
|
||||
}
|
||||
else if (File.Exists(text + ".dll.mdb"))
|
||||
{
|
||||
Console.WriteLine("Symbols will be read from " + text + ".dll.mdb");
|
||||
result = new MdbReaderProvider();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("No symbols for " + inputFile);
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool InheritsFromSyncList(TypeReference typeRef)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (typeRef.IsValueType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var typeReference in ResolveInheritanceHierarchy(typeRef))
|
||||
{
|
||||
if (typeReference.IsGenericInstance)
|
||||
{
|
||||
var typeDefinition = typeReference.Resolve();
|
||||
if (typeDefinition.HasGenericParameters && typeDefinition.FullName == Weaver.SyncListType.FullName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<TypeReference> ResolveInheritanceHierarchy(TypeReference type)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
yield return type;
|
||||
yield return Weaver.valueTypeType;
|
||||
yield return Weaver.objectType;
|
||||
yield break;
|
||||
}
|
||||
|
||||
while (type != null && type.FullName != Weaver.objectType.FullName)
|
||||
{
|
||||
yield return type;
|
||||
try
|
||||
{
|
||||
var typeDefinition = type.Resolve();
|
||||
if (typeDefinition == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
type = typeDefinition.BaseType;
|
||||
}
|
||||
catch
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
yield return Weaver.objectType;
|
||||
yield break;
|
||||
}
|
||||
|
||||
public static string DestinationFileFor(string outputDir, string assemblyPath)
|
||||
{
|
||||
var fileName = Path.GetFileName(assemblyPath);
|
||||
return Path.Combine(outputDir, fileName);
|
||||
}
|
||||
|
||||
public static string PrettyPrintType(TypeReference type)
|
||||
{
|
||||
string result;
|
||||
if (type.IsGenericInstance)
|
||||
{
|
||||
var genericInstanceType = (GenericInstanceType)type;
|
||||
var text = genericInstanceType.Name.Substring(0, genericInstanceType.Name.Length - 2);
|
||||
var text2 = "<";
|
||||
var text3 = ", ";
|
||||
IEnumerable<TypeReference> genericArguments = genericInstanceType.GenericArguments;
|
||||
result = text + text2 + string.Join(text3, Enumerable.ToArray<string>(Enumerable.Select<TypeReference, string>(genericArguments, new Func<TypeReference, string>(PrettyPrintType)))) + ">";
|
||||
}
|
||||
else if (type.HasGenericParameters)
|
||||
{
|
||||
result = type.Name.Substring(0, type.Name.Length - 2) + "<" + string.Join(", ", Enumerable.ToArray<string>(Enumerable.Select<GenericParameter, string>(type.GenericParameters, (GenericParameter x) => x.Name))) + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = type.Name;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ReaderParameters ReaderParameters(string assemblyPath, IEnumerable<string> extraPaths, IAssemblyResolver assemblyResolver, string unityEngineDLLPath, string unityUNetDLLPath)
|
||||
{
|
||||
var readerParameters = new ReaderParameters();
|
||||
if (assemblyResolver == null)
|
||||
{
|
||||
assemblyResolver = new DefaultAssemblyResolver();
|
||||
}
|
||||
|
||||
var addSearchDirectoryHelper = new Helpers.AddSearchDirectoryHelper(assemblyResolver);
|
||||
addSearchDirectoryHelper.AddSearchDirectory(Path.GetDirectoryName(assemblyPath));
|
||||
addSearchDirectoryHelper.AddSearchDirectory(UnityEngineDLLDirectoryName());
|
||||
addSearchDirectoryHelper.AddSearchDirectory(Path.GetDirectoryName(unityEngineDLLPath));
|
||||
addSearchDirectoryHelper.AddSearchDirectory(Path.GetDirectoryName(unityUNetDLLPath));
|
||||
if (extraPaths != null)
|
||||
{
|
||||
foreach (var directory in extraPaths)
|
||||
{
|
||||
addSearchDirectoryHelper.AddSearchDirectory(directory);
|
||||
}
|
||||
}
|
||||
|
||||
readerParameters.AssemblyResolver = assemblyResolver;
|
||||
readerParameters.SymbolReaderProvider = GetSymbolReaderProvider(assemblyPath);
|
||||
return readerParameters;
|
||||
}
|
||||
|
||||
public static WriterParameters GetWriterParameters(ReaderParameters readParams)
|
||||
{
|
||||
var writerParameters = new WriterParameters();
|
||||
if (readParams.SymbolReaderProvider is PdbReaderProvider)
|
||||
{
|
||||
writerParameters.SymbolWriterProvider = new PdbWriterProvider();
|
||||
}
|
||||
else if (readParams.SymbolReaderProvider is MdbReaderProvider)
|
||||
{
|
||||
writerParameters.SymbolWriterProvider = new MdbWriterProvider();
|
||||
}
|
||||
|
||||
return writerParameters;
|
||||
}
|
||||
|
||||
public static TypeReference MakeGenericType(TypeReference self, params TypeReference[] arguments)
|
||||
{
|
||||
if (self.GenericParameters.Count != arguments.Length)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var genericInstanceType = new GenericInstanceType(self);
|
||||
foreach (var item in arguments)
|
||||
{
|
||||
genericInstanceType.GenericArguments.Add(item);
|
||||
}
|
||||
|
||||
return genericInstanceType;
|
||||
}
|
||||
|
||||
public static MethodReference MakeHostInstanceGeneric(MethodReference self, params TypeReference[] arguments)
|
||||
{
|
||||
var methodReference = new MethodReference(self.Name, self.ReturnType, MakeGenericType(self.DeclaringType, arguments))
|
||||
{
|
||||
HasThis = self.HasThis,
|
||||
ExplicitThis = self.ExplicitThis,
|
||||
CallingConvention = self.CallingConvention
|
||||
};
|
||||
foreach (var parameterDefinition in self.Parameters)
|
||||
{
|
||||
methodReference.Parameters.Add(new ParameterDefinition(parameterDefinition.ParameterType));
|
||||
}
|
||||
|
||||
foreach (var genericParameter in self.GenericParameters)
|
||||
{
|
||||
methodReference.GenericParameters.Add(new GenericParameter(genericParameter.Name, methodReference));
|
||||
}
|
||||
|
||||
return methodReference;
|
||||
}
|
||||
|
||||
private class AddSearchDirectoryHelper
|
||||
{
|
||||
public AddSearchDirectoryHelper(IAssemblyResolver assemblyResolver)
|
||||
{
|
||||
var method = assemblyResolver.GetType().GetMethod("AddSearchDirectory", (BindingFlags)20, null, new Type[]
|
||||
{
|
||||
typeof(string)
|
||||
}, null);
|
||||
if (method == null)
|
||||
{
|
||||
throw new Exception("Assembly resolver doesn't implement AddSearchDirectory method.");
|
||||
}
|
||||
|
||||
_addSearchDirectory = (Helpers.AddSearchDirectoryHelper.AddSearchDirectoryDelegate)Delegate.CreateDelegate(typeof(Helpers.AddSearchDirectoryHelper.AddSearchDirectoryDelegate), assemblyResolver, method);
|
||||
}
|
||||
|
||||
public void AddSearchDirectory(string directory) => _addSearchDirectory(directory);
|
||||
|
||||
private readonly Helpers.AddSearchDirectoryHelper.AddSearchDirectoryDelegate _addSearchDirectory;
|
||||
|
||||
private delegate void AddSearchDirectoryDelegate(string directory);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
public static class Log
|
||||
{
|
||||
public static void Warning(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine($"WARN : {msg}");
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public static void Error(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine($"ERR : {msg}");
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
internal class MessageClassProcessor
|
||||
{
|
||||
public MessageClassProcessor(TypeDefinition td)
|
||||
{
|
||||
Weaver.DLog(td, "MessageClassProcessor for " + td.Name, new object[0]);
|
||||
m_td = td;
|
||||
}
|
||||
|
||||
public void Process()
|
||||
{
|
||||
Weaver.DLog(m_td, "MessageClassProcessor Start", new object[0]);
|
||||
Weaver.ResetRecursionCount();
|
||||
GenerateSerialization();
|
||||
if (!Weaver.fail)
|
||||
{
|
||||
GenerateDeSerialization();
|
||||
Weaver.DLog(m_td, "MessageClassProcessor Done", new object[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateSerialization()
|
||||
{
|
||||
Weaver.DLog(m_td, " MessageClass GenerateSerialization", new object[0]);
|
||||
foreach (var methodDefinition in m_td.Methods)
|
||||
{
|
||||
if (methodDefinition.Name == "Serialize")
|
||||
{
|
||||
Weaver.DLog(m_td, " Abort - is Serialize", new object[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_td.Fields.Count != 0)
|
||||
{
|
||||
foreach (var fieldDefinition in m_td.Fields)
|
||||
{
|
||||
if (fieldDefinition.FieldType.FullName == m_td.FullName)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_td.Name,
|
||||
" [",
|
||||
fieldDefinition.FullName,
|
||||
"]. [MessageBase] member cannot be self referencing."
|
||||
}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var methodDefinition2 = new MethodDefinition("Serialize", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
|
||||
methodDefinition2.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
|
||||
var ilprocessor = methodDefinition2.Body.GetILProcessor();
|
||||
foreach (var fieldDefinition2 in m_td.Fields)
|
||||
{
|
||||
if (!fieldDefinition2.IsStatic && !fieldDefinition2.IsPrivate && !fieldDefinition2.IsSpecialName)
|
||||
{
|
||||
if (fieldDefinition2.FieldType.Resolve().HasGenericParameters)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_td.Name,
|
||||
" [",
|
||||
fieldDefinition2.FieldType,
|
||||
"/",
|
||||
fieldDefinition2.FieldType.FullName,
|
||||
"]. [MessageBase] member cannot have generic parameters."
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
if (fieldDefinition2.FieldType.Resolve().IsInterface)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_td.Name,
|
||||
" [",
|
||||
fieldDefinition2.FieldType,
|
||||
"/",
|
||||
fieldDefinition2.FieldType.FullName,
|
||||
"]. [MessageBase] member cannot be an interface."
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
var writeFunc = Weaver.GetWriteFunc(fieldDefinition2.FieldType);
|
||||
if (writeFunc == null)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_td.Name,
|
||||
" unknown type [",
|
||||
fieldDefinition2.FieldType,
|
||||
"/",
|
||||
fieldDefinition2.FieldType.FullName,
|
||||
"]. [MessageBase] member variables must be basic types."
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc));
|
||||
}
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
|
||||
m_td.Methods.Add(methodDefinition2);
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateDeSerialization()
|
||||
{
|
||||
Weaver.DLog(m_td, " GenerateDeserialization", new object[0]);
|
||||
foreach (var methodDefinition in m_td.Methods)
|
||||
{
|
||||
if (methodDefinition.Name == "Deserialize")
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_td.Fields.Count != 0)
|
||||
{
|
||||
var methodDefinition2 = new MethodDefinition("Deserialize", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
|
||||
methodDefinition2.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
||||
var ilprocessor = methodDefinition2.Body.GetILProcessor();
|
||||
foreach (var fieldDefinition in m_td.Fields)
|
||||
{
|
||||
if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate && !fieldDefinition.IsSpecialName)
|
||||
{
|
||||
var readFunc = Weaver.GetReadFunc(fieldDefinition.FieldType);
|
||||
if (readFunc == null)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateDeSerialization for ",
|
||||
m_td.Name,
|
||||
" unknown type [",
|
||||
fieldDefinition.FieldType,
|
||||
"]. [SyncVar] member variables must be basic types."
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldDefinition));
|
||||
}
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
|
||||
m_td.Methods.Add(methodDefinition2);
|
||||
}
|
||||
}
|
||||
|
||||
private TypeDefinition m_td;
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
internal class MonoBehaviourProcessor
|
||||
{
|
||||
public MonoBehaviourProcessor(TypeDefinition td) => m_td = td;
|
||||
|
||||
public void Process()
|
||||
{
|
||||
ProcessSyncVars();
|
||||
ProcessMethods();
|
||||
}
|
||||
|
||||
private void ProcessSyncVars()
|
||||
{
|
||||
foreach (var fieldDefinition in m_td.Fields)
|
||||
{
|
||||
foreach (var customAttribute in fieldDefinition.CustomAttributes)
|
||||
{
|
||||
if (customAttribute.AttributeType.FullName == Weaver.SyncVarType.FullName)
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses [SyncVar] ",
|
||||
fieldDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Helpers.InheritsFromSyncList(fieldDefinition.FieldType))
|
||||
{
|
||||
Log.Error(string.Format("Script {0} defines field {1} with type {2}, but it's not a NetworkBehaviour", m_td.FullName, fieldDefinition.Name, Helpers.PrettyPrintType(fieldDefinition.FieldType)));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessMethods()
|
||||
{
|
||||
foreach (var methodDefinition in m_td.Methods)
|
||||
{
|
||||
foreach (var customAttribute in methodDefinition.CustomAttributes)
|
||||
{
|
||||
if (customAttribute.AttributeType.FullName == Weaver.CommandType.FullName)
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses [Command] ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
|
||||
if (customAttribute.AttributeType.FullName == Weaver.ClientRpcType.FullName)
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses [ClientRpc] ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
|
||||
if (customAttribute.AttributeType.FullName == Weaver.TargetRpcType.FullName)
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses [TargetRpc] ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
|
||||
var text = customAttribute.Constructor.DeclaringType.ToString();
|
||||
if (text == "UnityEngine.Networking.ServerAttribute")
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses the attribute [Server] on the method ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
else if (text == "UnityEngine.Networking.ServerCallbackAttribute")
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses the attribute [ServerCallback] on the method ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
else if (text == "UnityEngine.Networking.ClientAttribute")
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses the attribute [Client] on the method ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
else if (text == "UnityEngine.Networking.ClientCallbackAttribute")
|
||||
{
|
||||
Log.Error(string.Concat(new string[]
|
||||
{
|
||||
"Script ",
|
||||
m_td.FullName,
|
||||
" uses the attribute [ClientCallback] on the method ",
|
||||
methodDefinition.Name,
|
||||
" but is not a NetworkBehaviour."
|
||||
}));
|
||||
Weaver.fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TypeDefinition m_td;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Start weaving process.");
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
Log.Error("No args supplied!");
|
||||
}
|
||||
|
||||
var unityEngine = args[0];
|
||||
var qnetDLL = args[1];
|
||||
var unetDLL = args[2];
|
||||
var outputDirectory = args[3];
|
||||
var assembly = args[4];
|
||||
|
||||
CheckDLLPath(unityEngine);
|
||||
CheckDLLPath(qnetDLL);
|
||||
CheckDLLPath(unetDLL);
|
||||
CheckOutputDirectory(outputDirectory);
|
||||
CheckAssemblyPath(assembly);
|
||||
Weaver.WeaveAssemblies(assembly, null, null, outputDirectory, unityEngine, qnetDLL, unetDLL);
|
||||
}
|
||||
|
||||
private static void CheckDLLPath(string path)
|
||||
{
|
||||
Console.WriteLine($"Check dll {path} ...");
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new Exception("dll could not be located at " + path + "!");
|
||||
}
|
||||
|
||||
Console.WriteLine($"Path OK!");
|
||||
}
|
||||
|
||||
private static void CheckAssemblyPath(string assemblyPath)
|
||||
{
|
||||
Console.WriteLine($"Check assembly path {assemblyPath} ...");
|
||||
if (!File.Exists(assemblyPath))
|
||||
{
|
||||
throw new Exception("Assembly " + assemblyPath + " does not exist!");
|
||||
}
|
||||
|
||||
Console.WriteLine($"Assembly Path OK!");
|
||||
}
|
||||
|
||||
private static void CheckOutputDirectory(string outputDir)
|
||||
{
|
||||
Console.WriteLine($"Check output path {outputDir} ...");
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
Directory.CreateDirectory(outputDir);
|
||||
}
|
||||
|
||||
Console.WriteLine($"Output Path OK!");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("QNetWeaver")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("QNetWeaver")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("e23551f3-c095-4f50-8bf7-85bb2661859b")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -1,72 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E23551F3-C095-4F50-8BF7-85BB2661859B}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>QNetWeaver</RootNamespace>
|
||||
<AssemblyName>QNetWeaver</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Unity.Cecil">
|
||||
<HintPath>..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Cecil.Mdb">
|
||||
<HintPath>..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.Mdb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Cecil.Pdb">
|
||||
<HintPath>..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.Pdb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.UNetWeaver">
|
||||
<HintPath>..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.UNetWeaver.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Helpers.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="MessageClassProcessor.cs" />
|
||||
<Compile Include="MonoBehaviourProcessor.cs" />
|
||||
<Compile Include="NetworkBehaviourProcessor.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SyncListStructProcessor.cs" />
|
||||
<Compile Include="Weaver.cs" />
|
||||
<Compile Include="WeaverLists.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
@ -1,309 +0,0 @@
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
internal class SyncListStructProcessor
|
||||
{
|
||||
public SyncListStructProcessor(TypeDefinition typeDef)
|
||||
{
|
||||
Weaver.DLog(typeDef, "SyncListStructProcessor for " + typeDef.Name, new object[0]);
|
||||
m_TypeDef = typeDef;
|
||||
}
|
||||
|
||||
public void Process()
|
||||
{
|
||||
var genericInstanceType = (GenericInstanceType)m_TypeDef.BaseType;
|
||||
if (genericInstanceType.GenericArguments.Count == 0)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error("SyncListStructProcessor no generic args");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ItemType = Weaver.scriptDef.MainModule.ImportReference(genericInstanceType.GenericArguments[0]);
|
||||
Weaver.DLog(m_TypeDef, "SyncListStructProcessor Start item:" + m_ItemType.FullName, new object[0]);
|
||||
Weaver.ResetRecursionCount();
|
||||
var methodReference = GenerateSerialization();
|
||||
if (!Weaver.fail)
|
||||
{
|
||||
var methodReference2 = GenerateDeserialization();
|
||||
if (methodReference2 != null && methodReference != null)
|
||||
{
|
||||
GenerateReadFunc(methodReference2);
|
||||
GenerateWriteFunc(methodReference);
|
||||
Weaver.DLog(m_TypeDef, "SyncListStructProcessor Done", new object[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateReadFunc(MethodReference readItemFunc)
|
||||
{
|
||||
var text = "_ReadStruct" + m_TypeDef.Name + "_";
|
||||
if (m_TypeDef.DeclaringType != null)
|
||||
{
|
||||
text += m_TypeDef.DeclaringType.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
text += "None";
|
||||
}
|
||||
|
||||
var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
|
||||
methodDefinition.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
||||
methodDefinition.Parameters.Add(new ParameterDefinition("instance", ParameterAttributes.None, m_TypeDef));
|
||||
methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
|
||||
methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
|
||||
methodDefinition.Body.InitLocals = true;
|
||||
var ilprocessor = methodDefinition.Body.GetILProcessor();
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkReadUInt16));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
var method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListClear, new TypeReference[]
|
||||
{
|
||||
m_ItemType
|
||||
});
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
|
||||
var instruction = ilprocessor.Create(OpCodes.Nop);
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Br, instruction));
|
||||
var instruction2 = ilprocessor.Create(OpCodes.Nop);
|
||||
ilprocessor.Append(instruction2);
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, readItemFunc));
|
||||
var self = Weaver.ResolveMethod(Weaver.SyncListStructType, "AddInternal");
|
||||
var method2 = Helpers.MakeHostInstanceGeneric(self, new TypeReference[]
|
||||
{
|
||||
m_ItemType
|
||||
});
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Add));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_U2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
|
||||
ilprocessor.Append(instruction);
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Blt, instruction2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
|
||||
Weaver.RegisterReadByReferenceFunc(m_TypeDef.FullName, methodDefinition);
|
||||
}
|
||||
|
||||
private void GenerateWriteFunc(MethodReference writeItemFunc)
|
||||
{
|
||||
var text = "_WriteStruct" + m_TypeDef.GetElementType().Name + "_";
|
||||
if (m_TypeDef.DeclaringType != null)
|
||||
{
|
||||
text += m_TypeDef.DeclaringType.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
text += "None";
|
||||
}
|
||||
|
||||
var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
|
||||
methodDefinition.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
|
||||
methodDefinition.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(m_TypeDef)));
|
||||
methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
|
||||
methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
|
||||
methodDefinition.Body.InitLocals = true;
|
||||
var ilprocessor = methodDefinition.Body.GetILProcessor();
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
var self = Weaver.ResolveMethod(Weaver.SyncListStructType, "get_Count");
|
||||
var method = Helpers.MakeHostInstanceGeneric(self, new TypeReference[]
|
||||
{
|
||||
m_ItemType
|
||||
});
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriteUInt16));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
|
||||
var instruction = ilprocessor.Create(OpCodes.Nop);
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Br, instruction));
|
||||
var instruction2 = ilprocessor.Create(OpCodes.Nop);
|
||||
ilprocessor.Append(instruction2);
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
|
||||
var self2 = Weaver.ResolveMethod(Weaver.SyncListStructType, "GetItem");
|
||||
var method2 = Helpers.MakeHostInstanceGeneric(self2, new TypeReference[]
|
||||
{
|
||||
m_ItemType
|
||||
});
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, writeItemFunc));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Add));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_U2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
|
||||
ilprocessor.Append(instruction);
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Blt, instruction2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
|
||||
Weaver.RegisterWriteFunc(m_TypeDef.FullName, methodDefinition);
|
||||
}
|
||||
|
||||
private MethodReference GenerateSerialization()
|
||||
{
|
||||
Weaver.DLog(m_TypeDef, " SyncListStruct GenerateSerialization", new object[0]);
|
||||
foreach (var methodDefinition in m_TypeDef.Methods)
|
||||
{
|
||||
if (methodDefinition.Name == "SerializeItem")
|
||||
{
|
||||
Weaver.DLog(m_TypeDef, " Abort - is SerializeItem", new object[0]);
|
||||
return methodDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
var methodDefinition2 = new MethodDefinition("SerializeItem", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
|
||||
methodDefinition2.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
|
||||
methodDefinition2.Parameters.Add(new ParameterDefinition("item", ParameterAttributes.None, m_ItemType));
|
||||
var ilprocessor = methodDefinition2.Body.GetILProcessor();
|
||||
MethodReference result;
|
||||
if (m_ItemType.IsGenericInstance)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error("GenerateSerialization for " + Helpers.PrettyPrintType(m_ItemType) + " failed. Struct passed into SyncListStruct<T> can't have generic parameters");
|
||||
result = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var fieldDefinition in m_ItemType.Resolve().Fields)
|
||||
{
|
||||
if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate && !fieldDefinition.IsSpecialName)
|
||||
{
|
||||
var fieldReference = Weaver.scriptDef.MainModule.ImportReference(fieldDefinition);
|
||||
var typeDefinition = fieldReference.FieldType.Resolve();
|
||||
if (typeDefinition.HasGenericParameters)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_TypeDef.Name,
|
||||
" [",
|
||||
typeDefinition,
|
||||
"/",
|
||||
typeDefinition.FullName,
|
||||
"]. UNet [MessageBase] member cannot have generic parameters."
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeDefinition.IsInterface)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_TypeDef.Name,
|
||||
" [",
|
||||
typeDefinition,
|
||||
"/",
|
||||
typeDefinition.FullName,
|
||||
"]. UNet [MessageBase] member cannot be an interface."
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
var writeFunc = Weaver.GetWriteFunc(fieldDefinition.FieldType);
|
||||
if (writeFunc == null)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateSerialization for ",
|
||||
m_TypeDef.Name,
|
||||
" unknown type [",
|
||||
typeDefinition,
|
||||
"/",
|
||||
typeDefinition.FullName,
|
||||
"]. UNet [MessageBase] member variables must be basic types."
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_2));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldReference));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc));
|
||||
}
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
|
||||
m_TypeDef.Methods.Add(methodDefinition2);
|
||||
result = methodDefinition2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private MethodReference GenerateDeserialization()
|
||||
{
|
||||
Weaver.DLog(m_TypeDef, " GenerateDeserialization", new object[0]);
|
||||
foreach (var methodDefinition in m_TypeDef.Methods)
|
||||
{
|
||||
if (methodDefinition.Name == "DeserializeItem")
|
||||
{
|
||||
return methodDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
var methodDefinition2 = new MethodDefinition("DeserializeItem", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, m_ItemType);
|
||||
methodDefinition2.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
||||
var ilprocessor = methodDefinition2.Body.GetILProcessor();
|
||||
ilprocessor.Body.InitLocals = true;
|
||||
ilprocessor.Body.Variables.Add(new VariableDefinition(m_ItemType));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca, 0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Initobj, m_ItemType));
|
||||
foreach (var fieldDefinition in m_ItemType.Resolve().Fields)
|
||||
{
|
||||
if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate && !fieldDefinition.IsSpecialName)
|
||||
{
|
||||
var fieldReference = Weaver.scriptDef.MainModule.ImportReference(fieldDefinition);
|
||||
var typeDefinition = fieldReference.FieldType.Resolve();
|
||||
var readFunc = Weaver.GetReadFunc(fieldDefinition.FieldType);
|
||||
if (readFunc == null)
|
||||
{
|
||||
Weaver.fail = true;
|
||||
Log.Error(string.Concat(new object[]
|
||||
{
|
||||
"GenerateDeserialization for ",
|
||||
m_TypeDef.Name,
|
||||
" unknown type [",
|
||||
typeDefinition,
|
||||
"]. UNet [SyncVar] member variables must be basic types."
|
||||
}));
|
||||
return null;
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca, 0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldReference));
|
||||
}
|
||||
}
|
||||
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
|
||||
ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
|
||||
m_TypeDef.Methods.Add(methodDefinition2);
|
||||
return methodDefinition2;
|
||||
}
|
||||
|
||||
private TypeDefinition m_TypeDef;
|
||||
|
||||
private TypeReference m_ItemType;
|
||||
}
|
||||
}
|
2038
QNetWeaver/Weaver.cs
2038
QNetWeaver/Weaver.cs
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
||||
using Mono.Cecil;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QNetWeaver
|
||||
{
|
||||
internal class WeaverLists
|
||||
{
|
||||
public List<FieldDefinition> replacedFields = new List<FieldDefinition>();
|
||||
|
||||
public List<MethodDefinition> replacementProperties = new List<MethodDefinition>();
|
||||
|
||||
public List<FieldDefinition> netIdFields = new List<FieldDefinition>();
|
||||
|
||||
public List<MethodDefinition> replacedMethods = new List<MethodDefinition>();
|
||||
|
||||
public List<MethodDefinition> replacementMethods = new List<MethodDefinition>();
|
||||
|
||||
public HashSet<string> replacementMethodNames = new HashSet<string>();
|
||||
|
||||
public List<EventDefinition> replacedEvents = new List<EventDefinition>();
|
||||
|
||||
public List<MethodDefinition> replacementEvents = new List<MethodDefinition>();
|
||||
|
||||
public Dictionary<string, MethodReference> readFuncs;
|
||||
|
||||
public Dictionary<string, MethodReference> readByReferenceFuncs;
|
||||
|
||||
public Dictionary<string, MethodReference> writeFuncs;
|
||||
|
||||
public List<MethodDefinition> generatedReadFunctions = new List<MethodDefinition>();
|
||||
|
||||
public List<MethodDefinition> generatedWriteFunctions = new List<MethodDefinition>();
|
||||
|
||||
public TypeDefinition generateContainerClass;
|
||||
|
||||
public Dictionary<string, int> numSyncVars = new Dictionary<string, int>();
|
||||
}
|
||||
}
|
14
QSB.sln
14
QSB.sln
@ -1,22 +1,18 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29613.14
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSB", "QSB\QSB.csproj", "{1F00090A-C697-4C55-B401-192F3CFB9DC2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{E23551F3-C095-4F50-8BF7-85BB2661859B} = {E23551F3-C095-4F50-8BF7-85BB2661859B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuantumUNET", "QuantumUNET\QuantumUNET.csproj", "{C8C53004-1508-4F86-A419-4292C188DC2A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSBTests", "QSBTests\QSBTests.csproj", "{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QNetWeaver", "QNetWeaver\QNetWeaver.csproj", "{E23551F3-C095-4F50-8BF7-85BB2661859B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2569F98D-F671-42AA-82DE-505B05CDCEF2}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.gitignore = .gitignore
|
||||
Directory.Build.targets = Directory.Build.targets
|
||||
LICENSE = LICENSE
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
@ -39,10 +35,6 @@ Global
|
||||
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E23551F3-C095-4F50-8BF7-85BB2661859B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E23551F3-C095-4F50-8BF7-85BB2661859B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E23551F3-C095-4F50-8BF7-85BB2661859B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E23551F3-C095-4F50-8BF7-85BB2661859B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
11
QSB/Anglerfish/AnglerManager.cs
Normal file
11
QSB/Anglerfish/AnglerManager.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using QSB.Anglerfish.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.Anglerfish
|
||||
{
|
||||
public class AnglerManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
=> QSBWorldSync.Init<QSBAngler, AnglerfishController>();
|
||||
}
|
||||
}
|
82
QSB/Anglerfish/Events/AnglerChangeStateEvent.cs
Normal file
82
QSB/Anglerfish/Events/AnglerChangeStateEvent.cs
Normal file
@ -0,0 +1,82 @@
|
||||
using QSB.Anglerfish.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
using EventType = QSB.Events.EventType;
|
||||
|
||||
namespace QSB.Anglerfish.Events
|
||||
{
|
||||
public class AnglerChangeStateEvent : QSBEvent<AnglerChangeStateMessage>
|
||||
{
|
||||
public override EventType Type => EventType.AnglerChangeState;
|
||||
|
||||
public override void SetupListener()
|
||||
=> GlobalMessenger<QSBAngler>.AddListener(EventNames.QSBAnglerChangeState, Handler);
|
||||
|
||||
public override void CloseListener()
|
||||
=> GlobalMessenger<QSBAngler>.RemoveListener(EventNames.QSBAnglerChangeState, Handler);
|
||||
|
||||
private void Handler(QSBAngler qsbAngler) => SendEvent(CreateMessage(qsbAngler));
|
||||
|
||||
private AnglerChangeStateMessage CreateMessage(QSBAngler qsbAngler) => new()
|
||||
{
|
||||
ObjectId = qsbAngler.ObjectId,
|
||||
EnumValue = qsbAngler.AttachedObject._currentState,
|
||||
TargetId = TargetToId(qsbAngler.TargetTransform),
|
||||
LocalDisturbancePos = qsbAngler.AttachedObject._localDisturbancePos
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool isHost, AnglerChangeStateMessage message) => OnReceive(isHost, message);
|
||||
public override void OnReceiveRemote(bool isHost, AnglerChangeStateMessage message) => OnReceive(isHost, message);
|
||||
|
||||
private static void OnReceive(bool isHost, AnglerChangeStateMessage message)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromId<QSBAngler>(message.ObjectId);
|
||||
|
||||
if (isHost)
|
||||
{
|
||||
qsbAngler.TransferAuthority(message.FromId);
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = IdToTarget(message.TargetId);
|
||||
qsbAngler.AttachedObject._localDisturbancePos = message.LocalDisturbancePos;
|
||||
qsbAngler.AttachedObject.ChangeState(message.EnumValue);
|
||||
}
|
||||
|
||||
private static uint TargetToId(Transform transform)
|
||||
{
|
||||
if (transform == null)
|
||||
{
|
||||
return uint.MaxValue;
|
||||
}
|
||||
|
||||
if (transform == Locator.GetShipTransform())
|
||||
{
|
||||
return uint.MaxValue - 1;
|
||||
}
|
||||
|
||||
return QSBPlayerManager.LocalPlayerId;
|
||||
}
|
||||
|
||||
private static Transform IdToTarget(uint id)
|
||||
{
|
||||
if (id == uint.MaxValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (id == uint.MaxValue - 1)
|
||||
{
|
||||
return Locator.GetShipTransform();
|
||||
}
|
||||
|
||||
return QSBPlayerManager.GetPlayer(id).Body.transform;
|
||||
}
|
||||
}
|
||||
}
|
26
QSB/Anglerfish/Events/AnglerChangeStateMessage.cs
Normal file
26
QSB/Anglerfish/Events/AnglerChangeStateMessage.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using QSB.WorldSync.Events;
|
||||
using QuantumUNET.Transport;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Anglerfish.Events
|
||||
{
|
||||
public class AnglerChangeStateMessage : EnumWorldObjectMessage<AnglerfishController.AnglerState>
|
||||
{
|
||||
public uint TargetId;
|
||||
public Vector3 LocalDisturbancePos;
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
TargetId = reader.ReadUInt32();
|
||||
LocalDisturbancePos = reader.ReadVector3();
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(TargetId);
|
||||
writer.Write(LocalDisturbancePos);
|
||||
}
|
||||
}
|
||||
}
|
362
QSB/Anglerfish/Patches/AnglerPatches.cs
Normal file
362
QSB/Anglerfish/Patches/AnglerPatches.cs
Normal file
@ -0,0 +1,362 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Anglerfish.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Anglerfish.Patches
|
||||
{
|
||||
public class AnglerPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.GetTargetPosition))]
|
||||
public static bool GetTargetPosition(AnglerfishController __instance, ref Vector3 __result)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__result = qsbAngler.TargetTransform != null
|
||||
? qsbAngler.TargetTransform.position
|
||||
: __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnSectorOccupantRemoved))]
|
||||
public static bool OnSectorOccupantRemoved(AnglerfishController __instance,
|
||||
SectorDetector sectorDetector)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(qsbAngler.TargetTransform != null) || !(sectorDetector.GetAttachedOWRigidbody().transform == qsbAngler.TargetTransform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.UpdateState))]
|
||||
public static bool UpdateState(AnglerfishController __instance)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (__instance._currentState)
|
||||
{
|
||||
case AnglerfishController.AnglerState.Investigating:
|
||||
if ((__instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos) - __instance._anglerBody.GetPosition()).sqrMagnitude >= __instance._arrivalDistance * (double)__instance._arrivalDistance)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Chasing:
|
||||
if (qsbAngler.TargetTransform == null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((qsbAngler.TargetTransform.position - __instance._anglerBody.GetPosition()).sqrMagnitude <= __instance._escapeDistance * (double)__instance._escapeDistance)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Consuming:
|
||||
if (__instance._consumeComplete)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (qsbAngler.TargetTransform == null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
}
|
||||
|
||||
var num = Time.time - __instance._consumeStartTime;
|
||||
if (qsbAngler.TargetTransform.CompareTag("Player") && num > (double)__instance._consumeDeathDelay)
|
||||
{
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
__instance.ApplyDrag(1f);
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
__instance._consumeComplete = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!qsbAngler.TargetTransform.CompareTag("Ship"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (num > (double)__instance._consumeShipCrushDelay)
|
||||
{
|
||||
qsbAngler.TargetTransform.GetComponentInChildren<ShipDamageController>().TriggerSystemFailure();
|
||||
}
|
||||
|
||||
if (num <= (double)__instance._consumeDeathDelay)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (PlayerState.IsInsideShip())
|
||||
{
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
__instance.ApplyDrag(1f);
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
}
|
||||
|
||||
__instance._consumeComplete = true;
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Stunned:
|
||||
__instance._stunTimer -= Time.deltaTime;
|
||||
if (__instance._stunTimer > 0.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (qsbAngler.TargetTransform != null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.UpdateMovement))]
|
||||
public static bool UpdateMovement(AnglerfishController __instance)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.FixedUpdate();
|
||||
|
||||
if (__instance._anglerBody.GetVelocity().sqrMagnitude > (double)Mathf.Pow(__instance._chaseSpeed * 1.5f, 2f))
|
||||
{
|
||||
__instance.ApplyDrag(10f);
|
||||
}
|
||||
|
||||
switch (__instance._currentState)
|
||||
{
|
||||
case AnglerfishController.AnglerState.Lurking:
|
||||
__instance.ApplyDrag(1f);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Investigating:
|
||||
var targetPos = __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
|
||||
__instance.RotateTowardsTarget(targetPos, __instance._turnSpeed, __instance._turnSpeed);
|
||||
if (__instance._turningInPlace)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
__instance.MoveTowardsTarget(targetPos, __instance._investigateSpeed, __instance._acceleration);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Chasing:
|
||||
var velocity = qsbAngler.TargetVelocity;
|
||||
var normalized = velocity.normalized;
|
||||
var from = __instance._anglerBody.GetPosition() + __instance.transform.TransformDirection(__instance._mouthOffset) - qsbAngler.TargetTransform.position;
|
||||
var magnitude1 = velocity.magnitude;
|
||||
var num1 = Vector3.Angle(from, normalized);
|
||||
var a = magnitude1 * 2f;
|
||||
var num2 = a;
|
||||
if (num1 < 90.0)
|
||||
{
|
||||
var magnitude2 = (double)from.magnitude;
|
||||
var num3 = (float)magnitude2 * Mathf.Sin(num1 * ((float)Math.PI / 180f));
|
||||
var num4 = (float)magnitude2 * Mathf.Cos(num1 * ((float)Math.PI / 180f));
|
||||
var magnitude3 = __instance._anglerBody.GetVelocity().magnitude;
|
||||
var num5 = num4 / Mathf.Max(magnitude1, 0.0001f) / (num3 / Mathf.Max(magnitude3, 0.0001f));
|
||||
if (num5 <= 1.0)
|
||||
{
|
||||
var t = Mathf.Clamp01(num5);
|
||||
num2 = Mathf.Lerp(a, num4, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
var num6 = Mathf.InverseLerp(1f, 4f, num5);
|
||||
num2 = Mathf.Lerp(num4, 0.0f, num6 * num6);
|
||||
}
|
||||
}
|
||||
|
||||
__instance._targetPos = qsbAngler.TargetTransform.position + (normalized * num2);
|
||||
__instance.RotateTowardsTarget(__instance._targetPos, __instance._turnSpeed, __instance._quickTurnSpeed);
|
||||
if (__instance._turningInPlace)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
__instance.MoveTowardsTarget(__instance._targetPos, __instance._chaseSpeed, __instance._acceleration);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Consuming:
|
||||
__instance.ApplyDrag(1f);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Stunned:
|
||||
__instance.ApplyDrag(0.5f);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnImpact))]
|
||||
public static bool OnImpact(AnglerfishController __instance,
|
||||
ImpactData impact)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var attachedOwRigidbody = impact.otherCollider.GetAttachedOWRigidbody();
|
||||
if ((attachedOwRigidbody.CompareTag("Player") || attachedOwRigidbody.CompareTag("Ship"))
|
||||
&& __instance._currentState != AnglerfishController.AnglerState.Consuming
|
||||
&& __instance._currentState != AnglerfishController.AnglerState.Stunned)
|
||||
{
|
||||
qsbAngler.TargetTransform = attachedOwRigidbody.transform;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnClosestAudibleNoise))]
|
||||
public static bool OnClosestAudibleNoise(AnglerfishController __instance,
|
||||
NoiseMaker noiseMaker)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__instance._currentState is AnglerfishController.AnglerState.Consuming
|
||||
or AnglerfishController.AnglerState.Stunned)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((noiseMaker.GetNoiseOrigin() - __instance.transform.position).sqrMagnitude < __instance._pursueDistance * (double)__instance._pursueDistance)
|
||||
{
|
||||
if (!(qsbAngler.TargetTransform != noiseMaker.GetAttachedBody().transform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = noiseMaker.GetAttachedBody().transform;
|
||||
if (__instance._currentState == AnglerfishController.AnglerState.Chasing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__instance._currentState is not AnglerfishController.AnglerState.Lurking
|
||||
and not AnglerfishController.AnglerState.Investigating)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance._localDisturbancePos = __instance._brambleBody.transform.InverseTransformPoint(noiseMaker.GetNoiseOrigin());
|
||||
if (__instance._currentState == AnglerfishController.AnglerState.Investigating)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Investigating);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnCaughtObject))]
|
||||
public static bool OnCaughtObject(AnglerfishController __instance,
|
||||
OWRigidbody caughtBody)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
|
||||
if (__instance._currentState == AnglerfishController.AnglerState.Consuming)
|
||||
{
|
||||
if (qsbAngler.TargetTransform.CompareTag("Player") || !caughtBody.CompareTag("Player"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!caughtBody.CompareTag("Player") && !caughtBody.CompareTag("Ship"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = caughtBody.transform;
|
||||
__instance._consumeStartTime = Time.time;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Consuming);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
83
QSB/Anglerfish/TransformSync/AnglerTransformSync.cs
Normal file
83
QSB/Anglerfish/TransformSync/AnglerTransformSync.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using QSB.Anglerfish.WorldObjects;
|
||||
using QSB.Syncs.Unsectored.Rigidbodies;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Anglerfish.TransformSync
|
||||
{
|
||||
public class AnglerTransformSync : UnsectoredRigidbodySync
|
||||
{
|
||||
public override bool IsReady => QSBCore.WorldObjectsReady;
|
||||
public override bool UseInterpolation => false;
|
||||
|
||||
private QSBAngler _qsbAngler;
|
||||
private static readonly List<AnglerTransformSync> _instances = new();
|
||||
|
||||
protected override OWRigidbody GetRigidbody()
|
||||
=> _qsbAngler.AttachedObject._anglerBody;
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
_instances.Add(this);
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
_instances.Remove(this);
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
public override float GetNetworkSendInterval() => 1;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
_qsbAngler = QSBWorldSync.GetWorldFromId<QSBAngler>(_instances.IndexOf(this));
|
||||
_qsbAngler.TransformSync = this;
|
||||
|
||||
base.Init();
|
||||
SetReferenceTransform(_qsbAngler.AttachedObject._brambleBody.transform);
|
||||
}
|
||||
|
||||
private bool _shouldUpdate;
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
_shouldUpdate = true;
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
if (!_shouldUpdate)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_shouldUpdate = false;
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
protected override void OnRenderObject()
|
||||
{
|
||||
base.OnRenderObject();
|
||||
|
||||
if (!QSBCore.WorldObjectsReady
|
||||
|| !QSBCore.ShowLinesInDebug
|
||||
|| !IsReady
|
||||
|| ReferenceTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Line(AttachedObject.transform.position, _qsbAngler.AttachedObject.GetTargetPosition(), Color.white);
|
||||
}
|
||||
}
|
||||
}
|
69
QSB/Anglerfish/WorldObjects/QSBAngler.cs
Normal file
69
QSB/Anglerfish/WorldObjects/QSBAngler.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using QSB.Anglerfish.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace QSB.Anglerfish.WorldObjects
|
||||
{
|
||||
public class QSBAngler : WorldObject<AnglerfishController>
|
||||
{
|
||||
public AnglerTransformSync TransformSync;
|
||||
public Transform TargetTransform;
|
||||
public Vector3 TargetVelocity { get; private set; }
|
||||
|
||||
private Vector3 _lastTargetPosition;
|
||||
|
||||
public override void Init(AnglerfishController attachedObject, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = attachedObject;
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab).SpawnWithServerAuthority();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QNetworkServer.Destroy(TransformSync.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void TransferAuthority(uint id)
|
||||
{
|
||||
var conn = QNetworkServer.connections.First(x => x.GetPlayerId() == id);
|
||||
var identity = TransformSync.NetIdentity;
|
||||
|
||||
if (identity.ClientAuthorityOwner == conn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.ClientAuthorityOwner != null)
|
||||
{
|
||||
identity.RemoveClientAuthority(identity.ClientAuthorityOwner);
|
||||
}
|
||||
|
||||
identity.AssignClientAuthority(conn);
|
||||
|
||||
DebugLog.DebugWrite($"angler {ObjectId} - transferred authority to {id}");
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
{
|
||||
if (TargetTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TargetVelocity = TargetTransform.position - _lastTargetPosition;
|
||||
_lastTargetPosition = TargetTransform.position;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC
|
||||
{
|
||||
@ -11,10 +10,12 @@ namespace QSB.Animation.NPC
|
||||
{
|
||||
QSBWorldSync.Init<QSBCharacterAnimController, CharacterAnimController>();
|
||||
QSBWorldSync.Init<QSBTravelerController, TravelerController>();
|
||||
QSBWorldSync.Init<QSBSolanumController, NomaiConversationManager>();
|
||||
QSBWorldSync.Init<QSBSolanumAnimController, SolanumAnimController>();
|
||||
|
||||
//MOVE : this is the wrong place to put this... move it to Conversations?
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
||||
QSBWorldSync.OldDialogueTrees = QSBWorldSync.GetUnityObjects<CharacterDialogueTree>().ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace QSB.Animation.NPC.Events
|
||||
|
||||
private void Handler(AnimationEvent animEvent, int index) => SendEvent(CreateMessage(animEvent, index));
|
||||
|
||||
private NpcAnimationMessage CreateMessage(AnimationEvent animEvent, int index) => new NpcAnimationMessage
|
||||
private NpcAnimationMessage CreateMessage(AnimationEvent animEvent, int index) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
AnimationEvent = animEvent,
|
||||
|
@ -8,7 +8,6 @@ using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.Patches
|
||||
@ -24,7 +23,6 @@ namespace QSB.Animation.NPC.Patches
|
||||
CharacterAnimController __instance,
|
||||
float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
bool ____playerInHeadZone,
|
||||
bool ____inConversation,
|
||||
ref float ____currentLookWeight,
|
||||
ref Vector3 ____currentLookTarget,
|
||||
@ -39,7 +37,7 @@ namespace QSB.Animation.NPC.Patches
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController>(__instance); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
PlayerInfo playerToUse = null;
|
||||
if (____inConversation)
|
||||
@ -100,8 +98,8 @@ namespace QSB.Animation.NPC.Patches
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneExit))]
|
||||
public static bool HeadZoneExit(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitNonNomaiHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -109,21 +107,19 @@ namespace QSB.Animation.NPC.Patches
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneEntry))]
|
||||
public static bool HeadZoneEntry(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterNonNomaiHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(FacePlayerWhenTalking), nameof(FacePlayerWhenTalking.OnStartConversation))]
|
||||
public static bool OnStartConversation(
|
||||
FacePlayerWhenTalking __instance,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
public static bool OnStartConversation(FacePlayerWhenTalking __instance)
|
||||
{
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(__instance._dialogueTree);
|
||||
if (playerId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No player talking to {____dialogueTree.name}!", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - No player talking to {__instance._dialogueTree.name}!", MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -134,7 +130,7 @@ namespace QSB.Animation.NPC.Patches
|
||||
var angle = Vector3.Angle(__instance.transform.forward, vector2) * Mathf.Sign(Vector3.Dot(vector2, __instance.transform.right));
|
||||
var axis = __instance.transform.parent.InverseTransformDirection(__instance.transform.up);
|
||||
var lhs = Quaternion.AngleAxis(angle, axis);
|
||||
__instance.GetType().GetMethod("FaceLocalRotation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { lhs * __instance.transform.localRotation });
|
||||
__instance.FaceLocalRotation(lhs * __instance.transform.localRotation);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -173,22 +169,18 @@ namespace QSB.Animation.NPC.Patches
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(KidRockController), nameof(KidRockController.Update))]
|
||||
public static bool UpdateReplacement(
|
||||
KidRockController __instance,
|
||||
bool ____throwingRock,
|
||||
CharacterDialogueTree ____dialogueTree,
|
||||
float ____nextThrowTime)
|
||||
public static bool UpdateReplacement(KidRockController __instance)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldObjects<QSBCharacterAnimController>().First(x => x.GetDialogueTree() == ____dialogueTree);
|
||||
var qsbObj = QSBWorldSync.GetWorldObjects<QSBCharacterAnimController>().First(x => x.GetDialogueTree() == __instance._dialogueTree);
|
||||
|
||||
if (!____throwingRock && !qsbObj.InConversation() && Time.time > ____nextThrowTime)
|
||||
if (!__instance._throwingRock && !qsbObj.InConversation() && Time.time > __instance._nextThrowTime)
|
||||
{
|
||||
__instance.GetType().GetMethod("StartRockThrow", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null);
|
||||
__instance.StartRockThrow();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
229
QSB/Animation/NPC/Patches/SolanumPatches.cs
Normal file
229
QSB/Animation/NPC/Patches/SolanumPatches.cs
Normal file
@ -0,0 +1,229 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class SolanumPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SolanumAnimController), nameof(SolanumAnimController.LateUpdate))]
|
||||
public static bool SolanumLateUpdateReplacement(SolanumAnimController __instance)
|
||||
{
|
||||
if (__instance._animatorStateEvents == null)
|
||||
{
|
||||
__instance._animatorStateEvents = __instance._animator.GetBehaviour<AnimatorStateEvents>();
|
||||
__instance._animatorStateEvents.OnEnterState += __instance.OnEnterAnimatorState;
|
||||
}
|
||||
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance);
|
||||
var playersInHeadZone = qsbObj.GetPlayersInHeadZone();
|
||||
|
||||
var targetCamera = playersInHeadZone == null || playersInHeadZone.Count == 0
|
||||
? __instance._playerCameraTransform
|
||||
: QSBPlayerManager.GetClosestPlayerToWorldPoint(playersInHeadZone, __instance.transform.position).CameraBody.transform;
|
||||
|
||||
var targetValue = Quaternion.LookRotation(targetCamera.position - __instance._headBoneTransform.position, __instance.transform.up);
|
||||
__instance._currentLookRotation = __instance._lookSpring.Update(__instance._currentLookRotation, targetValue, Time.deltaTime);
|
||||
|
||||
var position = __instance._headBoneTransform.position + (__instance._currentLookRotation * Vector3.forward);
|
||||
__instance._localLookPosition = __instance.transform.InverseTransformPoint(position);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.OnEnterWatchVolume))]
|
||||
public static bool EnterWatchZone(NomaiConversationManager __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance._solanumAnimController);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterNomaiHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.OnExitWatchVolume))]
|
||||
public static bool ExitWatchZone(NomaiConversationManager __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance._solanumAnimController);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitNomaiHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.Update))]
|
||||
public static bool ReplacementUpdate(NomaiConversationManager __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBSolanumAnimController>(__instance._solanumAnimController);
|
||||
__instance._playerInWatchVolume = qsbObj.GetPlayersInHeadZone().Any();
|
||||
|
||||
if (!__instance._initialized)
|
||||
{
|
||||
__instance.InitializeNomaiText();
|
||||
}
|
||||
|
||||
//var heldItem = Locator.GetToolModeSwapper().GetItemCarryTool().GetHeldItem();
|
||||
//var holdingConversationStone = heldItem != null && heldItem is NomaiConversationStone;
|
||||
var holdingConversationStone = QSBPlayerManager.GetPlayerCarryItems().Any(x => x.Item2 != null && x.Item2.GetItemType() == ItemType.ConversationStone);
|
||||
|
||||
switch (__instance._state)
|
||||
{
|
||||
case NomaiConversationManager.State.WatchingSky:
|
||||
if (__instance._playerInWatchVolume)
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.WatchingPlayer;
|
||||
__instance._solanumAnimController.StartWatchingPlayer();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NomaiConversationManager.State.WatchingPlayer:
|
||||
if (!__instance._solanumAnimController.isPerformingAction)
|
||||
{
|
||||
// player left watch zone
|
||||
if (!__instance._playerInWatchVolume)
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.WatchingSky;
|
||||
__instance._solanumAnimController.StopWatchingPlayer();
|
||||
}
|
||||
else if (__instance._dialogueComplete)
|
||||
{
|
||||
// create conversation stones
|
||||
if (__instance._dialogueComplete && !__instance._conversationStonesCreated)
|
||||
{
|
||||
__instance._stoneCreationTimer -= Time.deltaTime;
|
||||
if (__instance._stoneCreationTimer <= 0f)
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.CreatingStones;
|
||||
__instance._solanumAnimController.PlayCreateWordStones();
|
||||
}
|
||||
}
|
||||
else if (__instance._conversationStonesCreated && !__instance._cairnRaised)
|
||||
{
|
||||
if (!holdingConversationStone)
|
||||
{
|
||||
__instance._stoneGestureTimer -= Time.deltaTime;
|
||||
if (__instance._stoneGestureTimer <= 0f)
|
||||
{
|
||||
__instance._solanumAnimController.PlayGestureToWordStones();
|
||||
__instance._stoneGestureTimer = UnityEngine.Random.Range(8f, 16f);
|
||||
}
|
||||
}
|
||||
// raise cairns
|
||||
else if (__instance._solanumAnimController.IsPlayerLooking())
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.RaisingCairns;
|
||||
__instance._solanumAnimController.PlayRaiseCairns();
|
||||
__instance._cairnAnimator.SetTrigger("Raise");
|
||||
__instance._cairnCollision.SetActivation(true);
|
||||
}
|
||||
}
|
||||
else if (__instance._activeResponseText == null && __instance._hasValidSocketedStonePair)
|
||||
{
|
||||
__instance._activeResponseText = __instance._pendingResponseText;
|
||||
__instance._pendingResponseText = null;
|
||||
__instance._state = NomaiConversationManager.State.WritingResponse;
|
||||
__instance._solanumAnimController.StartWritingMessage();
|
||||
}
|
||||
else if (__instance._activeResponseText != null && (!__instance._hasValidSocketedStonePair || __instance._pendingResponseText != null))
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.ErasingResponse;
|
||||
__instance._solanumAnimController.StartWritingMessage();
|
||||
}
|
||||
else if (!holdingConversationStone)
|
||||
{
|
||||
if (__instance._playerWasHoldingStone)
|
||||
{
|
||||
__instance.ResetStoneGestureTimer();
|
||||
}
|
||||
|
||||
__instance._stoneGestureTimer -= Time.deltaTime;
|
||||
if (__instance._stoneGestureTimer < 0f)
|
||||
{
|
||||
__instance._solanumAnimController.PlayGestureToWordStones();
|
||||
__instance.ResetStoneGestureTimer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!__instance._playerWasHoldingStone)
|
||||
{
|
||||
__instance.ResetCairnGestureTimer();
|
||||
}
|
||||
|
||||
__instance._cairnGestureTimer -= Time.deltaTime;
|
||||
if (__instance._cairnGestureTimer < 0f)
|
||||
{
|
||||
__instance._solanumAnimController.PlayGestureToCairns();
|
||||
__instance.ResetCairnGestureTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NomaiConversationManager.State.CreatingStones:
|
||||
if (!__instance._solanumAnimController.isPerformingAction)
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.WatchingPlayer;
|
||||
__instance._conversationStonesCreated = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NomaiConversationManager.State.RaisingCairns:
|
||||
if (!__instance._solanumAnimController.isPerformingAction)
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.WatchingPlayer;
|
||||
__instance._cairnRaised = true;
|
||||
__instance._stoneSocketATrigger.SetActivation(true);
|
||||
__instance._stoneSocketBTrigger.SetActivation(true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NomaiConversationManager.State.ErasingResponse:
|
||||
if (!__instance._solanumAnimController.isStartingWrite && !__instance._activeResponseText.IsAnimationPlaying())
|
||||
{
|
||||
__instance._activeResponseText = null;
|
||||
if (__instance._pendingResponseText == null)
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.WatchingPlayer;
|
||||
__instance._solanumAnimController.StopWritingMessage(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance._activeResponseText = __instance._pendingResponseText;
|
||||
__instance._pendingResponseText = null;
|
||||
__instance._state = NomaiConversationManager.State.WritingResponse;
|
||||
__instance._activeResponseText.Show();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NomaiConversationManager.State.WritingResponse:
|
||||
if (!__instance._solanumAnimController.isStartingWrite && !__instance._activeResponseText.IsAnimationPlaying())
|
||||
{
|
||||
__instance._state = NomaiConversationManager.State.WatchingPlayer;
|
||||
__instance._solanumAnimController.StopWritingMessage(true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
__instance._playerWasHoldingStone = holdingConversationStone;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
164
QSB/Animation/NPC/Patches/TravelerControllerPatches.cs
Normal file
164
QSB/Animation/NPC/Patches/TravelerControllerPatches.cs
Normal file
@ -0,0 +1,164 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.Patches
|
||||
{
|
||||
[HarmonyPatch(typeof(TravelerController))]
|
||||
public class TravelerControllerPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(TravelerController.OnStartConversation))]
|
||||
public static bool OnStartConversation(TravelerController __instance)
|
||||
{
|
||||
__instance._talking = true;
|
||||
|
||||
if (__instance is GabbroTravelerController gabbro)
|
||||
{
|
||||
if (gabbro._animator.enabled)
|
||||
{
|
||||
gabbro._animator.CrossFadeInFixedTime("Gabbro_Talking", 1.8f);
|
||||
gabbro._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Talking", 1.8f);
|
||||
}
|
||||
|
||||
Locator.GetTravelerAudioManager().StopTravelerAudio(gabbro.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__instance._animator != null && __instance._animator.enabled)
|
||||
{
|
||||
__instance._playingAnimID = __instance._animator.IsInTransition(0)
|
||||
? __instance._animator.GetNextAnimatorStateInfo(0).fullPathHash
|
||||
: __instance._animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
|
||||
|
||||
__instance._animator.SetTrigger("Talking");
|
||||
}
|
||||
|
||||
Locator.GetTravelerAudioManager().StopTravelerAudio(__instance.name);
|
||||
|
||||
if (__instance is ChertTravelerController chert)
|
||||
{
|
||||
chert._moodWeight = (float)chert._mood;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(TravelerController.OnEndConversation))]
|
||||
public static bool OnEndConversation(TravelerController __instance)
|
||||
{
|
||||
if (__instance is GabbroTravelerController gabbro)
|
||||
{
|
||||
if (gabbro._animator.enabled)
|
||||
{
|
||||
gabbro._animator.CrossFadeInFixedTime("Gabbro_Playing", gabbro._delayToRestartAudio, -1, -gabbro._delayToRestartAudio);
|
||||
gabbro._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Playing", gabbro._delayToRestartAudio, -1, -gabbro._delayToRestartAudio);
|
||||
}
|
||||
|
||||
Locator.GetTravelerAudioManager().PlayTravelerAudio(gabbro.name, gabbro._delayToRestartAudio);
|
||||
if (DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_REMINDER") || DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION"))
|
||||
{
|
||||
var conditionState = DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION");
|
||||
DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_REMINDER");
|
||||
DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_ATTENTION");
|
||||
GlobalMessenger<bool>.FireEvent("TriggerMapPromptReminder", conditionState);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__instance._animator != null && __instance._animator.enabled)
|
||||
{
|
||||
if (__instance._delayToRestartAudio > 0f)
|
||||
{
|
||||
__instance._animator.CrossFadeInFixedTime(__instance._playingAnimID, __instance._delayToRestartAudio, -1, -__instance._delayToRestartAudio);
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance._animator.SetTrigger("Playing");
|
||||
}
|
||||
}
|
||||
|
||||
Locator.GetTravelerAudioManager().PlayTravelerAudio(__instance.name, __instance._delayToRestartAudio);
|
||||
}
|
||||
|
||||
__instance._talking = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class TravelerAudioManagerExtensions
|
||||
{
|
||||
/// bad, but works great
|
||||
private static SignalName TravelerToSignal(string name)
|
||||
{
|
||||
if (name.Contains("Esker"))
|
||||
{
|
||||
return SignalName.Traveler_Esker;
|
||||
}
|
||||
|
||||
if (name.Contains("Chert"))
|
||||
{
|
||||
return SignalName.Traveler_Chert;
|
||||
}
|
||||
|
||||
if (name.Contains("Riebeck"))
|
||||
{
|
||||
return SignalName.Traveler_Riebeck;
|
||||
}
|
||||
|
||||
if (name.Contains("Gabbro"))
|
||||
{
|
||||
return SignalName.Traveler_Gabbro;
|
||||
}
|
||||
|
||||
if (name.Contains("Feldspar"))
|
||||
{
|
||||
return SignalName.Traveler_Feldspar;
|
||||
}
|
||||
|
||||
if (name.Contains("Nomai"))
|
||||
{
|
||||
return SignalName.Traveler_Nomai;
|
||||
}
|
||||
|
||||
if (name.Contains("Prisoner"))
|
||||
{
|
||||
return SignalName.Traveler_Prisoner;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(name), name, null);
|
||||
}
|
||||
|
||||
internal static void StopTravelerAudio(this TravelerAudioManager manager, string name)
|
||||
{
|
||||
var signalName = TravelerToSignal(name);
|
||||
var audioSignal = manager._signals.First(x => x.GetName() == signalName);
|
||||
|
||||
audioSignal.GetOWAudioSource().FadeOut(0.5f);
|
||||
}
|
||||
|
||||
internal static void PlayTravelerAudio(this TravelerAudioManager manager, string name, float audioDelay)
|
||||
{
|
||||
var signalName = TravelerToSignal(name);
|
||||
var audioSignal = manager._signals.First(x => x.GetName() == signalName);
|
||||
|
||||
manager._playAfterDelay = false;
|
||||
manager._playAudioTime = Time.time + audioDelay;
|
||||
QSBCore.UnityEvents.RunWhen(() => Time.time >= manager._playAudioTime, () =>
|
||||
{
|
||||
if (!audioSignal.IsOnlyAudibleToScope() || audioSignal.GetOWAudioSource().isPlaying)
|
||||
{
|
||||
audioSignal.GetOWAudioSource().FadeIn(0.5f);
|
||||
audioSignal.GetOWAudioSource().timeSamples = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
using OWML.Utils;
|
||||
using QSB.Player;
|
||||
using QSB.Player;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBCharacterAnimController : NpcAnimController<CharacterAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new List<PlayerInfo>();
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new();
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
@ -32,9 +31,9 @@ namespace QSB.Animation.NPC.WorldObjects
|
||||
}
|
||||
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject.GetValue<CharacterDialogueTree>("_dialogueTree");
|
||||
=> AttachedObject._dialogueTree;
|
||||
|
||||
public override bool InConversation()
|
||||
=> AttachedObject.GetValue<bool>("_inConversation");
|
||||
=> AttachedObject._inConversation;
|
||||
}
|
||||
}
|
||||
|
40
QSB/Animation/NPC/WorldObjects/QSBSolanumAnimController.cs
Normal file
40
QSB/Animation/NPC/WorldObjects/QSBSolanumAnimController.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBSolanumAnimController : WorldObject<SolanumAnimController>
|
||||
{
|
||||
private readonly List<PlayerInfo> _playersInHeadZone = new();
|
||||
|
||||
public override void Init(SolanumAnimController controller, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = controller;
|
||||
}
|
||||
|
||||
public List<PlayerInfo> GetPlayersInHeadZone()
|
||||
=> _playersInHeadZone;
|
||||
|
||||
public void AddPlayerToHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersInHeadZone.Add(player);
|
||||
}
|
||||
|
||||
public void RemovePlayerFromHeadZone(PlayerInfo player)
|
||||
{
|
||||
if (!_playersInHeadZone.Contains(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersInHeadZone.Remove(player);
|
||||
}
|
||||
}
|
||||
}
|
11
QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs
Normal file
11
QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBSolanumController : NpcAnimController<NomaiConversationManager>
|
||||
{
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject._characterDialogueTree;
|
||||
|
||||
public override bool InConversation()
|
||||
=> AttachedObject._solanumAnimController._animator.GetBool("ListeningToPlayer");
|
||||
}
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
using OWML.Utils;
|
||||
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
namespace QSB.Animation.NPC.WorldObjects
|
||||
{
|
||||
internal class QSBTravelerController : NpcAnimController<TravelerController>
|
||||
{
|
||||
public override CharacterDialogueTree GetDialogueTree()
|
||||
=> AttachedObject.GetValue<CharacterDialogueTree>("_dialogueSystem");
|
||||
=> AttachedObject._dialogueSystem;
|
||||
|
||||
public override bool InConversation()
|
||||
=> AttachedObject.GetValue<bool>("_talking");
|
||||
=> AttachedObject._talking;
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ namespace QSB.Animation.Player
|
||||
|
||||
public void SetSuitState(bool state)
|
||||
{
|
||||
if (!Player.PlayerStates.IsReady)
|
||||
if (!Player.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -225,7 +225,7 @@ namespace QSB.Animation.Player
|
||||
|
||||
InvisibleAnimator.runtimeAnimatorController = controller;
|
||||
VisibleAnimator.runtimeAnimatorController = controller;
|
||||
if (type != AnimationType.PlayerSuited && type != AnimationType.PlayerUnsuited)
|
||||
if (type is not AnimationType.PlayerSuited and not AnimationType.PlayerUnsuited)
|
||||
{
|
||||
VisibleAnimator.SetTrigger("Playing");
|
||||
InvisibleAnimator.SetTrigger("Playing");
|
||||
|
@ -13,7 +13,7 @@ namespace QSB.Animation.Player
|
||||
private Animator _from;
|
||||
private Animator _to;
|
||||
|
||||
private readonly Dictionary<string, AnimFloatParam> _floatParams = new Dictionary<string, AnimFloatParam>();
|
||||
private readonly Dictionary<string, AnimFloatParam> _floatParams = new();
|
||||
|
||||
public void Init(Animator from, Animator to)
|
||||
{
|
||||
|
@ -1,4 +1,6 @@
|
||||
using QuantumUNET;
|
||||
using QSB.Utility;
|
||||
using QSB.Utility.VariableSync;
|
||||
using QuantumUNET;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
@ -14,13 +16,15 @@ namespace QSB.Animation.Player
|
||||
private PlayerCharacterController _playerController;
|
||||
private Animator _bodyAnim;
|
||||
|
||||
[SyncVar]
|
||||
private float _crouchValue;
|
||||
public FloatVariableSyncer CrouchVariableSyncer;
|
||||
public float CrouchValue = 0f;
|
||||
|
||||
public void Init(PlayerCharacterController playerController, Animator bodyAnim)
|
||||
{
|
||||
_playerController = playerController;
|
||||
_bodyAnim = bodyAnim;
|
||||
|
||||
CrouchVariableSyncer.Init(() => CrouchValue, val => CrouchValue = val);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
@ -42,7 +46,7 @@ namespace QSB.Animation.Player
|
||||
}
|
||||
|
||||
var jumpChargeFraction = _playerController.GetJumpCrouchFraction();
|
||||
_crouchValue = jumpChargeFraction;
|
||||
CrouchVariableSyncer.ValueToSync.Value = jumpChargeFraction;
|
||||
}
|
||||
|
||||
private void SyncRemoteCrouch()
|
||||
@ -52,7 +56,7 @@ namespace QSB.Animation.Player
|
||||
return;
|
||||
}
|
||||
|
||||
CrouchParam.Target = _crouchValue;
|
||||
CrouchParam.Target = CrouchValue;
|
||||
CrouchParam.Smooth(CrouchSmoothTime);
|
||||
var jumpChargeFraction = CrouchParam.Current;
|
||||
_bodyAnim.SetLayerWeight(CrouchLayerIndex, jumpChargeFraction);
|
||||
|
@ -12,7 +12,7 @@ namespace QSB.Animation.Player.Events
|
||||
|
||||
private void Handler(uint attachedNetId, string name) => SendEvent(CreateMessage(attachedNetId, name));
|
||||
|
||||
private AnimationTriggerMessage CreateMessage(uint attachedNetId, string name) => new AnimationTriggerMessage
|
||||
private AnimationTriggerMessage CreateMessage(uint attachedNetId, string name) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
AttachedNetId = attachedNetId,
|
||||
@ -22,7 +22,7 @@ namespace QSB.Animation.Player.Events
|
||||
public override void OnReceiveRemote(bool server, AnimationTriggerMessage message)
|
||||
{
|
||||
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(message.AttachedNetId);
|
||||
if (!QSBCore.WorldObjectsReady || animationSync != null)
|
||||
if (!QSBCore.WorldObjectsReady || animationSync == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace QSB.Animation.Player.Events
|
||||
|
||||
private void Handler(uint player, AnimationType type) => SendEvent(CreateMessage(player, type));
|
||||
|
||||
private EnumMessage<AnimationType> CreateMessage(uint player, AnimationType type) => new EnumMessage<AnimationType>
|
||||
private EnumMessage<AnimationType> CreateMessage(uint player, AnimationType type) => new()
|
||||
{
|
||||
AboutId = player,
|
||||
EnumValue = type
|
||||
@ -22,7 +22,7 @@ namespace QSB.Animation.Player.Events
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<AnimationType> message)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady || !QSBPlayerManager.GetPlayer(message.AboutId).PlayerStates.IsReady)
|
||||
if (!QSBCore.WorldObjectsReady || !QSBPlayerManager.GetPlayer(message.AboutId).IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace QSB.Animation.Player.Events
|
||||
private void HandleSuitUp() => SendEvent(CreateMessage(true));
|
||||
private void HandleSuitDown() => SendEvent(CreateMessage(false));
|
||||
|
||||
private ToggleMessage CreateMessage(bool value) => new ToggleMessage
|
||||
private ToggleMessage CreateMessage(bool value) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ToggleValue = value
|
||||
@ -32,9 +32,9 @@ namespace QSB.Animation.Player.Events
|
||||
public override void OnReceiveRemote(bool server, ToggleMessage message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
player.PlayerStates.SuitedUp = message.ToggleValue;
|
||||
player.SuitedUp = message.ToggleValue;
|
||||
|
||||
if (!QSBCore.WorldObjectsReady || !player.PlayerStates.IsReady)
|
||||
if (!QSBCore.WorldObjectsReady || !player.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -46,7 +46,7 @@ namespace QSB.Animation.Player.Events
|
||||
|
||||
public override void OnReceiveLocal(bool server, ToggleMessage message)
|
||||
{
|
||||
QSBPlayerManager.LocalPlayer.PlayerStates.SuitedUp = message.ToggleValue;
|
||||
QSBPlayerManager.LocalPlayer.SuitedUp = message.ToggleValue;
|
||||
var animator = QSBPlayerManager.LocalPlayer.AnimationSync;
|
||||
var type = message.ToggleValue ? AnimationType.PlayerSuited : AnimationType.PlayerUnsuited;
|
||||
animator.CurrentType = type;
|
||||
|
@ -1,23 +1,27 @@
|
||||
using QuantumUNET;
|
||||
using QSB.Utility.VariableSync;
|
||||
using QuantumUNET;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace QSB.Animation.Player.Thrusters
|
||||
{
|
||||
public class JetpackAccelerationSync : QNetworkBehaviour
|
||||
{
|
||||
[SyncVar]
|
||||
private Vector3 _localAcceleration;
|
||||
[SyncVar]
|
||||
private bool _isThrusting;
|
||||
public Vector3VariableSyncer AccelerationVariableSyncer;
|
||||
public BoolVariableSyncer ThrustingVariableSyncer;
|
||||
public Vector3 LocalAcceleration => AccelerationVariableSyncer.ValueToSync.Value;
|
||||
public bool IsThrusting => ThrustingVariableSyncer.ValueToSync.Value;
|
||||
|
||||
private Vector3 _localAcceleration;
|
||||
private bool _isThrusting;
|
||||
private ThrusterModel _thrusterModel;
|
||||
|
||||
public Vector3 LocalAcceleration => _localAcceleration;
|
||||
public bool IsThrusting => _isThrusting;
|
||||
|
||||
public void Init(ThrusterModel model)
|
||||
=> _thrusterModel = model;
|
||||
{
|
||||
_thrusterModel = model;
|
||||
|
||||
AccelerationVariableSyncer.Init(() => _localAcceleration, val => _localAcceleration = val);
|
||||
ThrustingVariableSyncer.Init(() => _isThrusting, val => _isThrusting = val);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
@ -31,8 +35,8 @@ namespace QSB.Animation.Player.Thrusters
|
||||
{
|
||||
if (_thrusterModel != null)
|
||||
{
|
||||
_localAcceleration = _thrusterModel.GetLocalAcceleration();
|
||||
_isThrusting = _thrusterModel.IsTranslationalThrusterFiring();
|
||||
AccelerationVariableSyncer.ValueToSync.Value = _thrusterModel.GetLocalAcceleration();
|
||||
ThrustingVariableSyncer.ValueToSync.Value = _thrusterModel.IsTranslationalThrusterFiring();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace QSB.Animation.Player.Thrusters
|
||||
private Thruster _thruster;
|
||||
private Light _light;
|
||||
private AnimationCurve _scaleByThrust = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||
private DampedSpring _scaleSpring = new DampedSpring();
|
||||
private DampedSpring _scaleSpring = new();
|
||||
private float _belowMaxThrustScalar = 1f;
|
||||
private MeshRenderer _thrusterRenderer;
|
||||
private Vector3 _thrusterFilter;
|
||||
@ -82,5 +82,16 @@ namespace QSB.Animation.Player.Thrusters
|
||||
}
|
||||
|
||||
private float GetThrustFraction() => Vector3.Dot(_attachedPlayer.JetpackAcceleration.LocalAcceleration, _thrusterFilter);
|
||||
|
||||
private void OnRenderObject()
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady || !QSBCore.ShowLinesInDebug)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Popcron.Gizmos.Sphere(_light.transform.position, 0.05f, Color.yellow, 4);
|
||||
Popcron.Gizmos.Line(_light.transform.position, _light.transform.parent.position, Color.yellow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,10 +47,18 @@ namespace QSB.Animation.Player.Thrusters
|
||||
var gameObject = controller.gameObject;
|
||||
var oldThruster = controller.GetValue<Thruster>("_thruster");
|
||||
var oldLight = controller.GetValue<Light>("_light");
|
||||
var localPos = oldThruster switch
|
||||
{
|
||||
Thruster.Up_RightThruster or Thruster.Up_LeftThruster => new Vector3(0, 0, 3),
|
||||
Thruster.Down_RightThruster or Thruster.Down_LeftThruster => new Vector3(0, 0, 7),
|
||||
_ => new Vector3(0, 0, 5),
|
||||
};
|
||||
oldLight.transform.localPosition = localPos;
|
||||
|
||||
var oldAnimCurve = controller.GetValue<AnimationCurve>("_scaleByThrust");
|
||||
var oldScaleSpring = controller.GetValue<DampedSpring>("_scaleSpring");
|
||||
var oldScalar = controller.GetValue<float>("_belowMaxThrustScalar");
|
||||
var oldBase = controller.GetValue<float>("_baseLightRadius");
|
||||
var oldBase = oldLight.range;
|
||||
Object.Destroy(controller);
|
||||
var newObj = gameObject.AddComponent<RemoteThrusterFlameController>();
|
||||
newObj.InitFromOld(oldThruster, oldLight, oldAnimCurve, oldScaleSpring, oldScalar, oldBase, player);
|
||||
|
BIN
QSB/AssetBundles/conversation
Normal file
BIN
QSB/AssetBundles/conversation
Normal file
Binary file not shown.
@ -1,12 +1,12 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3328595786
|
||||
CRC: 2681871399
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: b1b55f9f86f72ed72608b36f0729af6d
|
||||
Hash: d9191ca383ce2fbef699ba7106af389e
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 50a27bfc3e679077929938a6fa57f4db
|
||||
Hash: a0ed95779b7375b06978e51f19fbfba7
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
@ -25,6 +25,10 @@ ClassTypes:
|
||||
Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 1015169618, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 602583937, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
- Class: 128
|
||||
@ -39,6 +43,6 @@ ClassTypes:
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/DialogueBubble.prefab
|
||||
- Assets/Prefabs/DialogueBubble.prefab
|
||||
- Assets/GameAssets/Texture2D/UI_DialogueBox_d.png
|
||||
Dependencies: []
|
BIN
QSB/AssetBundles/debug
Normal file
BIN
QSB/AssetBundles/debug
Normal file
Binary file not shown.
32
QSB/AssetBundles/debug.manifest
Normal file
32
QSB/AssetBundles/debug.manifest
Normal file
@ -0,0 +1,32 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 1531115438
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 289361968514e20b1d351d2d2fda5b6e
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: ae2cf77de671e115b4e55d2b65767202
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
Script: {instanceID: 0}
|
||||
- Class: 4
|
||||
Script: {instanceID: 0}
|
||||
- Class: 21
|
||||
Script: {instanceID: 0}
|
||||
- Class: 23
|
||||
Script: {instanceID: 0}
|
||||
- Class: 33
|
||||
Script: {instanceID: 0}
|
||||
- Class: 43
|
||||
Script: {instanceID: 0}
|
||||
- Class: 48
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/Prefabs/Cube.prefab
|
||||
- Assets/Prefabs/Capsule.prefab
|
||||
- Assets/Materials/DebugVis.mat
|
||||
- Assets/Prefabs/Sphere.prefab
|
||||
Dependencies: []
|
BIN
QSB/AssetBundles/instruments
Normal file
BIN
QSB/AssetBundles/instruments
Normal file
Binary file not shown.
68
QSB/AssetBundles/instruments.manifest
Normal file
68
QSB/AssetBundles/instruments.manifest
Normal file
@ -0,0 +1,68 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 443713126
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 7d0ca7d72c1b77d3f455afb9deb14138
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: a1e72967751de663a1cbd29bd1e98be5
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 21
|
||||
Script: {instanceID: 0}
|
||||
- Class: 28
|
||||
Script: {instanceID: 0}
|
||||
- Class: 43
|
||||
Script: {instanceID: 0}
|
||||
- Class: 48
|
||||
Script: {instanceID: 0}
|
||||
- Class: 74
|
||||
Script: {instanceID: 0}
|
||||
- Class: 90
|
||||
Script: {instanceID: 0}
|
||||
- Class: 91
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_ao.png
|
||||
- Assets/GameAssets/AnimationClip/Riebeck_Playing.anim
|
||||
- Assets/GameAssets/Avatar/Traveller_HEA_Chert_ANIM_Chatter_ChipperAvatar.asset
|
||||
- Assets/GameAssets/AnimationClip/Chert_Drum_Panicked.anim
|
||||
- Assets/GameAssets/Material/Traveller_HEA_Riebeck_mat.mat
|
||||
- Assets/GameAssets/AnimatorController/Traveller_Chert.controller
|
||||
- Assets/GameAssets/AnimationClip/Chert_Chatter_Chipper.anim
|
||||
- Assets/GameAssets/AnimationClip/Chert_Drum_Chipper.anim
|
||||
- Assets/GameAssets/Mesh/NewDrum_polySurface2.asset
|
||||
- Assets/GameAssets/AnimationClip/Playing_banjo.anim
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_n.png
|
||||
- Assets/GameAssets/Avatar/Traveller_HEA_Riebeck_ANIM_TalkingAvatar.asset
|
||||
- Assets/GameAssets/Texture2D/Structure_HEA_VillageCabin_n.png
|
||||
- Assets/GameAssets/AnimationClip/Chert_Chatter_Nervous.anim
|
||||
- Assets/GameAssets/Mesh/Chert_DrumStick_Geo1.asset
|
||||
- Assets/GameAssets/Material/Structure_HEA_VillageMetal_mat.mat
|
||||
- Assets/GameAssets/Texture2D/Structure_HEA_VillageCabin_d.png
|
||||
- Assets/GameAssets/Material/Structure_HEA_VillageCabin_mat.mat
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_d.png
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_n.png
|
||||
- Assets/GameAssets/AnimationClip/Playing_to_idle.anim
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_n.png
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_s.png
|
||||
- Assets/GameAssets/AnimationClip/Chert_Chatter_Panicked.anim
|
||||
- Assets/GameAssets/Material/Traveller_HEA_Riebeck_Banjo_mat.mat
|
||||
- Assets/GameAssets/AnimationClip/Chert_Dream.anim
|
||||
- Assets/GameAssets/AnimationClip/Riebeck_Talking.anim
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_d.png
|
||||
- Assets/GameAssets/AnimationClip/Riebeck_DreamIdle.anim
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_ao.png
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_s.png
|
||||
- Assets/GameAssets/Texture2D/Structure_HEA_VillageMetal_n.png
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_d.png
|
||||
- Assets/GameAssets/AnimatorController/Traveller_Riebeck.controller
|
||||
- Assets/GameAssets/Texture2D/Structure_HEA_VillageMetal_s.png
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_ao.png
|
||||
- Assets/GameAssets/Texture2D/Structure_HEA_VillageMetal_d.png
|
||||
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_s.png
|
||||
- Assets/GameAssets/Material/Traveller_HEA_Chert_mat.mat
|
||||
- Assets/GameAssets/Texture2D/Structure_HEA_VillageCabin_s.png
|
||||
Dependencies: []
|
BIN
QSB/AssetBundles/network
Normal file
BIN
QSB/AssetBundles/network
Normal file
Binary file not shown.
55
QSB/AssetBundles/network.manifest
Normal file
55
QSB/AssetBundles/network.manifest
Normal file
@ -0,0 +1,55 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 1923832523
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 4fc717bd6085672c7fc1dafa5359e292
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 9036f53e57d0e71c74f56622ad045de9
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
Script: {instanceID: 0}
|
||||
- Class: 4
|
||||
Script: {instanceID: 0}
|
||||
- Class: 114
|
||||
Script: {fileID: -1208705890, guid: 8929207a0d76fd54a8a2a820c652720f, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 1142416158, guid: 8929207a0d76fd54a8a2a820c652720f, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 519208029, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -790547616, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 916105004, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1309757293, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 78926581, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1381557116, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1937550126, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -749020886, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -2281650, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 2036222940, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1164351254, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 806682216, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 677635994, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/Prefabs/NetworkProbe.prefab
|
||||
- Assets/Prefabs/NETWORK_Player_Body.prefab
|
||||
- Assets/Prefabs/NetworkOrb.prefab
|
||||
- Assets/Prefabs/NetworkAngler.prefab
|
||||
- Assets/Prefabs/NetworkShip.prefab
|
||||
Dependencies: []
|
@ -14,7 +14,7 @@ namespace QSB.CampfireSync.Events
|
||||
|
||||
private void Handler(int objId, Campfire.State state) => SendEvent(CreateMessage(objId, state));
|
||||
|
||||
private EnumWorldObjectMessage<Campfire.State> CreateMessage(int objId, Campfire.State state) => new EnumWorldObjectMessage<Campfire.State>
|
||||
private EnumWorldObjectMessage<Campfire.State> CreateMessage(int objId, Campfire.State state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ObjectId = objId,
|
||||
|
@ -15,7 +15,7 @@ namespace QSB.CampfireSync.Patches
|
||||
[HarmonyPatch(typeof(Campfire), nameof(Campfire.OnPressInteract))]
|
||||
public static bool LightCampfireEvent(Campfire __instance)
|
||||
{
|
||||
var qsbCampfire = QSBWorldSync.GetWorldFromUnity<QSBCampfire, Campfire>(__instance);
|
||||
var qsbCampfire = QSBWorldSync.GetWorldFromUnity<QSBCampfire>(__instance);
|
||||
if (__instance._state == Campfire.State.LIT)
|
||||
{
|
||||
qsbCampfire.StartRoasting();
|
||||
|
@ -29,7 +29,6 @@ namespace QSB.ClientServerStateSync
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"CHANGE CLIENT STATE FROM {QSBPlayerManager.LocalPlayer.State} to {newState}");
|
||||
QSBPlayerManager.LocalPlayer.State = newState;
|
||||
OnChangeState?.Invoke(newState);
|
||||
}
|
||||
@ -46,31 +45,30 @@ namespace QSB.ClientServerStateSync
|
||||
switch (newScene)
|
||||
{
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"SERVER LOAD TITLESCREEN");
|
||||
newState = ClientState.InTitleScreen;
|
||||
break;
|
||||
case OWScene.Credits_Fast:
|
||||
DebugLog.DebugWrite($"SERVER LOAD SHORT CREDITS");
|
||||
newState = ClientState.WatchingShortCredits;
|
||||
break;
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"SERVER LOAD LONG CREDITS");
|
||||
newState = ClientState.WatchingLongCredits;
|
||||
break;
|
||||
case OWScene.SolarSystem:
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
// reloading scene
|
||||
DebugLog.DebugWrite($"SERVER RELOAD SOLARSYSTEM");
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
// loading in from title screen
|
||||
DebugLog.DebugWrite($"SERVER LOAD SOLARSYSTEM");
|
||||
newState = ClientState.AliveInSolarSystem;
|
||||
}
|
||||
|
||||
break;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
newState = ClientState.AliveInEye;
|
||||
break;
|
||||
default:
|
||||
newState = ClientState.NotLoaded;
|
||||
@ -82,22 +80,18 @@ namespace QSB.ClientServerStateSync
|
||||
switch (newScene)
|
||||
{
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"CLIENT LOAD TITLESCREEN");
|
||||
newState = ClientState.InTitleScreen;
|
||||
break;
|
||||
case OWScene.Credits_Fast:
|
||||
DebugLog.DebugWrite($"CLIENT LOAD SHORT CREDITS");
|
||||
newState = ClientState.WatchingShortCredits;
|
||||
break;
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"CLIENT LOAD LONG CREDITS");
|
||||
newState = ClientState.WatchingLongCredits;
|
||||
break;
|
||||
case OWScene.SolarSystem:
|
||||
if (serverState == ServerState.WaitingForAllPlayersToDie)
|
||||
{
|
||||
DebugLog.DebugWrite($"SEVER IN DEATH PHASE - WAIT");
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
break;
|
||||
}
|
||||
@ -105,13 +99,11 @@ namespace QSB.ClientServerStateSync
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
// reloading scene
|
||||
DebugLog.DebugWrite($"CLIENT RELOAD SOLARSYSTEM");
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
// loading in from title screen
|
||||
DebugLog.DebugWrite($"CLIENT LOAD SOLARSYSTEM");
|
||||
if (serverState == ServerState.WaitingForAllPlayersToReady)
|
||||
{
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
@ -121,6 +113,10 @@ namespace QSB.ClientServerStateSync
|
||||
newState = ClientState.AliveInSolarSystem;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
break;
|
||||
default:
|
||||
newState = ClientState.NotLoaded;
|
||||
@ -165,32 +161,17 @@ namespace QSB.ClientServerStateSync
|
||||
|
||||
private ClientState ForceGetCurrentState()
|
||||
{
|
||||
DebugLog.DebugWrite($"ForceGetCurrentState");
|
||||
var currentScene = LoadManager.GetCurrentScene();
|
||||
var lastScene = LoadManager.GetPreviousScene();
|
||||
|
||||
switch (currentScene)
|
||||
return currentScene switch
|
||||
{
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"- TitleScreen");
|
||||
return ClientState.InTitleScreen;
|
||||
case OWScene.Credits_Fast:
|
||||
DebugLog.DebugWrite($"- Short Credits");
|
||||
return ClientState.WatchingShortCredits;
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"- Long Credits");
|
||||
return ClientState.WatchingLongCredits;
|
||||
case OWScene.SolarSystem:
|
||||
DebugLog.DebugWrite($"- SolarSystem");
|
||||
return ClientState.AliveInSolarSystem;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
DebugLog.DebugWrite($"- Eye");
|
||||
return ClientState.AliveInEye;
|
||||
default:
|
||||
DebugLog.DebugWrite($"- Not Loaded");
|
||||
return ClientState.NotLoaded;
|
||||
}
|
||||
OWScene.TitleScreen => ClientState.InTitleScreen,
|
||||
OWScene.Credits_Fast => ClientState.WatchingShortCredits,
|
||||
OWScene.Credits_Final or OWScene.PostCreditsScene => ClientState.WatchingLongCredits,
|
||||
OWScene.SolarSystem => ClientState.AliveInSolarSystem,
|
||||
OWScene.EyeOfTheUniverse => ClientState.AliveInEye,
|
||||
_ => ClientState.NotLoaded,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace QSB.ClientServerStateSync.Events
|
||||
|
||||
private void Handler(ClientState state) => SendEvent(CreateMessage(state));
|
||||
|
||||
private EnumMessage<ClientState> CreateMessage(ClientState state) => new EnumMessage<ClientState>
|
||||
private EnumMessage<ClientState> CreateMessage(ClientState state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = state
|
||||
|
@ -15,7 +15,7 @@ namespace QSB.ClientServerStateSync.Events
|
||||
|
||||
private void Handler(ServerState state) => SendEvent(CreateMessage(state));
|
||||
|
||||
private EnumMessage<ServerState> CreateMessage(ServerState state) => new EnumMessage<ServerState>
|
||||
private EnumMessage<ServerState> CreateMessage(ServerState state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = state
|
||||
|
@ -54,17 +54,14 @@ namespace QSB.ClientServerStateSync
|
||||
case OWScene.Credits_Fast:
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"SERVER LOAD CREDITS");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.Credits);
|
||||
break;
|
||||
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"SERVER LOAD TITLE SCREEN");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
|
||||
break;
|
||||
|
||||
case OWScene.SolarSystem:
|
||||
DebugLog.DebugWrite($"SERVER LOAD SOLARSYSTEM");
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToReady);
|
||||
@ -77,7 +74,6 @@ namespace QSB.ClientServerStateSync
|
||||
break;
|
||||
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
DebugLog.DebugWrite($"EYE");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToReady);
|
||||
break;
|
||||
|
||||
@ -98,21 +94,15 @@ namespace QSB.ClientServerStateSync
|
||||
|
||||
private ServerState ForceGetCurrentState()
|
||||
{
|
||||
DebugLog.DebugWrite($"ForceGetCurrentState");
|
||||
|
||||
var currentScene = LoadManager.GetCurrentScene();
|
||||
var lastScene = LoadManager.GetPreviousScene();
|
||||
|
||||
switch (currentScene)
|
||||
{
|
||||
case OWScene.SolarSystem:
|
||||
DebugLog.DebugWrite($"- SolarSystem");
|
||||
return ServerState.InSolarSystem;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
DebugLog.DebugWrite($"- Eye");
|
||||
return ServerState.InEye;
|
||||
default:
|
||||
DebugLog.DebugWrite($"- Not Loaded");
|
||||
return ServerState.NotLoaded;
|
||||
}
|
||||
}
|
||||
@ -132,12 +122,27 @@ namespace QSB.ClientServerStateSync
|
||||
|
||||
if (_currentState == ServerState.WaitingForAllPlayersToReady)
|
||||
{
|
||||
if (QSBPlayerManager.PlayerList.All(x => x.State == ClientState.WaitingForOthersToReadyInSolarSystem)
|
||||
|| QSBPlayerManager.PlayerList.All(x => x.State == ClientState.AliveInSolarSystem))
|
||||
if (QSBPlayerManager.PlayerList.All(x
|
||||
=> x.State is ClientState.WaitingForOthersToReadyInSolarSystem
|
||||
or ClientState.AliveInSolarSystem
|
||||
or ClientState.AliveInEye))
|
||||
{
|
||||
DebugLog.DebugWrite($"All ready!!");
|
||||
QSBEventManager.FireEvent(EventNames.QSBStartLoop);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
|
||||
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
|
||||
}
|
||||
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InEye);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Error - All players were ready in non-universe scene!?", OWML.Common.MessageType.Error);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
|
||||
}
|
||||
|
||||
_blockNextCheck = true;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class CameraFacingBillboard : MonoBehaviour
|
||||
UpdateRotation();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
private void LateUpdate()
|
||||
=> UpdateRotation();
|
||||
|
||||
private void UpdateRotation()
|
||||
|
@ -21,7 +21,7 @@ namespace QSB.ConversationSync
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
_boxPrefab = QSBCore.ConversationAssetBundle.LoadAsset<GameObject>("assets/dialoguebubble.prefab");
|
||||
_boxPrefab = QSBCore.ConversationAssetBundle.LoadAsset<GameObject>("assets/Prefabs/dialoguebubble.prefab");
|
||||
|
||||
var font = (Font)Resources.Load(@"fonts\english - latin\HVD Fonts - BrandonGrotesque-Bold_Dynamic");
|
||||
if (font == null)
|
||||
@ -118,9 +118,7 @@ namespace QSB.ConversationSync
|
||||
newBox.transform.SetParent(parent);
|
||||
newBox.transform.localPosition = new Vector3(0, vertOffset, 0);
|
||||
newBox.transform.rotation = parent.rotation;
|
||||
newBox.AddComponent<CameraFacingBillboard>();
|
||||
newBox.GetComponent<Text>().text = text;
|
||||
newBox.AddComponent<ZOverride>();
|
||||
newBox.SetActive(true);
|
||||
return newBox;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace QSB.ConversationSync.Events
|
||||
|
||||
private void Handler(uint id, string message, ConversationType type) => SendEvent(CreateMessage(id, message, type));
|
||||
|
||||
private ConversationMessage CreateMessage(uint id, string message, ConversationType type) => new ConversationMessage
|
||||
private ConversationMessage CreateMessage(uint id, string message, ConversationType type) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ObjectId = (int)id,
|
||||
|
@ -15,7 +15,7 @@ namespace QSB.ConversationSync.Events
|
||||
|
||||
private void Handler(int objId, uint playerId, bool state) => SendEvent(CreateMessage(objId, playerId, state));
|
||||
|
||||
private ConversationStartEndMessage CreateMessage(int objId, uint playerId, bool state) => new ConversationStartEndMessage
|
||||
private ConversationStartEndMessage CreateMessage(int objId, uint playerId, bool state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
TreeId = objId,
|
||||
|
@ -12,7 +12,7 @@ namespace QSB.ConversationSync.Events
|
||||
|
||||
private void Handler(string name, bool state) => SendEvent(CreateMessage(name, state));
|
||||
|
||||
private DialogueConditionMessage CreateMessage(string name, bool state) => new DialogueConditionMessage
|
||||
private DialogueConditionMessage CreateMessage(string name, bool state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ConditionName = name,
|
||||
|
@ -1,6 +1,7 @@
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.DeathSync.Events
|
||||
@ -14,7 +15,7 @@ namespace QSB.DeathSync.Events
|
||||
|
||||
private void Handler(EndLoopReason type) => SendEvent(CreateMessage(type));
|
||||
|
||||
private EnumMessage<EndLoopReason> CreateMessage(EndLoopReason type) => new EnumMessage<EndLoopReason>
|
||||
private EnumMessage<EndLoopReason> CreateMessage(EndLoopReason type) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = type
|
||||
@ -29,6 +30,8 @@ namespace QSB.DeathSync.Events
|
||||
switch (message.EnumValue)
|
||||
{
|
||||
case EndLoopReason.AllPlayersDead:
|
||||
QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime);
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.RespawnSync;
|
||||
using QSB.Utility;
|
||||
|
||||
namespace QSB.DeathSync.Events
|
||||
@ -14,7 +15,7 @@ namespace QSB.DeathSync.Events
|
||||
|
||||
private void Handler(DeathType type) => SendEvent(CreateMessage(type));
|
||||
|
||||
private PlayerDeathMessage CreateMessage(DeathType type) => new PlayerDeathMessage
|
||||
private PlayerDeathMessage CreateMessage(DeathType type) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
EnumValue = type,
|
||||
|
@ -14,7 +14,7 @@ namespace QSB.DeathSync.Events
|
||||
|
||||
private void Handler() => SendEvent(CreateMessage());
|
||||
|
||||
private PlayerMessage CreateMessage() => new PlayerMessage
|
||||
private PlayerMessage CreateMessage() => new()
|
||||
{
|
||||
AboutId = LocalPlayerId
|
||||
};
|
||||
@ -25,7 +25,19 @@ namespace QSB.DeathSync.Events
|
||||
public override void OnReceiveRemote(bool server, PlayerMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($" ~~~ LOOP START ~~~");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInEye);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Got StartLoop event when not in universe!", OWML.Common.MessageType.Error);
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.NotLoaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,14 +5,19 @@ namespace QSB.DeathSync
|
||||
{
|
||||
public static class Necronomicon
|
||||
{
|
||||
private static readonly Dictionary<DeathType, string[]> Darkhold = new Dictionary<DeathType, string[]>
|
||||
private static readonly Dictionary<DeathType, string[]> Darkhold = new()
|
||||
{
|
||||
{ DeathType.Default, new[] // Running out of health
|
||||
{
|
||||
DeathType.Default,
|
||||
new[] // Running out of health
|
||||
{
|
||||
"{0} died",
|
||||
"{0} was killed"
|
||||
} },
|
||||
{ DeathType.Impact, new[] // Hitting the ground/wall/object
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Impact,
|
||||
new[] // Hitting the ground/wall/object
|
||||
{
|
||||
"{0} forgot to use retro-rockets",
|
||||
"{0} bonked into the ground too hard",
|
||||
@ -22,8 +27,11 @@ namespace QSB.DeathSync
|
||||
"{0} was killed",
|
||||
"{0} died due to impact",
|
||||
"{0} impacted the ground too hard"
|
||||
} },
|
||||
{ DeathType.Asphyxiation, new[] // Running out of oxygen
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Asphyxiation,
|
||||
new[] // Running out of oxygen
|
||||
{
|
||||
"{0} forgot to breathe",
|
||||
"{0} asphyxiated",
|
||||
@ -33,14 +41,20 @@ namespace QSB.DeathSync
|
||||
"{0} ran out of air",
|
||||
"{0} ran out of oxygen",
|
||||
"{0} didn't need air anyway"
|
||||
} },
|
||||
{ DeathType.Energy, new[] // Electricity, sun, etc.
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Energy,
|
||||
new[] // Electricity, sun, etc.
|
||||
{
|
||||
"{0} was cooked",
|
||||
"{0} died",
|
||||
"{0} was killed"
|
||||
} },
|
||||
{ DeathType.Supernova, new[] // Supernova
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Supernova,
|
||||
new[] // Supernova
|
||||
{
|
||||
"{0} ran out of time",
|
||||
"{0} burnt up",
|
||||
@ -52,8 +66,11 @@ namespace QSB.DeathSync
|
||||
"{0} became cosmic marshmallow",
|
||||
"{0} photosynthesized too much",
|
||||
"{0} died due to the supernova"
|
||||
} },
|
||||
{ DeathType.Digestion, new[] // Anglerfish
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Digestion,
|
||||
new[] // Anglerfish
|
||||
{
|
||||
"{0} was eaten",
|
||||
"{0} found a fish",
|
||||
@ -61,14 +78,21 @@ namespace QSB.DeathSync
|
||||
"{0} messed with the wrong fish",
|
||||
"{0} was digested",
|
||||
"{0} died due to digestion"
|
||||
} },
|
||||
{ DeathType.BigBang, new[] // End of the game
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.BigBang,
|
||||
new[] // End of the game
|
||||
{
|
||||
// TODO : maybe don't show these?
|
||||
"{0} sacrificed themself for the universe",
|
||||
"{0} knows the true meaning of sacrifice",
|
||||
"{0} won at the cost of their life"
|
||||
} },
|
||||
{ DeathType.Crushed, new[] // Crushed in sand
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Crushed,
|
||||
new[] // Crushed in sand
|
||||
{
|
||||
"{0} went through the tunnel too slow",
|
||||
"{0} didn't make it out in time",
|
||||
@ -78,18 +102,20 @@ namespace QSB.DeathSync
|
||||
"{0} went swimming in the sand",
|
||||
"{0} underestimated the danger of sand",
|
||||
"{0} died due to being crushed"
|
||||
} },
|
||||
{ DeathType.Meditation, new[] // Meditation
|
||||
}
|
||||
},
|
||||
{
|
||||
"{0} broke QSB. this is a bug, you should never see this"
|
||||
} },
|
||||
{ DeathType.TimeLoop, new[] // Escaping the supernova
|
||||
DeathType.TimeLoop,
|
||||
new[] // Escaping the supernova
|
||||
{
|
||||
"{0} ran out of time",
|
||||
"{0} lost track of time",
|
||||
"{0} watched the sun go kaboom"
|
||||
} },
|
||||
{ DeathType.Lava, new[] // Lava
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.Lava,
|
||||
new[] // Lava
|
||||
{
|
||||
"{0} died in lava",
|
||||
"{0} was melted",
|
||||
@ -99,17 +125,47 @@ namespace QSB.DeathSync
|
||||
"{0} became one with the glowing gooey rock",
|
||||
"{0} died due to lava",
|
||||
"{0} got burnt in the lava"
|
||||
} },
|
||||
{ DeathType.BlackHole, new[] // ATP core black hole
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.BlackHole,
|
||||
new[] // ATP core black hole
|
||||
{
|
||||
"{0} should visit the Ash Twin Project again",
|
||||
"{0} waited inside the Ash Twin Project",
|
||||
"{0} chased their memories"
|
||||
} }
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.DreamExplosion,
|
||||
new[] // using the prototype
|
||||
{
|
||||
"{0} exploded",
|
||||
"{0} was an early adopter",
|
||||
"{0} went kaboom",
|
||||
"{0} was fried",
|
||||
"{0} died due to explosion",
|
||||
"{0} used the wrong artifact"
|
||||
}
|
||||
},
|
||||
{
|
||||
DeathType.CrushedByElevator,
|
||||
new[] // elevator-induced pancakeness
|
||||
{
|
||||
"{0} was crushed",
|
||||
"{0} was squished",
|
||||
"{0} was crushed by an elevator",
|
||||
"{0} stood under an elevator",
|
||||
"{0} became a flat-hearther",
|
||||
"{0} was squished by an elevator"
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
public static string GetPhrase(DeathType deathType, int index) =>
|
||||
Darkhold[deathType][index];
|
||||
public static string GetPhrase(DeathType deathType, int index)
|
||||
=> !Darkhold.ContainsKey(deathType)
|
||||
? Darkhold[DeathType.Default][index]
|
||||
: Darkhold[deathType][index];
|
||||
|
||||
public static int GetRandomIndex(DeathType deathType)
|
||||
=> new Random().Next(0, Darkhold[deathType].Length);
|
||||
|
@ -209,10 +209,7 @@ namespace QSB.DeathSync.Patches
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
|
||||
public static void DeathManager_KillPlayer_Postfix(DeathType deathType)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
|
||||
}
|
||||
public static void DeathManager_KillPlayer_Postfix(DeathType deathType) => QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.Awake))]
|
||||
|
@ -1,166 +0,0 @@
|
||||
using HarmonyLib;
|
||||
using OWML.Utils;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.DeathSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class RespawnPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerRecoveryPoint), nameof(PlayerRecoveryPoint.OnGainFocus))]
|
||||
public static bool PlayerRecoveryPoint_OnGainFocus(
|
||||
PlayerResources ____playerResources,
|
||||
bool ____refuelsPlayer,
|
||||
bool ____healsPlayer,
|
||||
SingleInteractionVolume ____interactVolume
|
||||
)
|
||||
{
|
||||
if (____playerResources == null)
|
||||
{
|
||||
____playerResources = Locator.GetPlayerTransform().GetComponent<PlayerResources>();
|
||||
}
|
||||
|
||||
var isAtFullHealth = ____playerResources.GetHealthFraction() == 1f;
|
||||
var isAtFullFuel = ____playerResources.GetFuelFraction() == 1f;
|
||||
var canBeRefueled = false;
|
||||
var canBeHealed = false;
|
||||
|
||||
if (!isAtFullFuel && ____refuelsPlayer)
|
||||
{
|
||||
canBeRefueled = true;
|
||||
}
|
||||
|
||||
if (!isAtFullHealth && ____healsPlayer)
|
||||
{
|
||||
canBeHealed = true;
|
||||
}
|
||||
|
||||
var showRespawnPrompt = false;
|
||||
|
||||
var uitextType = UITextType.None;
|
||||
if (canBeHealed && canBeRefueled)
|
||||
{
|
||||
// Heal and refuel
|
||||
uitextType = UITextType.RefillPrompt_0;
|
||||
|
||||
____interactVolume.SetKeyCommandVisible(true);
|
||||
}
|
||||
else if (canBeHealed)
|
||||
{
|
||||
// Heal
|
||||
uitextType = UITextType.RefillPrompt_2;
|
||||
|
||||
____interactVolume.SetKeyCommandVisible(true);
|
||||
}
|
||||
else if (canBeRefueled)
|
||||
{
|
||||
// Refuel
|
||||
uitextType = UITextType.RefillPrompt_4;
|
||||
____interactVolume.SetKeyCommandVisible(true);
|
||||
}
|
||||
else if (RespawnManager.Instance.RespawnNeeded)
|
||||
{
|
||||
showRespawnPrompt = true;
|
||||
}
|
||||
else if (____refuelsPlayer && ____healsPlayer)
|
||||
{
|
||||
// Fuel and health full
|
||||
uitextType = UITextType.RefillPrompt_7;
|
||||
____interactVolume.SetKeyCommandVisible(false);
|
||||
}
|
||||
else if (____refuelsPlayer)
|
||||
{
|
||||
// Fuel full
|
||||
uitextType = UITextType.RefillPrompt_8;
|
||||
____interactVolume.SetKeyCommandVisible(false);
|
||||
}
|
||||
else if (____healsPlayer)
|
||||
{
|
||||
// Health full
|
||||
uitextType = UITextType.RefillPrompt_9;
|
||||
____interactVolume.SetKeyCommandVisible(false);
|
||||
}
|
||||
|
||||
if (showRespawnPrompt)
|
||||
{
|
||||
____interactVolume.GetValue<ScreenPrompt>("_screenPrompt").SetText($"<CMD> Respawn Player");
|
||||
____interactVolume.GetValue<ScreenPrompt>("_noCommandIconPrompt").SetText("Respawn Player");
|
||||
}
|
||||
|
||||
if (uitextType != UITextType.None)
|
||||
{
|
||||
____interactVolume.ChangePrompt(uitextType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerRecoveryPoint), nameof(PlayerRecoveryPoint.OnPressInteract))]
|
||||
public static bool PlayerRecoveryPoint_OnPressInteract(
|
||||
PlayerRecoveryPoint __instance,
|
||||
PlayerResources ____playerResources,
|
||||
ref bool ____recovering,
|
||||
bool ____refuelsPlayer,
|
||||
bool ____healsPlayer,
|
||||
PlayerAudioController ____playerAudioController,
|
||||
SingleInteractionVolume ____interactVolume
|
||||
)
|
||||
{
|
||||
var playerNeedsRefueling = ____playerResources.GetFuelFraction() != 1f;
|
||||
var playerNeedsHealing = ____playerResources.GetHealthFraction() != 1f;
|
||||
var canBeInteractedWith = false;
|
||||
|
||||
if (playerNeedsRefueling && ____refuelsPlayer)
|
||||
{
|
||||
canBeInteractedWith = true;
|
||||
}
|
||||
|
||||
if (playerNeedsHealing && ____healsPlayer)
|
||||
{
|
||||
canBeInteractedWith = true;
|
||||
}
|
||||
|
||||
if (RespawnManager.Instance.RespawnNeeded)
|
||||
{
|
||||
canBeInteractedWith = true;
|
||||
}
|
||||
|
||||
if (canBeInteractedWith)
|
||||
{
|
||||
if (RespawnManager.Instance.RespawnNeeded && !playerNeedsRefueling && !playerNeedsHealing)
|
||||
{
|
||||
RespawnManager.Instance.RespawnSomePlayer();
|
||||
return false;
|
||||
}
|
||||
|
||||
____playerResources.StartRefillResources(____refuelsPlayer, ____healsPlayer);
|
||||
|
||||
if (____playerAudioController != null)
|
||||
{
|
||||
if (playerNeedsRefueling && ____refuelsPlayer)
|
||||
{
|
||||
____playerAudioController.PlayRefuel();
|
||||
}
|
||||
|
||||
if (playerNeedsHealing && ____healsPlayer)
|
||||
{
|
||||
____playerAudioController.PlayMedkit();
|
||||
}
|
||||
}
|
||||
|
||||
____recovering = true;
|
||||
__instance.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
____interactVolume.ResetInteraction();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,9 @@ using OWML.Utils;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.RespawnSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
@ -75,7 +77,7 @@ namespace QSB.DeathSync
|
||||
}
|
||||
else
|
||||
{
|
||||
var allAstroobjects = Resources.FindObjectsOfTypeAll<AstroObject>().Where(x => x.GetAstroObjectName() != AstroObject.Name.None && x.GetAstroObjectType() != AstroObject.Type.Satellite);
|
||||
var allAstroobjects = QSBWorldSync.GetUnityObjects<AstroObject>().Where(x => x.GetAstroObjectName() != AstroObject.Name.None && x.GetAstroObjectType() != AstroObject.Type.Satellite);
|
||||
var ordered = allAstroobjects.OrderBy(x => Vector3.SqrMagnitude(x.transform.position));
|
||||
DeathClosestAstroObject = ordered.First().transform;
|
||||
}
|
||||
@ -138,4 +140,4 @@ namespace QSB.DeathSync
|
||||
&& spawnPoint.IsShipSpawn() == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs
Normal file
10
QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using QSB.EchoesOfTheEye.AirlockSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.AirlockSync
|
||||
{
|
||||
internal class AirlockManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init<QSBGhostAirlock, GhostAirlock>();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.AirlockSync.WorldObjects
|
||||
{
|
||||
internal class QSBGhostAirlock : WorldObject<GhostAirlock>
|
||||
{
|
||||
public override void Init(GhostAirlock airlock, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = airlock;
|
||||
}
|
||||
}
|
||||
}
|
10
QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs
Normal file
10
QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using QSB.EchoesOfTheEye.LightSensorSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.LightSensorSync
|
||||
{
|
||||
internal class LightSensorManager : WorldObjectManager
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init<QSBSingleLightSensor, SingleLightSensor>();
|
||||
}
|
||||
}
|
149
QSB/EchoesOfTheEye/LightSensorSync/Patches/LightSensorPatches.cs
Normal file
149
QSB/EchoesOfTheEye/LightSensorSync/Patches/LightSensorPatches.cs
Normal file
@ -0,0 +1,149 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Tools.FlashlightTool;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.LightSensorSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class LightSensorPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SingleLightSensor), nameof(SingleLightSensor.UpdateIllumination))]
|
||||
public static bool UpdateIlluminationReplacement(SingleLightSensor __instance)
|
||||
{
|
||||
__instance._illuminated = false;
|
||||
if (__instance._illuminatingDreamLanternList != null)
|
||||
{
|
||||
__instance._illuminatingDreamLanternList.Clear();
|
||||
}
|
||||
|
||||
var vector = __instance.transform.TransformPoint(__instance._localSensorOffset);
|
||||
var sensorWorldDir = Vector3.zero;
|
||||
if (__instance._directionalSensor)
|
||||
{
|
||||
sensorWorldDir = __instance.transform.TransformDirection(__instance._localDirection).normalized;
|
||||
}
|
||||
|
||||
if (__instance._lightSources == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < __instance._lightSources.Count; i++)
|
||||
{
|
||||
var source = __instance._lightSources[i];
|
||||
|
||||
if ((__instance._lightSourceMask & source.GetLightSourceType()) == source.GetLightSourceType()
|
||||
&& source.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance))
|
||||
{
|
||||
var lightSourceType = source.GetLightSourceType();
|
||||
switch (lightSourceType)
|
||||
{
|
||||
case LightSourceType.UNDEFINED:
|
||||
{
|
||||
var owlight = source as OWLight2;
|
||||
var occludableLight = owlight.GetLight().shadows != LightShadows.None
|
||||
&& owlight.GetLight().shadowStrength > 0.5f;
|
||||
|
||||
if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
|
||||
&& !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.FLASHLIGHT:
|
||||
{
|
||||
if (source is Flashlight && (source as Flashlight) == Locator.GetFlashlight())
|
||||
{
|
||||
var position = Locator.GetPlayerCamera().transform.position;
|
||||
var to = __instance.transform.position - position;
|
||||
if (Vector3.Angle(Locator.GetPlayerCamera().transform.forward, to) <= __instance._maxSpotHalfAngle
|
||||
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir, true))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = QSBPlayerManager.PlayerList.First(x => x.FlashLight == (QSBFlashlight)source);
|
||||
|
||||
var position = player.Camera.transform.position;
|
||||
var to = __instance.transform.position - position;
|
||||
if (Vector3.Angle(player.Camera.transform.forward, to) <= __instance._maxSpotHalfAngle
|
||||
&& !__instance.CheckOcclusion(position, vector, sensorWorldDir, true))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.PROBE:
|
||||
{
|
||||
var probe = Locator.GetProbe();
|
||||
if (probe != null
|
||||
&& probe.IsLaunched()
|
||||
&& !probe.IsRetrieving()
|
||||
&& probe.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
|
||||
&& !__instance.CheckOcclusion(probe.GetLightSourcePosition(), vector, sensorWorldDir, true))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.FLASHLIGHT | LightSourceType.PROBE:
|
||||
case LightSourceType.FLASHLIGHT | LightSourceType.DREAM_LANTERN:
|
||||
case LightSourceType.PROBE | LightSourceType.DREAM_LANTERN:
|
||||
case LightSourceType.FLASHLIGHT | LightSourceType.PROBE | LightSourceType.DREAM_LANTERN:
|
||||
break;
|
||||
case LightSourceType.DREAM_LANTERN:
|
||||
{
|
||||
var dreamLanternController = __instance._lightSources[i] as DreamLanternController;
|
||||
if (dreamLanternController.IsLit()
|
||||
&& dreamLanternController.IsFocused(__instance._lanternFocusThreshold)
|
||||
&& dreamLanternController.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
|
||||
&& !__instance.CheckOcclusion(dreamLanternController.GetLightPosition(), vector, sensorWorldDir, true))
|
||||
{
|
||||
__instance._illuminatingDreamLanternList.Add(dreamLanternController);
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LightSourceType.SIMPLE_LANTERN:
|
||||
foreach (var owlight in __instance._lightSources[i].GetLights())
|
||||
{
|
||||
var occludableLight = owlight.GetLight().shadows != LightShadows.None
|
||||
&& owlight.GetLight().shadowStrength > 0.5f;
|
||||
var maxDistance = Mathf.Min(__instance._maxSimpleLanternDistance, __instance._maxDistance);
|
||||
if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, maxDistance) && !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if (lightSourceType == LightSourceType.VOLUME_ONLY)
|
||||
{
|
||||
__instance._illuminated = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.EchoesOfTheEye.LightSensorSync.WorldObjects
|
||||
{
|
||||
internal class QSBSingleLightSensor : WorldObject<SingleLightSensor>
|
||||
{
|
||||
public override void Init(SingleLightSensor sensor, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = sensor;
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ namespace QSB.ElevatorSync.Events
|
||||
|
||||
private void Handler(int id, bool isGoingUp) => SendEvent(CreateMessage(id, isGoingUp));
|
||||
|
||||
private BoolWorldObjectMessage CreateMessage(int id, bool isGoingUp) => new BoolWorldObjectMessage
|
||||
private BoolWorldObjectMessage CreateMessage(int id, bool isGoingUp) => new()
|
||||
{
|
||||
State = isGoingUp,
|
||||
ObjectId = id
|
||||
|
@ -17,7 +17,7 @@ namespace QSB.ElevatorSync.Patches
|
||||
public static void Elevator_StartLift(Elevator __instance)
|
||||
{
|
||||
var isGoingUp = __instance.GetValue<bool>("_goingToTheEnd");
|
||||
var id = QSBWorldSync.GetIdFromUnity<QSBElevator, Elevator>(__instance);
|
||||
var id = QSBWorldSync.GetIdFromUnity<QSBElevator>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBStartLift, id, isGoingUp);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using OWML.Utils;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ElevatorSync.WorldObjects
|
||||
@ -12,42 +11,65 @@ namespace QSB.ElevatorSync.WorldObjects
|
||||
private SingleInteractionVolume _interactVolume;
|
||||
private OWAudioSource _owAudioSourceOneShot;
|
||||
private OWAudioSource _owAudioSourceLP;
|
||||
private OWTriggerVolume _elevatorTrigger;
|
||||
|
||||
public override void Init(Elevator elevator, int id)
|
||||
{
|
||||
AttachedObject = elevator;
|
||||
ObjectId = id;
|
||||
QSBCore.UnityEvents.RunWhen(() => AttachedObject.GetValue<SingleInteractionVolume>("_interactVolume") != null, InitValues);
|
||||
QSBCore.UnityEvents.RunWhen(() => AttachedObject._interactVolume != null, InitValues);
|
||||
}
|
||||
|
||||
private void InitValues()
|
||||
{
|
||||
_startLocalPos = AttachedObject.GetValue<Vector3>("_startLocalPos");
|
||||
_endLocalPos = AttachedObject.GetValue<Vector3>("_endLocalPos");
|
||||
_interactVolume = AttachedObject.GetValue<SingleInteractionVolume>("_interactVolume");
|
||||
_owAudioSourceOneShot = AttachedObject.GetValue<OWAudioSource>("_owAudioSourceOneShot");
|
||||
_owAudioSourceLP = AttachedObject.GetValue<OWAudioSource>("_owAudioSourceLP");
|
||||
_startLocalPos = AttachedObject._startLocalPos;
|
||||
_endLocalPos = AttachedObject._endLocalPos;
|
||||
_interactVolume = AttachedObject._interactVolume;
|
||||
_owAudioSourceOneShot = AttachedObject._owAudioSourceOneShot;
|
||||
_owAudioSourceLP = AttachedObject._owAudioSourceLP;
|
||||
|
||||
var boxShape = AttachedObject.gameObject.AddComponent<BoxShape>();
|
||||
boxShape.center = new Vector3(0, 1.75f, 0.25f);
|
||||
boxShape.size = new Vector3(3, 3.5f, 3);
|
||||
|
||||
_elevatorTrigger = AttachedObject.gameObject.GetAddComponent<OWTriggerVolume>();
|
||||
}
|
||||
|
||||
public void RemoteCall(bool isGoingUp)
|
||||
{
|
||||
SetDirection(isGoingUp);
|
||||
RemoteStartLift();
|
||||
if (_elevatorTrigger.IsTrackingObject(Locator.GetPlayerDetector()))
|
||||
{
|
||||
SetDirection(isGoingUp);
|
||||
|
||||
AttachedObject._attachPoint.AttachPlayer();
|
||||
|
||||
if (Locator.GetPlayerSuit().IsWearingSuit(true) && Locator.GetPlayerSuit().IsTrainingSuit())
|
||||
{
|
||||
Locator.GetPlayerSuit().RemoveSuit(false);
|
||||
}
|
||||
|
||||
RemoteStartLift();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDirection(isGoingUp);
|
||||
RemoteStartLift();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDirection(bool isGoingUp)
|
||||
{
|
||||
var targetPos = isGoingUp ? _endLocalPos : _startLocalPos;
|
||||
AttachedObject.SetValue("_goingToTheEnd", isGoingUp);
|
||||
AttachedObject.SetValue("_targetLocalPos", targetPos);
|
||||
_interactVolume.transform.Rotate(0f, 180f, 0f);
|
||||
var targetPos = isGoingUp ? _endLocalPos : _startLocalPos;
|
||||
AttachedObject._targetLocalPos = targetPos;
|
||||
AttachedObject._goingToTheEnd = isGoingUp;
|
||||
}
|
||||
|
||||
private void RemoteStartLift()
|
||||
{
|
||||
AttachedObject.enabled = true;
|
||||
AttachedObject.SetValue("_initLocalPos", AttachedObject.transform.localPosition);
|
||||
AttachedObject.SetValue("_initLiftTime", Time.time);
|
||||
AttachedObject._initLocalPos = AttachedObject.transform.localPosition;
|
||||
AttachedObject._initLiftTime = Time.time;
|
||||
_owAudioSourceOneShot.PlayOneShot(AudioType.TH_LiftActivate);
|
||||
_owAudioSourceLP.FadeIn(0.5f);
|
||||
_interactVolume.DisableInteraction();
|
||||
|
@ -62,8 +62,8 @@
|
||||
public static string QSBCampfireState = "QSBCampfireState";
|
||||
public static string QSBMarshmallowEvent = "QSBMarshmallowEvent";
|
||||
public static string QSBAnimTrigger = "QSBAnimTrigger";
|
||||
public static string QSBEnterHeadZone = "QSBEnterHeadZone";
|
||||
public static string QSBExitHeadZone = "QSBExitHeadZone";
|
||||
public static string QSBEnterNonNomaiHeadZone = "QSBEnterNonNomaiHeadZone";
|
||||
public static string QSBExitNonNomaiHeadZone = "QSBExitNonNomaiHeadZone";
|
||||
public static string QSBNpcAnimEvent = "QSBNpcAnimEvent";
|
||||
public static string QSBHatchState = "QSBHatchState";
|
||||
public static string QSBEnableFunnel = "QSBEnableFunnel";
|
||||
@ -87,5 +87,17 @@
|
||||
public static string QSBServerState = "QSBServerState";
|
||||
public static string QSBClientState = "QSBClientState";
|
||||
public static string QSBDebugEvent = "QSBDebugEvent";
|
||||
public static string QSBEnterNomaiHeadZone = "QSBEnterNomaiHeadZone";
|
||||
public static string QSBExitNomaiHeadZone = "QSBExitNomaiHeadZone";
|
||||
public static string QSBEnterSatelliteCamera = "QSBEnterSatelliteCamera";
|
||||
public static string QSBExitSatelliteCamera = "QSBExitSatelliteCamera";
|
||||
public static string QSBSatelliteSnapshot = "QSBSatelliteSnapshot";
|
||||
public static string QSBAnglerChangeState = "QSBAnglerChangeState";
|
||||
public static string QSBMeteorPreLaunch = "QSBMeteorPreLaunch";
|
||||
public static string QSBMeteorLaunch = "QSBMeteorLaunch";
|
||||
public static string QSBMeteorSpecialImpact = "QSBMeteorSpecialImpact";
|
||||
public static string QSBFragmentDamage = "QSBFragmentDamage";
|
||||
public static string QSBFragmentResync = "QSBFragmentResync";
|
||||
public static string QSBLearnLaunchCodes = "QSBLearnLaunchCodes";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,13 @@
|
||||
public enum EventType
|
||||
{
|
||||
/*
|
||||
* MISC.
|
||||
* MISC.
|
||||
*/
|
||||
DebugEvent,
|
||||
SatelliteProjector,
|
||||
SatelliteProjectorSnapshot,
|
||||
LaunchCodes,
|
||||
VariableSync,
|
||||
|
||||
/*
|
||||
* SERVER EVENTS
|
||||
@ -131,6 +135,14 @@
|
||||
RetrieveProbe,
|
||||
PlayerRetrieveProbe,
|
||||
LaunchProbe,
|
||||
PlayerLaunchProbe
|
||||
PlayerLaunchProbe,
|
||||
|
||||
AnglerChangeState,
|
||||
|
||||
MeteorPreLaunch,
|
||||
MeteorLaunch,
|
||||
MeteorSpecialImpact,
|
||||
FragmentDamage,
|
||||
FragmentResync
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
{
|
||||
public interface IQSBEvent
|
||||
{
|
||||
EventType Type { get; }
|
||||
|
||||
void SetupListener();
|
||||
void CloseListener();
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using OWML.Common;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Events;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Components;
|
||||
@ -75,10 +77,24 @@ namespace QSB.Events
|
||||
|
||||
if (PlayerTransformSync.LocalInstance == null || PlayerTransformSync.LocalInstance.GetComponent<QNetworkIdentity>() == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to handle message of type <{message.GetType().Name}> before localplayer was established.", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - Tried to handle message of type <{GetType().Name}> before localplayer was established.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (QSBPlayerManager.PlayerExists(message.FromId))
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.FromId);
|
||||
|
||||
if (!player.IsReady
|
||||
&& player.PlayerId != LocalPlayerId
|
||||
&& (player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem)
|
||||
&& (message is not PlayerInformationEvent or PlayerReadyEvent))
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Got message from player {message.FromId}, but they were not ready. Asking for state resync, just in case.", MessageType.Warning);
|
||||
QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (message.FromId == QSBPlayerManager.LocalPlayerId ||
|
||||
@ -92,7 +108,7 @@ namespace QSB.Events
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Exception handling message {message.GetType().Name} : {ex}", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - Exception handling message {GetType().Name} : {ex}", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using QSB.Anglerfish.Events;
|
||||
using QSB.Animation.NPC.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
using QSB.CampfireSync.Events;
|
||||
@ -6,26 +7,33 @@ using QSB.ClientServerStateSync.Events;
|
||||
using QSB.ConversationSync.Events;
|
||||
using QSB.DeathSync.Events;
|
||||
using QSB.ElevatorSync.Events;
|
||||
using QSB.FrequencySync.Events;
|
||||
using QSB.GeyserSync.Events;
|
||||
using QSB.ItemSync.Events;
|
||||
using QSB.LogSync.Events;
|
||||
using QSB.MeteorSync.Events;
|
||||
using QSB.OrbSync.Events;
|
||||
using QSB.Player.Events;
|
||||
using QSB.ProbeSync.Events;
|
||||
using QSB.QuantumSync.Events;
|
||||
using QSB.RespawnSync.Events;
|
||||
using QSB.RoastingSync.Events;
|
||||
using QSB.SatelliteSync.Events;
|
||||
using QSB.ShipSync.Events;
|
||||
using QSB.ShipSync.Events.Component;
|
||||
using QSB.ShipSync.Events.Hull;
|
||||
using QSB.StatueSync.Events;
|
||||
using QSB.TimeSync.Events;
|
||||
using QSB.Tools.Events;
|
||||
using QSB.Tools.FlashlightTool.Events;
|
||||
using QSB.Tools.ProbeLauncherTool.Events;
|
||||
using QSB.TranslationSync.Events;
|
||||
using QSB.Tools.ProbeTool.Events;
|
||||
using QSB.Tools.SignalscopeTool.Events;
|
||||
using QSB.Tools.SignalscopeTool.FrequencySync.Events;
|
||||
using QSB.Tools.TranslatorTool.Events;
|
||||
using QSB.Tools.TranslatorTool.TranslationSync.Events;
|
||||
using QSB.Utility;
|
||||
using QSB.Utility.Events;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace QSB.Events
|
||||
{
|
||||
@ -33,7 +41,7 @@ namespace QSB.Events
|
||||
{
|
||||
public static bool Ready { get; private set; }
|
||||
|
||||
private static List<IQSBEvent> _eventList = new List<IQSBEvent>();
|
||||
private static List<IQSBEvent> _eventList = new();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
@ -69,6 +77,9 @@ namespace QSB.Events
|
||||
new ServerStateEvent(),
|
||||
new ClientStateEvent(),
|
||||
new DebugEvent(),
|
||||
new SatelliteProjectorEvent(),
|
||||
new SatelliteProjectorSnapshotEvent(),
|
||||
new LaunchCodesEvent(),
|
||||
// World Objects
|
||||
new ElevatorEvent(),
|
||||
new GeyserEvent(),
|
||||
@ -86,6 +97,12 @@ namespace QSB.Events
|
||||
new MoveToCarryEvent(),
|
||||
new StartStatueEvent(),
|
||||
new CampfireStateEvent(),
|
||||
new AnglerChangeStateEvent(),
|
||||
new MeteorPreLaunchEvent(),
|
||||
new MeteorLaunchEvent(),
|
||||
new MeteorSpecialImpactEvent(),
|
||||
new FragmentDamageEvent(),
|
||||
new FragmentResyncEvent(),
|
||||
// Conversation/dialogue/exploration
|
||||
new ConversationEvent(),
|
||||
new ConversationStartEndEvent(),
|
||||
@ -115,6 +132,26 @@ namespace QSB.Events
|
||||
|
||||
_eventList.ForEach(ev => ev.SetupListener());
|
||||
|
||||
var duplicates = _eventList
|
||||
.GroupBy(qsbEvent => qsbEvent.Type)
|
||||
.Where(group => group.Count() > 1);
|
||||
|
||||
if (duplicates.Count() != 0)
|
||||
{
|
||||
var totalSb = new StringBuilder();
|
||||
foreach (var group in duplicates)
|
||||
{
|
||||
totalSb.Append($"{group.Key}\r\n");
|
||||
foreach (var qsbEvent in group)
|
||||
{
|
||||
totalSb.Append($"- {qsbEvent.GetType().Name}\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
DebugLog.ToConsole($"Error - These QSBEvents handle the same EventType!\r\n{totalSb}", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Ready = true;
|
||||
|
||||
DebugLog.DebugWrite("Event Manager ready.", MessageType.Success);
|
||||
@ -203,4 +240,4 @@ namespace QSB.Events
|
||||
GlobalMessenger<T, U, V, W, X, Y>.FireEvent(eventName, arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace QSB.GeyserSync.Events
|
||||
|
||||
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
|
||||
|
||||
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new BoolWorldObjectMessage
|
||||
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new()
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
ObjectId = id,
|
||||
|
@ -1,5 +1,6 @@
|
||||
using QSB.Events;
|
||||
using QSB.ItemSync.WorldObjects;
|
||||
using QSB.ItemSync.WorldObjects.Items;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
@ -19,7 +20,7 @@ namespace QSB.ItemSync.Events
|
||||
private void Handler(int objectId, Vector3 position, Vector3 normal, Sector sector)
|
||||
=> SendEvent(CreateMessage(objectId, position, normal, sector));
|
||||
|
||||
private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Sector sector) => new DropItemMessage
|
||||
private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Sector sector) => new()
|
||||
{
|
||||
ObjectId = objectId,
|
||||
Position = position,
|
||||
@ -31,6 +32,9 @@ namespace QSB.ItemSync.Events
|
||||
{
|
||||
var worldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ObjectId);
|
||||
worldObject.DropItem(message.Position, message.Normal, message.Sector);
|
||||
|
||||
var player = QSBPlayerManager.GetPlayer(message.FromId);
|
||||
player.HeldItem = worldObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace QSB.ItemSync.Events
|
||||
writer.Write(ObjectId);
|
||||
writer.Write(Position);
|
||||
writer.Write(Normal);
|
||||
var qsbSector = QSBWorldSync.GetWorldFromUnity<QSBSector, Sector>(Sector);
|
||||
var qsbSector = QSBWorldSync.GetWorldFromUnity<QSBSector>(Sector);
|
||||
writer.Write(qsbSector.ObjectId);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
using QSB.Events;
|
||||
using QSB.ItemSync.WorldObjects;
|
||||
using QSB.ItemSync.WorldObjects.Items;
|
||||
using QSB.Player;
|
||||
using QSB.WorldSync;
|
||||
using QSB.WorldSync.Events;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ItemSync.Events
|
||||
{
|
||||
@ -20,7 +19,7 @@ namespace QSB.ItemSync.Events
|
||||
private void Handler(int itemId)
|
||||
=> SendEvent(CreateMessage(itemId));
|
||||
|
||||
private WorldObjectMessage CreateMessage(int itemid) => new WorldObjectMessage
|
||||
private WorldObjectMessage CreateMessage(int itemid) => new()
|
||||
{
|
||||
AboutId = QSBPlayerManager.LocalPlayerId,
|
||||
ObjectId = itemid
|
||||
@ -31,26 +30,21 @@ namespace QSB.ItemSync.Events
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
var itemObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ObjectId);
|
||||
var itemType = itemObject.GetItemType();
|
||||
Transform itemSocket = null;
|
||||
switch (itemType)
|
||||
|
||||
player.HeldItem = itemObject;
|
||||
var itemSocket = itemType switch
|
||||
{
|
||||
case ItemType.Scroll:
|
||||
itemSocket = player.ScrollSocket;
|
||||
break;
|
||||
case ItemType.SharedStone:
|
||||
itemSocket = player.SharedStoneSocket;
|
||||
break;
|
||||
case ItemType.WarpCore:
|
||||
itemSocket = ((QSBWarpCoreItem)itemObject).IsVesselCoreType()
|
||||
? player.VesselCoreSocket
|
||||
: player.WarpCoreSocket;
|
||||
break;
|
||||
default:
|
||||
itemSocket = player.ItemSocket;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
ItemType.Scroll => player.ScrollSocket,
|
||||
ItemType.SharedStone => player.SharedStoneSocket,
|
||||
ItemType.WarpCore => ((QSBWarpCoreItem)itemObject).IsVesselCoreType()
|
||||
? player.VesselCoreSocket
|
||||
: player.WarpCoreSocket,
|
||||
ItemType.Lantern => player.SimpleLanternSocket,
|
||||
ItemType.DreamLantern => player.DreamLanternSocket,
|
||||
ItemType.SlideReel => player.SlideReelSocket,
|
||||
ItemType.VisionTorch => player.VisionTorchSocket,
|
||||
_ => player.ItemSocket,
|
||||
};
|
||||
itemObject.PickUpItem(itemSocket, message.AboutId);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using QSB.Events;
|
||||
using QSB.ItemSync.WorldObjects;
|
||||
using QSB.ItemSync.WorldObjects.Items;
|
||||
using QSB.ItemSync.WorldObjects.Sockets;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
@ -19,7 +20,7 @@ namespace QSB.ItemSync.Events
|
||||
private void Handler(int socketId, int itemId, SocketEventType type)
|
||||
=> SendEvent(CreateMessage(socketId, itemId, type));
|
||||
|
||||
private SocketItemMessage CreateMessage(int socketId, int itemId, SocketEventType type) => new SocketItemMessage
|
||||
private SocketItemMessage CreateMessage(int socketId, int itemId, SocketEventType type) => new()
|
||||
{
|
||||
AboutId = QSBPlayerManager.LocalPlayerId,
|
||||
SocketId = socketId,
|
||||
@ -31,6 +32,8 @@ namespace QSB.ItemSync.Events
|
||||
{
|
||||
var socketWorldObject = QSBWorldSync.GetWorldFromId<IQSBOWItemSocket>(message.SocketId);
|
||||
var itemWorldObject = QSBWorldSync.GetWorldFromId<IQSBOWItem>(message.ItemId);
|
||||
var player = QSBPlayerManager.GetPlayer(message.FromId);
|
||||
player.HeldItem = null;
|
||||
switch (message.SocketType)
|
||||
{
|
||||
case SocketEventType.Socket:
|
||||
|
@ -1,5 +1,6 @@
|
||||
using OWML.Common;
|
||||
using QSB.ItemSync.WorldObjects;
|
||||
using QSB.ItemSync.WorldObjects.Items;
|
||||
using QSB.ItemSync.WorldObjects.Sockets;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
|
||||
@ -10,80 +11,22 @@ namespace QSB.ItemSync
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Info);
|
||||
QSBWorldSync.Init<QSBScrollSocket, ScrollSocket>();
|
||||
|
||||
// Items
|
||||
QSBWorldSync.Init<QSBScrollItem, ScrollItem>();
|
||||
QSBWorldSync.Init<QSBSharedStoneSocket, SharedStoneSocket>();
|
||||
QSBWorldSync.Init<QSBSharedStone, SharedStone>();
|
||||
QSBWorldSync.Init<QSBWarpCoreSocket, WarpCoreSocket>();
|
||||
QSBWorldSync.Init<QSBWarpCoreItem, WarpCoreItem>();
|
||||
QSBWorldSync.Init<QSBNomaiConversationStoneSocket, NomaiConversationStoneSocket>();
|
||||
QSBWorldSync.Init<QSBNomaiConversationStone, NomaiConversationStone>();
|
||||
}
|
||||
QSBWorldSync.Init<QSBSimpleLanternItem, SimpleLanternItem>();
|
||||
QSBWorldSync.Init<QSBSlideReelItem, SlideReelItem>();
|
||||
|
||||
public static IQSBOWItem GetObject(OWItem unityObject)
|
||||
{
|
||||
if (unityObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to run GetObject (Item) with null unity object!", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
IQSBOWItem worldObj = null;
|
||||
if (unityObject.GetType() == typeof(ScrollItem))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBScrollItem, ScrollItem>((ScrollItem)unityObject);
|
||||
}
|
||||
else if (unityObject.GetType() == typeof(SharedStone))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBSharedStone, SharedStone>((SharedStone)unityObject);
|
||||
}
|
||||
else if (unityObject.GetType() == typeof(WarpCoreItem))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBWarpCoreItem, WarpCoreItem>((WarpCoreItem)unityObject);
|
||||
}
|
||||
else if (unityObject.GetType() == typeof(NomaiConversationStone))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBNomaiConversationStone, NomaiConversationStone>((NomaiConversationStone)unityObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - couldn't work out type of OWItem {unityObject.name}.", MessageType.Warning);
|
||||
}
|
||||
|
||||
return worldObj;
|
||||
}
|
||||
|
||||
public static IQSBOWItemSocket GetObject(OWItemSocket unityObject)
|
||||
{
|
||||
if (unityObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Trying to run GetObject (Socket) with null unity object!", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
|
||||
IQSBOWItemSocket worldObj = null;
|
||||
if (unityObject.GetType() == typeof(ScrollSocket))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBScrollSocket, ScrollSocket>((ScrollSocket)unityObject);
|
||||
}
|
||||
else if (unityObject.GetType() == typeof(SharedStoneSocket))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBSharedStoneSocket, SharedStoneSocket>((SharedStoneSocket)unityObject);
|
||||
}
|
||||
else if (unityObject.GetType() == typeof(WarpCoreSocket))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBWarpCoreSocket, WarpCoreSocket>((WarpCoreSocket)unityObject);
|
||||
}
|
||||
else if (unityObject.GetType() == typeof(NomaiConversationStone))
|
||||
{
|
||||
worldObj = QSBWorldSync.GetWorldFromUnity<QSBNomaiConversationStoneSocket, NomaiConversationStoneSocket>((NomaiConversationStoneSocket)unityObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - couldn't work out type of OWItemSocket {unityObject.name}.", MessageType.Warning);
|
||||
}
|
||||
|
||||
return worldObj;
|
||||
// Sockets
|
||||
QSBWorldSync.Init<QSBScrollSocket, ScrollSocket>();
|
||||
QSBWorldSync.Init<QSBSharedStoneSocket, SharedStoneSocket>();
|
||||
QSBWorldSync.Init<QSBWarpCoreSocket, WarpCoreSocket>();
|
||||
QSBWorldSync.Init<QSBNomaiConversationStoneSocket, NomaiConversationStoneSocket>();
|
||||
QSBWorldSync.Init<QSBSlideReelSocket, SlideReelSocket>();
|
||||
QSBWorldSync.Init<QSBSlideProjectorSocket, SlideProjectorSocket>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.ItemSync.WorldObjects.Items;
|
||||
using QSB.ItemSync.WorldObjects.Sockets;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
@ -17,7 +20,9 @@ namespace QSB.ItemSync.Patches
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.MoveItemToCarrySocket))]
|
||||
public static bool ItemTool_MoveItemToCarrySocket(OWItem item)
|
||||
{
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(item));
|
||||
var qsbObj = (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(item);
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(qsbObj);
|
||||
QSBPlayerManager.LocalPlayer.HeldItem = qsbObj;
|
||||
QSBEventManager.FireEvent(EventNames.QSBMoveToCarry, itemId);
|
||||
return true;
|
||||
}
|
||||
@ -26,8 +31,10 @@ namespace QSB.ItemSync.Patches
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.SocketItem))]
|
||||
public static bool ItemTool_SocketItem(OWItem ____heldItem, OWItemSocket socket)
|
||||
{
|
||||
var socketId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
|
||||
var qsbObj = (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(____heldItem);
|
||||
var socketId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItemSocket)QSBWorldSync.GetWorldFromUnity(socket));
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(qsbObj);
|
||||
QSBPlayerManager.LocalPlayer.HeldItem = null;
|
||||
QSBEventManager.FireEvent(EventNames.QSBSocketItem, socketId, itemId, SocketEventType.Socket);
|
||||
return true;
|
||||
}
|
||||
@ -36,7 +43,9 @@ namespace QSB.ItemSync.Patches
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.StartUnsocketItem))]
|
||||
public static bool ItemTool_StartUnsocketItem(OWItemSocket socket)
|
||||
{
|
||||
var socketId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
|
||||
var item = (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(socket.GetSocketedItem());
|
||||
QSBPlayerManager.LocalPlayer.HeldItem = item;
|
||||
var socketId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItemSocket)QSBWorldSync.GetWorldFromUnity(socket));
|
||||
QSBEventManager.FireEvent(EventNames.QSBSocketItem, socketId, 0, SocketEventType.StartUnsocket);
|
||||
return true;
|
||||
}
|
||||
@ -45,7 +54,7 @@ namespace QSB.ItemSync.Patches
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.CompleteUnsocketItem))]
|
||||
public static bool ItemTool_CompleteUnsocketItem(OWItem ____heldItem)
|
||||
{
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItem)QSBWorldSync.GetWorldFromUnity(____heldItem));
|
||||
QSBEventManager.FireEvent(EventNames.QSBSocketItem, 0, itemId, SocketEventType.CompleteUnsocket);
|
||||
return true;
|
||||
}
|
||||
@ -70,7 +79,7 @@ namespace QSB.ItemSync.Patches
|
||||
sector = sectorGroup.GetSector();
|
||||
if (sector == null && sectorGroup is SectorCullGroup)
|
||||
{
|
||||
SectorProxy controllingProxy = (sectorGroup as SectorCullGroup).GetControllingProxy();
|
||||
var controllingProxy = (sectorGroup as SectorCullGroup).GetControllingProxy();
|
||||
if (controllingProxy != null)
|
||||
{
|
||||
sector = controllingProxy.GetSector();
|
||||
@ -81,9 +90,10 @@ namespace QSB.ItemSync.Patches
|
||||
var parent = (customDropTarget == null)
|
||||
? targetRigidbody.transform
|
||||
: customDropTarget.GetItemDropTargetTransform(hit.collider.gameObject);
|
||||
var objectId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
|
||||
var objectId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItem)QSBWorldSync.GetWorldFromUnity(____heldItem));
|
||||
____heldItem.DropItem(hit.point, hit.normal, parent, sector, customDropTarget);
|
||||
____heldItem = null;
|
||||
QSBPlayerManager.LocalPlayer.HeldItem = null;
|
||||
Locator.GetToolModeSwapper().UnequipTool();
|
||||
var parentSector = parent.GetComponentInChildren<Sector>();
|
||||
if (parentSector != null)
|
||||
|
@ -1,7 +1,7 @@
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ItemSync.WorldObjects
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
public interface IQSBOWItem : IWorldObjectTypeSubset
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
namespace QSB.ItemSync.WorldObjects
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
internal class QSBNomaiConversationStone : QSBOWItem<NomaiConversationStone>
|
||||
{
|
@ -1,10 +1,11 @@
|
||||
using OWML.Utils;
|
||||
using QSB.ItemSync.WorldObjects.Sockets;
|
||||
using QSB.Player;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ItemSync.WorldObjects
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
internal class QSBOWItem<T> : WorldObject<T>, IQSBOWItem
|
||||
where T : OWItem
|
||||
@ -18,13 +19,25 @@ namespace QSB.ItemSync.WorldObjects
|
||||
|
||||
public override void Init(T attachedObject, int id)
|
||||
{
|
||||
if (attachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - AttachedObject is null! Type:{GetType().Name}", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
InitialParent = attachedObject.transform.parent;
|
||||
InitialPosition = attachedObject.transform.localPosition;
|
||||
InitialRotation = attachedObject.transform.localRotation;
|
||||
InitialSector = QSBWorldSync.GetWorldFromUnity<QSBSector, Sector>(attachedObject.GetSector());
|
||||
if (InitialParent.GetComponent<OWItemSocket>() != null)
|
||||
InitialSector = QSBWorldSync.GetWorldFromUnity<QSBSector>(attachedObject.GetSector());
|
||||
|
||||
if (InitialParent == null)
|
||||
{
|
||||
var qsbObj = ItemManager.GetObject(InitialParent.GetComponent<OWItemSocket>());
|
||||
DebugLog.ToConsole($"Warning - InitialParent of {attachedObject.name} is null!", OWML.Common.MessageType.Warning);
|
||||
}
|
||||
|
||||
if (InitialParent?.GetComponent<OWItemSocket>() != null)
|
||||
{
|
||||
var qsbObj = (IQSBOWItemSocket)QSBWorldSync.GetWorldFromUnity(InitialParent.GetComponent<OWItemSocket>());
|
||||
InitialSocket = qsbObj;
|
||||
}
|
||||
|
||||
@ -76,10 +89,10 @@ namespace QSB.ItemSync.WorldObjects
|
||||
{
|
||||
AttachedObject.transform.SetParent(sector.transform);
|
||||
AttachedObject.transform.localScale = Vector3.one;
|
||||
var localDropNormal = AttachedObject.GetValue<Vector3>("_localDropNormal");
|
||||
var localDropNormal = AttachedObject._localDropNormal;
|
||||
var lhs = Quaternion.FromToRotation(AttachedObject.transform.TransformDirection(localDropNormal), normal);
|
||||
AttachedObject.transform.rotation = lhs * AttachedObject.transform.rotation;
|
||||
var localDropOffset = AttachedObject.GetValue<Vector3>("_localDropOffset");
|
||||
var localDropOffset = AttachedObject._localDropOffset;
|
||||
AttachedObject.transform.position = sector.transform.TransformPoint(position) + AttachedObject.transform.TransformDirection(localDropOffset);
|
||||
AttachedObject.SetSector(sector);
|
||||
AttachedObject.SetColliderActivation(true);
|
@ -1,4 +1,4 @@
|
||||
namespace QSB.ItemSync.WorldObjects
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
internal class QSBScrollItem : QSBOWItem<ScrollItem>
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
namespace QSB.ItemSync.WorldObjects
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
internal class QSBSharedStone : QSBOWItem<SharedStone>
|
||||
{
|
21
QSB/ItemSync/WorldObjects/Items/QSBSimpleLanternItem.cs
Normal file
21
QSB/ItemSync/WorldObjects/Items/QSBSimpleLanternItem.cs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
internal class QSBSimpleLanternItem : QSBOWItem<SimpleLanternItem>
|
||||
{
|
||||
public override void Init(SimpleLanternItem attachedObject, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = attachedObject;
|
||||
base.Init(attachedObject, id);
|
||||
}
|
||||
|
||||
public override void PlaySocketAnimation()
|
||||
=> AttachedObject.PlaySocketAnimation();
|
||||
|
||||
public override void PlayUnsocketAnimation()
|
||||
=> AttachedObject.PlayUnsocketAnimation();
|
||||
|
||||
public override void OnCompleteUnsocket()
|
||||
=> AttachedObject.OnCompleteUnsocket();
|
||||
}
|
||||
}
|
21
QSB/ItemSync/WorldObjects/Items/QSBSlideReelItem.cs
Normal file
21
QSB/ItemSync/WorldObjects/Items/QSBSlideReelItem.cs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace QSB.ItemSync.WorldObjects.Items
|
||||
{
|
||||
internal class QSBSlideReelItem : QSBOWItem<SlideReelItem>
|
||||
{
|
||||
public override void Init(SlideReelItem attachedObject, int id)
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = attachedObject;
|
||||
base.Init(attachedObject, id);
|
||||
}
|
||||
|
||||
public override void PlaySocketAnimation()
|
||||
=> AttachedObject.PlaySocketAnimation();
|
||||
|
||||
public override void PlayUnsocketAnimation()
|
||||
=> AttachedObject.PlayUnsocketAnimation();
|
||||
|
||||
public override void OnCompleteUnsocket()
|
||||
=> AttachedObject.OnCompleteUnsocket();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user