Index: src/cgame/cg_buildable.c =================================================================== --- src/cgame/cg_buildable.c (revision 2092) +++ src/cgame/cg_buildable.c (working copy) @@ -551,8 +551,9 @@ const vec3_t mins, const vec3_t maxs, vec3_t outAxis[ 3 ], vec3_t outOrigin ) { - vec3_t forward, start, end; - trace_t tr; + vec3_t forward, start, end, diff; + trace_t tr, box_tr; + float mag; AngleVectors( angles, forward, NULL, NULL ); VectorCopy( normal, outAxis[ 2 ] ); @@ -572,16 +573,28 @@ VectorMA( inOrigin, -TRACE_DEPTH, normal, end ); VectorMA( inOrigin, 1.0f, normal, start ); + + //Take both capsule and box traces. If the capsule trace does not differ + // significantly from the box trace use it. This may cause buildables to be + // positioned *inside* the surface on which it is placed. This is intentional + CG_CapTrace( &tr, start, mins, maxs, end, skipNumber, CONTENTS_SOLID | CONTENTS_PLAYERCLIP ); - if( tr.fraction == 1.0f ) - { - //erm we missed completely - try again with a box trace - CG_Trace( &tr, start, mins, maxs, end, skipNumber, - CONTENTS_SOLID | CONTENTS_PLAYERCLIP ); - } + CG_Trace( &box_tr, start, mins, maxs, end, skipNumber, + CONTENTS_SOLID | CONTENTS_PLAYERCLIP ); + VectorSubtract (tr.endpos, box_tr.endpos, diff); + + //there's got to be a function somewhere for this, but I can't find it. + mag = diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]; + mag = sqrt (mag); + + if( mag > 15.0f || tr.fraction == 1.0f) + //this is either too far off of the bbox to be useful for gameplay purposes + // or the model is positioned in thin air anyways. + tr = box_tr; + VectorMA( inOrigin, tr.fraction * -TRACE_DEPTH, normal, outOrigin ); }