Okay, I think you all are correct. Thanks for the extra info on how movement and sneak work.
That would make sense, there is no sneak mode. It all based on movement speed and stealth skill. Within the enemy sense script and the stealth check routine, there is no boolean to indicate a stealth mode is being activated or not. This means it is running as long as you're in range of enemy senses.
As for the base movement speed needing to be at minimum equal to half base speed, yes it is an equal or greater check (>=).
Here is the base speed code. As hazel says, it is not a clear cut /2 and /4. Instead, it is a more complicated formula, but I did figure out the ratios for it:
Code: Select all
public float GetBaseSpeed()
{
Entity.PlayerEntity player = GameManager.Instance.PlayerEntity;
float baseSpeed = 0;
float playerSpeed = player.Stats.LiveSpeed;
if (playerMotor == null) // fixes null reference bug.
playerMotor = GameManager.Instance.PlayerMotor;
// crouching speed penalty doesn't apply if swimming.
if (playerMotor.IsCrouching && !levitateMotor.IsSwimming)
baseSpeed = (playerSpeed + dfCrouchBase) / classicToUnitySpeedUnitRatio;
else if (playerMotor.IsRiding)
{
float rideSpeed = (GameManager.Instance.TransportManager.TransportMode == TransportModes.Cart) ? dfCartBase : dfRideBase;
baseSpeed = (playerSpeed + rideSpeed) / classicToUnitySpeedUnitRatio;
}
else
baseSpeed = GetWalkSpeed(player);
return baseSpeed;
}
When walk is activated, base speed takes the players speed stat, adds 150 to it, and then divides that by 39.5. So, walk speed is actually, ((SpeedState + 150)/39.5). This gives you the base speed for walking.
Crouch seems it takes the players speed stat, adds 50 to it, and then divides that by 39.5. So, crouch speed is actually, ((SpeedState + 50)/39.5). However, it seems the way the math works out, according to the code, crouch speed will always end up being 77% slower than base walk speed (it's a third of walk speeds 150) and since it is lower the 50% (aka /2) crouch will always allow stealth to remain activated, if not encountered within the enemy senses routine.
The interesting thing, is it seems basespeed returns the walk speed, which would mean when even walking, you are going faster than half the base speed. As a result, I think I made a mistake, only crouching or standing still will keep you stealthed once detected. Unless there are other movement mods, outside of walk, run, and crouch, I don't know about. Maybe climbing? Climbing takes current movement speed divides it by three and then doubles the speed if you have the adept climbing modifier from character creation. So you can stay hidden in climbing mode too, if I am understanding the playerspeedchanger script correctly.
Code: Select all
public float GetClimbingSpeed()
{
// Climbing effect states "target can climb twice as well" - doubling climbing speed
Entity.PlayerEntity player = GameManager.Instance.PlayerEntity;
float climbingBoost = player.IsEnhancedClimbing ? 2f : 1f;
return (playerMotor.Speed / 3) * climbingBoost;
}
Here is Running. This looks off if you do the math for the equation, but that is because it uses the base speed after its calculated to return the run speed. Think of it has a multiplier for the current base speed.
Code: Select all
public bool IsRunning
{
get { return speed == speedChanger.GetRunSpeed(speedChanger.GetBaseSpeed()); }
}
Code: Select all
/// <summary>
/// Get LiveSpeed adjusted for running
/// </summary>
/// <param name="baseSpeed"></param>
/// <returns></returns>
public float GetRunSpeed(float baseSpeed)
{
if (useRunSpeedOverride)
return runSpeedOverride;
Entity.PlayerEntity player = GameManager.Instance.PlayerEntity;
return baseSpeed * (1.25f + (player.Skills.GetLiveSkillValue(DFCareer.Skills.Running) / 200f));
}
Here is walk:
Code: Select all
/// <summary>
/// Get LiveSpeed adjusted for walking
/// </summary>
/// <param name="player">the PlayerEntity to use</param>
/// <returns></returns>
public float GetWalkSpeed(Entity.PlayerEntity player)
{
if (useWalkSpeedOverride)
return walkSpeedOverride;
else
return (player.Stats.LiveSpeed + dfWalkBase) / classicToUnitySpeedUnitRatio;
}
Not sure how I overlooked this at the front of the script. According to the code, sneak mode does have a use. It will take whatever speed you're at, half it, and subtract 1. According to this, you should be able to use sneak mode to sneak within whatever movement mode you want.
Code: Select all
/// <summary>
/// Determines how speed should be changed based on player's input
/// </summary>
/// <param name="speed"></param>
public void HandleInputSpeedAdjustment(ref float speed)
{
if (playerMotor.IsGrounded)
{
if (InputManager.Instance.HasAction(InputManager.Actions.Run) && CanRun())
{
try
{
// If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down
if (!toggleRun)
speed = GetRunSpeed(speed);
else
speed = (speed == GetBaseSpeed() ? GetRunSpeed(speed) : GetBaseSpeed());
}
catch
{
speed = GetRunSpeed(speed);
}
}
// Handle sneak key. Reduces movement speed to half, then subtracts 1 in classic speed units
else if (InputManager.Instance.HasAction(InputManager.Actions.Sneak))
{
speed /= 2;
speed -= (1 / classicToUnitySpeedUnitRatio);
}
}
}
Here is the code that decides if you are moving half speed or not. And yes, crouch is always half base speed and will ensure stealth checks can happen within the StealthCheck Routine while crouched and moving.
Code: Select all
public bool IsMovingLessThanHalfSpeed
{
get
{
if (IsStandingStill)
{
return true;
}
if (isCrouching)
{
return (speedChanger.GetWalkSpeed(GameManager.Instance.PlayerEntity) / 2) >= speed;
}
return (speedChanger.GetBaseSpeed() / 2) >= speed;
}