Skip to content

Commit

Permalink
Merge pull request #40 from Alexejhero/carry-fixes
Browse files Browse the repository at this point in the history
Maybe fix a couple things
  • Loading branch information
Alexejhero authored Nov 2, 2023
2 parents 34540ea + 3707fb5 commit 3c8dd84
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 60 deletions.
58 changes: 54 additions & 4 deletions SCHIZO/Creatures/Components/CarryCreature.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.Collections;
using UnityEngine;

namespace SCHIZO.Creatures.Components;

/// <summary>Adapted from <see cref="CollectShiny"/></summary>
partial class CarryCreature
partial class CarryCreature : IOnTakeDamage, IOnMeleeAttack
{
private GetCarried target;
private bool targetPickedUp;
Expand All @@ -13,6 +14,41 @@ partial class CarryCreature

public EcoTargetType EcoTargetType => (EcoTargetType) _ecoTargetType;

void IOnTakeDamage.OnTakeDamage(DamageInfo damageInfo)
{
if (damageInfo.damage > 0) Drop();
}

bool IOnMeleeAttack.HandleMeleeAttack(GameObject target)
{
// prevent bite after releasing
if (target.GetComponent<GetCarried>()) return true;

// pick up held creature instead of eating it
Player player = target.GetComponent<Player>();
if (!player) return false;

GameObject heldObject = Inventory.main.GetHeldObject();
if (!heldObject) return false;

GetCarried heldCarryable = heldObject.GetComponent<GetCarried>();
if (!heldCarryable) return false;

if (EcoTargetType != heldObject.GetComponent<IEcoTarget>()?.GetTargetType()) return false;

Inventory.main.DropHeldItem(false);
heldObject.SetActive(true); // really makes you think
StartCoroutine(DelayedPickupHack());
creature.SetFriend(player.gameObject, 120f);
return true;

IEnumerator DelayedPickupHack() // not sure how or why but WM sometimes doesn't get scaled correctly unless we wait a frame
{
yield return null;
TryPickup(heldCarryable);
}
}

public override float Evaluate(float time)
{
if (timeNextFindTarget < time)
Expand All @@ -38,6 +74,7 @@ public bool TryPickup(GetCarried getCarried)
private bool TryPickupTarget()
{
if (!target || !target.gameObject || !target.gameObject.activeInHierarchy) return false;
if (!target.CanBePickedUp()) return false;

if (target.GetComponentInParent<Player>())
{
Expand All @@ -56,11 +93,21 @@ private bool TryPickupTarget()
targetPickedUp = true;

RepositionTarget(target);
StartCoroutine(DelayedReposition()); // some component just really likes running updates for a few frames after it gets disabled

swimBehaviour.SwimTo(transform.position + Vector3.up + 5f * Random.onUnitSphere, Vector3.up, swimVelocity);
timeNextUpdate = Time.time + 1f;

return true;

IEnumerator DelayedReposition()
{
for (int i = 0; i < 5; i++)
{
yield return new WaitForSeconds(0.05f);
RepositionTarget(target);
}
}
}

private void RepositionTarget(GetCarried getCarried)
Expand All @@ -72,7 +119,7 @@ private void RepositionTarget(GetCarried getCarried)
Vector3 offset = getCarried.pickupPoint
? -getCarried.pickupPoint.localPosition
: Vector3.zero;
offset.Scale(attachPoint.lossyScale);
offset.Scale(new Vector3(1f / targetTransform.localScale.x, 1f / targetTransform.localScale.y, 1f / targetTransform.localScale.z));
targetTransform.localPosition = offset;
}

Expand All @@ -90,7 +137,10 @@ private void Drop()
private void DropTarget(GameObject targetObject)
{
targetObject.transform.SetParent(null, true);
UWE.Utils.SetCollidersEnabled(targetObject, true);
GameObject colliderTarget = targetObject;
FPModel fpModel = targetObject.GetComponent<FPModel>();
if (fpModel) colliderTarget = fpModel.propModel;
UWE.Utils.SetCollidersEnabled(colliderTarget, true);
UWE.Utils.SetIsKinematic(targetObject.GetComponent<Rigidbody>(), false);
if (targetObject.GetComponent<LargeWorldEntity>() is { } lwe)
LargeWorldStreamer.main!?.cellManager.RegisterEntity(lwe);
Expand Down Expand Up @@ -158,7 +208,7 @@ public override void Perform(float time, float deltaTime)
float roll = Random.value;
if (roll < ADHD)
{
LOGGER.LogWarning($"dropping because {roll}<{ADHD}");
//LOGGER.LogWarning($"dropping because {roll}<{ADHD}");
Drop();
}
}
Expand Down
12 changes: 8 additions & 4 deletions SCHIZO/Creatures/Components/GetCarried.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ partial class GetCarried
{
public bool isCarried;

private float nextCarryNoiseTime;
private float _nextCarryNoiseTime;
private float _lastPickedUpTime;
private List<(MonoBehaviour component, bool wasEnabled)> _disabledComponents;
private static readonly List<Type> toDisable = new()
{
Expand All @@ -30,6 +31,8 @@ public override void Awake()

public override float Evaluate(float time) => isCarried ? 99f : -99f; // manual start/end

public bool CanBePickedUp() => Time.time - _lastPickedUpTime > 5f;

private void DisableComponents()
{
_disabledComponents.Clear();
Expand All @@ -56,6 +59,7 @@ public void OnPickedUp()
{
pickupSounds!?.Play(emitter);
isCarried = true;
_lastPickedUpTime = Time.time;
StartPerform(Time.time);
}

Expand All @@ -69,7 +73,7 @@ public void OnDropped()
public override void StartPerform(float time)
{
DisableComponents();
nextCarryNoiseTime = time + carryNoiseInterval * (1 + Random.value);
_nextCarryNoiseTime = time + carryNoiseInterval * (1 + Random.value);
if (!isCarried) OnPickedUp();
}

Expand All @@ -91,9 +95,9 @@ public override void Perform(float time, float deltaTime)
creature.Tired.Add(deltaTime / 2f);
}

if (time > nextCarryNoiseTime)
if (time > _nextCarryNoiseTime)
{
nextCarryNoiseTime = time + carryNoiseInterval * (1 + Random.value);
_nextCarryNoiseTime = time + carryNoiseInterval * (1 + Random.value);
carrySounds!?.Play(emitter);
}
}
Expand Down
14 changes: 14 additions & 0 deletions SCHIZO/Creatures/Components/IOnMeleeAttack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using UnityEngine;

namespace SCHIZO.Creatures.Components;

public partial interface IOnMeleeAttack
{
/// <summary>
/// Handle an attack before it does damage to the target.<br/>
/// Useful if you want to do something else instead.
/// </summary>
/// <returns>Whether the attack was "handled" (i.e. whether to cancel the attack).</returns>
// don't rename this to OnMeleeAttack, MeleeAttack sends a message named "OnMeleeAttack" to a completely different component
bool HandleMeleeAttack(GameObject target);
}
11 changes: 7 additions & 4 deletions SCHIZO/Creatures/Ermshark/Ermshark.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections;
using SCHIZO.Helpers;
using SCHIZO.Sounds.Players;
using UnityEngine;
using UWE;

Expand Down Expand Up @@ -27,6 +29,8 @@ public void OnTakeDamage(DamageInfo damageInfo)
{
if (liveMixin.health > 0) return;

actions.ForEach(action => action.StopPerform());

if (mitosisRemaining > 0)
{
Mitosis(damageInfo.position, liveMixin.damageEffect);
Expand All @@ -39,7 +43,7 @@ public void OnTakeDamage(DamageInfo damageInfo)
}
else
{
gameObject.SetActive(false); // todo verify this works
gameObject.SetActive(false);
Destroy(gameObject, 5);
}
}
Expand All @@ -50,10 +54,9 @@ private void SOS() // Save the shark from dying (reloading the save will respawn
transform.GetChild(0).localScale = Vector3.zero;
liveMixin.ResetHealth();

enabled = false;
OnKill(); // disables self and SwimBehaviour
locomotion.enabled = false;
hurtSoundPlayer.enabled = false;
ambientSoundPlayer.enabled = false;
GetComponents<SoundPlayer>().ForEach(soundPlayer => soundPlayer.enabled = false);
}

private void Mitosis(Vector3 position, GameObject hurtEffect)
Expand Down
34 changes: 10 additions & 24 deletions SCHIZO/Creatures/Ermshark/ErmsharkAttack.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Linq;
using Nautilus.Utility;
using SCHIZO.Creatures.Components;
using SCHIZO.Helpers;
using UnityEngine;

namespace SCHIZO.Creatures.Ermshark;
Expand All @@ -13,31 +16,20 @@ public override void OnTouch(Collider collider)
GameObject target = GetTarget(collider);

if (global::CreatureData.GetCreatureType(gameObject) == global::CreatureData.GetCreatureType(target)) return;
if (target.GetComponent<GetCarried>()) return; // prevents tutel scream when released
if (GetComponentsInParent<IOnMeleeAttack>().Any(handler => handler.HandleMeleeAttack(target))) return;

Player player = target.GetComponent<Player>();
if (player)
{
GameObject heldObject = Inventory.main.GetHeldObject();
if (heldObject)
if (heldObject && canBeFed && player.CanBeAttacked() && TryEat(heldObject, true))
{
if (heldObject.GetComponent<GetCarried>() is { } heldTutel)
{
Inventory.main.DropHeldItem(false);
creature.GetComponent<CarryCreature>().TryPickup(heldTutel);
creature.SetFriend(player.gameObject, 120f);
return;
}
else if (canBeFed && player.CanBeAttacked() && TryEat(heldObject, true))
{
// if (attackSound) Utils.PlayEnvSound(attackSound, mouth.transform.position);
gameObject.SendMessage("OnMeleeAttack", heldObject, SendMessageOptions.DontRequireReceiver);
return;
}
if (this.GetBiteSound()) Utils.PlayEnvSound(this.GetBiteSound(), mouth.transform.position);
gameObject.SendMessage("OnMeleeAttack", heldObject, SendMessageOptions.DontRequireReceiver);
return;
}
}

// TODO: verify if ermshark can attack vehicles and cyclopses
if (CanBite(target))
{
timeLastBite = Time.time;
Expand All @@ -48,14 +40,8 @@ public override void OnTouch(Collider collider)
living.NotifyCreatureDeathsOfCreatureAttack();
}
Vector3 damageFxPos = collider.ClosestPointOnBounds(mouth.transform.position);
if (damageFX != null)
{
Instantiate(damageFX, damageFxPos, damageFX.transform.rotation);
}
/*if (attackSound != null)
{
Utils.PlayEnvSound(attackSound, damageFxPos);
}*/
if (damageFX) Instantiate(damageFX, damageFxPos, damageFX.transform.rotation);
if (this.GetBiteSound()) Utils.PlayEnvSound(this.GetBiteSound(), damageFxPos);

if (attackSounds) attackSounds.Play(emitter);

Expand Down
33 changes: 33 additions & 0 deletions SCHIZO/Helpers/RetargetHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using UnityEngine;

namespace SCHIZO.Helpers;

Expand All @@ -19,4 +20,36 @@ public static
return belowZero;
#endif
}
#if BELOWZERO
public static float Evaluate(this CreatureAction action, Creature creature, float time)
=> action.Evaluate(time);
public static void StartPerform(this CreatureAction action, Creature creature, float time)
=> action.StartPerform(time);
public static void Perform(this CreatureAction action, Creature creature, float time, float deltaTime)
=> action.Perform(time, deltaTime);
public static void StopPerform(this CreatureAction action, Creature creature, float time)
=> action.StopPerform(time);
public static FMOD_CustomEmitter GetBiteSound(this MeleeAttack attack)
=> attack.biteSound;
#else
public static float Evaluate(this CreatureAction action, float time)
=> action.Evaluate(action.creature, time);
public static void StartPerform(this CreatureAction action, float time)
=> action.StartPerform(action.creature, time);
public static void Perform(this CreatureAction action, float time, float deltaTime)
=> action.Perform(action.creature, time, deltaTime);
public static void StopPerform(this CreatureAction action, float time)
=> action.StopPerform(action.creature, time);
public static FMOD_StudioEventEmitter GetBiteSound(this MeleeAttack attack)
=> attack.attackSound;
#endif
public static float Evaluate(this CreatureAction action)
=> action.Evaluate(Time.time);
public static void StartPerform(this CreatureAction action)
=> action.StartPerform(action.creature, Time.time);
public static void Perform(this CreatureAction action)
=> action.Perform(action.creature, Time.time, Time.deltaTime);
public static void StopPerform(this CreatureAction action)
=> action.StopPerform(action.creature, Time.time);

}
Loading

0 comments on commit 3c8dd84

Please sign in to comment.