Sound scaling on footsteps was first implemented in UT2k3.
And some of the weapon's sounds are played by the projectile, not the weapon and most of these ignore the sound dampening.
Speaking of weapons, I was looking at the Rocket Launcher's lock system... boy what a mess it is.
Facts:
- Weapon doesn't do targeting at all, it calls the player owner's PickTarget function (apparently for speed reasons).
- PickTarget is a native function, you don't get to see the targeting criterias... I'll show you below.
It considers any non-player non-team pawn as targetable, that includes team sgBuildings.
Given the nature of PickTarget, it was optimized for speed, although RocketLauncher only needs to call that function TWICE in a 1.25 second span.
- TWICE? Yes, once to 'grab' target, and a second time to 'confirm' target.
There is a bug here, if 'grabbed' target differs from 'confirm' then lock fails, this means that rocket launcher cannot properly lock a target if some other pawn crosses your aim while you're trying to lock onto a specific enemy.
So, things to fix the rocket launcher mess:
- Specify an angle/wideness between enemy and crosshair where lock cannot be overriden by a second pawn (once you're following a target, it sticks there).
- Test the 'grabbed' target for said angle/availability first, before going back to selecting a new target (or coincidentally choosing the same one if out of secure angle).
- Use own targeting system so that sgBuilding's can be team-filtered (and maybe prioritize mines?)
- Increase weapon responsiveness by running the check timer at twice the rate when there's no grabbed target.
- - - Updated - - -
Extracted from leaked sources:
Code:void APawn::execPickTarget( FFrame& Stack, RESULT_DECL )
{
guardSlow(APawn::execPickTarget);
P_GET_FLOAT_REF(bestAim);
P_GET_FLOAT_REF(bestDist);
P_GET_VECTOR(FireDir);
P_GET_VECTOR(projStart);
P_FINISH;
APawn *pick = NULL;
for ( APawn *next=GetLevel()->GetLevelInfo()->PawnList; next!=NULL; next=next->nextPawn )
{
if ( (next != this) && (next->Health > 0) && next->bProjTarget
&& (!PlayerReplicationInfo || !next->PlayerReplicationInfo
|| !GetLevel()->GetLevelInfo()->Game->bTeamGame
|| (PlayerReplicationInfo->Team != next->PlayerReplicationInfo->Team)) )
{
FLOAT newAim = FireDir | (next->Location - projStart);
if ( newAim > 0 )
{
FLOAT FireDist = (next->Location - projStart).SizeSquared();
if ( FireDist < 4000000.f )
{
FireDist = appSqrt(FireDist);
newAim = newAim/FireDist;
if ( (newAim > *bestAim) && LineOfSightTo(next) )
{
pick = next;
*bestAim = newAim;
*bestDist = FireDist;
}
}
}
}
}
*(APawn**)Result = pick;
unguardSlow;
}