This is the code for the player's animation:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using DG.Tweening;
using EatTheRich.Utilities;
using Photon.Deterministic;
using Quantum;
using Spine;
using Spine.Unity;
using UnityEngine;
using UnityEngine.UIElements;
using Sequence = DG.Tweening.Sequence;
namespace EatTheRich
{
public unsafe class UnityPlayerAgentAnimation : MonoBehaviour
{
public int headAccessoryIndex;
public int eyeIndex;
public int outfitIndex;
public int legOutfitIndex;
public int skinToneIndex;
public int accessoryIndex;
private List<string> headSkins;
private List<string> eyeSkins;
private List<string> outfitSkins;
private List<string> legOutfitSkins;
private List<string> skinTones;
private List<string> accessorySkins;
[SerializeField] private SkeletonAnimation _sklamPlayer;
private PlayerController _sklamPlayerController;
#region Private Properties
private EntityRef _entityRef = default;
private QuantumGame _game = null;
private bool _isInitialized = false;
private Sequence _invulnerableTween;
private bool _isEnabled;
private bool _blnIsMoving;
private bool _blnIsHoldingItem; // Track if the player is holding an item
private bool _blnIsKnockedOut;
private bool _blnIsDepositing; // Track if the player is in the deposit animation
private bool _blnIsDashing;
private bool _blnIsHurting;
private bool _blnIsAttacking;
private bool _blnIsHoldingWeapon;
private float _fltIdleDelay = 0.2f; //When transitioning from moving to idle, add this delay so that when player immediately moves again he will no longer reset the running animation
private float _fltCurrentIdleDelayValue = 0f;
private Bone bone;
public string boneName;
#endregion
#region Monobehaviours
public void OnEnable()
{
_isEnabled = true;
}
public void OnDisable()
{
_isEnabled = false;
//Deinitialize();
}
#endregion
#region Signals
private void SubscribeToSignals()
{
GameSignals.UPDATE_FOOD_ON_PLATE.AddListener(OnUpdateFoodOnPlateSignal);
}
private void UnsubscribeFromSignals()
{
GameSignals.UPDATE_FOOD_ON_PLATE.RemoveListener(OnUpdateFoodOnPlateSignal);
}
private void OnUpdateFoodOnPlateSignal(Frame p_frame, EntityRef p_etyPlate)
{
if (_entityRef != EntityRef.None && p_frame.Exists(_entityRef))
{
if (p_frame.Unsafe.TryGetPointer<AgentItemComponent>(_entityRef, out var cmpAgentItem))
{
if (cmpAgentItem->heldItemEntity == p_etyPlate)
{
UpdatePlateHeldItemSkin(p_frame, p_etyPlate);
}
}
}
}
#endregion
#region Event Listeners
private void SubscribeToQuantumEvents()
{
QuantumEvent.Subscribe<EventOnStatusActivatedEvent>(this, OnStatusActivatedEvent);
QuantumEvent.Subscribe<EventOnStatusDeactivatedEvent>(this, OnStatusDeactivatedEvent);
QuantumEvent.Subscribe<EventOnAgentHoldItem>(this, OnAgentHeldItemEvent);
QuantumEvent.Subscribe<EventOnAgentRemoveHeldItem>(this, OnAgentRemoveHeldItem);
QuantumEvent.Subscribe<EventOnInteractWithObject>(this, OnAgentInteractedWithObject);
QuantumEvent.Subscribe<EventOnAgentSetCurrentAttackStateEvent>(this, OnAgentSetCurrentAttackState);
QuantumEvent.Subscribe<EventOnSTPClearPlateEvent>(this, OnClearPlate);
QuantumEvent.Subscribe<EventOnPlayerReconnectedEvent>(this, OnReconnect);
QuantumEvent.Subscribe<EventOnStartDashEvent>(this, OnStartDash);
QuantumEvent.Subscribe<EventOnEndDashEvent>(this, OnEndDash);
QuantumEvent.Subscribe<EventSetCurrentWeaponEvent>(this, OnSetCurrentWeaponEvent);
QuantumEvent.Subscribe<EventOnAgentMRDeathEvent>(this, OnAgentMRDeathEvent);
QuantumEvent.Subscribe<EventOnAgentMRSpawnCorpseEvent>(this, OnAgentMRSpawnCorpseEvent);
QuantumEvent.Subscribe<EventOnAgentMRRespawnEvent>(this, OnAgentMRRespawnEvent);
QuantumEvent.Subscribe<EventOnAgentRemovedMRComponent>(this, OnAgentMRRemovedEvent);
}
private void UnsubscribeFromQuantumEvents()
{
QuantumEvent.UnsubscribeListener<EventOnStatusActivatedEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnStatusDeactivatedEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentHoldItem>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentRemoveHeldItem>(this);
QuantumEvent.UnsubscribeListener<EventOnInteractWithObject>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentSetCurrentAttackStateEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnSTPClearPlateEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnPlayerReconnectedEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnStartDashEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnEndDashEvent>(this);
QuantumEvent.UnsubscribeListener<EventSetCurrentWeaponEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentMRDeathEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentMRSpawnCorpseEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentMRRespawnEvent>(this);
QuantumEvent.UnsubscribeListener<EventOnAgentRemovedMRComponent>(this);
}
private void OnStatusDeactivatedEvent(EventOnStatusDeactivatedEvent p_callback)
{
Frame frame = p_callback.frame;
EntityRef etyAgent = p_callback.agentEntityRef;
if (etyAgent == _entityRef)
{
switch (p_callback.status.statusType)
{
case STATUS.Knocked_Out:
case STATUS.Stunned:
bool blnKnockedout = false;
if (frame.Unsafe.TryGetPointer<AgentStatusComponent>(etyAgent, out var cmpAgentStatus))
{
blnKnockedout = cmpAgentStatus->blnIsKnockedOut;
}
if (!blnKnockedout)
{
SetIsKnockedOut(false);
}
break;
case STATUS.Invulnerable:
_sklamPlayer.skeleton.A = 1f;
_invulnerableTween.Pause();
break;
default:
break;
}
}
}
private void OnStatusActivatedEvent(EventOnStatusActivatedEvent p_callback)
{
OnStatusActivated(p_callback.agentEntityRef, p_callback.status.statusType, true);
}
private unsafe void OnAgentHeldItemEvent(EventOnAgentHoldItem p_callback)
{
OnAgentHeldItem(p_callback.frame, p_callback.source, p_callback.heldItem);
}
private void OnAgentRemoveHeldItem(EventOnAgentRemoveHeldItem p_callback)
{
if (p_callback.source == _entityRef)
{
SetIsHoldingItem(false);
RemoveHeldItemFromSkin();
}
}
private void OnAgentInteractedWithObject(EventOnInteractWithObject p_callback)
{
if (_entityRef == p_callback.actorEntity)
{
if (p_callback.objType == INTERACTABLE_OBJECT_TYPE.Egg_Repository)
{
SetIsDepositing(true);
}
}
}
private void OnAgentSetCurrentAttackState(EventOnAgentSetCurrentAttackStateEvent p_callback)
{
if (p_callback.etyOwner == _entityRef)
{
if (p_callback.state == AGENT_ATTACK_STATE.Attack_Delay)
{ // Start of attack
SetIsAttacking(true);
}
else if (p_callback.state == AGENT_ATTACK_STATE.None)
{ // End of attack
SetIsAttacking(false);
}
}
}
private unsafe void OnClearPlate(EventOnSTPClearPlateEvent p_callback)
{
Frame frame = QuantumRunner.Default.Game.Frames.Predicted;
if (frame != null)
{
AgentItemComponent* cmpAgentItem = frame.Unsafe.GetPointer<AgentItemComponent>(_entityRef);
EntityRef etyOwner = p_callback.etyOwner;
if (etyOwner == cmpAgentItem->heldItemEntity)
{
UpdatePlateHeldItemSkin(frame, cmpAgentItem->heldItemEntity);
}
}
}
private void OnReconnect(EventOnPlayerReconnectedEvent p_callback)
{
if (PlayerQuantumManager.Instance.IsMainPlayer(p_callback.agentEntityRef))
{
OnReconnectStatusUpdate(p_callback.frame);
OnReconnectHeldItemUpdate(p_callback.frame);
OnReconnectHeldWeaponUpdate(p_callback.frame);
}
}
private void OnSetCurrentWeaponEvent(EventSetCurrentWeaponEvent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
OnSetCurrentWeapon(p_callback.frame, p_callback.aguidWeapon);
}
}
private void OnAgentMRDeathEvent(EventOnAgentMRDeathEvent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
SetIsHurting(true);
}
}
private void OnAgentMRSpawnCorpseEvent(EventOnAgentMRSpawnCorpseEvent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
SetIsHurting(false);
}
}
private void OnAgentMRRespawnEvent(EventOnAgentMRRespawnEvent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
SetIsHurting(false);
}
}
private void OnAgentMRRemovedEvent(EventOnAgentRemovedMRComponent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
SetIsHurting(false);
}
}
#endregion
#region General
public void Initialize(EntityRef entityRef)
{
//_sklamPlayer.keepAnimatorStateOnDisable = true;
CategorizeSkins();
_entityRef = entityRef;
_game = QuantumRunner.Default.Game;
_invulnerableTween = DOTween.Sequence();
_invulnerableTween.Append(DOTween.ToAlpha(() => _sklamPlayer.skeleton.GetColor(), c => _sklamPlayer.skeleton.SetColor(c), 1f, 0.1f));
_invulnerableTween.Append(DOTween.ToAlpha(() => _sklamPlayer.skeleton.GetColor(), c => _sklamPlayer.skeleton.SetColor(c), 0.5f, 0.1f));
_invulnerableTween.SetLoops(-1, LoopType.Yoyo);
_invulnerableTween.Pause();
_isInitialized = true;
// //had to set sorting orders per player because if players with the same sorting order overlap, they start flickering.
// meshRenderer.sortingOrder = QuantumRunner.Default.Game.PlayerIsLocal(playerRef) ? 20 - playerRef._index : playerRef._index;
SubscribeToQuantumEvents();
SubscribeToSignals();
_sklamPlayerController = _sklamPlayer.GetComponent<PlayerController>();
bone = _sklamPlayer.Skeleton.FindBone(boneName);
}
public void Deinitialize()
{
_isInitialized = false;
UnsubscribeFromQuantumEvents();
UnsubscribeFromSignals();
}
public void UpdateAnimation()
{
MovementAnimation();
}
// public void RandomizeSkin() {
// var skeleton = skeletonMecanim.Skeleton;
// var skeletonData = skeleton.Data;
// var mixAndMatchSkin = new Skin("random-skin");
// mixAndMatchSkin.AddSkin(skeletonData.FindSkin(headSkins.GetRandomElement(out headAccessoryIndex)));
// mixAndMatchSkin.AddSkin(skeletonData.FindSkin(eyeSkins.GetRandomElement(out eyeIndex)));
// mixAndMatchSkin.AddSkin(skeletonData.FindSkin(outfitSkins.GetRandomElement(out outfitIndex)));
// mixAndMatchSkin.AddSkin(skeletonData.FindSkin(legOutfitSkins.GetRandomElement(out legOutfitIndex)));
// mixAndMatchSkin.AddSkin(skeletonData.FindSkin(skinTones.GetRandomElement(out skinToneIndex)));
// mixAndMatchSkin.AddSkin(skeletonData.FindSkin(accessorySkins.GetRandomElement(out accessoryIndex)));
// skeleton.SetSkin(mixAndMatchSkin);
// skeleton.SetSlotsToSetupPose();
// skeletonMecanim.Update();
// }
public void UpdateSkinGivenData(AgentSkinData p_skinData)
{
MaccimaLogger.Log($"UpdateSkinGivenData of {_entityRef}");
Skeleton skeleton = _sklamPlayer.Skeleton;
SkeletonData skeletonData = skeleton.Data;
Skin currentSkin = new Skin("random-skin");
headAccessoryIndex = p_skinData.headAccessory;
eyeIndex = p_skinData.eyeSkin;
outfitIndex = p_skinData.outfitSkin;
legOutfitIndex = p_skinData.legSkin;
skinToneIndex = p_skinData.skinTone;
accessoryIndex = p_skinData.accessorySkin;
if (!headSkins.IsIndexInList(headAccessoryIndex)) { headAccessoryIndex = 0; }
if (!eyeSkins.IsIndexInList(eyeIndex)) { eyeIndex = 0; }
if (!outfitSkins.IsIndexInList(outfitIndex)) { outfitIndex = 0; }
if (!legOutfitSkins.IsIndexInList(legOutfitIndex)) { legOutfitIndex = 0; }
if (!skinTones.IsIndexInList(skinToneIndex)) { skinToneIndex = 0; }
if (!accessorySkins.IsIndexInList(accessoryIndex)) { accessoryIndex = 0; }
currentSkin.AddSkin(skeletonData.FindSkin(headSkins[headAccessoryIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(eyeSkins[eyeIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(outfitSkins[outfitIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(legOutfitSkins[legOutfitIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(skinTones[skinToneIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(accessorySkins[accessoryIndex]));
skeleton.SetSkin(currentSkin);
skeleton.SetSlotsToSetupPose();
_sklamPlayer.LateUpdate();
}
private void AddHeldItemToSkin(string p_skinPath)
{
MaccimaLogger.Log($"Add Held item {p_skinPath} to {_entityRef}");
var skeleton = _sklamPlayer.Skeleton;
var skeletonData = skeleton.Data;
Skin currentSkin = new Skin("random-skin");
if (!headSkins.IsIndexInList(headAccessoryIndex)) { headAccessoryIndex = 0; }
if (!eyeSkins.IsIndexInList(eyeIndex)) { eyeIndex = 0; }
if (!outfitSkins.IsIndexInList(outfitIndex)) { outfitIndex = 0; }
if (!legOutfitSkins.IsIndexInList(legOutfitIndex)) { legOutfitIndex = 0; }
if (!skinTones.IsIndexInList(skinToneIndex)) { skinToneIndex = 0; }
if (!accessorySkins.IsIndexInList(accessoryIndex)) { accessoryIndex = 0; }
currentSkin.AddSkin(skeletonData.FindSkin(headSkins[headAccessoryIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(eyeSkins[eyeIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(outfitSkins[outfitIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(legOutfitSkins[legOutfitIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(skinTones[skinToneIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(accessorySkins[accessoryIndex]));
//add held item
currentSkin.AddSkin(skeletonData.FindSkin(p_skinPath));
skeleton.SetSkin(currentSkin);
skeleton.SetSlotsToSetupPose();
_sklamPlayer.LateUpdate();
}
public void AddHeldItemToSkin(EntityRef p_etyHeldItem)
{
var frame = QuantumRunner.Default.Game.Frames.Verified;
if (frame != null)
{
if (frame.Unsafe.TryGetPointer<ItemComponent>(p_etyHeldItem, out var cmpItem))
{
ItemData itemData = frame.FindAsset<ItemData>(cmpItem->itemData.Id);
if (itemData.itemName == ITEM_NAME.Egg)
{
if (frame.TryGet(p_etyHeldItem, out EggItemComponent eggItemComponent))
{
string skinPath = "ITEMS/BREAD";
switch (eggItemComponent.currentColor)
{
case COLOR.Red:
skinPath = "ITEMS/MEAT";
break;
case COLOR.Blue:
skinPath = "ITEMS/CAKE";
break;
case COLOR.Green:
skinPath = "ITEMS/FISH";
break;
case COLOR.Yellow:
skinPath = "ITEMS/BREAD";
break;
}
AddHeldItemToSkin(skinPath);
}
}
else if (itemData.itemName == ITEM_NAME.Flag)
{
AddHeldItemToSkin("ITEMS/PAPER");
}
else if (itemData.itemName == ITEM_NAME.STP_Fish_Ingredient)
{
AddHeldItemToSkin("ITEMS/FISH");
}
else if (itemData.itemName == ITEM_NAME.STP_Meat_Ingredient)
{
AddHeldItemToSkin("ITEMS/MEAT");
}
else if (itemData.itemName == ITEM_NAME.STP_Plate)
{
UpdatePlateHeldItemSkin(frame, p_etyHeldItem);
}
}
}
}
public void AddHeldWeaponToSkin(Frame p_frame, AssetGuid p_aguidWeapon)
{
if (p_frame != null)
{
if (p_aguidWeapon != default)
{
WeaponData weaponData = p_frame.FindAsset<WeaponData>(p_aguidWeapon);
if (weaponData is GunData)
{
SetIsHoldingItem(true);
/* SetIsHoldingWeapon(true);*/
AddHeldItemToSkin("ITEMS/GUN");
}
}
}
}
private void RemoveHeldItemFromSkin()
{
MaccimaLogger.Log($"Removed Held item from {_entityRef}");
var skeleton = _sklamPlayer.Skeleton;
var skeletonData = skeleton.Data;
Skin currentSkin = new Skin("random-skin");
if (!headSkins.IsIndexInList(headAccessoryIndex)) { headAccessoryIndex = 0; }
if (!eyeSkins.IsIndexInList(eyeIndex)) { eyeIndex = 0; }
if (!outfitSkins.IsIndexInList(outfitIndex)) { outfitIndex = 0; }
if (!legOutfitSkins.IsIndexInList(legOutfitIndex)) { legOutfitIndex = 0; }
if (!skinTones.IsIndexInList(skinToneIndex)) { skinToneIndex = 0; }
if (!accessorySkins.IsIndexInList(accessoryIndex)) { accessoryIndex = 0; }
currentSkin.AddSkin(skeletonData.FindSkin(headSkins[headAccessoryIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(eyeSkins[eyeIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(outfitSkins[outfitIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(legOutfitSkins[legOutfitIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(skinTones[skinToneIndex]));
currentSkin.AddSkin(skeletonData.FindSkin(accessorySkins[accessoryIndex]));
skeleton.SetSkin(currentSkin);
skeleton.SetSlotsToSetupPose();
_sklamPlayer.LateUpdate();
}
private void CategorizeSkins()
{
headSkins = new List<string>();
eyeSkins = new List<string>();
outfitSkins = new List<string>();
legOutfitSkins = new List<string>();
skinTones = new List<string>();
accessorySkins = new List<string>();
for (int i = 0; i < _sklamPlayer.skeleton.Data.Skins.Items.Length; i++)
{
Skin skin = _sklamPlayer.skeleton.Data.Skins.Items[i];
if (skin.Name.Contains("Hair", StringComparison.InvariantCultureIgnoreCase))
{
headSkins.Add(skin.Name);
}
else if (skin.Name.Contains("Eyes", StringComparison.InvariantCultureIgnoreCase))
{
eyeSkins.Add(skin.Name);
}
else if (skin.Name.Contains("Outfits-Chest", StringComparison.InvariantCultureIgnoreCase))
{
outfitSkins.Add(skin.Name);
}
else if (skin.Name.Contains("Outfits-Legs", StringComparison.InvariantCultureIgnoreCase))
{
legOutfitSkins.Add(skin.Name);
}
else if (skin.Name.Contains("Skintone", StringComparison.InvariantCultureIgnoreCase))
{
skinTones.Add(skin.Name);
}
else if (skin.Name.Contains("Accessories - Head", StringComparison.InvariantCultureIgnoreCase))
{
accessorySkins.Add(skin.Name);
}
}
}
#endregion
#region Status
private void OnStatusActivated(EntityRef p_etyPlayer, STATUS p_statusType, bool p_doFlashEffect)
{
if (p_etyPlayer == _entityRef)
{
switch (p_statusType)
{
case STATUS.Knocked_Out:
case STATUS.Stunned:
SetIsKnockedOut(true);
if (p_doFlashEffect)
{
if (PlayerQuantumManager.Instance.PlayerIsLocal(QuantumRunner.Default.Game.Frames.Verified, _entityRef))
{
// UIManager.Instance.ShowFlashEffect();
GameSignals.DO_CAMERA_SHAKE_FOR_PLAYER.Dispatch(_entityRef);
}
}
break;
case STATUS.Invulnerable:
_sklamPlayer.skeleton.A = 1f;
_invulnerableTween.Restart();
_invulnerableTween.Play();
break;
default:
break;
}
}
}
private void OnReconnectStatusUpdate(Frame p_frame)
{
if (_entityRef != EntityRef.None)
{
if (p_frame.Unsafe.TryGetPointer<AgentStatusComponent>(_entityRef, out var cmpAgentStatus))
{
for (int i = 0; i < cmpAgentStatus->statuses.Length; i++)
{
Status status = cmpAgentStatus->statuses[i];
if (status.isActivated)
{
OnStatusActivated(_entityRef, status.statusType, false);
}
}
}
}
}
#endregion
#region Items
private void OnAgentHeldItem(Frame p_frame, EntityRef p_etyPlayer, EntityRef p_etyHeldItem)
{
if (p_etyPlayer == _entityRef)
{
Frame frame = p_frame;
if (frame.Unsafe.TryGetPointer<ItemComponent>(p_etyHeldItem, out var cmpItem))
{
SetIsHoldingItem(true);
ItemData itemData = frame.FindAsset<ItemData>(cmpItem->itemData.Id);
switch (itemData.itemName)
{
case ITEM_NAME.Egg:
if (frame.TryGet(p_etyHeldItem, out EggItemComponent eggItemComponent))
{
string skinPath = "ITEMS/BREAD";
switch (eggItemComponent.currentColor)
{
case COLOR.Red:
skinPath = "ITEMS/MEAT";
break;
case COLOR.Blue:
skinPath = "ITEMS/CAKE";
break;
case COLOR.Green:
skinPath = "ITEMS/FISH";
break;
case COLOR.Yellow:
skinPath = "ITEMS/BREAD";
break;
}
AddHeldItemToSkin(skinPath);
}
break;
case ITEM_NAME.Flag:
AddHeldItemToSkin("ITEMS/PAPER");
break;
//case ITEM_NAME.STP_Fish_Ingredient:
// AddHeldItemToSkin("ITEMS/FISH");
// break;
//case ITEM_NAME.STP_Meat_Ingredient:
// AddHeldItemToSkin("ITEMS/MEAT");
// break;
case ITEM_NAME.STP_Fish_Ingredient:
case ITEM_NAME.STP_Meat_Ingredient:
UpdateFoodHeldItemSkin(frame, p_etyHeldItem);
break;
case ITEM_NAME.STP_Plate:
UpdatePlateHeldItemSkin(frame, p_etyHeldItem);
break;
}
}
}
}
private void OnReconnectHeldItemUpdate(Frame p_frame)
{
if (_entityRef != EntityRef.None)
{
if (p_frame.Unsafe.TryGetPointer<AgentItemComponent>(_entityRef, out var cmpAgentItem))
{
if (cmpAgentItem->HasHeldItem(p_frame))
{
OnAgentHeldItem(p_frame, _entityRef, cmpAgentItem->heldItemEntity);
}
}
}
}
#endregion
#region Weapon
private unsafe void OnSetCurrentWeapon(Frame p_frame, AssetGuid p_aguidWeapon)
{
if (p_aguidWeapon != default)
{
SetIsHoldingItem(true);
/*SetIsHoldingWeapon(true);*/
AddHeldWeaponToSkin(p_frame, p_aguidWeapon);
}
else
{
SetIsHoldingItem(false);
/* SetIsHoldingWeapon(false);*/
RemoveHeldItemFromSkin();
}
}
private void OnReconnectHeldWeaponUpdate(Frame p_frame)
{
if (_entityRef != EntityRef.None)
{
if (p_frame.Unsafe.TryGetPointer<AgentWeaponComponent>(_entityRef, out var cmpAgentWeapon))
{
if (cmpAgentWeapon->HasCurrentWeapon())
{
OnSetCurrentWeapon(p_frame, cmpAgentWeapon->aguidCurrentWeapon);
}
}
}
}
#endregion
#region Movement
private void MovementAnimation()
{
if (_isInitialized && _isEnabled)
{
AgentMovementComponent* cmpAgentMovement = _game.Frames.Verified.Unsafe.GetPointer<AgentMovementComponent>(_entityRef);
_sklamPlayer.skeleton.ScaleX = (float)cmpAgentMovement->fpAgentOrientationX;
// Check if knocked out
if (_blnIsKnockedOut || _blnIsDepositing || _blnIsAttacking)
{
return;
}
SetIsMoving(cmpAgentMovement->velocity.Magnitude.AsFloat > 0.1f);
}
}
private void OnStartDash(EventOnStartDashEvent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
SetIsDashing(true);
}
}
private void OnEndDash(EventOnEndDashEvent p_callback)
{
if (p_callback.etyAgent == _entityRef)
{
SetIsDashing(false);
}
}
private void SetIsMoving(bool p_blnState)
{
if (_blnIsMoving != p_blnState)
{
if (p_blnState)
{
_fltCurrentIdleDelayValue = _fltIdleDelay;
TransitionToMovingBase();
}
else
{
_fltCurrentIdleDelayValue -= Time.deltaTime;
if (_fltCurrentIdleDelayValue <= 0f)
{
_fltCurrentIdleDelayValue = 0f;
TransitionToIdleBase();
}
else
{
return;
}
}
_blnIsMoving = p_blnState;
}
}
private void TransitionToIdleOrMoving()
{
if (_blnIsMoving)
{
TransitionToMovingBase();
}
else
{
TransitionToIdleBase();
}
}
private void TransitionToMovingBase()
{
if (_blnIsHoldingItem)
{
//Player is running and holding item
_sklamPlayer.AnimationState.SetAnimation(0, "a_running_holding", true);
}
else
{
//Player is running without holding item
_sklamPlayer.AnimationState.SetAnimation(0, "a_running_default9", true);
}
}
private void TransitionToIdleBase()
{
if (_blnIsHoldingItem)
{
//Player is in place/idle and holding item
_sklamPlayer.AnimationState.SetAnimation(0, "a_idle_holding", true);
}
else
{
//Player is without holding item
_sklamPlayer.AnimationState.SetAnimation(0, "a_idle", true);
}
}
private void SetIsHoldingItem(bool p_blnState)
{
if (_blnIsHoldingItem != p_blnState)
{
_blnIsHoldingItem = p_blnState;
if (_blnIsHoldingItem || _blnIsHoldingWeapon)
{
if (_blnIsMoving)
{
_sklamPlayer.AnimationState.SetAnimation(0, "a_running_holding", true);
}
else
{
_sklamPlayer.AnimationState.SetAnimation(0, "a_idle_holding", true);
}
}
else
{
if (_blnIsKnockedOut || _blnIsDepositing)
{
return;
}
TransitionToIdleOrMoving();
}
}
}
private void SetIsDashing(bool p_blnState)
{
if (_blnIsDashing != p_blnState)
{
_blnIsDashing = p_blnState;
if (_blnIsDashing)
{
if (_blnIsAttacking)
{
return;
}
_sklamPlayer.AnimationState.SetAnimation(0, "a_dashing", true);
}
else
{
TransitionToIdleOrMoving();
}
}
}
private void SetIsDepositing(bool p_blnState)
{
if (_blnIsDepositing != p_blnState)
{
_blnIsDepositing = p_blnState;
if (_blnIsDepositing)
{
// Set deposit animation
OnDoingDeposit();
_sklamPlayer.AnimationState.SetAnimation(0, "a_deposit", false).Complete += StopDepositing;
}
else
{
OnDepositDone();
TransitionToIdleOrMoving();
}
}
}
private void StopDepositing(TrackEntry p_tEntry)
{
SetIsDepositing(false);
}
private void SetIsHurting(bool p_blnState)
{
_blnIsHurting = p_blnState;
if (_blnIsHurting)
{
_sklamPlayer.AnimationState.SetAnimation(0, "a_hurt", true);
}
else
{
TransitionToIdleOrMoving();
}
}
private void SetIsKnockedOut(bool p_blnState)
{
if (_blnIsKnockedOut != p_blnState)
{
_blnIsKnockedOut = p_blnState;
if (_blnIsKnockedOut)
{
SetIsDepositing(false);
_sklamPlayer.AnimationState.SetAnimation(0, "a_knockedout", true);
}
else
{
TransitionToIdleOrMoving();
}
}
}
private void SetIsAttacking(bool p_blnState)
{
if (_blnIsAttacking != p_blnState)
{
_blnIsAttacking = p_blnState;
if (_blnIsAttacking)
{
TrackEntry entry = _sklamPlayer.AnimationState.SetAnimation(0, "a_attack2", false);
entry.TimeScale = 2;
}
else
{
if (_blnIsKnockedOut)
{
return;
}
TransitionToIdleOrMoving();
}
}
}
/* private void SetIsHoldingWeapon(bool p_blnState)
{
if (_blnIsHoldingWeapon != p_blnState)
{
blnIsHoldingWeapon = p_blnState;
if (blnIsHoldingWeapon)
{
_sklamPlayer.AnimationState.SetAnimation(0, "aim_gun", true);
}
else
{
TransitionToIdleOrMoving();
}
}
}*/
public void Update()
{
if (_blnIsHoldingItem)
{
if (_sklamPlayerController == null)
_sklamPlayerController = GetComponent<PlayerController>();
bone.SetPositionSkeletonSpace(_sklamPlayerController.GetLastAimPosition());
}
}
#endregion
#region Deposit
public void OnDoingDeposit()
{
if (PlayerQuantumManager.Instance.PlayerIsLocal(QuantumRunner.Default.Game.Frames.Verified, _entityRef))
{
GameSignals.SET_MOVEMENT_STATE.Dispatch(_entityRef, false);
}
}
public void OnDepositDone()
{
if (PlayerQuantumManager.Instance.PlayerIsLocal(QuantumRunner.Default.Game.Frames.Verified, _entityRef))
{
GameSignals.SET_MOVEMENT_STATE.Dispatch(_entityRef, true);
}
}
#endregion
#region Serve The Poor
private unsafe void UpdateFoodHeldItemSkin(Frame p_frame, EntityRef p_etyHeldItem)
{
EntityRef etySTPManager = p_frame.Unsafe.GetPointerSingleton<MainGameManager>()->etySTPMainManager;
if (etySTPManager == default)
{
//AddHeldItemToSkin($"ITEMS/{p_strDefaultSkinName}");
return;
}
STPMainManager* cmpSTPMainManager = p_frame.Unsafe.GetPointer<STPMainManager>(etySTPManager);
STPIngredientComponent* cmpIngredient = p_frame.Unsafe.GetPointer<STPIngredientComponent>(p_etyHeldItem);
STPFoodItemData foodData = cmpSTPMainManager->GetFoodItemDataThatMatchIngredient(p_frame, cmpIngredient->ingredient);
if (foodData != null)
{
AddHeldItemToSkin($"ITEMS/{foodData.strSkinNameInAgentWithoutPlate}");
}
else
{
LaborMinigameDBData laborMinigameDB = p_frame.FindAsset<LaborMinigameDBData>(p_frame.RuntimeConfig.laborMinigameDB.Id);
AssetRefLaborMinigameData arefSTP = laborMinigameDB.GetLaborMinigameData(p_frame, LABOR_MINIGAME.Serve_The_Poor);
ServeThePoorMinigameDataAsset assetSTP = UnityDB.FindAsset<ServeThePoorMinigameDataAsset>(arefSTP.Id);
string strSkinName = assetSTP.GetSTPIngredientSkinName(cmpIngredient->ingredient);
if (!string.IsNullOrEmpty(strSkinName))
{
AddHeldItemToSkin($"ITEMS/{strSkinName}");
}
//else {
// AddHeldItemToSkin($"ITEMS/{p_strDefaultSkinName}");
//}
//for (int i = 0; i < cmpIngredient->recipeOnPlate.arrIngredients.Length; i++) {
// STPIngredient ingredient = cmpIngredient->recipeOnPlate.arrIngredients[i];
// if (ingredient.ingredient == STP_INGREDIENT.Fish) {
// if (ingredient.cuttingMethod == STP_CUTTING_METHOD.Mashed) {
// AddHeldItemToSkin("ITEMS/PLATE_MASHFISH");
// } else {
// AddHeldItemToSkin("ITEMS/PLATE_FISH");
// }
// isEmpty = false;
// break;
// } else if (ingredient.ingredient == STP_INGREDIENT.Meat) {
// AddHeldItemToSkin("ITEMS/PLATE_MEAT");
// isEmpty = false;
// break;
// }
//}
}
}
private unsafe void UpdatePlateHeldItemSkin(Frame p_frame, EntityRef p_etyHeldItem)
{
STPPlateComponent* cmpPlate = p_frame.Unsafe.GetPointer<STPPlateComponent>(p_etyHeldItem);
bool isEmpty = true;
if (cmpPlate->aguidFoodOnPlate != default)
{
STPFoodItemData foodOnPlate = p_frame.FindAsset<STPFoodItemData>(cmpPlate->aguidFoodOnPlate);
AddHeldItemToSkin($"ITEMS/{foodOnPlate.strSkinNameInAgentWithPlate}");
isEmpty = false;
Debug.Log("UPDATE PLATE: " + foodOnPlate.strSkinNameInAgentWithPlate);
}
//else {
// for (int i = 0; i < cmpPlate->recipeOnPlate.arrIngredients.Length; i++) {
// STPIngredient ingredient = cmpPlate->recipeOnPlate.arrIngredients[i];
// if (ingredient.ingredient == STP_INGREDIENT.Fish) {
// if (ingredient.cuttingMethod == STP_CUTTING_METHOD.Mashed) {
// AddHeldItemToSkin("ITEMS/PLATE_MASHFISH");
// } else {
// AddHeldItemToSkin("ITEMS/PLATE_FISH");
// }
// isEmpty = false;
// break;
// } else if (ingredient.ingredient == STP_INGREDIENT.Meat) {
// AddHeldItemToSkin("ITEMS/PLATE_MEAT");
// isEmpty = false;
// break;
// }
// }
//}
if (isEmpty)
{
if (cmpPlate->blnIsDirty)
{
AddHeldItemToSkin("ITEMS/PLATE_EMPTY");
}
else
{
AddHeldItemToSkin("ITEMS/PLATE_CLEAN");
}
}
}
#endregion
}
}