#include "q_shared.h"#include "bg_public.h"#include "bg_local.h"#include "../namespace_begin.h"#include "../namespace_end.h"Go to the source code of this file.
Defines | |
| #define | MAX_IMPACT_TURN_ANGLE 45.0f |
| #define | MAX_CLIP_PLANES 5 |
Functions | |
| qboolean | BG_UnrestrainedPitchRoll (playerState_t *ps, Vehicle_t *pVeh) |
| void | trap_FX_PlayEffectID (int id, vec3_t org, vec3_t fwd, int vol, int rad) |
| void | PM_SetPMViewAngle (playerState_t *ps, vec3_t angle, usercmd_t *ucmd) |
| void | PM_VehicleImpact (bgEntity_t *pEnt, trace_t *trace) |
| qboolean | PM_GroundSlideOkay (float zNormal) |
| qboolean | PM_SlideMove (qboolean gravity) |
| void | PM_StepSlideMove (qboolean gravity) |
Variables | |
| bgEntity_t * | pm_entSelf |
| bgEntity_t * | pm_entVeh |
|
|
Definition at line 628 of file bg_slidemove.c. Referenced by PM_SlideMove(). |
|
|
Definition at line 47 of file bg_slidemove.c. Referenced by PM_VehicleImpact(). |
|
||||||||||||
|
Definition at line 7785 of file bg_pmove.c.
07786 {
07787 if ( bg_fighterAltControl.integer
07788 && ps->clientNum < MAX_CLIENTS //real client
07789 && ps->m_iVehicleNum//in a vehicle
07790 && pVeh //valid vehicle data pointer
07791 && pVeh->m_pVehicleInfo//valid vehicle info
07792 && pVeh->m_pVehicleInfo->type == VH_FIGHTER )//fighter
07793 //FIXME: specify per vehicle instead of assuming true for all fighters
07794 //FIXME: map/server setting?
07795 {//can roll and pitch without limitation!
07796 return qtrue;
07797 }
07798 return qfalse;
07799 }
|
|
|
||||||||||||||||
|
Definition at line 1342 of file bg_pmove.c. References ANGLE2SHORT, usercmd_s::angles, playerState_s::delta_angles, playerState_t, ucmd, usercmd_t, vec3_t, VectorCopy, and playerState_s::viewangles. Referenced by PM_AdjustAngleForWallJump(), PM_AdjustAngleForWallRun(), PM_AdjustAngleForWallRunUp(), PM_AdjustAnglesForWallRunUpFlipAlt(), PM_VehFaceHyperspacePoint(), PM_VehForcedTurning(), PM_VehicleViewAngles(), and PmoveSingle().
01343 {
01344 int i;
01345
01346 for (i=0 ; i<3 ; i++)
01347 { // set the delta angle
01348 int cmdAngle;
01349
01350 cmdAngle = ANGLE2SHORT(angle[i]);
01351 ps->delta_angles[i] = cmdAngle - ucmd->angles[i];
01352 }
01353 VectorCopy (angle, ps->viewangles);
01354 }
|
|
|
Definition at line 629 of file bg_slidemove.c. References trace_t::allsolid, bgEntity_t, CLASS_VEHICLE, playerState_s::clientNum, DotProduct, trace_t::endpos, trace_t::entityNum, ET_NPC, entityState_s::eType, trace_t::fraction, pml_t::frametime, playerState_s::gravity, pml_t::groundPlane, pml_t::groundTrace, pml_t::impactSpeed, bgEntity_s::m_pVehicle, MAX_CLIENTS, MAX_CLIP_PLANES, pmove_t::maxs, pmove_t::mins, cplane_s::normal, entityState_s::NPC_class, playerState_s::origin, OVERCLIP, trace_t::plane, pm, PM_AddTouchEnt(), PM_ClipVelocity(), pm_entSelf, playerState_s::pm_flags, PM_GroundSlideOkay(), playerState_s::pm_time, PM_VehicleImpact(), PMF_STUCK_TO_WALL, pml, pmove_t::ps, qboolean, qtrue, bgEntity_s::s, pmove_t::trace, pmove_t::tracemask, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorNormalize(), VectorNormalize2(), VectorScale, and playerState_s::velocity. Referenced by PM_StepSlideMove().
00629 {
00630 int bumpcount, numbumps;
00631 vec3_t dir;
00632 float d;
00633 int numplanes;
00634 vec3_t normal, planes[MAX_CLIP_PLANES];
00635 vec3_t primal_velocity;
00636 vec3_t clipVelocity;
00637 int i, j, k;
00638 trace_t trace;
00639 vec3_t end;
00640 float time_left;
00641 float into;
00642 vec3_t endVelocity;
00643 vec3_t endClipVelocity;
00644 //qboolean damageSelf = qtrue;
00645
00646 numbumps = 4;
00647
00648 VectorCopy (pm->ps->velocity, primal_velocity);
00649
00650 if ( gravity ) {
00651 VectorCopy( pm->ps->velocity, endVelocity );
00652 endVelocity[2] -= pm->ps->gravity * pml.frametime;
00653 pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
00654 primal_velocity[2] = endVelocity[2];
00655 if ( pml.groundPlane ) {
00656 if ( PM_GroundSlideOkay( pml.groundTrace.plane.normal[2] ) )
00657 {// slide along the ground plane
00658 PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
00659 pm->ps->velocity, OVERCLIP );
00660 }
00661 }
00662 }
00663
00664 time_left = pml.frametime;
00665
00666 // never turn against the ground plane
00667 if ( pml.groundPlane ) {
00668 numplanes = 1;
00669 VectorCopy( pml.groundTrace.plane.normal, planes[0] );
00670 if ( !PM_GroundSlideOkay( planes[0][2] ) )
00671 {
00672 planes[0][2] = 0;
00673 VectorNormalize( planes[0] );
00674 }
00675 } else {
00676 numplanes = 0;
00677 }
00678
00679 // never turn against original velocity
00680 VectorNormalize2( pm->ps->velocity, planes[numplanes] );
00681 numplanes++;
00682
00683 for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ ) {
00684
00685 // calculate position we are trying to move to
00686 VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );
00687
00688 // see if we can make it there
00689 pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
00690
00691 if (trace.allsolid) {
00692 // entity is completely trapped in another solid
00693 pm->ps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration
00694 return qtrue;
00695 }
00696
00697 if (trace.fraction > 0) {
00698 // actually covered some distance
00699 VectorCopy (trace.endpos, pm->ps->origin);
00700 }
00701
00702 if (trace.fraction == 1) {
00703 break; // moved the entire distance
00704 }
00705
00706 // save entity for contact
00707 PM_AddTouchEnt( trace.entityNum );
00708
00709 if (pm->ps->clientNum >= MAX_CLIENTS)
00710 {
00711 bgEntity_t *pEnt = pm_entSelf;
00712
00713 if (pEnt && pEnt->s.eType == ET_NPC && pEnt->s.NPC_class == CLASS_VEHICLE &&
00714 pEnt->m_pVehicle)
00715 { //do vehicle impact stuff then
00716 PM_VehicleImpact(pEnt, &trace);
00717 }
00718 }
00719 #ifdef QAGAME
00720 else
00721 {
00722 if ( PM_ClientImpact( &trace ) )
00723 {
00724 continue;
00725 }
00726 }
00727 #endif
00728
00729 time_left -= time_left * trace.fraction;
00730
00731 if (numplanes >= MAX_CLIP_PLANES) {
00732 // this shouldn't really happen
00733 VectorClear( pm->ps->velocity );
00734 return qtrue;
00735 }
00736
00737 VectorCopy( trace.plane.normal, normal );
00738
00739 if ( !PM_GroundSlideOkay( normal[2] ) )
00740 {//wall-running
00741 //never push up off a sloped wall
00742 normal[2] = 0;
00743 VectorNormalize( normal );
00744 }
00745 //
00746 // if this is the same plane we hit before, nudge velocity
00747 // out along it, which fixes some epsilon issues with
00748 // non-axial planes
00749 //
00750 if ( !(pm->ps->pm_flags&PMF_STUCK_TO_WALL) )
00751 {//no sliding if stuck to wall!
00752 for ( i = 0 ; i < numplanes ; i++ ) {
00753 if ( VectorCompare( normal, planes[i] ) ) {//DotProduct( normal, planes[i] ) > 0.99 ) {
00754 VectorAdd( normal, pm->ps->velocity, pm->ps->velocity );
00755 break;
00756 }
00757 }
00758 if ( i < numplanes ) {
00759 continue;
00760 }
00761 }
00762 VectorCopy (normal, planes[numplanes]);
00763 numplanes++;
00764
00765 //
00766 // modify velocity so it parallels all of the clip planes
00767 //
00768
00769 // find a plane that it enters
00770 for ( i = 0 ; i < numplanes ; i++ ) {
00771 into = DotProduct( pm->ps->velocity, planes[i] );
00772 if ( into >= 0.1 ) {
00773 continue; // move doesn't interact with the plane
00774 }
00775
00776 // see how hard we are hitting things
00777 if ( -into > pml.impactSpeed ) {
00778 pml.impactSpeed = -into;
00779 }
00780
00781 // slide along the plane
00782 PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );
00783
00784 // slide along the plane
00785 PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );
00786
00787 // see if there is a second plane that the new move enters
00788 for ( j = 0 ; j < numplanes ; j++ ) {
00789 if ( j == i ) {
00790 continue;
00791 }
00792 if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) {
00793 continue; // move doesn't interact with the plane
00794 }
00795
00796 // try clipping the move to the plane
00797 PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
00798 PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP );
00799
00800 // see if it goes back into the first clip plane
00801 if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) {
00802 continue;
00803 }
00804
00805 // slide the original velocity along the crease
00806 CrossProduct (planes[i], planes[j], dir);
00807 VectorNormalize( dir );
00808 d = DotProduct( dir, pm->ps->velocity );
00809 VectorScale( dir, d, clipVelocity );
00810
00811 CrossProduct (planes[i], planes[j], dir);
00812 VectorNormalize( dir );
00813 d = DotProduct( dir, endVelocity );
00814 VectorScale( dir, d, endClipVelocity );
00815
00816 // see if there is a third plane the the new move enters
00817 for ( k = 0 ; k < numplanes ; k++ ) {
00818 if ( k == i || k == j ) {
00819 continue;
00820 }
00821 if ( DotProduct( clipVelocity, planes[k] ) >= 0.1 ) {
00822 continue; // move doesn't interact with the plane
00823 }
00824
00825 // stop dead at a triple plane interaction
00826 VectorClear( pm->ps->velocity );
00827 return qtrue;
00828 }
00829 }
00830
00831 // if we have fixed all interactions, try another move
00832 VectorCopy( clipVelocity, pm->ps->velocity );
00833 VectorCopy( endClipVelocity, endVelocity );
00834 break;
00835 }
00836 }
00837
00838 if ( gravity ) {
00839 VectorCopy( endVelocity, pm->ps->velocity );
00840 }
00841
00842 // don't change velocity if in a timer (FIXME: is this correct?)
00843 if ( pm->ps->pm_time ) {
00844 VectorCopy( primal_velocity, pm->ps->velocity );
00845 }
00846
00847 return ( bumpcount != 0 );
00848 }
|
|
|
Definition at line 856 of file bg_slidemove.c. References trace_t::allsolid, BG_InReboundHold(), bgEntity_t, c_pmove, CLASS_ATST, CLASS_RANCOR, CLASS_VEHICLE, playerState_s::clientNum, Com_Printf(), pmove_t::debugLevel, DotProduct, trace_t::endpos, trace_t::entityNum, EV_STEP_12, EV_STEP_16, EV_STEP_4, EV_STEP_8, trace_t::fraction, vehicleInfo_t::hoverHeight, playerState_s::legsAnim, bgEntity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_CLIENTS, pmove_t::maxs, MIN_WALK_NORMAL, pmove_t::mins, cplane_s::normal, entityState_s::NPC_class, playerState_s::origin, OVERCLIP, trace_t::plane, pm, PM_AddEvent(), PM_ClipVelocity(), pm_entSelf, PM_SlideMove(), pmove_t::ps, qboolean, qfalse, qtrue, bgEntity_s::s, STEPSIZE, pmove_t::stepSlideFix, pmove_t::trace, pmove_t::tracemask, vehicleInfo_t::type, vec3_t, VectorCopy, VectorNormalize(), VectorSet, VectorSubtract, playerState_s::velocity, and VH_WALKER.
00856 {
00857 vec3_t start_o, start_v;
00858 vec3_t down_o, down_v;
00859 trace_t trace;
00860 // float down_dist, up_dist;
00861 // vec3_t delta, delta2;
00862 vec3_t up, down;
00863 float stepSize;
00864 qboolean isGiant = qfalse;
00865 bgEntity_t *pEnt;
00866 qboolean skipStep = qfalse;
00867
00868 VectorCopy (pm->ps->origin, start_o);
00869 VectorCopy (pm->ps->velocity, start_v);
00870
00871 if ( BG_InReboundHold( pm->ps->legsAnim ) )
00872 {
00873 gravity = qfalse;
00874 }
00875
00876 if ( PM_SlideMove( gravity ) == 0 ) {
00877 return; // we got exactly where we wanted to go first try
00878 }
00879
00880 pEnt = pm_entSelf;
00881
00882 if (pm->ps->clientNum >= MAX_CLIENTS)
00883 {
00884 if (pEnt && pEnt->s.NPC_class == CLASS_VEHICLE &&
00885 pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->hoverHeight > 0)
00886 {
00887 return;
00888 }
00889 }
00890
00891 VectorCopy(start_o, down);
00892 down[2] -= STEPSIZE;
00893 pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
00894 VectorSet(up, 0, 0, 1);
00895 // never step up when you still have up velocity
00896 if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
00897 DotProduct(trace.plane.normal, up) < 0.7))
00898 {
00899 return;
00900 }
00901
00902 VectorCopy (pm->ps->origin, down_o);
00903 VectorCopy (pm->ps->velocity, down_v);
00904
00905 VectorCopy (start_o, up);
00906
00907 if (pm->ps->clientNum >= MAX_CLIENTS)
00908 {
00909 // apply ground friction, even if on ladder
00910 if (pEnt &&
00911 pEnt->s.NPC_class == CLASS_ATST ||
00912 (pEnt->s.NPC_class == CLASS_VEHICLE &&
00913 pEnt->m_pVehicle &&
00914 pEnt->m_pVehicle->m_pVehicleInfo->type == VH_WALKER)
00915 )
00916 {//AT-STs can step high
00917 up[2] += 66.0f;
00918 isGiant = qtrue;
00919 }
00920 else if ( pEnt && pEnt->s.NPC_class == CLASS_RANCOR )
00921 {//also can step up high
00922 up[2] += 64.0f;
00923 isGiant = qtrue;
00924 }
00925 else
00926 {
00927 up[2] += STEPSIZE;
00928 }
00929 }
00930 else
00931 {
00932 up[2] += STEPSIZE;
00933 }
00934
00935 // test the player position if they were a stepheight higher
00936 pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
00937 if ( trace.allsolid ) {
00938 if ( pm->debugLevel ) {
00939 Com_Printf("%i:bend can't step\n", c_pmove);
00940 }
00941 return; // can't step up
00942 }
00943
00944 stepSize = trace.endpos[2] - start_o[2];
00945 // try slidemove from this position
00946 VectorCopy (trace.endpos, pm->ps->origin);
00947 VectorCopy (start_v, pm->ps->velocity);
00948
00949 PM_SlideMove( gravity );
00950
00951 // push down the final amount
00952 VectorCopy (pm->ps->origin, down);
00953 down[2] -= stepSize;
00954 pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
00955
00956 if ( pm->stepSlideFix )
00957 {
00958 if ( pm->ps->clientNum < MAX_CLIENTS
00959 && trace.plane.normal[2] < MIN_WALK_NORMAL )
00960 {//normal players cannot step up slopes that are too steep to walk on!
00961 vec3_t stepVec;
00962 //okay, the step up ends on a slope that it too steep to step up onto,
00963 //BUT:
00964 //If the step looks like this:
00965 // (B)\__
00966 // \_____(A)
00967 //Then it might still be okay, so we figure out the slope of the entire move
00968 //from (A) to (B) and if that slope is walk-upabble, then it's okay
00969 VectorSubtract( trace.endpos, down_o, stepVec );
00970 VectorNormalize( stepVec );
00971 if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
00972 {
00973 skipStep = qtrue;
00974 }
00975 }
00976 }
00977
00978 if ( !trace.allsolid
00979 && !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
00980 {
00981 if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
00982 && isGiant
00983 && trace.entityNum < MAX_CLIENTS
00984 && pEnt
00985 && pEnt->s.NPC_class == CLASS_RANCOR )
00986 {//Rancor don't step on clients
00987 if ( pm->stepSlideFix )
00988 {
00989 VectorCopy (down_o, pm->ps->origin);
00990 VectorCopy (down_v, pm->ps->velocity);
00991 }
00992 else
00993 {
00994 VectorCopy (start_o, pm->ps->origin);
00995 VectorCopy (start_v, pm->ps->velocity);
00996 }
00997 }
00998 /*
00999 else if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
01000 && isGiant
01001 && trace.entityNum < MAX_CLIENTS
01002 && pEnt
01003 && pEnt->s.NPC_class == CLASS_ATST
01004 && OnSameTeam( pEnt, traceEnt) )
01005 {//NPC AT-ST's don't step up on allies
01006 VectorCopy (start_o, pm->ps->origin);
01007 VectorCopy (start_v, pm->ps->velocity);
01008 }
01009 */
01010 else
01011 {
01012 VectorCopy (trace.endpos, pm->ps->origin);
01013 if ( pm->stepSlideFix )
01014 {
01015 if ( trace.fraction < 1.0 ) {
01016 PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
01017 }
01018 }
01019 }
01020 }
01021 else
01022 {
01023 if ( pm->stepSlideFix )
01024 {
01025 VectorCopy (down_o, pm->ps->origin);
01026 VectorCopy (down_v, pm->ps->velocity);
01027 }
01028 }
01029 if ( !pm->stepSlideFix )
01030 {
01031 if ( trace.fraction < 1.0 ) {
01032 PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
01033 }
01034 }
01035
01036 #if 0
01037 // if the down trace can trace back to the original position directly, don't step
01038 pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
01039 if ( trace.fraction == 1.0 ) {
01040 // use the original move
01041 VectorCopy (down_o, pm->ps->origin);
01042 VectorCopy (down_v, pm->ps->velocity);
01043 if ( pm->debugLevel ) {
01044 Com_Printf("%i:bend\n", c_pmove);
01045 }
01046 } else
01047 #endif
01048 {
01049 // use the step move
01050 float delta;
01051
01052 delta = pm->ps->origin[2] - start_o[2];
01053 if ( delta > 2 ) {
01054 if ( delta < 7 ) {
01055 PM_AddEvent( EV_STEP_4 );
01056 } else if ( delta < 11 ) {
01057 PM_AddEvent( EV_STEP_8 );
01058 } else if ( delta < 15 ) {
01059 PM_AddEvent( EV_STEP_12 );
01060 } else {
01061 PM_AddEvent( EV_STEP_16 );
01062 }
01063 }
01064 if ( pm->debugLevel ) {
01065 Com_Printf("%i:stepped\n", c_pmove);
01066 }
01067 }
01068 }
|
|
||||||||||||
|
Definition at line 48 of file bg_slidemove.c. References AngleNormalize180(), AnglesSubtract(), AngleVectors(), entityState_s::apos, BG_KnockDownable(), bgEntity_t, entityShared_t::bmodel, CLASS_VEHICLE, gentity_s::classname, gentity_s::client, pmove_t::cmd, DAMAGE_NO_ARMOR, DotProduct, trace_t::entityNum, ENTITYNUM_WORLD, ET_MISSILE, ET_MOVER, ET_NPC, ET_PLAYER, ET_TERRAIN, entityState_s::eType, EV_PLAY_EFFECT_ID, fabs(), FighterIsLanded(), trace_t::fraction, pml_t::frametime, G_AddEvent(), G_CanBeEnemy(), G_Damage(), g_entities, gentity_t, HANDEXTEND_KNOCKDOWN, vehicleInfo_t::iImpactFX, gentity_s::inuse, level, Vehicle_s::m_fTimeModifier, Vehicle_s::m_iHitDebounce, Vehicle_s::m_iLastImpactDmg, Vehicle_s::m_iRemovedSurfaces, Vehicle_s::m_LandTrace, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, bgEntity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_ulFlags, Vehicle_s::m_vFullAngleVelocity, Vehicle_s::m_vOrientation, vehicleInfo_t::mass, MAX_CLIENTS, MAX_IMPACT_TURN_ANGLE, MIN_LANDING_SLOPE, MIN_LANDING_SPEED, MOD_FALLING, MOD_MELEE, cplane_s::normal, entityState_s::NPC_class, NULL, entityState_s::number, entityState_s::origin, playerState_s::origin, playerState_s::otherKiller, playerState_s::otherKillerTime, entityState_s::owner, entityShared_t::ownerNum, PITCH, trace_t::plane, pm, PM_BGEntForNum(), pml, gclient_s::ps, pmove_t::ps, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, ROLL, bgEntity_s::s, gentity_s::s, usercmd_s::serverTime, entityState_s::solid, SOLID_BMODEL, gentity_s::spawnflags, entityState_s::speed, playerState_s::speed, vehicleInfo_t::surfDestruction, level_locals_t::time, vehicleInfo_t::toughness, TR_STATIONARY, trap_FX_PlayEffectID(), trajectory_t::trType, vehicleInfo_t::type, vec3_origin, vec3_t, vectoangles(), VectorAdd, VectorCopy, VectorNormalize(), VectorNormalize2(), VectorScale, VectorSubtract, VEH_CRASHING, Vehicle_t, playerState_s::velocity, VH_FIGHTER, VH_SPEEDER, and YAW. Referenced by PM_SlideMove().
00049 {
00050 // See if the vehicle has crashed into the ground.
00051 Vehicle_t *pSelfVeh = pEnt->m_pVehicle;
00052 float magnitude = VectorLength( pm->ps->velocity ) * pSelfVeh->m_pVehicleInfo->mass / 50.0f;
00053 qboolean forceSurfDestruction = qfalse;
00054 #ifdef QAGAME
00055 gentity_t *hitEnt = trace!=NULL?&g_entities[trace->entityNum]:NULL;
00056
00057 if (!hitEnt ||
00058 (pSelfVeh && pSelfVeh->m_pPilot &&
00059 hitEnt && hitEnt->s.eType == ET_MISSILE && hitEnt->inuse &&
00060 hitEnt->r.ownerNum == pSelfVeh->m_pPilot->s.number)
00061 )
00062 {
00063 return;
00064 }
00065
00066 if ( pSelfVeh//I have a vehicle struct
00067 && pSelfVeh->m_iRemovedSurfaces )//vehicle has bits removed
00068 {//spiralling to our deaths, explode on any solid impact
00069 if ( hitEnt->s.NPC_class == CLASS_VEHICLE )
00070 {//hit another vehicle, explode!
00071 //Give credit to whoever got me into this death spiral state
00072 gentity_t *parent = (gentity_t *)pSelfVeh->m_pParentEntity;
00073 gentity_t *killer = NULL;
00074 if (parent->client->ps.otherKiller < ENTITYNUM_WORLD &&
00075 parent->client->ps.otherKillerTime > level.time)
00076 {
00077 gentity_t *potentialKiller = &g_entities[parent->client->ps.otherKiller];
00078
00079 if (potentialKiller->inuse && potentialKiller->client)
00080 { //he's valid I guess
00081 killer = potentialKiller;
00082 }
00083 }
00084 //FIXME: damage hitEnt, some, too? Our explosion should hurt them some, but...
00085 G_Damage( (gentity_t *)pEnt, killer, killer, NULL, pm->ps->origin, 999999, DAMAGE_NO_ARMOR, MOD_FALLING );//FIXME: MOD_IMPACT
00086 return;
00087 }
00088 else if ( !VectorCompare( trace->plane.normal, vec3_origin )
00089 && (trace->entityNum == ENTITYNUM_WORLD || hitEnt->r.bmodel ) )
00090 {//have a valid hit plane and we hit a solid brush
00091 vec3_t moveDir;
00092 float impactDot;
00093 VectorCopy( pm->ps->velocity, moveDir );
00094 VectorNormalize( moveDir );
00095 impactDot = DotProduct( moveDir, trace->plane.normal );
00096 if ( impactDot <= -0.7f )//hit rather head-on and hard
00097 {// Just DIE now
00098 //Give credit to whoever got me into this death spiral state
00099 gentity_t *parent = (gentity_t *)pSelfVeh->m_pParentEntity;
00100 gentity_t *killer = NULL;
00101 if (parent->client->ps.otherKiller < ENTITYNUM_WORLD &&
00102 parent->client->ps.otherKillerTime > level.time)
00103 {
00104 gentity_t *potentialKiller = &g_entities[parent->client->ps.otherKiller];
00105
00106 if (potentialKiller->inuse && potentialKiller->client)
00107 { //he's valid I guess
00108 killer = potentialKiller;
00109 }
00110 }
00111 G_Damage( (gentity_t *)pEnt, killer, killer, NULL, pm->ps->origin, 999999, DAMAGE_NO_ARMOR, MOD_FALLING );//FIXME: MOD_IMPACT
00112 return;
00113 }
00114 }
00115 }
00116
00117 if ( trace->entityNum < ENTITYNUM_WORLD
00118 && hitEnt->s.eType == ET_MOVER
00119 && hitEnt->s.apos.trType != TR_STATIONARY//rotating
00120 && (hitEnt->spawnflags&16) //IMPACT
00121 && Q_stricmp( "func_rotating", hitEnt->classname ) == 0 )
00122 {//hit a func_rotating that is supposed to destroy anything it touches!
00123 //guarantee the hit will happen, thereby taking off a piece of the ship
00124 forceSurfDestruction = qtrue;
00125 }
00126 else if ( (fabs(pm->ps->velocity[0])+fabs(pm->ps->velocity[1])) < 100.0f
00127 && pm->ps->velocity[2] > -100.0f )
00128 #else
00129 if ( (fabs(pm->ps->velocity[0])+fabs(pm->ps->velocity[1])) < 100.0f
00130 && pm->ps->velocity[2] > -100.0f )
00131 #endif
00132 /*
00133 if ( (pSelfVeh->m_ulFlags&VEH_GEARSOPEN)
00134 && trace->plane.normal[2] > 0.7f
00135 && fabs(pSelfVeh->m_vOrientation[PITCH]) < 0.2f
00136 && fabs(pSelfVeh->m_vOrientation[ROLL]) < 0.2f )*/
00137 {//we're landing, we're cool
00138 //FIXME: some sort of landing "thump", not the impactFX
00139 /*
00140 if ( pSelfVeh->m_pVehicleInfo->iImpactFX )
00141 {
00142 vec3_t up = {0,0,1};
00143 #ifdef QAGAME
00144 G_PlayEffectID( pSelfVeh->m_pVehicleInfo->iImpactFX, pm->ps->origin, up );
00145 #else
00146 trap_FX_PlayEffectID( pSelfVeh->m_pVehicleInfo->iImpactFX, pm->ps->origin, up, -1, -1 );
00147 #endif
00148 }
00149 */
00150 //this was annoying me -rww
00151 //FIXME: this shouldn't even be getting called when the vehicle is at rest!
00152 #ifdef QAGAME
00153 if (hitEnt && (hitEnt->s.eType == ET_PLAYER || hitEnt->s.eType == ET_NPC) && pSelfVeh->m_pVehicleInfo->type == VH_FIGHTER)
00154 { //always smack players
00155 }
00156 else
00157 #endif
00158 {
00159 return;
00160 }
00161 }
00162 if ( pSelfVeh &&
00163 (pSelfVeh->m_pVehicleInfo->type == VH_SPEEDER || pSelfVeh->m_pVehicleInfo->type == VH_FIGHTER) && //this is kind of weird on tauntauns and atst's..
00164 (magnitude >= 100||forceSurfDestruction) )
00165 {
00166 if ( pEnt->m_pVehicle->m_iHitDebounce < pm->cmd.serverTime
00167 || forceSurfDestruction )
00168 {//a bit of a hack, may conflict with getting shot, but...
00169 //FIXME: impact sound and effect should be gotten from g_vehicleInfo...?
00170 //FIXME: should pass in trace.endpos and trace.plane.normal
00171 vec3_t vehUp;
00172 #ifndef QAGAME
00173 bgEntity_t *hitEnt;
00174 #endif
00175
00176 if ( trace && !pSelfVeh->m_iRemovedSurfaces && !forceSurfDestruction )
00177 {
00178 qboolean turnFromImpact = qfalse, turnHitEnt = qfalse;
00179 float l = pm->ps->speed*0.5f;
00180 vec3_t bounceDir;
00181 #ifndef QAGAME
00182 bgEntity_t *hitEnt = PM_BGEntForNum(trace->entityNum);
00183 #endif
00184 if ( (trace->entityNum == ENTITYNUM_WORLD || hitEnt->s.solid == SOLID_BMODEL)//bounce off any brush
00185 && !VectorCompare(trace->plane.normal, vec3_origin) )//have a valid plane to bounce off of
00186 { //bounce off in the opposite direction of the impact
00187 if (pSelfVeh->m_pVehicleInfo->type == VH_SPEEDER)
00188 {
00189 pm->ps->speed *= pml.frametime;
00190 VectorCopy(trace->plane.normal, bounceDir);
00191 }
00192 else if ( trace->plane.normal[2] >= MIN_LANDING_SLOPE//flat enough to land on
00193 && pSelfVeh->m_LandTrace.fraction < 1.0f //ground present
00194 && pm->ps->speed <= MIN_LANDING_SPEED )
00195 {//could land here, don't bounce off, in fact, return altogether!
00196 return;
00197 }
00198 else
00199 {
00200 if (pSelfVeh->m_pVehicleInfo->type == VH_FIGHTER)
00201 {
00202 turnFromImpact = qtrue;
00203 }
00204 VectorCopy(trace->plane.normal, bounceDir);
00205 }
00206 }
00207 else if ( pSelfVeh->m_pVehicleInfo->type == VH_FIGHTER )
00208 {//check for impact with another fighter
00209 #ifndef QAGAME
00210 bgEntity_t *hitEnt = PM_BGEntForNum(trace->entityNum);
00211 #endif
00212 if ( hitEnt->s.NPC_class == CLASS_VEHICLE
00213 && hitEnt->m_pVehicle
00214 && hitEnt->m_pVehicle->m_pVehicleInfo
00215 && hitEnt->m_pVehicle->m_pVehicleInfo->type == VH_FIGHTER )
00216 {//two vehicles hit each other, turn away from the impact
00217 turnFromImpact = qtrue;
00218 turnHitEnt = qtrue;
00219 #ifndef QAGAME
00220 VectorSubtract( pm->ps->origin, hitEnt->s.origin, bounceDir );
00221 #else
00222 VectorSubtract( pm->ps->origin, hitEnt->r.currentOrigin, bounceDir );
00223 #endif
00224 VectorNormalize( bounceDir );
00225 }
00226 }
00227 if ( turnFromImpact )
00228 {//bounce off impact surf and turn away
00229 vec3_t pushDir={0}, turnAwayAngles, turnDelta;
00230 float turnStrength, pitchTurnStrength, yawTurnStrength;
00231 vec3_t moveDir;
00232 float bounceDot, turnDivider;
00233 //bounce
00234 if ( !turnHitEnt )
00235 {//hit wall
00236 VectorScale(bounceDir, (pm->ps->speed*0.25f/pSelfVeh->m_pVehicleInfo->mass), pushDir);
00237 }
00238 else
00239 {//hit another fighter
00240 #ifndef QAGAME
00241 VectorScale( bounceDir, (pm->ps->speed+hitEnt->s.speed)*0.5f, bounceDir );
00242 #else
00243 if ( hitEnt->client )
00244 {
00245 VectorScale( bounceDir, (pm->ps->speed+hitEnt->client->ps.speed)*0.5f, pushDir );
00246 }
00247 else
00248 {
00249 VectorScale( bounceDir, (pm->ps->speed+hitEnt->s.speed)*0.5f, pushDir );
00250 }
00251 #endif
00252 VectorScale(pushDir, (l/pSelfVeh->m_pVehicleInfo->mass), pushDir);
00253 VectorScale(pushDir, 0.1f, pushDir);
00254 }
00255 VectorNormalize2( pm->ps->velocity, moveDir );
00256 bounceDot = DotProduct( moveDir, bounceDir )*-1;
00257 if ( bounceDot < 0.1f )
00258 {
00259 bounceDot = 0.1f;
00260 }
00261 VectorScale( pushDir, bounceDot, pushDir );
00262 VectorAdd(pm->ps->velocity, pushDir, pm->ps->velocity);
00263 //turn
00264 turnDivider = (pSelfVeh->m_pVehicleInfo->mass/400.0f);
00265 if ( turnHitEnt )
00266 {//don't turn as much when hit another ship
00267 turnDivider *= 4.0f;
00268 }
00269 if ( turnDivider < 0.5f )
00270 {
00271 turnDivider = 0.5f;
00272 }
00273 turnStrength = (magnitude/2000.0f);
00274 if ( turnStrength < 0.1f )
00275 {
00276 turnStrength = 0.1f;
00277 }
00278 else if ( turnStrength > 2.0f )
00279 {
00280 turnStrength = 2.0f;
00281 }
00282 //get the angles we are going to turn towards
00283 vectoangles( bounceDir, turnAwayAngles );
00284 //get the delta from our current angles to those new angles
00285 AnglesSubtract( turnAwayAngles, pSelfVeh->m_vOrientation, turnDelta );
00286 //now do pitch
00287 if ( !bounceDir[2] )
00288 {//shouldn't be any pitch
00289 }
00290 else
00291 {
00292 pitchTurnStrength = turnStrength*turnDelta[PITCH];
00293 if ( pitchTurnStrength > MAX_IMPACT_TURN_ANGLE )
00294 {
00295 pitchTurnStrength = MAX_IMPACT_TURN_ANGLE;
00296 }
00297 else if ( pitchTurnStrength < -MAX_IMPACT_TURN_ANGLE )
00298 {
00299 pitchTurnStrength = -MAX_IMPACT_TURN_ANGLE;
00300 }
00301 //pSelfVeh->m_vOrientation[PITCH] = AngleNormalize180(pSelfVeh->m_vOrientation[PITCH]+pitchTurnStrength/turnDivider*pSelfVeh->m_fTimeModifier);
00302 pSelfVeh->m_vFullAngleVelocity[PITCH] = AngleNormalize180(pSelfVeh->m_vOrientation[PITCH]+pitchTurnStrength/turnDivider*pSelfVeh->m_fTimeModifier);
00303 }
00304 //now do yaw
00305 if ( !bounceDir[0]
00306 && !bounceDir[1] )
00307 {//shouldn't be any yaw
00308 }
00309 else
00310 {
00311 yawTurnStrength = turnStrength*turnDelta[YAW];
00312 if ( yawTurnStrength > MAX_IMPACT_TURN_ANGLE )
00313 {
00314 yawTurnStrength = MAX_IMPACT_TURN_ANGLE;
00315 }
00316 else if ( yawTurnStrength < -MAX_IMPACT_TURN_ANGLE )
00317 {
00318 yawTurnStrength = -MAX_IMPACT_TURN_ANGLE;
00319 }
00320 //pSelfVeh->m_vOrientation[ROLL] = AngleNormalize180(pSelfVeh->m_vOrientation[ROLL]-yawTurnStrength/turnDivider*pSelfVeh->m_fTimeModifier);
00321 pSelfVeh->m_vFullAngleVelocity[ROLL] = AngleNormalize180(pSelfVeh->m_vOrientation[ROLL]-yawTurnStrength/turnDivider*pSelfVeh->m_fTimeModifier);
00322 }
00323 /*
00324 PM_SetPMViewAngle(pm->ps, pSelfVeh->m_vOrientation, &pSelfVeh->m_ucmd);
00325 if ( pm_entVeh )
00326 {//I'm a vehicle, so pm_entVeh is actually my pilot
00327 bgEntity_t *pilot = pm_entVeh;
00328 if ( !BG_UnrestrainedPitchRoll( pilot->playerState, pSelfVeh ) )
00329 {
00330 //set the rider's viewangles to the vehicle's viewangles
00331 PM_SetPMViewAngle(pilot->playerState, pSelfVeh->m_vOrientation, &pSelfVeh->m_ucmd);
00332 }
00333 }
00334 */
00335 #ifdef QAGAME//server-side, turn the guy we hit away from us, too
00336 if ( turnHitEnt//make the other guy turn and get pushed
00337 && hitEnt->client //must be a valid client
00338 && !FighterIsLanded( hitEnt->m_pVehicle, &hitEnt->client->ps )//but not if landed
00339 && !(hitEnt->spawnflags&2) )//and not if suspended
00340 {
00341 l = hitEnt->client->ps.speed;
00342 //now bounce *them* away and turn them
00343 //flip the bounceDir
00344 VectorScale( bounceDir, -1, bounceDir );
00345 //do bounce
00346 VectorScale( bounceDir, (pm->ps->speed+l)*0.5f, pushDir );
00347 VectorScale(pushDir, (l*0.5f/hitEnt->m_pVehicle->m_pVehicleInfo->mass), pushDir);
00348 VectorNormalize2( hitEnt->client->ps.velocity, moveDir );
00349 bounceDot = DotProduct( moveDir, bounceDir )*-1;
00350 if ( bounceDot < 0.1f )
00351 {
00352 bounceDot = 0.1f;
00353 }
00354 VectorScale( pushDir, bounceDot, pushDir );
00355 VectorAdd(hitEnt->client->ps.velocity, pushDir, hitEnt->client->ps.velocity);
00356 //turn
00357 |