264 lines
10 KiB
C#
264 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using Cielonos.MainGame.Characters;
|
|
using Cielonos.MainGame.FunctionalAnimation;
|
|
using MoreMountains.Feedbacks;
|
|
using MoreMountains.FeedbacksForThirdParty;
|
|
using Sirenix.OdinInspector;
|
|
using SLSUtilities.WwiseAssistance;
|
|
using SLSUtilities.FunctionalAnimation;
|
|
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace Cielonos.MainGame.Characters.Inventory
|
|
{
|
|
public abstract partial class ItemBase : SerializedMonoBehaviour
|
|
{
|
|
public Player player => MainGameManager.Instance.player;
|
|
protected PlayerAnimationSubcontroller animationSc => player.animationSc;
|
|
protected FunctionalAnimationSubmodule fullBodyFuncAnimSm => animationSc.fullBodyFuncAnimSm;
|
|
protected FunctionalAnimationSubmodule upperBodyFuncAnimSm => animationSc.upperBodyFuncAnimSm;
|
|
[HideInInspector]
|
|
private List<string> registeredFunctionNames = new List<string>();
|
|
|
|
[TitleGroup("Data")]
|
|
public FuncAnimDataCollection fullBodyFuncAnims;
|
|
public FuncAnimDataCollection upperBodyFuncAnims;
|
|
public ContentData contentData;
|
|
public ViewObjectData viewObjectData;
|
|
public VFXData vfxData;
|
|
public AttributeData passiveAttributeData;
|
|
public ComboData comboData;
|
|
public AttackData attackData;
|
|
public FunctionData functionData;
|
|
public AmmoData ammoData;
|
|
public BlockData blockData;
|
|
|
|
[TitleGroup("Audio")]
|
|
public AudioContainer audioContainer;
|
|
|
|
[TitleGroup("Submodules")]
|
|
public AttributeSubmodule passiveAttributeSm;
|
|
public ComboSubmodule comboSm;
|
|
public FunctionSubmodule functionSm;
|
|
public AmmoSubmodule ammoSm;
|
|
|
|
[TitleGroup("Subcontrollers")]
|
|
public FeedbackSubcontroller feedbackSc;
|
|
|
|
[TitleGroup("View Objects")]
|
|
public Dictionary<string, ItemViewObject> viewObjects = new Dictionary<string, ItemViewObject>();
|
|
}
|
|
|
|
public partial class ItemBase
|
|
{
|
|
public virtual void Initialize()
|
|
{
|
|
vfxData?.Initialize(player);
|
|
if(comboData != null) comboSm = new ComboSubmodule(this, comboData);
|
|
if(functionData != null) functionSm = new FunctionSubmodule(this, functionData);
|
|
if(ammoData != null) ammoSm = new AmmoSubmodule(this, ammoData);
|
|
if(passiveAttributeData != null) passiveAttributeSm = new AttributeSubmodule(this, passiveAttributeData);
|
|
}
|
|
|
|
public virtual void OnObtained()
|
|
{
|
|
passiveAttributeSm?.RefreshAllModifiedAttributes();
|
|
}
|
|
|
|
public virtual void OnDiscarded()
|
|
{
|
|
passiveAttributeSm?.RefreshAllModifiedAttributes();
|
|
}
|
|
|
|
protected virtual void Update()
|
|
{
|
|
functionSm?.Update(player.selfTimeSm.DeltaTime);
|
|
}
|
|
}
|
|
|
|
public partial class ItemBase
|
|
{
|
|
protected void SpawnViewObjects()
|
|
{
|
|
if (viewObjectData != null)
|
|
{
|
|
foreach (ViewObjectData.ViewObjectDataUnit unit in viewObjectData.viewObjectUnits)
|
|
{
|
|
Transform attachPoint = !unit.isCustomAttachPoint
|
|
? player.bodyPartsSc.GetPart(unit.normalAttachBodyPart)
|
|
: player.bodyPartsSc.GetPart(unit.customAttachPartName);
|
|
if (attachPoint != null)
|
|
{
|
|
ItemViewObject view = Instantiate(unit.objectPrefab, attachPoint).GetComponent<ItemViewObject>();
|
|
if (unit.applyOffset)
|
|
{
|
|
view.transform.localPosition = unit.positionOffset;
|
|
view.transform.localEulerAngles = unit.rotationOffset;
|
|
}
|
|
|
|
viewObjects[unit.objectName] = view;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DespawnViewObjects()
|
|
{
|
|
foreach (KeyValuePair<string, ItemViewObject> kvp in viewObjects)
|
|
{
|
|
Destroy(kvp.Value.gameObject);
|
|
}
|
|
|
|
viewObjects.Clear();
|
|
}
|
|
}
|
|
|
|
public partial class ItemBase
|
|
{
|
|
protected bool PlayTargetedAnimation(string animationName, CharacterBase target = null,
|
|
float adsorptionMinDistance = 1f, bool keepAdsorption = false, bool autoRotate = true,
|
|
FunctionalAnimationSubmodule funcAnimSm = null, float animationSpeedMultiplier = 1f,
|
|
float transitionDuration = 0.1f, bool isNormalizedTransition = false, string comboTreeName = "Main")
|
|
{
|
|
funcAnimSm ??= fullBodyFuncAnimSm;
|
|
|
|
FuncAnimData data = funcAnimSm.collection[animationName];
|
|
if (data.animInfo.tags.Contains("Attack") && data.animInfo.isAffectedBySpeedMultiplier)
|
|
{
|
|
animationSpeedMultiplier *= player.attributeSm["AttackSpeed"];
|
|
}
|
|
|
|
if (funcAnimSm.Play(data, animationSpeedMultiplier, transitionDuration, isNormalizedTransition))
|
|
{
|
|
float actionCoolDownTime = funcAnimSm.currentData.Interval(IntervalType.ActionDisruption).StartTime /
|
|
funcAnimSm.currentPlaySpeedMultiplier;
|
|
comboSm?[comboTreeName].SuspendThenSetup(actionCoolDownTime);
|
|
if (target != null)
|
|
{
|
|
if (autoRotate) player.landMovementSc.TurnToTarget(target);
|
|
if (keepAdsorption)
|
|
{
|
|
funcAnimSm.currentRuntimeFuncAnim.AddUpdateEvent(new SetRootAdsorptionAdjustment.Keep(target, adsorptionMinDistance));
|
|
}
|
|
else
|
|
{
|
|
funcAnimSm.currentRuntimeFuncAnim.AddUpdateUntilEvent(new SetRootAdsorptionAdjustment.Once(target, adsorptionMinDistance));
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected virtual void Swing(string feedBackName, Vector3 swingRotation = default, Vector3 swingPosition = default)
|
|
{
|
|
Vector3 playerForward = player.transform.forward;
|
|
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward;
|
|
|
|
Vector3 flatPlayerFwd = Vector3.ProjectOnPlane(playerForward, Vector3.up).normalized;
|
|
Vector3 flatCameraFwd = Vector3.ProjectOnPlane(cameraForward, Vector3.up).normalized;
|
|
|
|
Quaternion deltaRotation = Quaternion.FromToRotation(flatCameraFwd, flatPlayerFwd);
|
|
Vector3 tempRotVec = new Vector3(swingRotation.y, swingRotation.x, swingRotation.z);
|
|
Vector3 rotatedTemp = deltaRotation * tempRotVec;
|
|
Vector3 finalRotation = new Vector3(rotatedTemp.y, rotatedTemp.x, rotatedTemp.z);
|
|
Vector3 finalPosition = deltaRotation * swingPosition;
|
|
|
|
MMF_CinemachineRotation cinemachineRotation = feedbackSc[feedBackName].feedback.GetFeedbackOfType<MMF_CinemachineRotation>();
|
|
if (cinemachineRotation != null)
|
|
{
|
|
cinemachineRotation.RotationAmplitude = finalRotation;
|
|
}
|
|
|
|
MMF_CinemachinePosition cinemachinePosition = feedbackSc[feedBackName].feedback.GetFeedbackOfType<MMF_CinemachinePosition>();
|
|
if (cinemachinePosition != null)
|
|
{
|
|
cinemachinePosition.PositionAmplitude = finalPosition;
|
|
}
|
|
|
|
feedbackSc[feedBackName].Play();
|
|
}
|
|
}
|
|
|
|
public partial class ItemBase
|
|
{
|
|
public void RegisterFuncAnims()
|
|
{
|
|
if (fullBodyFuncAnims == null) return;
|
|
|
|
foreach (FuncAnimData funcAnim in fullBodyFuncAnims.animDataList)
|
|
{
|
|
player.animationSc.fullBodyFuncAnimSm.Add(funcAnim);
|
|
}
|
|
|
|
foreach (FuncAnimData funcAnim in upperBodyFuncAnims.animDataList)
|
|
{
|
|
player.animationSc.upperBodyFuncAnimSm.Add(funcAnim);
|
|
}
|
|
}
|
|
|
|
protected virtual void RegisterFunctionsToAnimSc(params Action[] functions)
|
|
{
|
|
RegisterFunctionsToAnimSc();
|
|
|
|
foreach (Action function in functions)
|
|
{
|
|
string functionName = function.Method.Name;
|
|
if (!player.animationSc.registeredFunctions.TryAdd(functionName, anim => function()))
|
|
{
|
|
Debug.LogWarning($"Function {functionName} is already registered.");
|
|
}
|
|
else
|
|
{
|
|
registeredFunctionNames.Add(functionName);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void RegisterFunctionsToAnimSc()
|
|
{
|
|
foreach (CustomFunction function in fullBodyFuncAnims.preloadFunctions)
|
|
{
|
|
string functionName = function.functionName;
|
|
string FAPF_functionName = new StringBuilder(functionName).Insert(0, "FAPF_").ToString();
|
|
MethodInfo method = GetType().GetMethod(FAPF_functionName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
|
|
if (method == null)
|
|
{
|
|
Debug.LogWarning($"Function {functionName} not found in {this.GetType().Name}. Skipping registration.");
|
|
continue;
|
|
}
|
|
|
|
Action<RuntimeFuncAnim> action = Delegate.CreateDelegate(typeof(Action<RuntimeFuncAnim>), this, method) as Action<RuntimeFuncAnim>;
|
|
registeredFunctionNames.Add(functionName);
|
|
player.animationSc.registeredFunctions.TryAdd(functionName, action);
|
|
}
|
|
}
|
|
|
|
protected void RemoveAllRegisteredFunctions()
|
|
{
|
|
foreach (string functionName in registeredFunctionNames)
|
|
{
|
|
if (!player.animationSc.registeredFunctions.Remove(functionName))
|
|
{
|
|
Debug.LogWarning($"Function {functionName} is not found.");
|
|
}
|
|
}
|
|
registeredFunctionNames.Clear();
|
|
}
|
|
}
|
|
|
|
public partial class ItemBase
|
|
{
|
|
protected virtual void FAPF_Swing(RuntimeFuncAnim rtFuncAnim)
|
|
{
|
|
CustomFunction.PC_StringVector3Vector3 p = rtFuncAnim.GetParams<CustomFunction.PC_StringVector3Vector3>();
|
|
Swing(p.str0, p.vec3_0, p.vec3_1);
|
|
}
|
|
}
|
|
} |