Skip to content

Commit

Permalink
Fix various issues with Mantis Lords
Browse files Browse the repository at this point in the history
  • Loading branch information
Extremelyd1 committed Jul 22, 2024
1 parent 4d3909c commit 2c74661
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 20 deletions.
31 changes: 31 additions & 0 deletions HKMP/Fsm/FsmPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,37 @@ private void OnFsmEnable(On.PlayMakerFSM.orig_OnEnable orig, PlayMakerFSM self)
self.RemoveFirstAction<BoolTest>("Check If Nail");
}
}

// Patch the Mantis Throne Main to not rely on animation events from the local player in case another
// player challenges the boss
if (self.name.Equals("Mantis Lord Throne 2") && self.Fsm.Name.Equals("Mantis Throne Main")) {
// Get the animation action for the animation clip that is played
var animationAction = self.GetFirstAction<Tk2dPlayAnimation>("End Challenge");

// Get the game object for the animation and check if it is not null
var go = self.Fsm.GetOwnerDefaultTarget(animationAction.gameObject);
if (go == null) {
return;
}

// Get the animator from the game object, the clip from the action and its length
var animator = go.GetComponent<tk2dSpriteAnimator>();
var clip = animator.GetClipByName(animationAction.clipName.Value);
var length = clip.Duration;

// Get the original watch animation action for the FSM event it sends
var watchAnimationAction = self.GetFirstAction<Tk2dWatchAnimationEvents>("End Challenge");

// Insert a wait action that takes exactly the duration of the animation and sends the original event
// when it finishes
self.InsertAction("End Challenge", new Wait {
time = length,
finishEvent = watchAnimationAction.animationCompleteEvent
}, 2);

// Remove the original watch animation action
self.RemoveFirstAction<Tk2dWatchAnimationEvents>("End Challenge");
}

// Code for modifying the collision check on collapsing floors to include remote players (not working)
// if (self.name.Equals("Collapser Small") && self.Fsm.Name.Equals("collapse small")) {
Expand Down
5 changes: 4 additions & 1 deletion HKMP/Game/Client/Entity/Action/EntityFsmActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2402,7 +2402,10 @@ private static void ApplyNetworkDataFromAction(EntityNetworkData data, GetPositi
private static bool GetNetworkDataFromAction(EntityNetworkData data, CallMethodProper action) {
Logger.Debug($"Getting network data for CallMethodProper: {action.Fsm.GameObject.name}, {action.Fsm.Name}");

return action.Fsm.GameObject.name.StartsWith("Colosseum Manager") && action.Fsm.Name.Equals("Battle Control");
return action.Fsm.GameObject.name.StartsWith("Colosseum Manager") &&
action.Fsm.Name.Equals("Battle Control") ||
action.Fsm.GameObject.name.StartsWith("Mantis Lord Throne") &&
action.Fsm.Name.Equals("Mantis Throne Main");
}

private static void ApplyNetworkDataFromAction(EntityNetworkData data, CallMethodProper action) {
Expand Down
49 changes: 40 additions & 9 deletions HKMP/Game/Client/Entity/Component/ChallengePromptComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Hkmp.Networking.Client;
using Hkmp.Networking.Packet.Data;
using Hkmp.Util;
using HutongGames.PlayMaker.Actions;
using UnityEngine;

namespace Hkmp.Game.Client.Entity.Component;
Expand All @@ -12,6 +13,11 @@ internal class ChallengePromptComponent : EntityComponent {
/// The game object that handles the challenge prompt pop-up.
/// </summary>
private readonly GameObject _promptObj;

/// <summary>
/// The FSM corresponding to the challenge prompt object.
/// </summary>
private readonly PlayMakerFSM _promptFsm;

public ChallengePromptComponent(
NetClient netClient,
Expand All @@ -21,13 +27,13 @@ HostClientPair<GameObject> gameObject
var hostObj = gameObject.Host;
var parent = hostObj.transform.parent;
_promptObj = parent.Find("Challenge Prompt").gameObject;
_promptFsm = _promptObj.LocateMyFSM("Challenge Start");

var promptFsm = _promptObj.LocateMyFSM("Challenge Start");
promptFsm.InsertMethod("Take Control", 6, () => {
_promptFsm.InsertMethod("Take Control", 6, () => {
var data = new EntityNetworkData {
Type = EntityComponentType.ChallengePrompt
};
data.Packet.Write(true);
data.Packet.Write(0);

SendData(data);
});
Expand All @@ -39,13 +45,38 @@ public override void InitializeHost() {

/// <inheritdoc />
public override void Update(EntityNetworkData data) {
var destroyPrompt = data.Packet.ReadBool();
if (!destroyPrompt) {
return;
}
var type = data.Packet.ReadByte();

// If the player is a scene client we destroy the prompt, otherwise we start the fight by progressing the FSM
if (IsControlled) {
if (_promptObj != null) {
Object.Destroy(_promptObj);
}
} else {
// Remove actions that rely on the local player
_promptFsm.RemoveFirstAction<Tk2dPlayAnimation>("Challenge");
_promptFsm.RemoveFirstAction<Tk2dWatchAnimationEvents>("Challenge");

// Get some actions that we want to re-use in another state
var activateObjAction = _promptFsm.GetFirstAction<ActivateGameObject>("Take Control");
var sendEventAction = _promptFsm.GetFirstAction<SendEventByName>("Take Control");

// Put these actions in the Challenge state for execution
_promptFsm.InsertAction("Challenge", activateObjAction, 0);
_promptFsm.InsertAction("Challenge", sendEventAction, 1);

if (_promptObj != null) {
Object.Destroy(_promptObj);
// Get the watch animation events action so we can get the FsmEvent is sends
var watchAnimationEvent = _promptFsm.GetFirstAction<Tk2dWatchAnimationEvents>("Challenge Audio");

// Insert a method that sends the event to go to the next stage instead of waiting for the animation to finish
_promptFsm.InsertMethod("Challenge Audio", 1, () => {
_promptFsm.Fsm.Event(watchAnimationEvent.animationCompleteEvent);
});
// Remove the original action
_promptFsm.RemoveFirstAction<Tk2dWatchAnimationEvents>("Challenge Audio");

// Start the FSM from the state 'Challenge'
_promptFsm.SetState("Challenge");
}
}

Expand Down
20 changes: 10 additions & 10 deletions HKMP/Game/Client/Entity/EntityManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,6 @@ public bool HandleEntityUpdate(EntityUpdate entityUpdate, bool alreadyInSceneUpd
/// <param name="entityUpdate">The reliable entity update to handle.</param>
/// <param name="alreadyInSceneUpdate">Whether this is the update from the already in scene packet.</param>
public bool HandleReliableEntityUpdate(ReliableEntityUpdate entityUpdate, bool alreadyInSceneUpdate = false) {
if (IsSceneHost) {
return true;
}

if (!_entities.TryGetValue(entityUpdate.Id, out var entity) || !IsSceneHostDetermined) {
if (IsSceneHostDetermined) {
Logger.Debug($"Could not find entity ({entityUpdate.Id}) to apply update for; storing update for now");
Expand All @@ -218,18 +214,22 @@ public bool HandleReliableEntityUpdate(ReliableEntityUpdate entityUpdate, bool a
return false;
}

if (entityUpdate.UpdateTypes.Contains(EntityUpdateType.Active)) {
entity.UpdateIsActive(entityUpdate.IsActive);
// Check if we are not the scene host for processing this data, active state and host FSM data should only
// be applied if we not the scene host, while data type below should always be applied
if (!IsSceneHost) {
if (entityUpdate.UpdateTypes.Contains(EntityUpdateType.Active)) {
entity.UpdateIsActive(entityUpdate.IsActive);
}

if (entityUpdate.UpdateTypes.Contains(EntityUpdateType.HostFsm)) {
entity.UpdateHostFsmData(entityUpdate.HostFsmData);
}
}

if (entityUpdate.UpdateTypes.Contains(EntityUpdateType.Data)) {
entity.UpdateData(entityUpdate.GenericData);
}

if (entityUpdate.UpdateTypes.Contains(EntityUpdateType.HostFsm)) {
entity.UpdateHostFsmData(entityUpdate.HostFsmData);
}

return true;
}

Expand Down

0 comments on commit 2c74661

Please sign in to comment.