示例#1
0
//
// R_PointToAngle - wrapper around R_PointToAngle2
//
angle_t
R_PointToAngle
( fixed_t	x,
  fixed_t	y )
{
    return R_PointToAngle2 (viewx, viewy, x, y);
}
示例#2
0
void A_Tracer2 (AActor *self)
{
	AActor *dest;
	angle_t exact;
	fixed_t dist;
	fixed_t slope;

	dest = self->tracer;

	if (dest == NULL || dest->health <= 0 || self->Speed == 0)
		return;

	// change angle
	exact = R_PointToAngle2 (self->x, self->y, dest->x, dest->y);

	if (exact != self->angle)
	{
		if (exact - self->angle > 0x80000000)
		{
			self->angle -= TRACEANGLE;
			if (exact - self->angle < 0x80000000)
				self->angle = exact;
		}
		else
		{
			self->angle += TRACEANGLE;
			if (exact - self->angle > 0x80000000)
				self->angle = exact;
		}
	}

	exact = self->angle >> ANGLETOFINESHIFT;
	self->momx = FixedMul (self->Speed, finecosine[exact]);
	self->momy = FixedMul (self->Speed, finesine[exact]);

	// change slope
	dist = P_AproxDistance (dest->x - self->x, dest->y - self->y);
	dist /= self->Speed;

	if (dist < 1)
	{
		dist = 1;
	}
	if (dest->height >= 56*FRACUNIT)
	{
		slope = (dest->z+40*FRACUNIT - self->z) / dist;
	}
	else
	{
		slope = (dest->z + self->height*2/3 - self->z) / dist;
	}
	if (slope < self->momz)
	{
		self->momz -= FRACUNIT/8;
	}
	else
	{
		self->momz += FRACUNIT/8;
	}
}
示例#3
0
BOOL R_AlignFlat (int linenum, int side, int fc)
{
	line_t *line = lines + linenum;
	sector_t *sec = side ? line->backsector : line->frontsector;

	if (!sec)
		return false;

	fixed_t x = line->v1->x;
	fixed_t y = line->v1->y;

	angle_t angle = R_PointToAngle2 (x, y, line->v2->x, line->v2->y);
	angle_t norm = (angle-ANG90) >> ANGLETOFINESHIFT;

	fixed_t dist = -FixedMul (finecosine[norm], x) - FixedMul (finesine[norm], y);

	if (side)
	{
		angle = angle + ANG180;
		dist = -dist;
	}

	if (fc)
	{
		sec->base_ceiling_angle = 0-angle;
		sec->base_ceiling_yoffs = dist & ((1<<(FRACBITS+8))-1);
	}
	else
	{
		sec->base_floor_angle = 0-angle;
		sec->base_floor_yoffs = dist & ((1<<(FRACBITS+8))-1);
	}

	return true;
}
示例#4
0
//Called while the bot moves after its player->dest mobj
//which can be a weapon/enemy/item whatever.
void FCajunMaster::Roam (AActor *actor, ticcmd_t *cmd)
{
	int delta;

	if (Reachable(actor, actor->player->dest))
	{ // Straight towards it.
		actor->player->angle = R_PointToAngle2(actor->x, actor->y, actor->player->dest->x, actor->player->dest->y);
	}
	else if (actor->movedir < 8) // turn towards movement direction if not there yet
	{
		actor->player->angle &= (angle_t)(7<<29);
		delta = actor->player->angle - (actor->movedir << 29);

		if (delta > 0)
			actor->player->angle -= ANG45;
		else if (delta < 0)
			actor->player->angle += ANG45;
	}

	// chase towards destination.
	if (--actor->movecount < 0 || !Move (actor, cmd))
	{
		NewChaseDir (actor, cmd);
	}
}
示例#5
0
void A_Punch(player_t *player, pspdef_t *psp)
{
  angle_t angle;
  int t, slope, damage = (P_Random(pr_punch)%10+1)<<1;

  if (player->powers[pw_strength])
    damage *= 10;

  angle = player->mo->angle;

  // killough 5/5/98: remove dependence on order of evaluation:
  t = P_Random(pr_punchangle);
  angle += (t - P_Random(pr_punchangle))<<18;

  /* killough 8/2/98: make autoaiming prefer enemies */
  if (!mbf_features ||
      (slope = P_AimLineAttack(player->mo, angle, MELEERANGE, MF_FRIEND),
       !linetarget))
    slope = P_AimLineAttack(player->mo, angle, MELEERANGE, 0);

  P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);

  if (!linetarget)
    return;

  S_StartSound(player->mo, sfx_punch);

  // turn to face target

  player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
                                      linetarget->x, linetarget->y);
  R_SmoothPlaying_Reset(player); // e6y
}
示例#6
0
void A_Punch(player_t* player, pspdef_t* psp)
{
    angle_t 	angle;
    int 		damage;
    int 		slope = 0;
    
    damage = ((P_Random() & 7) + 1) * 3;
    
    if(player->powers[pw_strength])
        damage *= 10;
    
    angle = player->mo->angle;
    angle += P_RandomShift(18);
    
    slope = P_AimLineAttack(player->mo, angle, 0, MELEERANGE);
    
    P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);
    
    // turn to face target
    if(linetarget)
    {
        S_StartSound(player->mo, sfx_punch);
        player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
            linetarget->x, linetarget->y);
    }
}
示例#7
0
//Called while the bot moves after its dest mobj
//which can be a weapon/enemy/item whatever.
void DBot::Roam (ticcmd_t *cmd)
{
	int delta;

	if (Reachable(dest))
	{ // Straight towards it.
		angle = R_PointToAngle2(player->mo->x, player->mo->y, dest->x, dest->y);
	}
	else if (player->mo->movedir < 8) // turn towards movement direction if not there yet
	{
		angle &= (angle_t)(7<<29);
		delta = angle - (player->mo->movedir << 29);

		if (delta > 0)
			angle -= ANG45;
		else if (delta < 0)
			angle += ANG45;
	}

	// chase towards destination.
	if (--player->mo->movecount < 0 || !Move (cmd))
	{
		NewChaseDir (cmd);
	}
}
示例#8
0
//
// A_Saw
//
void A_Saw(player_t *player, pspdef_t *psp)
{
    int     damage = 2 * (P_Random() % 10 + 1);
    angle_t angle = player->mo->angle + ((P_Random() - P_Random()) << 18);
    int     slope = P_AimLineAttack(player->mo, angle, MELEERANGE + 1);

    // use meleerange + 1 so the puff doesn't skip the flash
    P_LineAttack(player->mo, angle, MELEERANGE + 1, slope, damage);

    if (!linetarget)
    {
        S_StartSound(player->mo, sfx_sawful);
        return;
    }
    S_StartSound (player->mo, sfx_sawhit);

    // turn to face target
    angle = R_PointToAngle2(player->mo->x, player->mo->y, linetarget->x, linetarget->y);
    if (angle - player->mo->angle > ANG180)
    {
        if (angle - player->mo->angle < -ANG90 / 20)
            player->mo->angle = angle + ANG90 / 21;
        else
            player->mo->angle -= ANG90 / 20;
    }
    else
    {
        if (angle - player->mo->angle > ANG90 / 20)
            player->mo->angle = angle - ANG90 / 21;
        else
            player->mo->angle += ANG90 / 20;
    }
    player->mo->flags |= MF_JUSTATTACKED;
}
示例#9
0
OVERLAY void A_Punch(player_t *player, pspdef_t *psp)
{
  angle_t angle;
  int t, slope, damage = (P_Random(pr_punch)%10+1)<<1;

  if (player->powers[pw_strength])
    damage *= 10;

  angle = player->mo->angle;

  // killough 5/5/98: remove dependence on order of evaluation:
  t = P_Random(pr_punchangle);
  angle += (t - P_Random(pr_punchangle))<<18;
  slope = P_AimLineAttack(player->mo, angle, MELEERANGE);
  P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);

  if (!linetarget)
    return;

  S_StartSound(player->mo, sfx_punch);

  // turn to face target

  player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
                                      linetarget->x, linetarget->y);
}
示例#10
0
bool P_AlignFlat (int linenum, int side, int fc)
{
	line_t *line = lines + linenum;
	sector_t *sec = side ? line->backsector : line->frontsector;

	if (!sec)
		return false;

	fixed_t x = line->v1->x;
	fixed_t y = line->v1->y;

	angle_t angle = R_PointToAngle2 (x, y, line->v2->x, line->v2->y);
	angle_t norm = (angle-ANGLE_90) >> ANGLETOFINESHIFT;

	fixed_t dist = -DMulScale16 (finecosine[norm], x, finesine[norm], y);

	if (side)
	{
		angle = angle + ANGLE_180;
		dist = -dist;
	}

	sec->SetBase(fc, dist & ((1<<(FRACBITS+8))-1), 0-angle);
	return true;
}
示例#11
0
angle_t DCajunMaster::FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd)
{
	fixed_t dist;
	angle_t ang;
	AActor *actor;
	int m;

	SetBodyAt (bot->x + FixedMul(bot->momx, 5*FRACUNIT),
			   bot->y + FixedMul(bot->momy, 5*FRACUNIT),
			   bot->z + (bot->height / 2), 2);

	actor = bglobal.body2;

	dist = P_AproxDistance (actor->x-enemy->x, actor->y-enemy->y);
	if (dist < SAFE_SELF_MISDIST)
		return 0;
	//Predict.
	m = (((dist+1)/FRACUNIT) / GetDefault<ARocket>()->Speed);

	SetBodyAt (enemy->x + FixedMul (enemy->momx, (m+2*FRACUNIT)),
			   enemy->y + FixedMul(enemy->momy, (m+2*FRACUNIT)), ONFLOORZ, 1);
	dist = P_AproxDistance(actor->x-bglobal.body1->x, actor->y-bglobal.body1->y);
	//try the predicted location
	if (P_CheckSight (actor, bglobal.body1, 1)) //See the predicted location, so give a test missile
	{
		if (SafeCheckPosition (bot, actor->x, actor->y))
		{
			if (FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST)
			{
				ang = R_PointToAngle2 (actor->x, actor->y, bglobal.body1->x, bglobal.body1->y);
				return ang;
			}
		}
	}
	//Try fire straight.
	if (P_CheckSight (actor, enemy, 0))
	{
		if (FakeFire (bot, enemy, cmd) >= SAFE_SELF_MISDIST)
		{
			ang = R_PointToAngle2(bot->x, bot->y, enemy->x, enemy->y);
			return ang;
		}
	}
	return 0;
}
示例#12
0
//
// P_WallMomSlide
// Adjusts the xmove / ymove
// so that the next move will slide along the wall.
//
static void P_WallMomSlide(line_t *ld)
{
    int     side;
    angle_t lineangle;
    angle_t moveangle;
    angle_t deltaangle;
    fixed_t movelen;
    fixed_t newlen;

    // First check the simple cases.
    if(ld->slopetype == ST_HORIZONTAL)
    {
        tmymove = 0;
        return;
    }
    if(ld->slopetype == ST_VERTICAL)
    {
        tmxmove = 0;
        return;
    }

    side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
    lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);

    if(side == 1)
        lineangle += ANG180;

    moveangle = R_PointToAngle2(0, 0, tmxmove, tmymove);
    deltaangle = moveangle - lineangle;

    if(deltaangle > ANG180)
        deltaangle += ANG180;

    lineangle >>= ANGLETOFINESHIFT;
    deltaangle >>= ANGLETOFINESHIFT;

    movelen = P_ApproxDistance(tmxmove, tmymove);
    newlen = FixedMul(movelen, finecosine[deltaangle]);

    tmxmove = FixedMul(newlen, finecosine[lineangle]);
    tmymove = FixedMul(newlen, finesine[lineangle]);
}
示例#13
0
//doesnt check LOS, checks visibility with a set view angle.
//B_Checksight checks LOS (straight line)
//----------------------------------------------------------------------
//Check if mo1 has free line to mo2
//and if mo2 is within mo1 viewangle (vangle) given with normal degrees.
//if these conditions are true, the function returns true.
//GOOD TO KNOW is that the player's view angle
//in doom is 90 degrees infront.
bool DCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle)
{
	if (!P_CheckSight (from, to, 2))
		return false; // out of sight
	if (vangle == ANGLE_MAX)
		return true;
	if (vangle == 0)
		return false; //Looker seems to be blind.

	return abs (R_PointToAngle2 (from->x, from->y, to->x, to->y) - from->angle) <= vangle/2;
}
示例#14
0
void A_FiredChase (AActor *actor)
{
	int weaveindex = actor->special1;
	AActor *target = actor->target;
	angle_t ang;
	fixed_t dist;

	if (actor->reactiontime) actor->reactiontime--;
	if (actor->threshold) actor->threshold--;

	// Float up and down
	actor->z += FloatBobOffsets[weaveindex];
	actor->special1 = (weaveindex+2)&63;

	// Ensure it stays above certain height
	if (actor->z < actor->floorz + (64*FRACUNIT))
	{
		actor->z += 2*FRACUNIT;
	}

	if(!actor->target || !(actor->target->flags&MF_SHOOTABLE))
	{	// Invalid target
		P_LookForPlayers (actor,true);
		return;
	}

	// Strafe
	if (actor->special2 > 0)
	{
		actor->special2--;
	}
	else
	{
		actor->special2 = 0;
		actor->momx = actor->momy = 0;
		dist = P_AproxDistance (actor->x - target->x, actor->y - target->y);
		if (dist < FIREDEMON_ATTACK_RANGE)
		{
			if (pr_firedemonchase() < 30)
			{
				ang = R_PointToAngle2 (actor->x, actor->y, target->x, target->y);
				if (pr_firedemonchase() < 128)
					ang += ANGLE_90;
				else
					ang -= ANGLE_90;
				ang >>= ANGLETOFINESHIFT;
				actor->momx = finecosine[ang] << 3; //FixedMul (8*FRACUNIT, finecosine[ang]);
				actor->momy = finesine[ang] << 3; //FixedMul (8*FRACUNIT, finesine[ang]);
				actor->special2 = 3;		// strafe time
			}
		}
	}
示例#15
0
DEFINE_ACTION_FUNCTION(AActor, A_FiredChase)
{
	int weaveindex = self->special1;
	AActor *target = self->target;
	angle_t ang;
	fixed_t dist;

	if (self->reactiontime) self->reactiontime--;
	if (self->threshold) self->threshold--;

	// Float up and down
	self->z += finesine[weaveindex << BOBTOFINESHIFT] * 8;
	self->special1 = (weaveindex + 2) & 63;

	// Ensure it stays above certain height
	if (self->z < self->floorz + (64*FRACUNIT))
	{
		self->z += 2*FRACUNIT;
	}

	if(!self->target || !(self->target->flags&MF_SHOOTABLE))
	{	// Invalid target
		P_LookForPlayers (self,true, NULL);
		return;
	}

	// Strafe
	if (self->special2 > 0)
	{
		self->special2--;
	}
	else
	{
		self->special2 = 0;
		self->velx = self->vely = 0;
		dist = P_AproxDistance (self->x - target->x, self->y - target->y);
		if (dist < FIREDEMON_ATTACK_RANGE)
		{
			if (pr_firedemonchase() < 30)
			{
				ang = R_PointToAngle2 (self->x, self->y, target->x, target->y);
				if (pr_firedemonchase() < 128)
					ang += ANGLE_90;
				else
					ang -= ANGLE_90;
				ang >>= ANGLETOFINESHIFT;
				self->velx = finecosine[ang] << 3; //FixedMul (8*FRACUNIT, finecosine[ang]);
				self->vely = finesine[ang] << 3; //FixedMul (8*FRACUNIT, finesine[ang]);
				self->special2 = 3;		// strafe time
			}
		}
	}
示例#16
0
void A_Saw(player_t *player, pspdef_t *psp)
{
  int slope, damage;
  angle_t angle;
  int t;

  CHECK_WEAPON_CODEPOINTER("A_Saw", player);

  damage = 2*(P_Random(pr_saw)%10+1);
  angle = player->mo->angle;
  // killough 5/5/98: remove dependence on order of evaluation:
  t = P_Random(pr_saw);
  angle += (t - P_Random(pr_saw))<<18;

  /* Use meleerange + 1 so that the puff doesn't skip the flash
   * killough 8/2/98: make autoaiming prefer enemies */
  if (!mbf_features ||
      (slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1, MF_FRIEND),
       !linetarget))
    slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1, 0);

  P_LineAttack(player->mo, angle, MELEERANGE+1, slope, damage);

  if (!linetarget)
    {
      S_StartSound(player->mo, sfx_sawful);
      return;
    }

  S_StartSound(player->mo, sfx_sawhit);

  // turn to face target
  angle = R_PointToAngle2(player->mo->x, player->mo->y,
                          linetarget->x, linetarget->y);

  if (angle - player->mo->angle > ANG180) {
    if (angle - player->mo->angle < -ANG90/20)
      player->mo->angle = angle + ANG90/21;
    else
      player->mo->angle -= ANG90/20;
  } else {
    if (angle - player->mo->angle > ANG90/20)
      player->mo->angle = angle - ANG90/21;
    else
      player->mo->angle += ANG90/20;
  }

  player->mo->flags |= MF_JUSTATTACKED;
  R_SmoothPlaying_Reset(player); // e6y
}
示例#17
0
文件: st_stuff.c 项目: MP2E/kexplus
static void ST_DrawDamageMarkers(void)
{
	damagemarker_t *dmgmarker;

	for (dmgmarker = dmgmarkers.next; dmgmarker != &dmgmarkers;
	     dmgmarker = dmgmarker->next) {
		static vtx_t v[3];
		player_t *p;
		float angle;
		byte alpha;

		GL_SetState(GLSTATE_BLEND, 1);
		GL_SetOrtho(0);

		alpha = (dmgmarker->tics << 3);

		if (alpha < 0)
			alpha = 0;

		v[0].x = -8;
		v[0].a = alpha;
		v[1].x = 8;
		v[1].a = alpha;
		v[2].y = 4;
		v[2].r = 255;
		v[2].a = alpha;

		p = &players[consoleplayer];

		angle = (float)TRUEANGLES(p->mo->angle -
					  R_PointToAngle2(dmgmarker->source->x,
							  dmgmarker->source->y,
							  p->mo->x, p->mo->y));

		dglPushMatrix();
		dglTranslatef(160, 120, 0);
		dglRotatef(angle, 0.0f, 0.0f, 1.0f);
		dglTranslatef(0, 16, 0);
		dglDisable(GL_TEXTURE_2D);
		dglSetVertex(v);
		dglTriangle(0, 1, 2);
		dglDrawGeometry(3, v);
		dglEnable(GL_TEXTURE_2D);
		dglPopMatrix();

		GL_ResetViewport();
		GL_SetState(GLSTATE_BLEND, 0);
	}
}
示例#18
0
DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck)
{
	int i;

	for(i = 0; i < MAXPLAYERS; i++)
	{
		if (playeringame[i])
		{
			AActor *pmo = players[i].mo;
			if (P_CheckSight (self, pmo) && (abs (R_PointToAngle2 (pmo->x,
				pmo->y, self->x, self->y) - pmo->angle) <= ANGLE_45))
			{ // Previous state (pottery bit waiting state)
				self->SetState (self->state - 1);
				return;
			}
		}
	}		
}
示例#19
0
void A_Saw(player_t* player, pspdef_t* psp)
{
    angle_t 	angle;
    int 		damage;
    int 		slope = 0;
    
    damage = ((P_Random() & 7) + 1) * 3;
    angle = player->mo->angle;
    angle += P_RandomShift(18);
    
    // use meleerange + 1 se the puff doesn't skip the flash
    slope = P_AimLineAttack(player->mo, angle, 0, MELEERANGE+1);
    
    P_LineAttack(player->mo, angle, MELEERANGE + 1, slope, damage);
    
    if(!linetarget)
    {
        S_StartSound (player->mo, sfx_saw1);
        return;
    }

    S_StartSound (player->mo, sfx_saw2);
    
    // turn to face target
    angle = R_PointToAngle2(player->mo->x, player->mo->y, linetarget->x, linetarget->y);
    if(angle - player->mo->angle > ANG180)
    {
        if(angle - player->mo->angle < -ANG90/20)
            player->mo->angle = angle + ANG90/21;
        else
            player->mo->angle -= ANG90/20;
    }
    else
    {
        if(angle - player->mo->angle > ANG90/20)
            player->mo->angle = angle - ANG90/21;
        else
            player->mo->angle += ANG90/20;
    }

    player->mo->flags |= MF_JUSTATTACKED;
}
示例#20
0
//
// A_Punch
//
void A_Punch(player_t *player, pspdef_t *psp)
{
    int     damage = (P_Random() % 10 + 1) << 1;
    angle_t angle = player->mo->angle + ((P_Random() - P_Random()) << 18);
    int     slope = P_AimLineAttack(player->mo, angle, MELEERANGE);

    if (player->powers[pw_strength])
        damage *= 10;
    
    P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);

    if (!linetarget)
        return;

    S_StartSound(player->mo, sfx_punch);

    // turn to face target
    player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
                                        linetarget->x, linetarget->y);
}
示例#21
0
//
// A_Punch
//
DEFINE_ACTION_FUNCTION(AActor, A_Punch)
{
	angle_t 	angle;
	int 		damage;
	int 		pitch;
	AActor		*linetarget;

	if (self->player != NULL)
	{
		AWeapon *weapon = self->player->ReadyWeapon;
		if (weapon != NULL && !(weapon->WeaponFlags & WIF_DEHAMMO))
		{
			if (!weapon->DepleteAmmo (weapon->bAltFire))
				return;
		}
	}

	damage = (pr_punch()%10+1)<<1;

	if (self->FindInventory<APowerStrength>())	
		damage *= 10;

	angle = self->angle;

	angle += pr_punch.Random2() << 18;
	pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);

	P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &linetarget);

	// turn to face target
	if (linetarget)
	{
		S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);
		self->angle = R_PointToAngle2 (self->x,
										self->y,
										linetarget->x,
										linetarget->y);
	}
}
示例#22
0
OVERLAY void A_Saw(player_t *player, pspdef_t *psp)
{
  int slope, damage = 2*(P_Random(pr_saw)%10+1);
  angle_t angle = player->mo->angle;
  // killough 5/5/98: remove dependence on order of evaluation:
  int t = P_Random(pr_saw);
  angle += (t - P_Random(pr_saw))<<18;

  // Use meleerange + 1 so that the puff doesn't skip the flash
  slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1);
  P_LineAttack(player->mo, angle, MELEERANGE+1, slope, damage);

  if (!linetarget)
    {
      S_StartSound(player->mo, sfx_sawful);
      return;
    }

  S_StartSound(player->mo, sfx_sawhit);

  // turn to face target
  angle = R_PointToAngle2(player->mo->x, player->mo->y,
                          linetarget->x, linetarget->y);

  if (angle - player->mo->angle > ANG180) {
    if (angle - player->mo->angle < -ANG90/20)
      player->mo->angle = angle + ANG90/21;
    else
      player->mo->angle -= ANG90/20;
  } else {
    if (angle - player->mo->angle > ANG90/20)
      player->mo->angle = angle - ANG90/21;
    else
      player->mo->angle += ANG90/20;
  }

  player->mo->flags |= MF_JUSTATTACKED;
}
void AdjustPlayerAngle (AActor *pmo)
{
	angle_t angle;
	int difference;

	angle = R_PointToAngle2 (pmo->x, pmo->y, linetarget->x, linetarget->y);
	difference = (int)angle - (int)pmo->angle;
	if (abs(difference) > MAX_ANGLE_ADJUST)
	{
		if (difference > 0)
		{
			pmo->angle += MAX_ANGLE_ADJUST;
		}
		else
		{
			pmo->angle -= MAX_ANGLE_ADJUST;
		}
	}
	else
	{
		pmo->angle = angle;
	}
}
示例#24
0
static void MarinePunch(AActor *self, int damagemul)
{
	angle_t 	angle;
	int 		damage;
	int 		pitch;
	AActor		*linetarget;

	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	damage = ((pr_m_punch()%10+1) << 1) * damagemul;

	A_FaceTarget (self);
	angle = self->angle + (pr_m_punch.Random2() << 18);
	pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
	P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true);

	// turn to face target
	if (linetarget)
	{
		S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "*fist", 1, ATTN_NORM );

		self->angle = R_PointToAngle2 (self->x, self->y, linetarget->x, linetarget->y);
	}
}
示例#25
0
bool APathFollower::Interpolate ()
{
	fixed_t dx = 0, dy = 0, dz = 0;

	if ((args[2] & 8) && Time > 0.f)
	{
		dx = x;
		dy = y;
		dz = z;
	}

	if (CurrNode->Next==NULL) return false;

	UnlinkFromWorld ();
	if (args[2] & 1)
	{	// linear
		x = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->x), FIXED2FLOAT(CurrNode->Next->x)));
		y = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->y), FIXED2FLOAT(CurrNode->Next->y)));
		z = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->z), FIXED2FLOAT(CurrNode->Next->z)));
	}
	else
	{	// spline
		if (CurrNode->Next->Next==NULL) return false;

		x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->x), FIXED2FLOAT(CurrNode->x),
								FIXED2FLOAT(CurrNode->Next->x), FIXED2FLOAT(CurrNode->Next->Next->x)));
		y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->y), FIXED2FLOAT(CurrNode->y),
								FIXED2FLOAT(CurrNode->Next->y), FIXED2FLOAT(CurrNode->Next->Next->y)));
		z = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->z), FIXED2FLOAT(CurrNode->z),
								FIXED2FLOAT(CurrNode->Next->z), FIXED2FLOAT(CurrNode->Next->Next->z)));
	}
	LinkToWorld ();

	if (args[2] & 6)
	{
		if (args[2] & 8)
		{
			if (args[2] & 1)
			{ // linear
				dx = CurrNode->Next->x - CurrNode->x;
				dy = CurrNode->Next->y - CurrNode->y;
				dz = CurrNode->Next->z - CurrNode->z;
			}
			else if (Time > 0.f)
			{ // spline
				dx = x - dx;
				dy = y - dy;
				dz = z - dz;
			}
			else
			{
				int realarg = args[2];
				args[2] &= ~(2|4|8);
				Time += 0.1f;
				dx = x;
				dy = y;
				dz = z;
				Interpolate ();
				Time -= 0.1f;
				args[2] = realarg;
				dx = x - dx;
				dy = y - dy;
				dz = z - dz;
				x -= dx;
				y -= dy;
				z -= dz;
			}
			if (args[2] & 2)
			{ // adjust yaw
				angle = R_PointToAngle2 (0, 0, dx, dy);
			}
			if (args[2] & 4)
			{ // adjust pitch; use floats for precision
				float fdx = FIXED2FLOAT(dx);
				float fdy = FIXED2FLOAT(dy);
				float fdz = FIXED2FLOAT(-dz);
				float dist = (float)sqrt (fdx*fdx + fdy*fdy);
				float ang = dist != 0.f ? (float)atan2 (fdz, dist) : 0;
				pitch = (angle_t)(ang * 2147483648.f / PI);
			}
		}
		else
		{
			if (args[2] & 2)
			{ // interpolate angle
				float angle1 = (float)CurrNode->angle;
				float angle2 = (float)CurrNode->Next->angle;
				if (angle2 - angle1 <= -2147483648.f)
				{
					float lerped = Lerp (angle1, angle2 + 4294967296.f);
					if (lerped >= 4294967296.f)
					{
						angle = (angle_t)(lerped - 4294967296.f);
					}
					else
					{
						angle = (angle_t)lerped;
					}
				}
				else if (angle2 - angle1 >= 2147483648.f)
				{
					float lerped = Lerp (angle1, angle2 - 4294967296.f);
					if (lerped < 0.f)
					{
						angle = (angle_t)(lerped + 4294967296.f);
					}
					else
					{
						angle = (angle_t)lerped;
					}
				}
				else
				{
					angle = (angle_t)Lerp (angle1, angle2);
				}
			}
			if (args[2] & 1)
			{ // linear
				if (args[2] & 4)
				{ // interpolate pitch
					pitch = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->pitch), FIXED2FLOAT(CurrNode->Next->pitch)));
				}
			}
			else
			{ // spline
				if (args[2] & 4)
				{ // interpolate pitch
					pitch = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->pitch), FIXED2FLOAT(CurrNode->pitch),
						FIXED2FLOAT(CurrNode->Next->pitch), FIXED2FLOAT(CurrNode->Next->Next->pitch)));
				}
			}
		}
	}

	return true;
}
示例#26
0
文件: p_dialog.c 项目: derek57/WIP
//
// P_DialogStart
//
// villsa [STRIFE] New function
//
void P_DialogStart(player_t *player)
{
    int i = 0;
    int pic;
    int rnd = 0;
    char* byetext;
    int jumptoconv;

    if(menuactive || netgame)
        return;

    // are we facing towards our NPC?
    P_AimLineAttack(player->mo, player->mo->angle, (128*FRACUNIT));
    if(!linetarget)
    {
        P_AimLineAttack(player->mo, player->mo->angle + (ANG90/16), (128*FRACUNIT));
        if(!linetarget)
            P_AimLineAttack(player->mo, player->mo->angle - (ANG90/16), (128*FRACUNIT));
    }

    if(!linetarget)
       return;

    // already in combat, can't talk to it
    if(linetarget->flags & MF_NODIALOG)
       return;

    // set pointer to the character talking
    dialogtalker = linetarget;

    // play a sound
    if(player == &players[consoleplayer])
       S_StartSound(0, sfx_radio);

    linetarget->target = player->mo;         // target the player
    dialogtalker->reactiontime = 2;          // set reactiontime
    dialogtalkerangle = dialogtalker->angle; // remember original angle

    // face talker towards player
    A_FaceTarget(dialogtalker);

    // face towards NPC's direction
    player->mo->angle = R_PointToAngle2(player->mo->x,
                                        player->mo->y,
                                        dialogtalker->x,
                                        dialogtalker->y);
    // set pointer to player talking
    dialogplayer = player;

    // haleyjd 09/08/10: get any stored dialog state from this object
    jumptoconv = linetarget->miscdata;

    // check item requirements
    while(1)
    {
        int i = 0;
        currentdialog = P_DialogFind(linetarget->type, jumptoconv);

        // dialog's jumptoconv equal to 0? There's nothing to jump to.
        if(currentdialog->jumptoconv == 0)
            break;

        // villsa 09/08/10: converted into for loop
        for(i = 0; i < MDLG_MAXITEMS; i++)
        {
            // if the item is non-zero, the player must have at least one in his
            // or her inventory
            if(currentdialog->checkitem[i] != 0 &&
                P_PlayerHasItem(dialogplayer, currentdialog->checkitem[i]) < 1)
                break;
        }

        if(i < MDLG_MAXITEMS) // didn't find them all? this is our dialog!
            break;

        jumptoconv = currentdialog->jumptoconv;
    }

    M_DialogDimMsg(20, 28, currentdialog->text, false);
    dialogtext = P_DialogGetMsg(currentdialog->text);

    // get states
    dialogtalkerstates = P_DialogGetStates(linetarget->type);

    // have talker greet the player
    if(dialogtalkerstates->greet)
        P_SetMobjState(dialogtalker, dialogtalkerstates->greet);

    // get talker's name
    if(currentdialog->name[0])
        dialogname = currentdialog->name;
    else
    {
        // use a fallback:
        if(mobjinfo[linetarget->type].name)
            dialogname = DEH_String(mobjinfo[linetarget->type].name); // mobjtype name
        else
            dialogname = DEH_String("Person"); // default name - like Joe in Doom 3 :P
    }

    // setup number of choices to choose from
    for(i = 0; i < MDLG_MAXCHOICES; i++)
    {
        if(!currentdialog->choices[i].giveitem)
            break;
    }

    // set number of choices to menu
    dialogmenu.numitems = i + 1;

    rnd = M_Random() % 3;

    // setup dialog menu
    M_StartControlPanel();
    menupause = false;
    menuindialog = true;
    menupausetime = gametic + 17;
    currentMenu = &dialogmenu;

    if(i >= dialogmenu.lastOn)
        itemOn = dialogmenu.lastOn;
    else
        itemOn = 0;

    // get backdrop
    pic = W_CheckNumForName(currentdialog->backpic);
    dialogbgpiclumpnum = pic;
    if(pic != -1)
        V_DrawPatchDirect(0, 0, W_CacheLumpNum(pic, PU_CACHE));

    // get voice
    I_StartVoice(currentdialog->voice);

    // get bye text
    switch(rnd)
    {
    case 2:
        byetext = DEH_String("BYE!");
        break;
    case 1:
        byetext = DEH_String("Thanks, Bye!");
        break;
    default:
    case 0:
        byetext = DEH_String("See you later!");
        break;
    }

    DEH_snprintf(dialoglastmsgbuffer, sizeof(dialoglastmsgbuffer),
                 "%d) %s", i + 1, byetext);
}
示例#27
0
文件: p_dialog.c 项目: derek57/WIP
//
// P_DialogDrawer
//
// This function is set as the drawer callback for the dialog menu.
//
static void P_DialogDrawer(void)
{
    angle_t angle;
    int y;
    int i;
    int height;
    int finaly;
    char choicetext[64];
    char choicetext2[64];

    // Run down bonuscount faster than usual so that flashes from being given
    // items are less obvious.
    if(dialogplayer->bonuscount)
    {
        dialogplayer->bonuscount -= 3;
        if(dialogplayer->bonuscount < 0)
            dialogplayer->bonuscount = 0;
    }

    angle = R_PointToAngle2(dialogplayer->mo->x,
                            dialogplayer->mo->y,
                            dialogtalker->x,
                            dialogtalker->y);
    angle -= dialogplayer->mo->angle;

    // Dismiss the dialog if the player is out of alignment, or the thing he was
    // talking to is now engaged in battle.
    if ((angle > ANG45 && angle < (ANG270+ANG45))
     || (dialogtalker->flags & MF_NODIALOG) != 0)
    {
        P_DialogDoChoice(dialogmenu.numitems - 1);
    }

    dialogtalker->reactiontime = 2;

    // draw background
    if(dialogbgpiclumpnum != -1)
    {
        patch_t *patch = W_CacheLumpNum(dialogbgpiclumpnum, PU_CACHE);
        V_DrawPatchDirect(0, 0, patch);
    }

    // if there's a valid background pic, delay drawing the rest of the menu 
    // for a while; otherwise, it will appear immediately
    if(dialogbgpiclumpnum == -1 || menupausetime <= gametic)
    {
        if(menuindialog)
        {
            // time to pause the game?
            if(menupausetime + 3 < gametic)
                menupause = true;
        }

        // draw character name
        M_WriteText(12, 18, dialogname);
        y = 28;

        // show text (optional for dialogs with voices)
        if(dialogshowtext || currentdialog->voice[0] == '\0')
            y = M_WriteText(20, 28, dialogtext);

        height = 20 * dialogmenu.numitems;

        finaly = 175 - height;     // preferred height
        if(y > finaly)
            finaly = 199 - height; // height it will bump down to if necessary.

        // draw divider
        M_WriteText(42, finaly - 6, DEH_String("______________________________"));

        dialogmenu.y = finaly + 6;
        y = 0;

        // draw the menu items
        for(i = 0; i < dialogmenu.numitems - 1; i++)
        {
            DEH_snprintf(choicetext, sizeof(choicetext),
                         "%d) %s", i + 1, currentdialog->choices[i].text);
            
            // alternate text for items that need money
            if(currentdialog->choices[i].needamounts[0] > 0)
            {
                // haleyjd 20120401: necessary to avoid undefined behavior:
                M_StringCopy(choicetext2, choicetext, sizeof(choicetext2));
                DEH_snprintf(choicetext, sizeof(choicetext),
                             "%s for %d", choicetext2,
                             currentdialog->choices[i].needamounts[0]);
            }

            M_WriteText(dialogmenu.x, dialogmenu.y + 3 + y, choicetext);
            y += 19;
        }

        // draw the final item for dismissing the dialog
        M_WriteText(dialogmenu.x, 19 * i + dialogmenu.y + 3, dialoglastmsgbuffer);
    }
}
示例#28
0
文件: st_stuff.c 项目: Vraiment/VROOM
//
// This is a not-very-pretty routine which handles
//  the face states and their timing.
// the precedence of expressions is:
//  dead > evil grin > turned head > straight ahead
//
void ST_updateFaceWidget(void)
{
    int		i;
    angle_t	badguyangle;
    angle_t	diffang;
    static int	lastattackdown = -1;
    static int	priority = 0;
    boolean	doevilgrin;

    if (priority < 10)
    {
	// dead
	if (!plyr->health)
	{
	    priority = 9;
	    st_faceindex = ST_DEADFACE;
	    st_facecount = 1;
	}
    }

    if (priority < 9)
    {
	if (plyr->bonuscount)
	{
	    // picking up bonus
	    doevilgrin = false;

	    for (i=0;i<NUMWEAPONS;i++)
	    {
		if (oldweaponsowned[i] != plyr->weaponowned[i])
		{
		    doevilgrin = true;
		    oldweaponsowned[i] = plyr->weaponowned[i];
		}
	    }
	    if (doevilgrin) 
	    {
		// evil grin if just picked up weapon
		priority = 8;
		st_facecount = ST_EVILGRINCOUNT;
		st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
	    }
	}

    }
  
    if (priority < 8)
    {
	if (plyr->damagecount
	    && plyr->attacker
	    && plyr->attacker != plyr->mo)
	{
	    // being attacked
	    priority = 7;
	    
	    if (plyr->health - st_oldhealth > ST_MUCHPAIN)
	    {
		st_facecount = ST_TURNCOUNT;
		st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
	    }
	    else
	    {
		badguyangle = R_PointToAngle2(plyr->mo->x,
					      plyr->mo->y,
					      plyr->attacker->x,
					      plyr->attacker->y);
		
		if (badguyangle > plyr->mo->angle)
		{
		    // whether right or left
		    diffang = badguyangle - plyr->mo->angle;
		    i = diffang > ANG180; 
		}
		else
		{
		    // whether left or right
		    diffang = plyr->mo->angle - badguyangle;
		    i = diffang <= ANG180; 
		} // confusing, aint it?

		
		st_facecount = ST_TURNCOUNT;
		st_faceindex = ST_calcPainOffset();
		
		if (diffang < ANG45)
		{
		    // head-on    
		    st_faceindex += ST_RAMPAGEOFFSET;
		}
		else if (i)
		{
		    // turn face right
		    st_faceindex += ST_TURNOFFSET;
		}
		else
		{
		    // turn face left
		    st_faceindex += ST_TURNOFFSET+1;
		}
	    }
	}
    }
  
    if (priority < 7)
    {
	// getting hurt because of your own damn stupidity
	if (plyr->damagecount)
	{
	    if (plyr->health - st_oldhealth > ST_MUCHPAIN)
	    {
		priority = 7;
		st_facecount = ST_TURNCOUNT;
		st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
	    }
	    else
	    {
		priority = 6;
		st_facecount = ST_TURNCOUNT;
		st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
	    }

	}

    }
  
    if (priority < 6)
    {
	// rapid firing
	if (plyr->attackdown)
	{
	    if (lastattackdown==-1)
		lastattackdown = ST_RAMPAGEDELAY;
	    else if (!--lastattackdown)
	    {
		priority = 5;
		st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
		st_facecount = 1;
		lastattackdown = 1;
	    }
	}
	else
	    lastattackdown = -1;

    }
  
    if (priority < 5)
    {
	// invulnerability
	if ((plyr->cheats & CF_GODMODE)
	    || plyr->powers[pw_invulnerability])
	{
	    priority = 4;

	    st_faceindex = ST_GODFACE;
	    st_facecount = 1;

	}

    }

    // look left or look right if the facecount has timed out
    if (!st_facecount)
    {
	st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3);
	st_facecount = ST_STRAIGHTFACECOUNT;
	priority = 0;
    }

    st_facecount--;

}
示例#29
0
DEFINE_ACTION_FUNCTION(AActor, A_M_Saw)
{
	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	A_FaceTarget (self);
	if (self->CheckMeleeRange ())
	{
		angle_t 	angle;
		int 		damage;
		AActor		*linetarget;

		damage = 2 * (pr_m_saw()%10+1);
		angle = self->angle + (pr_m_saw.Random2() << 18);
		
		P_LineAttack (self, angle, MELEERANGE+1,
					P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage,
					NAME_Melee, NAME_BulletPuff);

		if (!linetarget)
		{
			S_Sound (self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM);

			// [BC] If we're the server, tell clients to play this sound.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM );
			return;
		}
		S_Sound (self, CHAN_WEAPON, "weapons/sawhit", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawhit", 1, ATTN_NORM );
			
		// turn to face target
		angle = R_PointToAngle2 (self->x, self->y, linetarget->x, linetarget->y);
		if (angle - self->angle > ANG180)
		{
			if (angle - self->angle < (angle_t)(-ANG90/20))
				self->angle = angle + ANG90/21;
			else
				self->angle -= ANG90/20;
		}
		else
		{
			if (angle - self->angle > ANG90/20)
				self->angle = angle - ANG90/21;
			else
				self->angle += ANG90/20;
		}
	}
	else
	{
		S_Sound (self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM );
	}
	//A_Chase (self);
}
示例#30
0
void P_StartConversation (AActor *npc, AActor *pc)
{
	FStrifeDialogueReply *reply;
	menuitem_t item;
	const char *toSay;
	int i, j;

	pc->momx = pc->momy = 0;	// Stop moving
	pc->player->momx = pc->player->momy = 0;

	if (pc->player - players != consoleplayer)
		return;

	ConversationPC = pc;
	ConversationNPC = npc;

	CurNode = npc->Conversation;

	if (pc->player == &players[consoleplayer])
	{
		S_Sound (CHAN_VOICE, "misc/chat", 1, ATTN_NONE);
	}

	npc->reactiontime = 2;
	if (!(npc->flags & MF_FRIENDLY) && !(npc->flags4 & MF4_NOHATEPLAYERS))
	{
		npc->target = pc;
	}
	ConversationNPCAngle = npc->angle;
	A_FaceTarget (npc);
	pc->angle = R_PointToAngle2 (pc->x, pc->y, npc->x, npc->y);

	// Check if we should jump to another node
	while (CurNode->ItemCheck[0] != NULL)
	{
		if (CheckStrifeItem (CurNode->ItemCheck[0]) &&
			CheckStrifeItem (CurNode->ItemCheck[1]) &&
			CheckStrifeItem (CurNode->ItemCheck[2]))
		{
			int root = FindNode (ConversationNPC->GetDefault()->Conversation);
			CurNode = StrifeDialogues[root + CurNode->ItemCheckNode - 1];
		}
		else
		{
			break;
		}
	}

	if (CurNode->SpeakerVoice != 0)
	{
		S_SoundID (npc, CHAN_VOICE, CurNode->SpeakerVoice, 1, ATTN_NORM);
	}

	// Set up the menu
	ConversationMenu.PreDraw = DrawConversationMenu;
	ConversationMenu.EscapeHandler = CleanupConversationMenu;

	// Format the speaker's message.
	toSay = CurNode->Dialogue;
	if (strncmp (toSay, "RANDOM_", 7) == 0)
	{
		for (i = 0; i < NUM_RANDOM_TALKERS; ++i)
		{
			if (strcmp (RandomLines[i][0], toSay + 7) == 0)
			{
				toSay = RandomLines[i][1 + (pr_randomspeech() % NUM_RANDOM_LINES)];
				break;
			}
		}
	}
	DialogueLines = V_BreakLines (screen->GetWidth()/CleanXfac-24*2, toSay);

	// Fill out the possible choices
	ShowGold = false;
	item.type = numberedmore;
	item.e.mfunc = PickConversationReply;
	for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
	{
		if (reply->Reply == NULL)
		{
			continue;
		}
		ShowGold |= reply->NeedsGold;
		reply->ReplyLines = V_BreakLines (320-50-10, reply->Reply);
		for (j = 0; reply->ReplyLines[j].width != -1; ++j)
		{
			item.label = reply->ReplyLines[j].string;
			item.b.position = j == 0 ? i : 0;
			item.c.extra = reply;
			ConversationItems.Push (item);
		}
		++i;
	}
	item.label = RandomGoodbyes[pr_randomspeech() % NUM_RANDOM_GOODBYES];
	item.b.position = i;
	item.c.extra = NULL;
	ConversationItems.Push (item);

	// Determine where the top of the reply list should be positioned.
	i = (gameinfo.gametype & GAME_Raven) ? 9 : 8;
	ConversationMenu.y = MIN<int> (140, 192 - ConversationItems.Size() * i);
	for (i = 0; DialogueLines[i].width != -1; ++i)
	{ }
	i = 44 + i * 10;
	if (ConversationMenu.y - 100 < i - screen->GetHeight() / CleanYfac / 2)
	{
		ConversationMenu.y = i - screen->GetHeight() / CleanYfac / 2 + 100;
	}
	ConversationMenu.indent = 50;

	// Finish setting up the menu
	ConversationMenu.items = &ConversationItems[0];
	ConversationMenu.numitems = ConversationItems.Size();
	if (CurNode != PrevNode)
	{ // Only reset the selection if showing a different menu.
		ConversationMenu.lastOn = 0;
		PrevNode = CurNode;
	}
	ConversationMenu.DontDim = true;

	// And open the menu
	M_StartControlPanel (false);
	OptionsActive = true;
	menuactive = MENU_OnNoPause;
	ConversationPauseTic = gametic + 20;
	M_SwitchMenu (&ConversationMenu);
}