PDA

View Full Version : sgTranslocatorTarget rewrite



Higor
08-23-2012, 06:53 PM
Fixes translocation through solid actors after ground impact.
Fixes clientside simulation of actor impacts.
Blocking actor collision enhanced to the point of almost treating those as solid cylinders.
sgBuilding added as special exception, translocator will always bounce off these.
Removed redundant code already existing in class Botpack.TranslocatorTarget.


//================================================== ===========================
// sgTranslocatorTarget.
//
// Revised by Higor
// - Fixes several collision issues and enhances client simulation by providing
// impact information.
// - Damage simulation still pending (for mid-air launches)
//================================================== ===========================
class sgTranslocatorTarget expands TranslocatorTarget;
/*
Ideas:
> Alt fire to shoot a trans so that it falls and sticks at where you aim at...
Auto trans on impact (optional?, maybe if ALTFIRE is held after firing it) for the alt fire mode.
Fail ALT shoot if no possible trajectory to aim point (no curve, or too far) (optional).
> Make the trans stick to a teammate instead of falling.
> Teammates can repair a disrupted trans.
> Being affected by Boosters and Super Boosters.
*/

function Throw(Pawn Thrower, float force, vector StartPosition)
{
local vector dir;

dir = vector(Thrower.ViewRotation);
if ( Thrower.IsA('Bot') )
Velocity = force * dir + vect(0,0,200);
else
{
dir.Z = dir.Z + 0.35 * (1 - Abs(dir.Z));
Velocity = FMin(force, Master.MaxTossForce + (Master.Charge *150)) * Normal(dir);
}
bBounce = true;
DropFrom(StartPosition);
}


////////////////////////////////////////////////////////
auto state Pickup
{
simulated singular function Touch( Actor Other )
{
local bool bMasterTouch;
local vector NewPos;
local float aRatio;

if ( !Other.bIsPawn || Other.IsA('sgBuilding'))
{
if ( (Physics == PHYS_Falling) && !Other.IsA('Inventory') && !Other.IsA('Triggers') && !Other.IsA('NavigationPoint') )
BounceActor( Other);
return;
}

bMasterTouch = ( Other == Instigator );

if ( Physics == PHYS_None )
{
if ( bMasterTouch )
{
PlaySound(Sound'Botpack.Pickups.AmmoPick',,2.0);
Master.TTarget = None;
Master.bTTargetOut = false;
if ( Other.IsA('PlayerPawn') )
PlayerPawn(Other).ClientWeaponEvent('TouchTarget') ;
destroy();
}
return;
}
if ( bMasterTouch )
return;
NewPos = Other.Location;
NewPos.Z = Location.Z;
SetLocation(NewPos);
Velocity = vect(0,0,0);
if ( Level.Game.bTeamGame
&& (Instigator.PlayerReplicationInfo.Team == Pawn(Other).PlayerReplicationInfo.Team) )
return;

if ( Instigator.IsA('Bot') )
Master.Translocate();
}

//Make an ultra precise bounce on both server and clients
simulated function BounceActor( actor Other)
{
local bool bOldHit;
local int i;
local vector aVec, oVec;

//No brushes
if ( (Mover(Other) != none) || (LevelInfo(Other) != none) || (Other == none) )
return;

//Evaluate location and exact hitnormal/hitlocation, use 10 step precision for it at first (no gravity pull, sorry)
//First point avoided, didn't touch during last tick anyways
While (++i <= 10)
{
aVec = OldLocation + (Location - OldLocation) * 0.1 * float(i);
if ( abs(aVec.Z - Other.Location.Z) <= (CollisionHeight + Other.CollisionHeight) )
if ( VSize( (Other.Location - aVec) * vect(1,1,0)) <= (CollisionRadius + Other.CollisionRadius) )
{
oVec = OldLocation + (Location - OldLocation) * 0.1 * float(i-1);
break;
}
}

//No collision detected here, do not bounce
if ( oVec == vect(0,0,0) )
return;

SetLocation( oVec);

//Compare Z component of hull normal and location diff normal, so we know if we hit side or ceil/floor
oVec = Normal(vect(0,0,1) * (Other.CollisionHeight + CollisionHeight) + vect(1,0,0) * (Other.CollisionRadius + CollisionRadius));
aVec = Normal( Location - Other.Location);
bOldHit = bAlreadyHit; //Save this and restore later
if ( aVec.Z > oVec.Z )
{
aVec = Location;
aVec.Z = Other.Location.Z + CollisionHeight + Other.CollisionHeight;
SetLocation( aVec);
//Bounce
if ( !bAlreadyHit || Other.bIsPawn )
{
HitWall( vect(0,0,1), Other);
if ( Other.bIsPawn )
{
bAlreadyHit = False;
Velocity += (Location - Other.Location);
}
}
else
{ //Land
SetPhysics( PHYS_None);
Velocity = vect(0,0,0);
Landed( vect(0,0,1) );
}
}
else if ( aVec.Z < -oVec.Z )
{
aVec = Location;
aVec.Z = Other.Location.Z - (CollisionHeight + Other.CollisionHeight);
SetLocation( aVec);
bAlreadyHit = false;
HitWall( vect(0,0,-1), Other);
bAlreadyHit = bAlreadyHit || bOldHit;
}
else
{
aVec = Other.Location + Normal( (Location - Other.Location)*vect(1,1,0)) * (CollisionRadius + Other.CollisionRadius);
aVec.Z = Location.Z;
SetLocation( aVec);
bAlreadyHit = false;
HitWall( Normal((Location - Other.Location)*vect(1,1,0)) , Other);
bAlreadyHit = bAlreadyHit || bOldHit;
}

}
}

SAM
08-24-2012, 05:39 PM
Is this to prevent contianer through wall/floor? If so, there's already a fix ferali made. Just SW will not compile it...anyway, does your example allow for teleporters to be made through walls?

Higor
08-24-2012, 08:18 PM
My method specifies an individual building distance, on a fresh build, all builds have that value on 45.
With ini changes each building's distance can be reduced/increased, with 20 no building should go thru a wall, while with 50, chances are higher.

Therefore, it is customizable now.

EDIT: Both trans and building methods are already part of SW's test version.
EDIT 2: Once the release is made, Ill start working on 4way support for a future release.