Exemplo n.º 1
0
/*
==============
BotUpdateInput
==============
*/
void BotUpdateInput(bot_state_t *bs, int time, int elapsed_time)
{
    bot_input_t bi;
    int j;

    //add the delta angles to the bot's current view angles
    for (j = 0; j < 3; j++)
    {
        bs->viewangles[j] = AngleMod(bs->viewangles[j] + SHORT2ANGLE(bs->cur_ps.delta_angles[j]));
    }
    //change the bot view angles
    BotChangeViewAngles(bs, (float) elapsed_time / 1000);
    //retrieve the bot input
    botlib_export->ea.EA_GetInput(bs->client, (float) time / 1000, &bi);
    //respawn hack
    if (bi.actionflags & ACTION_RESPAWN)
    {
        if (bs->lastucmd.buttons & BUTTON_ATTACK) bi.actionflags &= ~(ACTION_RESPAWN|ACTION_ATTACK);
    }
    //convert the bot input to a usercmd
    BotInputToUserCommand(&bi, &bs->lastucmd, bs->cur_ps.delta_angles, time);
    //subtract the delta angles
    for (j = 0; j < 3; j++)
    {
        bs->viewangles[j] = AngleMod(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j]));
    }
}
Exemplo n.º 2
0
/*
==============
BotChangeViewAngle
==============
*/
float BotChangeViewAngle( float angle, float ideal_angle, float speed ) {
	float move;

	angle = AngleMod( angle );
	ideal_angle = AngleMod( ideal_angle );
	if ( angle == ideal_angle ) {
		return angle;
	}
	move = ideal_angle - angle;
	if ( ideal_angle > angle ) {
		if ( move > 180.0 ) {
			move -= 360.0;
		}
	} else {
		if ( move < -180.0 ) {
			move += 360.0;
		}
	}
	if ( move > 0 ) {
		if ( move > speed ) {
			move = speed;
		}
	} else {
		if ( move < -speed ) {
			move = -speed;
		}
	}
	return AngleMod( angle + move );
}
Exemplo n.º 3
0
/*
==============
BotUpdateInput
==============
*/
void BotUpdateInput( bot_state_t *bs, int time ) {
	bot_input_t bi;
	int j;

	//add the delta angles to the bot's current view angles
	for ( j = 0; j < 3; j++ ) {
		bs->viewangles[j] = AngleMod( bs->viewangles[j] + SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
	}
	//
	BotChangeViewAngles( bs, (float) time / 1000 );
	trap_EA_GetInput( bs->client, (float) time / 1000, &bi );
	//respawn hack
	if ( bi.actionflags & ACTION_RESPAWN ) {
		if ( bs->lastucmd.buttons & BUTTON_ATTACK ) {
			bi.actionflags &= ~( ACTION_RESPAWN | ACTION_ATTACK );
		}
	}
	//
	BotInputToUserCommand( &bi, &bs->lastucmd, bs->cur_ps.delta_angles, time );
	bs->lastucmd.serverTime = time;
	//subtract the delta angles
	for ( j = 0; j < 3; j++ ) {
		bs->viewangles[j] = AngleMod( bs->viewangles[j] - SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
	}
}
Exemplo n.º 4
0
/*
==============
AICast_InFieldOfVision
==============
*/
qboolean AICast_InFieldOfVision( vec3_t viewangles, float fov, vec3_t angles ) {
	int i;
	float diff, angle;

	for ( i = 0; i < 2; i++ )
	{
		angle = AngleMod( viewangles[i] );
		angles[i] = AngleMod( angles[i] );
		diff = angles[i] - angle;
		if ( angles[i] > angle ) {
			if ( diff > 180.0 ) {
				diff -= 360.0;
			}
		} else
		{
			if ( diff < -180.0 ) {
				diff += 360.0;
			}
		}
		if ( diff > 0 ) {
			if ( diff > fov * 0.5 ) {
				return qfalse;
			}
		} else
		{
			if ( diff < -fov * 0.5 ) {
				return qfalse;
			}
		}
	}
	return qtrue;
}
Exemplo n.º 5
0
/*
==============
BotChangeViewAngles
==============
*/
void BotChangeViewAngles(bot_state_t *bs, float thinktime)
{
    float diff, factor, maxchange, anglespeed, disired_speed;
    int i;

    if (bs->ideal_viewangles[PITCH] > 180) bs->ideal_viewangles[PITCH] -= 360;
    //
    if (bs->enemy >= 0)
    {
        factor = botlib_export->ai.Characteristic_BFloat(bs->character, CHARACTERISTIC_VIEW_FACTOR, 0.01f, 1);
        maxchange = botlib_export->ai.Characteristic_BFloat(bs->character, CHARACTERISTIC_VIEW_MAXCHANGE, 1, 1800);
    }
    else
    {
        factor = 0.05f;
        maxchange = 360;
    }
    if (maxchange < 240) maxchange = 240;
    maxchange *= thinktime;
    for (i = 0; i < 2; i++)
    {
        //
        if (bot_challenge->integer)
        {
            //smooth slowdown view model
            diff = fabs(AngleDifference(bs->viewangles[i], bs->ideal_viewangles[i]));
            anglespeed = diff * factor;
            if (anglespeed > maxchange) anglespeed = maxchange;
            bs->viewangles[i] = BotChangeViewAngle(bs->viewangles[i],
                                                   bs->ideal_viewangles[i], anglespeed);
        }
        else
        {
            //over reaction view model
            bs->viewangles[i] = AngleMod(bs->viewangles[i]);
            bs->ideal_viewangles[i] = AngleMod(bs->ideal_viewangles[i]);
            diff = AngleDifference(bs->viewangles[i], bs->ideal_viewangles[i]);
            disired_speed = diff * factor;
            bs->viewanglespeed[i] += (bs->viewanglespeed[i] - disired_speed);
            if (bs->viewanglespeed[i] > 180) bs->viewanglespeed[i] = maxchange;
            if (bs->viewanglespeed[i] < -180) bs->viewanglespeed[i] = -maxchange;
            anglespeed = bs->viewanglespeed[i];
            if (anglespeed > maxchange) anglespeed = maxchange;
            if (anglespeed < -maxchange) anglespeed = -maxchange;
            bs->viewangles[i] += anglespeed;
            bs->viewangles[i] = AngleMod(bs->viewangles[i]);
            //demping
            bs->viewanglespeed[i] *= 0.45 * (1 - factor);
        }
        //BotAI_Print(PRT_MESSAGE, "ideal_angles %f %f\n", bs->ideal_viewangles[0], bs->ideal_viewangles[1], bs->ideal_viewangles[2]);`
        //bs->viewangles[i] = bs->ideal_viewangles[i];
    }
    //bs->viewangles[PITCH] = 0;
    if (bs->viewangles[PITCH] > 180) bs->viewangles[PITCH] -= 360;
    //elementary action: view
    botlib_export->ea.EA_View(bs->client, bs->viewangles);
}
Exemplo n.º 6
0
/*
==================
UI_SwingAngles
==================
*/
static void UI_SwingAngles( float destination, float swingTolerance, float clampTolerance,
                            float speed, float *angle, qbool *swinging ) {
    float	swing;
    float	move;
    float	scale;

    if ( !*swinging ) {
        // see if a swing should be started
        swing = AngleSubtract( *angle, destination );
        if ( swing > swingTolerance || swing < -swingTolerance ) {
            *swinging = qtrue;
        }
    }

    if ( !*swinging ) {
        return;
    }

    // modify the speed depending on the delta
    // so it doesn't seem so linear
    swing = AngleSubtract( destination, *angle );
    scale = fabs( swing );
    if ( scale < swingTolerance * 0.5 ) {
        scale = 0.5;
    } else if ( scale < swingTolerance ) {
        scale = 1.0;
    } else {
        scale = 2.0;
    }

    // swing towards the destination angle
    if ( swing >= 0 ) {
        move = uiInfo.uiDC.frameTime * scale * speed;
        if ( move >= swing ) {
            move = swing;
            *swinging = qfalse;
        }
        *angle = AngleMod( *angle + move );
    } else if ( swing < 0 ) {
        move = uiInfo.uiDC.frameTime * scale * -speed;
        if ( move <= swing ) {
            move = swing;
            *swinging = qfalse;
        }
        *angle = AngleMod( *angle + move );
    }

    // clamp to no more than tolerance
    swing = AngleSubtract( destination, *angle );
    if ( swing > clampTolerance ) {
        *angle = AngleMod( destination - (clampTolerance - 1) );
    } else if ( swing < -clampTolerance ) {
        *angle = AngleMod( destination + (clampTolerance - 1) );
    }
}
void ME_RotateSelection( int delta )
{
	IGME_vehicle_t* veh;
	sbox3_t			box;
	bool		boxinit = false;
	vec3_t			mins = { -1, -1, -1 },
					maxs = { 1, 1, 1 };
	vec3_t			center;
	vec3_t			dir, angles;
	int				i;
	float			dist;

	for( i = 0; i < IGME_MAX_VEHICLES; ++i ) {
		veh = &cgs.IGME.vehicles[i];
		if( !veh->selected ) continue;
		if( !boxinit ) {
			VectorAdd( veh->origin, mins, box.mins );
			VectorAdd( veh->origin, maxs, box.maxs );
			boxinit = true;
		} else {
			AddToBox( &box, veh->origin );		
		}
	}	
	BoxCenter( &box, &center );	

	for( i = 0; i < IGME_MAX_VEHICLES; ++i ) {
		veh = &cgs.IGME.vehicles[i];
		if( !veh->selected ) continue;
		// get direction vector and dist
		VectorSubtract( veh->origin, center, dir );
		dist = VectorNormalize(dir);
		vectoangles( dir, angles );
		// rotate
		veh->angles[1] += delta;
		AngleMod( veh->angles[1] );
		angles[1] += delta;
		AngleMod( angles[1] );
		// move object
		AngleVectors(angles, dir, 0, 0);
		VectorScale(dir, dist, dir);
		VectorAdd(center, dir, veh->origin);
	}

//			if( rotate ) {
//				veh->angles[1] -= x;
//				AngleMod( veh->angles[1] );
//			}

}
Exemplo n.º 8
0
void CRayEffectPainter::PaintHit (CG16bitImage &Dest, int x, int y, const CVector &vHitPos, SViewportPaintCtx &Ctx)

//	PaintHit
//
//	Paint the effect when hit

	{
	//	Make sure we've computed all our temporaries

	CalcIntermediates();

	//	Compute the two end points of the line. We paint from the head to the tail.

	int iLength = (Ctx.iMaxLength != -1 ? Min(Ctx.iMaxLength, m_iLength) : m_iLength);
	CVector vFrom = PolarToVector(AngleMod(Ctx.iRotation + m_iXformRotation), -iLength);
	int xTo = x + (int)(vFrom.GetX() + 0.5);
	int yTo = y - (int)(vFrom.GetY() + 0.5);

	int xFrom;
	int yFrom;
	Ctx.XFormRel.Transform(vHitPos, &xFrom, &yFrom);

	//	Paint the ray

	PaintRay(Dest, xFrom, yFrom, xTo, yTo, Ctx);
	}
Exemplo n.º 9
0
void CRayEffectPainter::Paint (CG16bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx)

//	Paint
//
//	Paint the effect

	{
	DEBUG_TRY

	//	Make sure we've computed all our temporaries

	CalcIntermediates();

	//	Compute the two end points of the line. We paint from the head to the tail.

	int iLength = (Ctx.iMaxLength != -1 ? Min(Ctx.iMaxLength, m_iLength) : m_iLength);
	CVector vFrom = PolarToVector(AngleMod(Ctx.iRotation + m_iXformRotation), -iLength);
	int xTo = x + (int)(vFrom.GetX() + 0.5);
	int yTo = y - (int)(vFrom.GetY() + 0.5);
	int xFrom = x;
	int yFrom = y;

	//	Paint the ray

	PaintRay(Dest, xFrom, yFrom, xTo, yTo, Ctx);

	DEBUG_CATCH
	}
Exemplo n.º 10
0
/*
======================
UI_MachinegunSpinAngle
======================
*/
float	UI_MachinegunSpinAngle( playerInfo_t *pi ) {
    int		delta;
    float	angle;
    float	speed;
    int		torsoAnim;

    delta = dp_realtime - pi->barrelTime;
    if ( pi->barrelSpinning ) {
        angle = pi->barrelAngle + delta * SPIN_SPEED;
    } else {
        if ( delta > COAST_TIME ) {
            delta = COAST_TIME;
        }

        speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME );
        angle = pi->barrelAngle + delta * speed;
    }

    torsoAnim = pi->torsoAnim  & ~ANIM_TOGGLEBIT;
    if( torsoAnim == TORSO_RIFLE_ATTACK ) {
        torsoAnim = TORSO_PISTOL_ATTACK;
    }
    if ( pi->barrelSpinning == !(torsoAnim == TORSO_PISTOL_ATTACK) ) {
        pi->barrelTime = dp_realtime;
        pi->barrelAngle = AngleMod( angle );
        pi->barrelSpinning = !!(torsoAnim == TORSO_PISTOL_ATTACK);
    }

    return angle;
}
Exemplo n.º 11
0
static float CG_MachinegunSpinAngle( centity_t *cent, qboolean firing )
{
  int   delta;
  float angle;
  float speed;

  delta = cg.time - cent->pe.barrelTime;
  if( cent->pe.barrelSpinning )
    angle = cent->pe.barrelAngle + delta * SPIN_SPEED;
  else
  {
    if( delta > COAST_TIME )
      delta = COAST_TIME;

    speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME );
    angle = cent->pe.barrelAngle + delta * speed;
  }

  if( cent->pe.barrelSpinning == !firing )
  {
    cent->pe.barrelTime = cg.time;
    cent->pe.barrelAngle = AngleMod( angle );
    cent->pe.barrelSpinning = firing;
  }

  return angle;
}
Exemplo n.º 12
0
/*
======================
UI_MachinegunSpinAngle
======================
*/
float	UI_MachinegunSpinAngle( uiPlayerInfo_t *pi ) {
	int		delta;
	float	angle;
	float	speed;
	int		torsoAnim;

	delta = dp_realtime - pi->barrelTime;
	if ( pi->barrelSpinning ) {
		angle = pi->barrelAngle + delta * SPIN_SPEED;
	} else {
		if ( delta > COAST_TIME ) {
			delta = COAST_TIME;
		}

		speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME );
		angle = pi->barrelAngle + delta * speed;
	}

	torsoAnim = pi->torsoAnim  & ~ANIM_TOGGLEBIT;
#ifdef TA_WEAPSYS
	if (BG_PlayerAttackAnim(torsoAnim))
#else
	if( torsoAnim == TORSO_ATTACK2 )
#endif
	{
		torsoAnim = TORSO_ATTACK;
	}
	if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) {
		pi->barrelTime = dp_realtime;
		pi->barrelAngle = AngleMod( angle );
		pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK);
	}

	return angle;
}
Exemplo n.º 13
0
/*
===============
UI_PlayerAngles
===============
*/
static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[ 3 ], vec3_t torso[ 3 ], vec3_t head[ 3 ] )
{
	vec3_t legsAngles, torsoAngles, headAngles;
	float  dest;
	float  adjust;

	VectorCopy( pi->viewAngles, headAngles );
	headAngles[ YAW ] = AngleMod( headAngles[ YAW ] );
	VectorClear( legsAngles );
	VectorClear( torsoAngles );

	// --------- yaw -------------

	// allow yaw to drift a bit
	if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE || ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND )
	{
		// if not standing still, always point all in the same direction
		pi->torso.yawing = qtrue; // always center
		pi->torso.pitching = qtrue; // always center
		pi->legs.yawing = qtrue; // always center
	}

	// adjust legs for movement dir
	adjust = UI_MovedirAdjustment( pi );
	legsAngles[ YAW ] = headAngles[ YAW ] + adjust;
	torsoAngles[ YAW ] = headAngles[ YAW ] + 0.25 * adjust;

	// torso
	UI_SwingAngles( torsoAngles[ YAW ], 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing );
	UI_SwingAngles( legsAngles[ YAW ], 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing );

	torsoAngles[ YAW ] = pi->torso.yawAngle;
	legsAngles[ YAW ] = pi->legs.yawAngle;

	// --------- pitch -------------

	// only show a fraction of the pitch angle in the torso
	if ( headAngles[ PITCH ] > 180 )
	{
		dest = ( -360 + headAngles[ PITCH ] ) * 0.75;
	}
	else
	{
		dest = headAngles[ PITCH ] * 0.75;
	}

	UI_SwingAngles( dest, 15, 30, 0.1, &pi->torso.pitchAngle, &pi->torso.pitching );
	torsoAngles[ PITCH ] = pi->torso.pitchAngle;

	// pull the angles back out of the hierarchial chain
	AnglesSubtract( headAngles, torsoAngles, headAngles );
	AnglesSubtract( torsoAngles, legsAngles, torsoAngles );

	AnglesSubtract( legsAngles, pi->moveAngles, legsAngles );  // NERVE - SMF

	AnglesToAxis( legsAngles, legs );
	AnglesToAxis( torsoAngles, torso );
	AnglesToAxis( headAngles, head );
}
Exemplo n.º 14
0
CVector CDockingPorts::GetPortPos (CSpaceObject *pOwner, const SDockingPort &Port, CSpaceObject *pShip, bool *retbPaintInFront, int *retiRotation) const

//	GetPortPos
//
//	Get the absolute position of the port (or relative, if pOwner == NULL)

	{
	if (pOwner == NULL)
		{
		if (retbPaintInFront)
			*retbPaintInFront = (Port.iLayer != plSendToBack);

		if (retiRotation)
			*retiRotation = Port.iRotation;

		return Port.vPos;
		}
	else if (pOwner->GetRotation() == 0)
		{
		const CVector &vOwnerPos = pOwner->GetPos();
		if (retbPaintInFront)
			{
			switch (Port.iLayer)
				{
				case plBringToFront:
					*retbPaintInFront = true;
					break;

				case plSendToBack:
					*retbPaintInFront = false;
					break;

				default:
					*retbPaintInFront = (Port.vPos.GetY() < 0.0);
				}
			}

		if (retiRotation)
			*retiRotation = Port.iRotation;

		return (vOwnerPos + Port.vPos + (pShip ? pShip->GetDockingPortOffset(Port.iRotation) : NullVector));
		}
	else
		{
		const CVector &vOwnerPos = pOwner->GetPos();
		CVector vPortPos = Port.vPos.Rotate(pOwner->GetRotation());
		int iNewRotation = AngleMod(Port.iRotation + pOwner->GetRotation());

		if (retbPaintInFront)
			*retbPaintInFront = (vPortPos.GetY() < 0.0);

		if (retiRotation)
			*retiRotation = iNewRotation;

		return (vOwnerPos + vPortPos + (pShip ? pShip->GetDockingPortOffset(iNewRotation) : NullVector));
		}
	}
Exemplo n.º 15
0
int CIntegralRotationDesc::GetFrameIndex (int iAngle) const

//	GetFrameIndex
//
//	Returns the frame index, 0 to m_iCount-1, that corresponds to the given 
//	angle. Remember that frame 0 points straight up and frames rotate clockwise.

	{
	Metric rIndex = AngleMod(90 - iAngle) * m_iCount / 360.0;
	return (int)rIndex;
	}
Exemplo n.º 16
0
static void UI_PlayerAngles( playerInfo_t *pi, matrix3 legs, matrix3 torso, matrix3 head ) {
	vector3		legsAngles, torsoAngles, headAngles;
	float		dest;
	float		adjust;

	VectorCopy( &pi->viewAngles, &headAngles );
	headAngles.yaw = AngleMod( headAngles.yaw );
	VectorClear( &legsAngles );
	VectorClear( &torsoAngles );

	// --------- yaw -------------

	// allow yaw to drift a bit
	if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE 
		|| ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND  ) {
		// if not standing still, always point all in the same direction
		pi->torso.yawing = qtrue;	// always center
		pi->torso.pitching = qtrue;	// always center
		pi->legs.yawing = qtrue;	// always center
	}

	// adjust legs for movement dir
	adjust = UI_MovedirAdjustment( pi );
	legsAngles.yaw = headAngles.yaw + adjust;
	torsoAngles.yaw = headAngles.yaw + 0.25f * adjust;


	// torso
	UI_SwingAngles( torsoAngles.yaw, 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing );
	UI_SwingAngles( legsAngles.yaw, 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing );

	torsoAngles.yaw = pi->torso.yawAngle;
	legsAngles.yaw = pi->legs.yawAngle;

	// --------- pitch -------------

	// only show a fraction of the pitch angle in the torso
	if ( headAngles.pitch > 180 ) {
		dest = (-360 + headAngles.pitch) * 0.75f;
	} else {
		dest = headAngles.pitch * 0.75f;
	}
	UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching );
	torsoAngles.pitch = pi->torso.pitchAngle;

	// pull the angles back out of the hierarchial chain
	AnglesSubtract( &headAngles, &torsoAngles, &headAngles );
	AnglesSubtract( &torsoAngles, &legsAngles, &torsoAngles );
	AnglesToAxis( &legsAngles, legs );
	AnglesToAxis( &torsoAngles, torso );
	AnglesToAxis( &headAngles, head );
}
Exemplo n.º 17
0
/*
==============
BotChangeViewAngles
==============
*/
void BotChangeViewAngles(bot_state_t *bs, float thinktime) {
	float diff, factor, maxchange, anglespeed, disired_speed;
	int i;

	if (bs->ideal_viewangles[PITCH] > 180) bs->ideal_viewangles[PITCH] -= 360;
	
	factor = bs->skills.turnspeed;

	if (factor > 1)
	{
		factor = 1;
	}
	if (factor < 0.25)
	{
		factor = 0.25f;
	}
	maxchange = bs->skills.maxturn;

	//if (maxchange < 240) maxchange = 240;
	maxchange *= thinktime;
	for (i = 0; i < 2; i++) {
		bs->viewangles[i] = AngleMod(bs->viewangles[i]);
		bs->ideal_viewangles[i] = AngleMod(bs->ideal_viewangles[i]);
		diff = AngleDifference(bs->viewangles[i], bs->ideal_viewangles[i]);
		disired_speed = diff * factor;
		bs->viewanglespeed[i] += (bs->viewanglespeed[i] - disired_speed);
		if (bs->viewanglespeed[i] > 180) bs->viewanglespeed[i] = maxchange;
		if (bs->viewanglespeed[i] < -180) bs->viewanglespeed[i] = -maxchange;
		anglespeed = bs->viewanglespeed[i];
		if (anglespeed > maxchange) anglespeed = maxchange;
		if (anglespeed < -maxchange) anglespeed = -maxchange;
		bs->viewangles[i] += anglespeed;
		bs->viewangles[i] = AngleMod(bs->viewangles[i]);
		bs->viewanglespeed[i] *= 0.45 * (1 - factor);
	}
	if (bs->viewangles[PITCH] > 180) bs->viewangles[PITCH] -= 360;
	trap_EA_View(bs->client, bs->viewangles);
}
Exemplo n.º 18
0
/*
===================
PM_HeloAccelerate

===================
*/
static void PM_HeloAccelerate()
{
    float	throttle = pm->ps->fixed_throttle;
    int		maxthrottle = availableVehicles[pm->vehicle].maxthrottle;
//	int		minthrottle = availableVehicles[pm->vehicle].minthrottle;
	float	maxforwardspeed = availableVehicles[pm->vehicle].maxspeed;
	float	maxrightspeed = availableVehicles[pm->vehicle].turnspeed[YAW];
	float	maxliftspeed = maxforwardspeed*0.00525;
	float	maxspeed = sqrt(maxforwardspeed*maxforwardspeed + 
							maxrightspeed*maxrightspeed + 
							maxliftspeed*maxliftspeed);
	float	stallspeed = static_cast<float>(availableVehicles[pm->vehicle].stallspeed);
	float	curforwardspeed;
	float	curliftspeed;
	float	curliftspeedadjust;
	float	currightspeed;
	float	curspeed;
	float	curspeedadjust;
	float	totalthrottle;
	vec3_t	vehdir;
	
	// Copy Vehicle Direction
	VectorCopy( pm->ps->vehicleAngles, vehdir );
	vehdir[YAW] = AngleMod( vehdir[YAW] );

	curforwardspeed = (vehdir[PITCH]/MAX_HELO_PITCH)*availableVehicles[pm->vehicle].maxspeed;
	currightspeed = (vehdir[ROLL]/MAX_HELO_ROLL)*availableVehicles[pm->vehicle].turnspeed[YAW];
	curliftspeed = throttle > maxthrottle ? -(throttle-maxthrottle)*20 : throttle * 25;	// real vert speed	
	curliftspeedadjust = throttle > maxthrottle ? 0 : throttle * 25;					// adjusted vert speed, don't want down movement to effect fuel usage "more"
	curspeed = sqrt(curforwardspeed*curforwardspeed + currightspeed*currightspeed + curliftspeed*curliftspeed);						// real total speed
	curspeedadjust = sqrt(curforwardspeed*curforwardspeed + currightspeed*currightspeed + curliftspeedadjust*curliftspeedadjust);	// adjusted total speed, dont want down movement to effect throttle more
	totalthrottle = (curspeedadjust/maxspeed)*10;

	// check for fuel 
	if( pm->ps->stats[STAT_FUEL] <= 0 ) { 
		pm->ps->throttle = 0;
	}

	if( (pm->ps->ONOFF & OO_LANDED) && curspeed > stallspeed * 1.5f ) 
		curspeed = stallspeed *1.5f;

    pm->ps->speed = curspeed*10;

	pm->ps->throttle = throttle;

	// fuel flow
	PM_Helo_FuelFlow( totalthrottle );

}
Exemplo n.º 19
0
static float	CG_MachinegunSpinAngle( centity_t *cent ) {
	float angle, speed, delta = (cg.time - cent->pe.barrelTime) + cg.timeFraction;
	if ( cent->pe.barrelSpinning ) {
		angle = cent->pe.barrelAngle + delta * SPIN_SPEED;
	} else {
		if ( delta > COAST_TIME ) {
			delta = COAST_TIME;
		}
		speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME );
		angle = cent->pe.barrelAngle + delta * speed;
	}
	if ( cent->pe.barrelSpinning == !(cent->currentState.eFlags & EF_FIRING) ) {
		cent->pe.barrelTime = cg.time;
		cent->pe.barrelAngle = AngleMod( angle );
		cent->pe.barrelSpinning = !!(cent->currentState.eFlags & EF_FIRING);
	}
	return angle;
}
Exemplo n.º 20
0
void CIntegralRotationDesc::InitRotationCount (int iCount)

//	InitRotationCount
//
//	Initialize count

	{
	int i;

	//	If we're in backwards compatibility mode and if we've got a different
	//	count, then we need to recompute our degrees per tick.

	if (m_iManeuverability && iCount != m_iCount && iCount > 0)
		{
		m_rDegreesPerTick = (STD_SECONDS_PER_UPDATE * 360.0) / (iCount * m_iManeuverability);
		m_rAccelPerTick = m_rDegreesPerTick;
		m_rAccelPerTickStop = m_rDegreesPerTick;
		}

	//	Initialize count

	m_iCount = iCount;
	m_Rotations.DeleteAll();

	if (m_iCount > 0)
		{
		m_iMaxRotationRate = Max(1, mathRound(ROTATION_FRACTION * m_rDegreesPerTick * m_iCount / 360.0));
		m_iRotationAccel = Max(1, mathRound(ROTATION_FRACTION * m_rAccelPerTick * m_iCount / 360.0));
		m_iRotationAccelStop = Max(1, mathRound(ROTATION_FRACTION * m_rAccelPerTickStop * m_iCount / 360.0));

		Metric rFrameAngle = 360.0 / m_iCount;
		m_Rotations.InsertEmpty(m_iCount);
		for (i = 0; i < m_iCount; i++)
			m_Rotations[i].iRotation = AngleMod(mathRound(90.0 - i * rFrameAngle));
		}
	else
		{
		m_iMaxRotationRate = 0;
		m_iRotationAccel = 0;
		}
	}
Exemplo n.º 21
0
static float RankAngle (float a)
{
	vec3_t wishdir;
	float  delta;
	vec3_t ang1, ang2;
	vec3_t newvel;

	wishdir[0] = cos(a / 180 * M_PI);
	wishdir[1] = sin(a / 180 * M_PI);
	wishdir[2] = 0;

	VectorCopy (ra_curvel, newvel);
	Friction (newvel);
	Accelerate (wishdir, movevars.maxspeed, newvel);

	vectoangles (newvel, ang1);
	vectoangles (ra_intentions, ang2);

	delta = AngleMod(ang2[YAW] - ang1[YAW]);

	return -fabs(delta);
}
Exemplo n.º 22
0
/*
==============
BotAI
==============
*/
int BotAI(int playernum, float thinktime) {
	bot_state_t *bs;
	char buf[1024], *args;
	int j;

	EA_ResetInput(playernum);
	//
	bs = botstates[playernum];
	if (!bs || !bs->inuse) {
		BotAI_Print(PRT_FATAL, "BotAI: player %d is not setup\n", playernum);
		return qfalse;
	}

	//retrieve the current player state
	if (!BotAI_GetPlayerState( playernum, &bs->cur_ps )) {
		BotAI_Print(PRT_FATAL, "BotAI: failed to get player state for player %d\n", playernum);
		return qfalse;
	}

	//retrieve any waiting server commands
	while( trap_BotGetServerCommand(playernum, buf, sizeof(buf)) ) {
		//have buf point to the command and args to the command arguments
		args = strchr( buf, ' ');
		if (!args) continue;
		*args++ = '\0';

		//remove color espace sequences from the arguments
		RemoveColorEscapeSequences( args );

		if (!Q_stricmp(buf, "cp "))
			{ /*CenterPrintf*/ }
		else if (!Q_stricmp(buf, "cs"))
			{ /*ConfigStringModified*/ }
		else if (!Q_stricmp(buf, "print")) {
			//remove first and last quote from the chat message
			memmove(args, args+1, strlen(args));
			args[strlen(args)-1] = '\0';
			BotQueueConsoleMessage(bs->cs, CMS_NORMAL, args);
		}
		else if (!Q_stricmp(buf, "chat") || !Q_stricmp(buf, "tell")) {
			//remove first and last quote from the chat message
			memmove(args, args+1, strlen(args));
			args[strlen(args)-1] = '\0';
			BotQueueConsoleMessage(bs->cs, CMS_CHAT, args);
		}
		else if (!Q_stricmp(buf, "tchat")) {
			//remove first and last quote from the chat message
			memmove(args, args+1, strlen(args));
			args[strlen(args)-1] = '\0';
			BotQueueConsoleMessage(bs->cs, CMS_CHAT, args);
		}
#ifdef MISSIONPACK
		else if (!Q_stricmp(buf, "vchat")) {
			BotVoiceChatCommand(bs, SAY_ALL, args);
		}
		else if (!Q_stricmp(buf, "vtchat")) {
			BotVoiceChatCommand(bs, SAY_TEAM, args);
		}
		else if (!Q_stricmp(buf, "vtell")) {
			BotVoiceChatCommand(bs, SAY_TELL, args);
		}
#endif
		else if (!Q_stricmp(buf, "scores"))
			{ /*FIXME: parse scores?*/ }
		else if (!Q_stricmp(buf, "clientLevelShot"))
			{ /*ignore*/ }
	}
	//add the delta angles to the bot's current view angles
	for (j = 0; j < 3; j++) {
		bs->viewangles[j] = AngleMod(bs->viewangles[j] + SHORT2ANGLE(bs->cur_ps.delta_angles[j]));
	}
	//increase the local time of the bot
	bs->ltime += thinktime;
	//
	bs->thinktime = thinktime;
	//origin of the bot
	VectorCopy(bs->cur_ps.origin, bs->origin);
	//eye coordinates of the bot
	VectorCopy(bs->cur_ps.origin, bs->eye);
	bs->eye[2] += bs->cur_ps.viewheight;
	//get the area the bot is in
	bs->areanum = BotPointAreaNum(bs->origin);
	//the real AI
	BotDeathmatchAI(bs, thinktime);
	//set the weapon selection every AI frame
	EA_SelectWeapon(bs->playernum, bs->weaponnum);
	//subtract the delta angles
	for (j = 0; j < 3; j++) {
		bs->viewangles[j] = AngleMod(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j]));
	}
	//everything was ok
	return qtrue;
}
Exemplo n.º 23
0
void PM_BoatMove( void ) 
{
    vec3_t		viewdir;
    vec3_t		vehdir;
	vec3_t		turretdir;
    vec3_t		diff;
    vec3_t		turnspeed;
	vec3_t		forward, up;
	vec3_t		temp;
    bool	dead = (pm->ps->stats[STAT_HEALTH] <= 0);
	int			i;
	float		smove = pm->cmd.rightmove;
	float		turret_yaw = pm->ps->turretAngle;
	float		gun_pitch = pm->ps->gunAngle;
	float		speed;
	bool	reverse = false;
	float		lean = 0;

	// set speed
	PM_BoatAccelerate();

	// speed
	speed = (float)pm->ps->speed/10;
	VectorCopy( pm->ps->vehicleAngles, vehdir );
	vehdir[0] = 0;
	if( pm->ps->ONOFF & OO_STALLED ) {
		AngleVectors( vehdir, forward, NULL, NULL );
		VectorNegate( forward, forward );
		reverse = true;
	} else {
		AngleVectors( vehdir, forward, NULL, NULL );
	}
	VectorNormalize( pm->ps->velocity );
	VectorAdd( forward, pm->ps->velocity, forward );
	VectorScale( forward, speed, pm->ps->velocity );

	PM_SlideMove_Boat();

	// get the turnspeeds
	for( i = HULL_YAW; i <= GUN_PITCH; i++ ) {
	    turnspeed[i] = availableVehicles[pm->vehicle].turnspeed[i] * pml.frametime;
	}

	// set the hull angle dependent on speed
	if( !reverse ) {
		pm->ps->vehicleAngles[0] = (speed/(float)availableVehicles[pm->vehicle].maxspeed) *
				availableVehicles[pm->vehicle].tailangle;
		if( smove > 0 ) {
			lean = (speed/(float)availableVehicles[pm->vehicle].maxspeed) *
				availableVehicles[pm->vehicle].gearheight;
		} else if( smove < 0 ) {
			lean = -(speed/(float)availableVehicles[pm->vehicle].maxspeed) *
				availableVehicles[pm->vehicle].gearheight;
		}

	}
	if( pm->ps->vehicleAngles[2] != lean ) {
		diff[2] = lean - pm->ps->vehicleAngles[2];
		if( diff[2] < -turnspeed[2] ) {
			pm->ps->vehicleAngles[2] -= turnspeed[2];
		} else if( diff[2] > turnspeed[2] ) {
			pm->ps->vehicleAngles[2] += turnspeed[2];
		} else {
			pm->ps->vehicleAngles[2] += diff[2];
		}			
	}

	// get the actual turret angles
	AngleVectors( pm->ps->vehicleAngles, forward, 0, up );
	RotatePointAroundVector( temp, up, forward, turret_yaw );
	vectoangles( temp, turretdir );
	turretdir[PITCH] += gun_pitch;

//	Com_Printf( "vehd = %.1f %.1f %.1f (%.1f %.1f)\n", pm->ps->vehicleAngles[0], pm->ps->vehicleAngles[1],
//			pm->ps->vehicleAngles[2], turret_yaw, gun_pitch );
//	Com_Printf( "view = %.1f %.1f %.1f\n", pm->ps->viewangles[0], pm->ps->viewangles[1],
//			pm->ps->viewangles[2] );
//	Com_Printf( "turr = %.1f %.1f %.1f\n", turretdir[0], turretdir[1], turretdir[2] );

	// local vectors
    VectorCopy( pm->ps->vehicleAngles, vehdir );
	if( (pm->cmd.buttons & BUTTON_FREELOOK) && !dead ) { // freelook
		VectorCopy( turretdir, viewdir );
	}
	else { // normal - turret follows camera
		VectorCopy( pm->ps->viewangles, viewdir );
	}

	// set to 0<=x<=360
	viewdir[YAW] = AngleMod( viewdir[YAW] );
	vehdir[YAW] = AngleMod( vehdir[YAW] );
	turretdir[YAW] = AngleMod( turretdir[YAW] );
	viewdir[PITCH] = AngleMod( viewdir[PITCH] );
	vehdir[PITCH] = AngleMod( vehdir[PITCH] );
	turretdir[PITCH] = AngleMod( turretdir[PITCH] );

	// turn the hull
	if( pm->ps->ONOFF & OO_LANDED ) {
		// create a turning modifier for normal wheeled vehicles
		float topSpeed = availableVehicles[pm->vehicle].maxspeed;

		// maxium turn is allowed at a percentage of the top speed (0.5f behind 50% of top speed)
		float turnModifier = speed/(topSpeed * 0.2f);
		MF_LimitFloat( &turnModifier, 0.0f, 1.0f );

		if( smove > 0 ) {
			vehdir[YAW] -= (turnspeed[HULL_YAW] * turnModifier);
		} else if( smove < 0 ) {
			vehdir[YAW] += (turnspeed[HULL_YAW] * turnModifier);
		}
	}

	if( !(pm->cmd.buttons & BUTTON_FREELOOK) ) {
		float min, max;
		// get the angle difference
		for( i = PITCH; i <= YAW; i++ ) {
			diff[i] = viewdir[i] - turretdir[i];
			if( diff[i] > 180 ) diff[i] -= 360;
			else if( diff[i] < -180 ) diff[i] += 360;
		}	
		// turn the turret
		if( diff[YAW] < -turnspeed[TURRET_YAW] ) turret_yaw -= turnspeed[TURRET_YAW];
		else if( diff[YAW] > turnspeed[TURRET_YAW] ) turret_yaw += turnspeed[TURRET_YAW];
		else turret_yaw += diff[YAW];
		if( turret_yaw > 180 ) turret_yaw -= 360;// limit to +- 180
		min = availableWeapons[pm->ps->weaponIndex].minturns[1];
		max = availableWeapons[pm->ps->weaponIndex].maxturns[1];
		if( max > min ) {
			if( turret_yaw > max ) turret_yaw = max;
			else if( turret_yaw < min ) turret_yaw = min;
		} else {
			if( turret_yaw > 0 && turret_yaw < min ) turret_yaw = min;
			else if( turret_yaw < 0 && turret_yaw > max ) turret_yaw = max;
		}
		if( turret_yaw < 0 ) turret_yaw += 360;// clamp back to pos
		else if( turret_yaw > 360 ) turret_yaw -= 360;


		// turn the gun
		if( diff[PITCH] < -turnspeed[GUN_PITCH] ) gun_pitch -= turnspeed[GUN_PITCH];
		else if( diff[PITCH] > turnspeed[GUN_PITCH] ) gun_pitch += turnspeed[GUN_PITCH];
		else gun_pitch += diff[PITCH];
		min = availableWeapons[pm->ps->weaponIndex].minturns[0];
		max = availableWeapons[pm->ps->weaponIndex].maxturns[0];
		if( gun_pitch > 180 ) gun_pitch -= 360;// limit to +-180 to make it easier
		if( gun_pitch > max ) gun_pitch = max;
		else if( gun_pitch < min ) gun_pitch = min;
		if( gun_pitch < 0 ) gun_pitch += 360;// clamp it back to pos
		else if( gun_pitch > 360 ) gun_pitch -= 360;

//		Com_Printf( "gun %.1f (d %.1f)\n", gun_pitch, diff[PITCH] );
	}

	// return angles
	VectorCopy( vehdir, pm->ps->vehicleAngles );
	pm->ps->turretAngle = turret_yaw;
	pm->ps->gunAngle = gun_pitch;

}
Exemplo n.º 24
0
/*
==============
BotAI
==============
*/
int BotAI( int client, float thinktime ) {
	bot_state_t *bs;
	char buf[1024], *args;
	int j;

	trap_EA_ResetInput( client, NULL );
	//
	bs = botstates[client];
	if ( !bs || !bs->inuse ) {
		BotAI_Print( PRT_FATAL, "client %d hasn't been setup\n", client );
		return BLERR_AICLIENTNOTSETUP;
	}

	//retrieve the current client state
	BotAI_GetClientState( client, &bs->cur_ps );

	//retrieve any waiting console messages
	while ( trap_BotGetServerCommand( client, buf, sizeof( buf ) ) ) {
		//have buf point to the command and args to the command arguments
		args = strchr( buf, ' ' );
		if ( !args ) {
			continue;
		}
		*args++ = '\0';

		//remove color espace sequences from the arguments
		Q_CleanStr( args );

		//botai_import.Print(PRT_MESSAGE, "ConsoleMessage: \"%s\"\n", buf);
		if ( !Q_stricmp( buf, "cp " ) ) { /*CenterPrintf*/
		} else if ( !Q_stricmp( buf, "cs" ) )                                                      { /*ConfigStringModified*/
		} else if ( !Q_stricmp( buf, "print" ) )                                                                                                                       {
			trap_BotQueueConsoleMessage( bs->cs, CMS_NORMAL, args );
		} else if ( !Q_stricmp( buf, "chat" ) ) {
			trap_BotQueueConsoleMessage( bs->cs, CMS_CHAT, args );
		} else if ( !Q_stricmp( buf, "tchat" ) ) {
			trap_BotQueueConsoleMessage( bs->cs, CMS_CHAT, args );
		} else if ( !Q_stricmp( buf, "scores" ) ) { /*FIXME: parse scores?*/
		} else if ( !Q_stricmp( buf, "clientLevelShot" ) )                                                                    { /*ignore*/
		}
	}
	//add the delta angles to the bot's current view angles
	for ( j = 0; j < 3; j++ ) {
		bs->viewangles[j] = AngleMod( bs->viewangles[j] + SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
	}
	//increase the local time of the bot
	bs->ltime += thinktime;
	//
	bs->thinktime = thinktime;
	//origin of the bot
	VectorCopy( bs->cur_ps.origin, bs->origin );
	//eye coordinates of the bot
	VectorCopy( bs->cur_ps.origin, bs->eye );
	bs->eye[2] += bs->cur_ps.viewheight;
	//get the area the bot is in
	bs->areanum = BotPointAreaNum( bs->origin );
	//the real AI
	BotDeathmatchAI( bs, thinktime );
	//set the weapon selection every AI frame
	trap_EA_SelectWeapon( bs->client, bs->weaponnum );
	//subtract the delta angles
	for ( j = 0; j < 3; j++ ) {
		bs->viewangles[j] = AngleMod( bs->viewangles[j] - SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
	}
	//everything was ok
	return BLERR_NOERROR;
}
Exemplo n.º 25
0
void CLH2_SetRefEntAxis( refEntity_t* entity, vec3_t entityAngles, vec3_t angleAdd, int scale, int absoluteLight, int drawFlags ) {
	if ( drawFlags & H2DRF_TRANSLUCENT ) {
		entity->renderfx |= RF_TRANSLUCENT;
		entity->shaderRGBA[ 3 ] = 100;
	}

	vec3_t angles;
	if ( R_IsMeshModel( entity->hModel ) ) {
		if ( R_ModelFlags( entity->hModel ) & H2MDLEF_FACE_VIEW ) {
			//	yaw and pitch must be 0 so that renderer can safely multply matrices.
			angles[ PITCH ] = 0;
			angles[ YAW ] = 0;
			angles[ ROLL ] = entityAngles[ ROLL ];

			AnglesToAxis( angles, entity->axis );
		} else {
			if ( R_ModelFlags( entity->hModel ) & H2MDLEF_ROTATE ) {
				angles[ YAW ] = AngleMod( ( entity->origin[ 0 ] + entity->origin[ 1 ] ) * 0.8 + ( 108 * cl.serverTime * 0.001 ) );
			} else {
				angles[ YAW ] = entityAngles[ YAW ];
			}
			angles[ ROLL ] = entityAngles[ ROLL ];
			// stupid quake bug
			angles[ PITCH ] = -entityAngles[ PITCH ];

			if ( angleAdd[ 0 ] || angleAdd[ 1 ] || angleAdd[ 2 ] ) {
				float BaseAxis[ 3 ][ 3 ];
				AnglesToAxis( angles, BaseAxis );

				// For clientside rotation stuff
				float AddAxis[ 3 ][ 3 ];
				AnglesToAxis( angleAdd, AddAxis );

				MatrixMultiply( AddAxis, BaseAxis, entity->axis );
			} else {
				AnglesToAxis( angles, entity->axis );
			}
		}

		if ( ( R_ModelFlags( entity->hModel ) & H2MDLEF_ROTATE ) || ( scale != 0 && scale != 100 ) ) {
			entity->renderfx |= RF_LIGHTING_ORIGIN;
			VectorCopy( entity->origin, entity->lightingOrigin );
		}

		if ( R_ModelFlags( entity->hModel ) & H2MDLEF_ROTATE ) {
			// Floating motion
			float delta = sin( entity->origin[ 0 ] + entity->origin[ 1 ] + ( cl.serverTime * 0.001 * 3 ) ) * 5.5;
			VectorMA( entity->origin, delta, entity->axis[ 2 ], entity->origin );
			absoluteLight = 60 + 34 + sin( entity->origin[ 0 ] + entity->origin[ 1 ] + ( cl.serverTime * 0.001 * 3.8 ) ) * 34;
			drawFlags |= H2MLS_ABSLIGHT;
		}

		if ( scale != 0 && scale != 100 ) {
			float entScale = ( float )scale / 100.0;
			float esx;
			float esy;
			float esz;
			switch ( drawFlags & H2SCALE_TYPE_MASKIN ) {
			case H2SCALE_TYPE_UNIFORM:
				esx = entScale;
				esy = entScale;
				esz = entScale;
				break;
			case H2SCALE_TYPE_XYONLY:
				esx = entScale;
				esy = entScale;
				esz = 1;
				break;
			case H2SCALE_TYPE_ZONLY:
				esx = 1;
				esy = 1;
				esz = entScale;
				break;
			}
			float etz;
			switch ( drawFlags & H2SCALE_ORIGIN_MASKIN ) {
			case H2SCALE_ORIGIN_CENTER:
				etz = 0.5;
				break;
			case H2SCALE_ORIGIN_BOTTOM:
				etz = 0;
				break;
			case H2SCALE_ORIGIN_TOP:
				etz = 1.0;
				break;
			}

			vec3_t Out;
			R_CalculateModelScaleOffset( entity->hModel, esx, esy, esz, etz, Out );
			VectorMA( entity->origin, Out[ 0 ], entity->axis[ 0 ], entity->origin );
			VectorMA( entity->origin, Out[ 1 ], entity->axis[ 1 ], entity->origin );
			VectorMA( entity->origin, Out[ 2 ], entity->axis[ 2 ], entity->origin );
			VectorScale( entity->axis[ 0 ], esx, entity->axis[ 0 ] );
			VectorScale( entity->axis[ 1 ], esy, entity->axis[ 1 ] );
			VectorScale( entity->axis[ 2 ], esz, entity->axis[ 2 ] );
			entity->nonNormalizedAxes = true;
		}
	} else {
		angles[ YAW ] = entityAngles[ YAW ];
		angles[ ROLL ] = entityAngles[ ROLL ];
		angles[ PITCH ] = entityAngles[ PITCH ];

		AnglesToAxis( angles, entity->axis );
	}

	int mls = drawFlags & H2MLS_MASKIN;
	if ( mls == H2MLS_ABSLIGHT ) {
		entity->renderfx |= RF_ABSOLUTE_LIGHT;
		entity->absoluteLight = absoluteLight / 128.0;
	} else if ( mls != H2MLS_NONE ) {
		// Use a model light style (25-30)
		entity->renderfx |= RF_ABSOLUTE_LIGHT;
		entity->absoluteLight = cl_lightstyle[ 24 + mls ].value[ 0 ] / 2;
	}
}
Exemplo n.º 26
0
/*
============
AICast_CreateCharacter

  returns 0 if unable to create the character
============
*/
gentity_t *AICast_CreateCharacter( gentity_t *ent, float *attributes, cast_weapon_info_t *weaponInfo, char *castname, char *model, char *head, char *sex, char *color, char *handicap )
{
	gentity_t		*newent;
	gclient_t		*client;
	cast_state_t	*cs;
	char			**ppStr;
	int j;

	if (g_gametype.integer != GT_SINGLE_PLAYER)
	{	// no cast AI in multiplayer
		return NULL;
	}
	// are bots enabled?
	if ( !trap_Cvar_VariableIntegerValue( "bot_enable" ) ) {
		G_Printf( S_COLOR_RED "ERROR: Unable to spawn %s, 'bot_enable' is not set\n", ent->classname );
		return NULL;
	}
	//
	// make sure we have a free slot for them
	//
	if (level.numPlayingClients+1 > aicast_maxclients)
	{
		G_Error( "Exceeded sv_maxclients (%d), unable to create %s\n", aicast_maxclients, ent->classname );
		return NULL;
	}
	//
	// add it to the list (only do this if everything else passed)
	//

	newent = AICast_AddCastToGame( ent, castname, model, head, sex, color, handicap );

	if (!newent) {
		return NULL;
	}
	client = newent->client;
	//
	// setup the character..
	//
	cs = AICast_GetCastState( newent->s.number );
	//
	// setup the attributes
	memcpy( cs->attributes, attributes, sizeof(cs->attributes) );
	ppStr = &ent->aiAttributes;
	AICast_CheckLevelAttributes( cs, ent, ppStr );
	//
	AICast_SetAASIndex( cs );
	// make sure they face the right direction
	VectorCopy( ent->s.angles, cs->bs->ideal_viewangles );
	// factor in the delta_angles
	for (j = 0; j < 3; j++) {
		cs->bs->viewangles[j] = AngleMod(newent->s.angles[j] - SHORT2ANGLE(newent->client->ps.delta_angles[j]));
	}
	VectorCopy( ent->s.angles, newent->s.angles );
	VectorCopy( ent->s.origin, cs->startOrigin );
	//
	cs->lastEnemy = -1;
	cs->bs->enemy = -1;
	cs->leaderNum = -1;
	cs->castScriptStatus.scriptGotoEnt = -1;
	cs->aiCharacter = ent->aiCharacter;
	//
	newent->aiName = ent->aiName;
	newent->aiTeam = ent->aiTeam;
	newent->targetname = ent->targetname;
	//
	newent->AIScript_AlertEntity = ent->AIScript_AlertEntity;
	newent->aiInactive = ent->aiInactive;
	newent->aiCharacter = cs->aiCharacter;
	//
	// parse the AI script for this character (if applicable)
	cs->aiFlags |= AIFL_CORPSESIGHTING;		// this is on by default for all characters, disabled if they have a "friendlysightcorpse" script event
	AICast_ScriptParse( cs );
	//
	// setup bounding boxes
	//VectorCopy( mins, client->ps.mins );
	//VectorCopy( maxs, client->ps.maxs );
	AIChar_SetBBox( newent, cs );
	client->ps.friction = cs->attributes[RUNNING_SPEED]/300.0;
	//
	// clear weapons/ammo
	client->ps.weapon = 0;
	memcpy( client->ps.weapons, weaponInfo->startingWeapons, sizeof(weaponInfo->startingWeapons) );
	memcpy( client->ps.ammo, weaponInfo->startingAmmo, sizeof(client->ps.ammo) );
	//
	// starting health
	if (ent->health) {
		newent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] = ent->health;
	} else {
		newent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] = cs->attributes[STARTING_HEALTH];
	}
	//
	cs->weaponInfo = weaponInfo;
	//
	cs->lastThink = level.time;
	//
	newent->pain = AICast_Pain;
	newent->die = AICast_Die;
	//
	//update the attack inventory values
	AICast_UpdateBattleInventory(cs, cs->bs->enemy);

//----(SA)	make sure all clips are loaded so we don't hear everyone loading up
//			(we don't want to do this inside AICast_UpdateBattleInventory(), only on spawn or giveweapon)
	for (j=0; j<MAX_WEAPONS; j++) {
		Fill_Clip (&client->ps, j);
	}
//----(SA)	end

	// select a weapon
	AICast_ChooseWeapon( cs, qfalse );

	//
	// set the default function, overwrite if necessary
	cs->aiFlags |= AIFL_JUST_SPAWNED;
	AIFunc_DefaultStart( cs );
	//
	numcast++;
	//
	return newent;
}
Exemplo n.º 27
0
/*
============
AICast_Think

  entry point for all cast AI
============
*/
void AICast_Think( int client, float thinktime ) {
	gentity_t       *ent;
	cast_state_t    *cs;
	int i;
	int animIndex;
	animation_t     *anim;

//	if (saveGamePending || (strlen( g_missionStats.string ) > 2 )) {
//		return;
//	}

	//
	// get the cast ready for processing
	//
	cs = AICast_GetCastState( client );
	ent = &g_entities[client];
	//
	// make sure we are using the right AAS data for this entity (one's that don't get set will default to the player's AAS data)
	trap_AAS_SetCurrentWorld( cs->aasWorldIndex );
	//
	// make sure we have a valid navigation system
	//
	if ( !trap_AAS_Initialized() ) {
		return;
	}
	//
	trap_EA_ResetInput( client, NULL );
	cs->aiFlags &= ~AIFL_VIEWLOCKED;
	//cs->bs->weaponnum = ent->client->ps.weapon;
	//
	// turn off flags that are set each frame if needed
	ent->client->ps.eFlags &= ~( EF_NOSWINGANGLES | EF_MONSTER_EFFECT | EF_MONSTER_EFFECT2 | EF_MONSTER_EFFECT3 );
	// conditional flags
	if ( ent->aiCharacter == AICHAR_ZOMBIE ) {
		if ( COM_BitCheck( ent->client->ps.weapons, WP_MONSTER_ATTACK1 ) ) {
			cs->aiFlags |= AIFL_NO_FLAME_DAMAGE;
			SET_FLAMING_ZOMBIE( ent->s, 1 );
		} else {
			SET_FLAMING_ZOMBIE( ent->s, 0 );
		}
	}
	//
	// if we're dead, do special stuff only
	if ( ent->health <= 0 || cs->revivingTime || cs->rebirthTime ) {
		//
		if ( cs->revivingTime && cs->revivingTime < level.time ) {
			// start us thinking again
			ent->client->ps.pm_type = PM_NORMAL;
			cs->revivingTime = 0;
		}
		//
		if ( cs->rebirthTime && cs->rebirthTime < level.time ) {
			vec3_t mins, maxs;
			int touch[10], numTouch;
			float oldmaxZ;

			oldmaxZ = ent->r.maxs[2];

			// make sure the area is clear
			AIChar_SetBBox( ent, cs );

			VectorAdd( ent->r.currentOrigin, ent->r.mins, mins );
			VectorAdd( ent->r.currentOrigin, ent->r.maxs, maxs );
			trap_UnlinkEntity( ent );

			numTouch = trap_EntitiesInBox( mins, maxs, touch, 10 );

			if ( numTouch ) {
				for ( i = 0; i < numTouch; i++ ) {
					//if (!g_entities[touch[i]].client || g_entities[touch[i]].r.contents == CONTENTS_BODY)
					if ( g_entities[touch[i]].r.contents & MASK_PLAYERSOLID ) {
						break;
					}
				}
				if ( i == numTouch ) {
					numTouch = 0;
				}
			}

			if ( numTouch == 0 ) {    // ok to spawn

				// give them health when they start reviving, so we won't gib after
				// just a couple shots while reviving
				ent->health =
					ent->client->ps.stats[STAT_HEALTH] =
						ent->client->ps.stats[STAT_MAX_HEALTH] =
							( ( cs->attributes[STARTING_HEALTH] - 50 ) > 30 ? ( cs->attributes[STARTING_HEALTH] - 50 ) : 30 );

				ent->r.contents = CONTENTS_BODY;
				ent->clipmask = MASK_PLAYERSOLID;
				ent->takedamage = qtrue;
				ent->waterlevel = 0;
				ent->watertype = 0;
				ent->flags = 0;
				ent->die = AICast_Die;
				ent->client->ps.eFlags &= ~EF_DEAD;
				ent->s.eFlags &= ~EF_DEAD;

				cs->rebirthTime = 0;
				cs->deathTime = 0;

				// play the revive animation
				cs->revivingTime = level.time + BG_AnimScriptEvent( &ent->client->ps, ANIM_ET_REVIVE, qfalse, qtrue );;
			} else {
				// can't spawn yet, so set bbox back, and wait
				ent->r.maxs[2] = oldmaxZ;
				ent->client->ps.maxs[2] = ent->r.maxs[2];
			}
			trap_LinkEntity( ent );
		}
		// ZOMBIE should set effect flag if really dead
		if ( cs->aiCharacter == AICHAR_ZOMBIE && !ent->r.contents ) {
			ent->client->ps.eFlags |= EF_MONSTER_EFFECT2;
		}
		//
		if ( ent->health > GIB_HEALTH && cs->deathTime && cs->deathTime < ( level.time - 3000 ) ) {
/*
			// been dead for long enough, set our animation to the end frame
			switch ( ent->s.legsAnim & ~ANIM_TOGGLEBIT ) {
			case BOTH_DEATH1:
			case BOTH_DEAD1:
				anim = BOTH_DEAD1;
				break;
			case BOTH_DEATH2:
			case BOTH_DEAD2:
				anim = BOTH_DEAD2;
				break;
			case BOTH_DEATH3:
			case BOTH_DEAD3:
				anim = BOTH_DEAD3;
				break;
			default:
				G_Error( "%s has unknown death animation\n", ent->classname);
			}
			ent->client->ps.torsoAnim = ( ( ent->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
			ent->client->ps.legsAnim = ( ( ent->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
*/
			cs->deathTime = 0;
			ent->r.svFlags &= ~SVF_BROADCAST;
		}
		//
		// no more thinking required
		return;
	}
	//
	// set some anim conditions
	if ( cs->secondDeadTime ) {
		BG_UpdateConditionValue( cs->entityNum, ANIM_COND_SECONDLIFE, qtrue, qfalse );
	} else {
		BG_UpdateConditionValue( cs->entityNum, ANIM_COND_SECONDLIFE, qfalse, qfalse );
	}
	// set health value
	if ( ent->health <= 0.25 * cs->attributes[STARTING_HEALTH] ) {
		BG_UpdateConditionValue( cs->entityNum, ANIM_COND_HEALTH_LEVEL, 3, qfalse );
	} else if ( ent->health <= 0.5 * cs->attributes[STARTING_HEALTH] ) {
		BG_UpdateConditionValue( cs->entityNum, ANIM_COND_HEALTH_LEVEL, 2, qfalse );
	} else {
		BG_UpdateConditionValue( cs->entityNum, ANIM_COND_HEALTH_LEVEL, 1, qfalse );
	}
	//
	cs->speedScale = 1.0;           // reset each frame, set if required
	cs->actionFlags = 0;            // FIXME: move this to a Cast AI movement init function!
	//retrieve the current client state
	BotAI_GetClientState( client, &( cs->bs->cur_ps ) );
	//
	// setup movement speeds for the given state
	// walking
	animIndex = BG_GetAnimScriptAnimation( cs->entityNum, ent->client->ps.aiState, ANIM_MT_WALK );
	if ( animIndex >= 0 ) {
		anim = BG_GetAnimationForIndex( cs->entityNum, animIndex );
		cs->attributes[WALKING_SPEED] = anim->moveSpeed;
	}
	// crouching
	animIndex = BG_GetAnimScriptAnimation( cs->entityNum, ent->client->ps.aiState, ANIM_MT_WALKCR );
	if ( animIndex >= 0 ) {
		anim = BG_GetAnimationForIndex( cs->entityNum, animIndex );
		cs->attributes[CROUCHING_SPEED] = anim->moveSpeed;
	}
	// running
	animIndex = BG_GetAnimScriptAnimation( cs->entityNum, ent->client->ps.aiState, ANIM_MT_RUN );
	if ( animIndex >= 0 ) {
		anim = BG_GetAnimationForIndex( cs->entityNum, animIndex );
		cs->attributes[RUNNING_SPEED] = anim->moveSpeed;
	}
	// update crouch speed scale
	ent->client->ps.crouchSpeedScale = cs->attributes[CROUCHING_SPEED] / cs->attributes[RUNNING_SPEED];
	//
	// only enable headlook if we want to this frame
	ent->client->ps.eFlags &= ~EF_HEADLOOK;
	if ( cs->bs->enemy >= 0 ) {
		ent->client->ps.eFlags &= ~EF_STAND_IDLE2;  // never use alt idle if fighting
	}
	//
	// check for dead leader
	if ( cs->leaderNum >= 0 && g_entities[cs->leaderNum].health <= 0 ) {
		cs->leaderNum = -1;
	}
	//
#if 0
	// HACK for village2, if they are stuck, find a good position (there is a friendly guy placed inside a table)
	{
		trace_t tr;
		vec3_t org;
		trap_Trace( &tr, cs->bs->cur_ps.origin, cs->bs->cur_ps.mins, cs->bs->cur_ps.maxs, cs->bs->cur_ps.origin, cs->entityNum, CONTENTS_SOLID );
		while ( tr.startsolid ) {
			VectorCopy( cs->bs->cur_ps.origin, org );
			org[0] += 96 * crandom();
			org[1] += 96 * crandom();
			org[2] += 16 * crandom();
			trap_Trace( &tr, org, cs->bs->cur_ps.mins, cs->bs->cur_ps.maxs, org, cs->entityNum, CONTENTS_SOLID );
			G_SetOrigin( &g_entities[cs->entityNum], org );
			VectorCopy( org, g_entities[cs->entityNum].client->ps.origin );
		}
	}
#endif
	//add the delta angles to the cast's current view angles
	for ( i = 0; i < 3; i++ ) {
		cs->bs->viewangles[i] = AngleMod( cs->bs->viewangles[i] + SHORT2ANGLE( cs->bs->cur_ps.delta_angles[i] ) );
	}
	//
	//increase the local time of the cast
	cs->bs->ltime += thinktime;
	//
	cs->bs->thinktime = thinktime;
	//origin of the cast
	VectorCopy( cs->bs->cur_ps.origin, cs->bs->origin );
	//eye coordinates of the cast
	VectorCopy( cs->bs->cur_ps.origin, cs->bs->eye );
	cs->bs->eye[2] += cs->bs->cur_ps.viewheight;
	//get the area the cast is in
	cs->bs->areanum = BotPointAreaNum( cs->bs->origin );
	// clear flags each frame
	cs->bs->flags = 0;
	//
	// check enemy health
	if ( cs->bs->enemy >= 0 && g_entities[cs->bs->enemy].health <= 0 ) {
		cs->bs->enemy = -1;
	}
	//
	// if the previous movetype was temporary, set it back
	if ( cs->movestateType == MSTYPE_TEMPORARY ) {
		cs->movestate = MS_DEFAULT;
		cs->movestateType = MSTYPE_NONE;
	}
	// crouching?
	if (    ( cs->bs->attackcrouch_time > trap_AAS_Time() ) &&
			( ( cs->lastAttackCrouch > level.time - 500 ) || ( cs->thinkFuncChangeTime < level.time - 1000 ) ) ) {
		// if we are not moving, and we are firing, always stand, unless we are allowed to crouch + fire
		if ( VectorLength( cs->bs->cur_ps.velocity ) || ( cs->lastWeaponFired < level.time - 2000 ) || ( cs->aiFlags & AIFL_ATTACK_CROUCH ) ) {
			cs->lastAttackCrouch = level.time;
			trap_EA_Crouch( cs->bs->client );
		}
	}
	//
	//if (cs->bs->enemy >= 0) {
	//update the attack inventory values
	AICast_UpdateBattleInventory( cs, cs->bs->enemy );
	//}
	//
	// if we don't have ammo for the current weapon, get rid of it
	if ( !( COM_BitCheck( cs->bs->cur_ps.weapons, cs->bs->weaponnum ) ) || !AICast_GotEnoughAmmoForWeapon( cs, cs->bs->weaponnum ) ) {
		// select a weapon
		AICast_ChooseWeapon( cs, qfalse );
		// if still no ammo, select a blank weapon
		//if (!AICast_GotEnoughAmmoForWeapon( cs, cs->bs->weaponnum )) {
		//	cs->bs->weaponnum = WP_NONE;
		//}
	}
	//
	// in query mode, we do special handling (pause scripting, check for transition to alert/combat, etc)
	if ( cs->aiState == AISTATE_QUERY ) {
		AICast_QueryThink( cs );
	} else if ( cs->pauseTime < level.time )     {
		// do the thinking
		AICast_ProcessAIFunctions( cs, thinktime );
		//
		// make sure the correct weapon is selected
		trap_EA_SelectWeapon( cs->bs->client, cs->bs->weaponnum );
		//
		// process current script if it exists
		cs->castScriptStatusCurrent = cs->castScriptStatus;
		AICast_ScriptRun( cs, qfalse );
	}
	//
	// set special movestate if necessary
	if ( cs->movestateType != MSTYPE_NONE ) {
		switch ( cs->movestate ) {
		case MS_WALK:
			cs->actionFlags |= CASTACTION_WALK;
			break;
		case MS_CROUCH:
			trap_EA_Crouch( cs->entityNum );
			break;
		default:
			break; // TTimo gcc: MS_DEFAULT MS_RUN not handled in switch
		}
	}
	//
	//subtract the delta angles
	for ( i = 0; i < 3; i++ ) {
		cs->bs->viewangles[i] = AngleMod( cs->bs->viewangles[i] - SHORT2ANGLE( cs->bs->cur_ps.delta_angles[i] ) );
	}
}
Exemplo n.º 28
0
/*
==============
AICast_UpdateInput
==============
*/
void AICast_UpdateInput( cast_state_t *cs, int time ) {
	bot_input_t bi;
	bot_state_t *bs;
	int j;
	float speed;

	bs = cs->bs;

	//add the delta angles to the bot's current view angles
	for ( j = 0; j < 3; j++ ) {
		bs->viewangles[j] = AngleMod( bs->viewangles[j] + SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
	}
	//
	AICast_ChangeViewAngles( cs, (float) time / 1000 );
	//
	if ( cs->pauseTime > level.time ) {
		trap_EA_View( bs->client, bs->viewangles );
		trap_EA_GetInput( bs->client, (float) time / 1000, &bi );
		AICast_InputToUserCommand( cs, &bi, &bs->lastucmd, bs->cur_ps.delta_angles );
		g_entities[cs->bs->entitynum].client->ps.pm_flags &= ~PMF_RESPAWNED;
		//
		//subtract the delta angles
		for ( j = 0; j < 3; j++ ) {
			bs->viewangles[j] = AngleMod( bs->viewangles[j] - SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
		}
		//
		return;
	}
	//
	trap_EA_GetInput( bs->client, (float) time / 1000, &bi );
	//
	// restrict the speed according to the character and their current speedScale
	// HACK, don't slow down while crouching
	if ( bi.actionflags & ACTION_CROUCH && cs->speedScale < 1.0 ) {
		cs->speedScale = 1.0;
	}
	//
	// check some Cast AI specific movement flags
	if ( cs->actionFlags & CASTACTION_WALK ) {
		if ( cs->speedScale > ( cs->attributes[WALKING_SPEED] / cs->attributes[RUNNING_SPEED] ) ) {
			cs->speedScale = ( cs->attributes[WALKING_SPEED] / cs->attributes[RUNNING_SPEED] );
		}
	}
	// don't ever let the speed get too low
	if ( cs->speedScale < 0.25 ) {
		cs->speedScale = 0.25;
	}
	if ( cs->speedScale > 1.2 ) {
		cs->speedScale = 1.2;
	}
	//
	speed = cs->speedScale * cs->attributes[RUNNING_SPEED];
	//
	//if (speed <= (cs->attributes[WALKING_SPEED] + (cs->attributes[WALKING_SPEED] + 50 < cs->attributes[RUNNING_SPEED] ? 50 : -1)))	// do a fast shuffle if slightly over walking speed
	if ( speed <= cs->attributes[WALKING_SPEED] ) {
		cs->actionFlags |= CASTACTION_WALK;
	}
	//
	// we use 300 here, because the default player speed is 300, so Cast AI's can't move faster than that
	if ( ( bi.speed / 400.0 ) > ( speed / 300.0 ) ) {
		bi.speed = 400.0 * ( speed / 300.0 );
		if ( bi.speed > 400.0 ) {
			bi.speed = 400.0;   // just in case, we should never exceed this
		}
	}
	//
	// do a fast shuffle if slightly over walking speed
	if ( bi.speed <= ( 400.0 / 300.0 ) * ( cs->attributes[WALKING_SPEED] + ( cs->attributes[WALKING_SPEED] + 50 < cs->attributes[RUNNING_SPEED] ? 50 : -1 ) ) ) {
		cs->actionFlags |= CASTACTION_WALK;
	}
	//
	AICast_InputToUserCommand( cs, &bi, &bs->lastucmd, bs->cur_ps.delta_angles );
	//
	// check some Cast AI specific movement flags
	if ( cs->actionFlags & CASTACTION_WALK ) {
		bs->lastucmd.buttons |= BUTTON_WALKING; // play the walking animation
	}
	//
	//subtract the delta angles
	for ( j = 0; j < 3; j++ ) {
		bs->viewangles[j] = AngleMod( bs->viewangles[j] - SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) );
	}
	//
	// make sure the respawn flag is disabled (causes problems after multiple "map xxx" commands)
	g_entities[cs->bs->entitynum].client->ps.pm_flags &= ~PMF_RESPAWNED;
	// set the aiState
	g_entities[cs->bs->entitynum].client->ps.aiState = cs->aiState;
}
Exemplo n.º 29
0
/*
============
AICast_GetAvoid
============
*/
qboolean AICast_GetAvoid( cast_state_t *cs, bot_goal_t *goal, vec3_t outpos, qboolean reverse, int blockEnt ) {
	float yaw, oldyaw, distmoved, bestmoved, bestyaw;
	vec3_t bestpos;
	aicast_predictmove_t castmove;
	usercmd_t ucmd;
	qboolean enemyVisible;
	float angleDiff;
	// TTimo might be used uninitialized
	int starttraveltime = 0;
	int besttraveltime, traveltime;
	int invert;
	float inc;
	qboolean averting = qfalse;
	float maxYaw, simTime;
	static int lastTime;

	VectorCopy( vec3_origin, bestpos );

	//
	// if we are in the air, no chance of avoiding
	if ( cs->bs->cur_ps.groundEntityNum == ENTITYNUM_NONE && g_entities[cs->entityNum].waterlevel <= 1 ) {
		return qfalse;
	}
	//
	if ( cs->lastAvoid > level.time - rand() % 500 ) {
		return qfalse;
	}
	cs->lastAvoid = level.time + 50 + rand() % 500;
	//
	if ( lastTime == level.time ) {
		return qfalse;
	}
	lastTime = level.time;

	// if they have an enemy, and can currently see them, don't move out of their view
	enemyVisible =  ( cs->bs->enemy >= 0 ) &&
				   ( AICast_CheckAttack( cs, cs->bs->enemy, qfalse ) );
	//
	// look for a good direction to move out of the way
	bestmoved = 0;
	bestyaw = 360;
	besttraveltime = 9999999;
	if ( goal ) {
		starttraveltime = trap_AAS_AreaTravelTimeToGoalArea( cs->bs->areanum, cs->bs->origin, goal->areanum, cs->travelflags );
	}
	memcpy( &ucmd, &cs->bs->lastucmd, sizeof( usercmd_t ) );
	ucmd.forwardmove = 127;
	ucmd.rightmove = 0;
	ucmd.upmove = 0;
	if ( cs->dangerEntity >= 0 && cs->dangerEntityValidTime >= level.time ) {
		averting = qtrue;
	} else if ( !goal ) {
		averting = qtrue;   // not heading for a goal, so we must be getting out of someone's way
	}
	//
	maxYaw = 0;
	simTime = 1.2;
	//
	if ( averting ) {
		// avoiding danger, go anywhere!
		angleDiff = 300;
		inc = 60;
		invert = 1;
	} else {
		if ( level.time % 1000 < 500 ) {
			invert = 1;
		} else {
			invert = -1;
		}
		angleDiff = 140;
		inc = 35;
	}
	if ( blockEnt > aicast_maxclients ) {
		maxYaw = angleDiff;
		simTime = 0.5;
	}
	//
	for ( yaw = -angleDiff * invert; yaw*invert <= maxYaw; yaw += inc * invert ) {
		if ( !averting && !yaw ) {
			continue;
		}
		oldyaw = cs->bs->cur_ps.viewangles[YAW];
		cs->bs->cur_ps.viewangles[YAW] += yaw + reverse * 180;
		//
		ucmd.angles[YAW] = ANGLE2SHORT( AngleMod( cs->bs->cur_ps.viewangles[YAW] ) );
		//
		AICast_PredictMovement( cs, 5, 0.4, &castmove, &ucmd, -1 );
		// if we have a danger entity, try and get away from it at all costs
		if ( cs->dangerEntity >= 0 && cs->dangerEntityValidTime >= level.time ) {
			distmoved = Distance( castmove.endpos, cs->dangerEntityPos );
		} else if ( goal ) {
			//distmoved = 99999 - trap_AAS_AreaTravelTimeToGoalArea( BotPointAreaNum(castmove.endpos), castmove.endpos, goal->areanum, cs->travelflags );
			distmoved = 99999 - Distance( castmove.endpos, goal->origin );
		} else {
			distmoved = Distance( castmove.endpos, cs->bs->cur_ps.origin );
		}
		if (    ( distmoved > bestmoved )
				//&&	((cs->bs->origin[2] - castmove.endpos[2]) < 64)	// allow up, but not down (falling)
				&&  ( castmove.groundEntityNum != ENTITYNUM_NONE ) ) {
			// they all passed, check any other stuff
			if ( !enemyVisible || AICast_CheckAttackAtPos( cs->entityNum, cs->bs->enemy, castmove.endpos, qfalse, qfalse ) ) {
				if ( !goal || ( traveltime = trap_AAS_AreaTravelTimeToGoalArea( BotPointAreaNum( castmove.endpos ), castmove.endpos, goal->areanum, cs->travelflags ) ) < ( starttraveltime + 200 ) ) {
					bestyaw = yaw;
					bestmoved = distmoved;
					besttraveltime = traveltime;
					VectorCopy( castmove.endpos, bestpos );
				}
			}
		}
		//
		cs->bs->cur_ps.viewangles[YAW] = oldyaw;
	}
	//
	if ( bestmoved > 0 ) {
		VectorCopy( bestpos, outpos );
		return qtrue;
	} else {
		return qfalse;
	}

//G_Printf("GetAvoid: %i ms\n", -pretime + Sys_MilliSeconds() );
}
Exemplo n.º 30
0
bool CDeviceClass::SetItemProperty (CItemCtx &Ctx, const CString &sName, ICCItem *pValue, CString *retsError)

//	SetItemProperty
//
//	Sets a device property. Subclasses should call this if they do not 
//	understand the property.

	{
	CCodeChain &CC = g_pUniverse->GetCC();

	//	Get the installed device. We need this to set anything.

	CInstalledDevice *pDevice = Ctx.GetDevice();
	if (pDevice == NULL)
		{
		*retsError = CONSTLIT("Item is not an installed device on object.");
		return false;
		}

	//	Figure out what to set

	if (strEquals(sName, PROPERTY_FIRE_ARC))
		{
		//	A value of nil means no fire arc (and no omni)

		if (pValue == NULL || pValue->IsNil())
			{
			pDevice->SetOmniDirectional(false);
			pDevice->SetFireArc(0, 0);
			}

		//	A value of "omnidirectional" counts

		else if (strEquals(pValue->GetStringValue(), PROPERTY_OMNIDIRECTIONAL))
			{
			pDevice->SetOmniDirectional(true);
			pDevice->SetFireArc(0, 0);
			}

		//	A single value means that we just point in a direction

		else if (pValue->GetCount() == 1)
			{
			int iMinFireArc = AngleMod(pValue->GetElement(0)->GetIntegerValue());
			pDevice->SetOmniDirectional(false);
			pDevice->SetFireArc(iMinFireArc, iMinFireArc);
			}

		//	Otherwise we expect a list with two elements

		else if (pValue->GetCount() >= 2)
			{
			int iMinFireArc = AngleMod(pValue->GetElement(0)->GetIntegerValue());
			int iMaxFireArc = AngleMod(pValue->GetElement(1)->GetIntegerValue());
			pDevice->SetOmniDirectional(false);
			pDevice->SetFireArc(iMinFireArc, iMaxFireArc);
			}

		//	Invalid

		else
			{
			*retsError = CONSTLIT("Invalid fireArc parameter.");
			return false;
			}
		}

	else if (strEquals(sName, PROPERTY_LINKED_FIRE_OPTIONS))
		{
		//	Parse the options

		DWORD dwOptions;
		if (!::GetLinkedFireOptions(pValue, &dwOptions, retsError))
			return false;

		//	Set

		pDevice->SetLinkedFireOptions(dwOptions);
		}

	else if (strEquals(sName, PROPERTY_POS))
		{
		//	Get the parameters. We accept a single list parameter with angle/radius/z.
		//	(The latter is compatible with the return of objGetDevicePos.)

		int iPosAngle;
		int iPosRadius;
		int iZ;
		if (pValue == NULL || pValue->IsNil())
			{
			iPosAngle = 0;
			iPosRadius = 0;
			iZ = 0;
			}
		else if (pValue->GetCount() >= 2)
			{
			iPosAngle = pValue->GetElement(0)->GetIntegerValue();
			iPosRadius = pValue->GetElement(1)->GetIntegerValue();

			if (pValue->GetCount() >= 3)
				iZ = pValue->GetElement(2)->GetIntegerValue();
			else
				iZ = 0;
			}
		else
			{
			*retsError = CONSTLIT("Invalid angle and radius");
			return false;
			}

		//	Set it

		pDevice->SetPosAngle(iPosAngle);
		pDevice->SetPosRadius(iPosRadius);
		pDevice->SetPosZ(iZ);
		}

	else if (strEquals(sName, PROPERTY_SECONDARY))
		{
		if (pValue == NULL || !pValue->IsNil())
			pDevice->SetSecondary(true);
		else
			pDevice->SetSecondary(false);
		}

	else
		{
		*retsError = strPatternSubst(CONSTLIT("Unknown item property: %s."), sName);
		return false;
		}

	return true;
	}